diff --git a/help_template.go b/help_template.go deleted file mode 100644 index c1cf3d4..0000000 --- a/help_template.go +++ /dev/null @@ -1,76 +0,0 @@ -package clio - -import ( - "fmt" - "reflect" - - "github.com/spf13/cobra" - - "github.com/anchore/fangs" -) - -var _ postConstruct = updateHelpUsageTemplate - -func updateHelpUsageTemplate(a *application) { - cmd := a.root - - var helpUsageTemplate = fmt.Sprintf(`{{if (or .Long .Short)}}{{.Long}}{{if not .Long}}{{.Short}}{{end}} - -{{end}}Usage:{{if (and .Runnable (ne .CommandPath "%s"))}} - {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}} - {{.CommandPath}} [command]{{end}}{{if .HasExample}} - -{{.Example}}{{end}}{{if gt (len .Aliases) 0}} - -Aliases: - {{.NameAndAliases}}{{end}}{{if .HasAvailableSubCommands}} - -Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}} - {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} - -{{if not .CommandPath}}Global {{end}}Flags: -{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if (and .HasAvailableInheritedFlags (ne .CommandPath "%s"))}} - -Global Flags: -{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}} - -Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} - {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}} - -Use "{{if .CommandPath}}{{.CommandPath}} {{end}}[command] --help" for more information about a command.{{end}} -`, a.setupConfig.ID.Name, a.setupConfig.ID.Name) - - cmd.SetUsageTemplate(helpUsageTemplate) - cmd.SetHelpTemplate(helpUsageTemplate) -} - -var _ postConstruct = showConfigInRootHelp - -func showConfigInRootHelp(a *application) { - cmd := a.root - - helpFn := cmd.HelpFunc() - cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) { - // root.Example is set _after all added commands_ because it collects all the - // options structs in order to output an accurate "config file" summary - // note: since all commands tend to share help functions it's important to only patch the example - // when there is no parent command (i.e. the root command). - if cmd == a.root { - cfgs := append([]any{&a.state.Config, a}, a.state.Config.FromCommands...) - for _, cfg := range cfgs { - // load each config individually, as there may be conflicting names / types that will cause - // viper to fail to read them all and panic - if err := fangs.Load(a.setupConfig.FangsConfig, cmd, cfg); err != nil { - t := reflect.TypeOf(cfg) - panic(fmt.Sprintf("error loading config object: `%s:%s`: %s", t.PkgPath(), t.Name(), err.Error())) - } - } - summary := a.summarizeConfig(cmd) - if a.state.RedactStore != nil { - summary = a.state.RedactStore.RedactString(summary) - } - cmd.Example = summary - } - helpFn(cmd, args) - }) -} diff --git a/help_template_test.go b/help_template_test.go deleted file mode 100644 index 54aad7e..0000000 --- a/help_template_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package clio - -import ( - "bytes" - "io" - "os" - "testing" - - "github.com/spf13/cobra" - "github.com/stretchr/testify/require" - - "github.com/anchore/go-logger/adapter/redact" -) - -func Test_redactingHelpText(t *testing.T) { - cfg := NewSetupConfig(Identification{ - Name: "app", - Version: "1.2.3", - }). - WithConfigInRootHelp(). - WithGlobalConfigFlag() - - r := &redactor{ - Value: "asdf", - redact: "asdf", - } - - app := New(*cfg) - - root := app.SetupRootCommand(&cobra.Command{}, r) - - r.store = app.(*application).state.RedactStore - - stdout, _ := captureStd(func() { _ = root.Help() }) - - require.NotContains(t, stdout, "asdf") - require.Contains(t, stdout, "value: '*******'") -} - -func captureStd(fn func()) (stdout string, stderr string) { - oldOut := os.Stdout // keep backup of the real stdout - outR, outW, _ := os.Pipe() - os.Stdout = outW - - out := make(chan string) - // copy the output in a separate goroutine so printing can't block indefinitely - go func() { - var buf bytes.Buffer - _, _ = io.Copy(&buf, outR) - out <- buf.String() - }() - - oldErr := os.Stderr // keep backup of the real stderr - errR, errW, _ := os.Pipe() - os.Stderr = errW - - err := make(chan string) - // copy the output in a separate goroutine so printing can't block indefinitely - go func() { - var buf bytes.Buffer - _, _ = io.Copy(&buf, errR) - err <- buf.String() - }() - - fn() - - // back to normal state - _ = outW.Close() - os.Stdout = oldOut // restoring the real stdout - - _ = errW.Close() - os.Stdout = oldErr // restoring the real stderr - - return <-out, <-err -} - -type redactor struct { - Value string `mapstructure:"value"` - redact string - store redact.Store -} - -func (r *redactor) PostLoad() error { - r.store.Add(r.redact) - return nil -} diff --git a/setup_config.go b/setup_config.go index a39bf93..e484e64 100644 --- a/setup_config.go +++ b/setup_config.go @@ -123,5 +123,5 @@ func (c *SetupConfig) WithGlobalLoggingFlags() *SetupConfig { } func (c *SetupConfig) WithConfigInRootHelp() *SetupConfig { - return c.withPostConstructs(updateHelpUsageTemplate, showConfigInRootHelp) + return c.withPostConstructs() }