diff --git a/cli/server.go b/cli/server.go index b625083bfc3e0..3726a17a1399a 100644 --- a/cli/server.go +++ b/cli/server.go @@ -165,62 +165,24 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. opts = cfg.Options() ) serverCmd := &clibase.Cmd{ - Use: "server", - Short: "Start a Coder server", - Options: opts, - Middleware: clibase.RequireNArgs(0), + Use: "server", + Short: "Start a Coder server", + Options: opts, + Middleware: clibase.Chain( + writeConfigMW(cfg), + printDeprecatedOptions(), + clibase.RequireNArgs(0), + ), Handler: func(inv *clibase.Invocation) error { // Main command context for managing cancellation of running // services. ctx, cancel := context.WithCancel(inv.Context()) defer cancel() - if cfg.WriteConfig { - n, err := opts.MarshalYAML() - if err != nil { - return xerrors.Errorf("generate yaml: %w", err) - } - enc := yaml.NewEncoder(inv.Stdout) - enc.SetIndent(2) - err = enc.Encode(n) - if err != nil { - return xerrors.Errorf("encode yaml: %w", err) - } - err = enc.Close() - if err != nil { - return xerrors.Errorf("close yaml encoder: %w", err) - } - return nil - } - if cfg.Config != "" { cliui.Warnf(inv.Stderr, "YAML support is experimental and offers no compatibility guarantees.") } - // Print deprecation warnings. - for _, opt := range opts { - if opt.UseInstead == nil { - continue - } - - if opt.Value.String() == opt.Default { - 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, - ) - } - go dumpHandler(ctx) // Validate bind addresses. @@ -1222,6 +1184,71 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. return serverCmd } +// printDeprecatedOptions loops through all command options, and prints +// a warning for usage of deprecated options. +func printDeprecatedOptions() clibase.MiddlewareFunc { + return func(next clibase.HandlerFunc) clibase.HandlerFunc { + return func(inv *clibase.Invocation) error { + opts := inv.Command.Options + // Print deprecation warnings. + for _, opt := range opts { + if opt.UseInstead == nil { + continue + } + + if opt.Value.String() == opt.Default { + 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. +func writeConfigMW(cfg *codersdk.DeploymentValues) clibase.MiddlewareFunc { + return func(next clibase.HandlerFunc) clibase.HandlerFunc { + return func(inv *clibase.Invocation) error { + if !cfg.WriteConfig { + return next(inv) + } + + opts := inv.Command.Options + n, err := opts.MarshalYAML() + if err != nil { + return xerrors.Errorf("generate yaml: %w", err) + } + enc := yaml.NewEncoder(inv.Stdout) + enc.SetIndent(2) + err = enc.Encode(n) + if err != nil { + return xerrors.Errorf("encode yaml: %w", err) + } + err = enc.Close() + if err != nil { + return xerrors.Errorf("close yaml encoder: %w", err) + } + return nil + } + } +} + // isLocalURL returns true if the hostname of the provided URL appears to // resolve to a loopback address. func isLocalURL(ctx context.Context, u *url.URL) (bool, error) {