fleet/cmd/gitops-migrate/cmd_usage.go
Anthony Maxwell 288ea58bce
Feat: GitOps YAML Migration Tool (#32237)
# Overview

This pull request resolves #31165, implementing command-line tooling to
migrate GitOps YAML files following the [changes introduced in the
upcoming 4.74
release](https://github.com/fleetdm/fleet/pull/32237/files#diff-8769f6e90e8bdf15faad8f390fdf3ffb6fd2238b7d6087d83518c21464109119R7).

Aligning with the recommended steps in the `README`; [this is an example
of the first step](https://github.com/Illbjorn/fleet/pull/3/files)
(`gitops-migrate format`) and [this is an example of the second
step](https://github.com/Illbjorn/fleet/pull/4/files) (`gitops-migrate
migrate`).

---------

Signed-off-by: Illbjorn <am@hades.so>
Co-authored-by: Ian Littman <iansltx@gmail.com>
2025-09-08 12:42:25 -04:00

135 lines
3.8 KiB
Go

package main
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"text/template"
"github.com/fleetdm/fleet/v4/cmd/gitops-migrate/ansi"
"github.com/fleetdm/fleet/v4/cmd/gitops-migrate/log"
)
const (
cmdUsage = "usage"
cmdHelp = "help"
)
// output is the io.Writer used by the usage commands to output the help text
// once generated.
var output = io.Writer(os.Stderr)
func cmdUsageExec(_ context.Context, _ Args) error {
showUsageAndExit(0, "")
return nil
}
func showUsageAndExit(exitCode int, msg string, values ...any) {
// Init the 'strings.Builder' to compose our error message and usage text.
sb := new(strings.Builder)
// Format and print the provided message, if we received one.
if msg != "" {
fmt.Fprint(sb, ansi.Red, "ERROR: ", ansi.Reset)
fmt.Fprintf(sb, msg, values...)
fmt.Fprintln(sb)
}
// Generate the usage text.
err := usageText(sb)
if err != nil {
log.Fatalf("Failed to build usage text: %s.", err)
}
// Print the usage text and exit with the provided exit code.
fmt.Fprintln(output, sb.String())
os.Exit(exitCode)
}
type AppDetails struct {
Name string
Command string
}
var appDetails = map[string]string{
"Name": "Fleet GitOps Migration Tool",
"Command": "gitops-migrate",
}
var tmplFuncs = template.FuncMap{
"green": ansi.Colorizer(ansi.BoldGreen),
"magenta": ansi.Colorizer(ansi.BoldMagenta),
"cyan": ansi.Colorizer(ansi.BoldCyan),
"yellow": ansi.Colorizer(ansi.BoldYellow),
"pathJoin": filepath.Join,
}
var tmplText = `
{{ $gitops := (green "Fleet GitOps") -}}
{{- $changeVer := (green "4.74") -}}
Welcome to the {{ $gitops }} migration utility!
The purpose of this package is to assist with automated GitOps YAML file
transformations during the {{ $changeVer }} release.
{{ magenta ">> Commands" }}
format Formats all {{ green "Fleet GitOps" }} YAML files!
migrate Migrates a provided directory's {{ $gitops }} files.
backup Perform a backup of a target directory, output as a gzipped tarball.
restore Restore* a backup produced by the {{ green "backup" }} command.
usage Show this help text (analogous to the {{ magenta "--help" }} flag)!
{{ yellow "* NOTE:" }} Restore _will_ overwrite any existing files with the same name in
the specified output directory!
{{ magenta ">> Flags" }}
--debug Enables additional log output.
--help Show this help text (analogous to the {{ magenta "usage" }} command)!
{{ magenta ">> Examples" }}
{{ $sampleSrc := (pathJoin "." "fleet_gitops") -}}
{{- $sampleArchivePath := (pathJoin "." "fleet_backups") -}}
To perform a {{ $gitops }} migration where:
- {{ $gitops }} files reside in directory: '{{ $sampleSrc }}'.
{{ cyan "$" }} {{ magenta .Command }} migrate {{ $sampleSrc }}
To perform a backup of {{ $gitops }} files, where:
- {{ $gitops }} files reside in directory: '{{ $sampleSrc }}'.
- We want to produce a backup archive to '{{ $sampleArchivePath }}'.
{{ cyan "$" }} {{ magenta .Command }} backup {{ $sampleSrc }} {{ $sampleArchivePath }}
To restore a backup of {{ $gitops }} files, where:
- The backup archive is at: '{{ $sampleArchivePath }}'.
- We want to restore the backup archive to: '{{ $sampleSrc }}'.
{{ cyan "$" }} {{ magenta .Command }} restore {{ $sampleArchivePath }} {{ $sampleSrc }}
`
func usageText(w io.Writer) error {
// Init the template, apply custom template functions.
tmpl := template.New("usage")
tmpl.Funcs(tmplFuncs)
// Parse the template string.
var err error
tmpl, err = tmpl.Parse(tmplText)
if err != nil {
return fmt.Errorf("failed to parse 'text/template' template: %w", err)
}
// Exec the template.
err = tmpl.Execute(w, appDetails)
if err != nil {
return fmt.Errorf("failed to execute template: %w", err)
}
return nil
}