From ce908403aeebafd069e92d8c09b0a5f7f6dbf18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Matczuk?= Date: Fri, 17 Mar 2023 14:22:00 +0100 Subject: [PATCH] utils/cobrautil/templates: improve flags printing This patch slightly changes the kubectl based flag output to be more similar to curl help. Changes: * Use quoted name for value description - like in curl * Use (default XXX) - like in the stock cobra output * Add (env FORWARDER_XXX) - this is Forwarder specific, it simplifies working with containers and Systemd where flags are specified as environment variables. Sample output: -n, --dns-server (env FORWARDER_DNS_SERVER) DNS server(s) to use instead of system default, format: [:] (default port is 53). If specified multiple times, the first one is used as primary server, the rest are used as a fallback. --dns-timeout duration (default 5s) (env FORWARDER_DNS_TIMEOUT) Timeout for dialing DNS servers. --- cmd/forwarder/root.go | 10 ----- .../cobrautil/templates/help_flags_printer.go | 40 +++++++++++++++++-- utils/cobrautil/templates/templater.go | 13 ++---- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/cmd/forwarder/root.go b/cmd/forwarder/root.go index 5adf7b8d..9375d3b1 100644 --- a/cmd/forwarder/root.go +++ b/cmd/forwarder/root.go @@ -45,15 +45,5 @@ func rootCommand() *cobra.Command { version.Command(), ) - decorate(cmd) - return cmd } - -func decorate(cmd *cobra.Command) { - cobrautil.AppendEnvToUsage(cmd, envPrefix) - - for _, cmd := range cmd.Commands() { - decorate(cmd) - } -} diff --git a/utils/cobrautil/templates/help_flags_printer.go b/utils/cobrautil/templates/help_flags_printer.go index fdfdf08e..f102ea0f 100644 --- a/utils/cobrautil/templates/help_flags_printer.go +++ b/utils/cobrautil/templates/help_flags_printer.go @@ -32,14 +32,16 @@ const offset = 10 // processes the help flag and print // it to i/o writer type HelpFlagPrinter struct { + envPrefix string wrapLimit uint out io.Writer } // NewHelpFlagPrinter will initialize a HelpFlagPrinter given the // i/o writer -func NewHelpFlagPrinter(out io.Writer, wrapLimit uint) *HelpFlagPrinter { +func NewHelpFlagPrinter(out io.Writer, envPrefix string, wrapLimit uint) *HelpFlagPrinter { return &HelpFlagPrinter{ + envPrefix: envPrefix, wrapLimit: wrapLimit, out: out, } @@ -48,7 +50,7 @@ func NewHelpFlagPrinter(out io.Writer, wrapLimit uint) *HelpFlagPrinter { // PrintHelpFlag will beautify the help flags and print it out to p.out func (p *HelpFlagPrinter) PrintHelpFlag(flag *flag.Flag) { formatBuf := new(bytes.Buffer) - writeFlag(formatBuf, flag) + writeFlag(formatBuf, flag, p.envPrefix) wrappedStr := formatBuf.String() flagAndUsage := strings.Split(formatBuf.String(), "\n") @@ -67,10 +69,40 @@ func (p *HelpFlagPrinter) PrintHelpFlag(flag *flag.Flag) { // writeFlag will output the help flag based // on the format provided by getFlagFormat to i/o writer -func writeFlag(out io.Writer, f *flag.Flag) { +func writeFlag(out io.Writer, f *flag.Flag, envPrefix string) { + val, usage := flag.UnquoteUsage(f) + if val == "string" { + val = "" + } + if val != "" { + val = " " + val + } + + def := f.DefValue + if def == "[]" { + def = "" + } + if def != "" { + if f.Value.Type() == "string" { + def = fmt.Sprintf(" (default '%s')", f.DefValue) + } else { + def = fmt.Sprintf(" (default %s)", f.DefValue) + } + } + deprecated := "" if f.Deprecated != "" { deprecated = fmt.Sprintf(" (DEPRECATED: %s)", f.Deprecated) } - fmt.Fprintf(out, getFlagFormat(f), f.Shorthand, f.Name, f.DefValue, f.Usage, deprecated) + + env := fmt.Sprintf(" (env %s)", envName(envPrefix, f.Name)) + + fmt.Fprintf(out, getFlagFormat(f), f.Shorthand, f.Name, val, def, env, usage, deprecated) +} + +func envName(envPrefix, flagName string) string { + name := flagName + name = strings.ReplaceAll(name, "-", "_") + name = fmt.Sprintf("%s_%s", envPrefix, name) + return strings.ToUpper(name) } diff --git a/utils/cobrautil/templates/templater.go b/utils/cobrautil/templates/templater.go index 51c6ced5..f246c145 100644 --- a/utils/cobrautil/templates/templater.go +++ b/utils/cobrautil/templates/templater.go @@ -125,7 +125,7 @@ func (templater *templater) templateFuncs(exposedFlags ...string) template.FuncM "appendIfNotPresent": appendIfNotPresent, "flagsNotIntersected": flagsNotIntersected, "visibleFlags": visibleFlags, - "flagsUsages": flagsUsages, + "flagsUsages": templater.flagsUsages, "cmdGroups": templater.cmdGroups, "cmdGroupsString": templater.cmdGroupsString, "rootCmd": templater.rootCmdName, @@ -225,9 +225,9 @@ func (t *templater) usageLine(c *cobra.Command) string { } // flagsUsages will print out the kubectl help flags -func flagsUsages(f *flag.FlagSet) (string, error) { +func (t *templater) flagsUsages(f *flag.FlagSet) (string, error) { flagBuf := new(bytes.Buffer) - printer := NewHelpFlagPrinter(flagBuf, DefaultWrapLimit) + printer := NewHelpFlagPrinter(flagBuf, t.RootCmd.Name(), DefaultWrapLimit) f.VisitAll(func(flag *flag.Flag) { if flag.Hidden { @@ -241,12 +241,7 @@ func flagsUsages(f *flag.FlagSet) (string, error) { // getFlagFormat will output the flag format func getFlagFormat(f *flag.Flag) string { - var format string - format = "--%s=%s:\n%s%s" - if f.Value.Type() == "string" { - format = "--%s='%s':\n%s%s" - } - + format := "--%s%s%s%s\n%s%s" if len(f.Shorthand) > 0 { format = " -%s, " + format } else {