From 1c08580f2358acd21f868a11d7460cc385278847 Mon Sep 17 00:00:00 2001 From: Ethan <39577870+ethanndickson@users.noreply.github.com> Date: Tue, 19 Nov 2024 21:15:38 +1100 Subject: [PATCH] chore(cli): use option source name for deprecation warnings (#15581) Closes #15568. --- cli/root.go | 71 +++++++++++++++++++++++++++++++++++ cli/server.go | 36 ------------------ enterprise/cli/proxyserver.go | 1 - 3 files changed, 71 insertions(+), 37 deletions(-) diff --git a/cli/root.go b/cli/root.go index 9f9028c072..3f674db6d2 100644 --- a/cli/root.go +++ b/cli/root.go @@ -325,6 +325,15 @@ func (r *RootCmd) Command(subcommands []*serpent.Command) (*serpent.Command, err } }) + // Add the PrintDeprecatedOptions middleware to all commands. + cmd.Walk(func(cmd *serpent.Command) { + if cmd.Middleware == nil { + cmd.Middleware = PrintDeprecatedOptions() + } else { + cmd.Middleware = serpent.Chain(cmd.Middleware, PrintDeprecatedOptions()) + } + }) + if r.agentURL == nil { r.agentURL = new(url.URL) } @@ -1307,3 +1316,65 @@ func headerTransport(ctx context.Context, serverURL *url.URL, header []string, h } return transport, nil } + +// printDeprecatedOptions loops through all command options, and prints +// a warning for usage of deprecated options. +func PrintDeprecatedOptions() serpent.MiddlewareFunc { + return func(next serpent.HandlerFunc) serpent.HandlerFunc { + return func(inv *serpent.Invocation) error { + opts := inv.Command.Options + // Print deprecation warnings. + for _, opt := range opts { + if opt.UseInstead == nil { + continue + } + + if opt.ValueSource == serpent.ValueSourceNone || opt.ValueSource == serpent.ValueSourceDefault { + continue + } + + var warnStr strings.Builder + _, _ = warnStr.WriteString(translateSource(opt.ValueSource, opt)) + _, _ = warnStr.WriteString(" is deprecated, please use ") + for i, use := range opt.UseInstead { + _, _ = warnStr.WriteString(translateSource(opt.ValueSource, use)) + if i != len(opt.UseInstead)-1 { + _, _ = warnStr.WriteString(" and ") + } + } + _, _ = warnStr.WriteString(" instead.\n") + + cliui.Warn(inv.Stderr, + warnStr.String(), + ) + } + + return next(inv) + } + } +} + +// translateSource provides the name of the source of the option, depending on the +// supplied target ValueSource. +func translateSource(target serpent.ValueSource, opt serpent.Option) string { + switch target { + case serpent.ValueSourceFlag: + return fmt.Sprintf("`--%s`", opt.Flag) + case serpent.ValueSourceEnv: + return fmt.Sprintf("`%s`", opt.Env) + case serpent.ValueSourceYAML: + return fmt.Sprintf("`%s`", fullYamlName(opt)) + default: + return opt.Name + } +} + +func fullYamlName(opt serpent.Option) string { + var full strings.Builder + for _, name := range opt.Group.Ancestry() { + _, _ = full.WriteString(name.YAML) + _, _ = full.WriteString(".") + } + _, _ = full.WriteString(opt.YAML) + return full.String() +} diff --git a/cli/server.go b/cli/server.go index d678eb49c8..5962a71ca7 100644 --- a/cli/server.go +++ b/cli/server.go @@ -294,7 +294,6 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. Options: opts, Middleware: serpent.Chain( WriteConfigMW(vals), - PrintDeprecatedOptions(), serpent.RequireNArgs(0), ), Handler: func(inv *serpent.Invocation) error { @@ -1240,41 +1239,6 @@ func templateHelpers(options *coderd.Options) map[string]any { } } -// printDeprecatedOptions loops through all command options, and prints -// a warning for usage of deprecated options. -func PrintDeprecatedOptions() serpent.MiddlewareFunc { - return func(next serpent.HandlerFunc) serpent.HandlerFunc { - return func(inv *serpent.Invocation) error { - opts := inv.Command.Options - // Print deprecation warnings. - for _, opt := range opts { - if opt.UseInstead == nil { - continue - } - - if opt.ValueSource == serpent.ValueSourceNone || opt.ValueSource == serpent.ValueSourceDefault { - continue - } - - warnStr := opt.Name + " is deprecated, please use " - for i, use := range opt.UseInstead { - warnStr += use.Name + " " - if i != len(opt.UseInstead)-1 { - warnStr += "and " - } - } - warnStr += "instead.\n" - - cliui.Warn(inv.Stderr, - warnStr, - ) - } - - return next(inv) - } - } -} - // writeConfigMW will prevent the main command from running if the write-config // flag is set. Instead, it will marshal the command options to YAML and write // them to stdout. diff --git a/enterprise/cli/proxyserver.go b/enterprise/cli/proxyserver.go index 686055039b..758c52a8ff 100644 --- a/enterprise/cli/proxyserver.go +++ b/enterprise/cli/proxyserver.go @@ -110,7 +110,6 @@ func (r *RootCmd) proxyServer() *serpent.Command { Options: opts, Middleware: serpent.Chain( cli.WriteConfigMW(cfg), - cli.PrintDeprecatedOptions(), serpent.RequireNArgs(0), ), Handler: func(inv *serpent.Invocation) error {