diff options
author | a <[email protected]> | 2024-06-18 21:57:46 -0500 |
---|---|---|
committer | a <[email protected]> | 2024-06-18 21:57:46 -0500 |
commit | 7bc7e1680e79863f97bc60be44d9d0199fdda2a0 (patch) | |
tree | 8b04aa06958b704f762b1e9e768c175f6c1a2de0 | |
parent | edf4168c8e3e9659612d4e8da71944769dae0391 (diff) | |
download | caddy-7bc7e1680e79863f97bc60be44d9d0199fdda2a0.tar.gz caddy-7bc7e1680e79863f97bc60be44d9d0199fdda2a0.zip |
noot
-rw-r--r-- | cmd/cobra.go | 26 | ||||
-rw-r--r-- | cmd/commandfactory.go | 28 | ||||
-rw-r--r-- | cmd/commands.go | 53 | ||||
-rw-r--r-- | cmd/main.go | 15 |
4 files changed, 76 insertions, 46 deletions
diff --git a/cmd/cobra.go b/cmd/cobra.go index 1a2509206..5323d2ec5 100644 --- a/cmd/cobra.go +++ b/cmd/cobra.go @@ -8,9 +8,10 @@ import ( "github.com/caddyserver/caddy/v2" ) -var rootCmd = &cobra.Command{ - Use: "caddy", - Long: `Caddy is an extensible server platform written in Go. +var defaultFactory = NewRootCommandFactory(func() *cobra.Command { + return &cobra.Command{ + Use: "caddy", + Long: `Caddy is an extensible server platform written in Go. At its core, Caddy merely manages configuration. Modules are plugged in statically at compile-time to provide useful functionality. Caddy's @@ -91,23 +92,26 @@ package installers: https://caddyserver.com/docs/install Instructions for running Caddy in production are also available: https://caddyserver.com/docs/running `, - Example: ` $ caddy run + Example: ` $ caddy run $ caddy run --config caddy.json $ caddy reload --config caddy.json $ caddy stop`, - // kind of annoying to have all the help text printed out if - // caddy has an error provisioning its modules, for instance... - SilenceUsage: true, - Version: onlyVersionText(), -} + // kind of annoying to have all the help text printed out if + // caddy has an error provisioning its modules, for instance... + SilenceUsage: true, + Version: onlyVersionText(), + } +}) const fullDocsFooter = `Full documentation is available at: https://caddyserver.com/docs/command-line` func init() { - rootCmd.SetVersionTemplate("{{.Version}}\n") - rootCmd.SetHelpTemplate(rootCmd.HelpTemplate() + "\n" + fullDocsFooter + "\n") + defaultFactory.Use(func(cmd *cobra.Command) { + cmd.SetVersionTemplate("{{.Version}}\n") + cmd.SetHelpTemplate(cmd.HelpTemplate() + "\n" + fullDocsFooter + "\n") + }) } func onlyVersionText() string { diff --git a/cmd/commandfactory.go b/cmd/commandfactory.go new file mode 100644 index 000000000..49a38a4e1 --- /dev/null +++ b/cmd/commandfactory.go @@ -0,0 +1,28 @@ +package caddycmd + +import ( + "github.com/spf13/cobra" +) + +type RootCommandFactory struct { + constructor func() *cobra.Command + options []func(*cobra.Command) +} + +func NewRootCommandFactory(fn func() *cobra.Command) *RootCommandFactory { + return &RootCommandFactory{ + constructor: fn, + } +} + +func (f *RootCommandFactory) Use(fn func(cmd *cobra.Command)) { + f.options = append(f.options, fn) +} + +func (f *RootCommandFactory) Build() *cobra.Command { + o := f.constructor() + for _, v := range f.options { + v(o) + } + return o +} diff --git a/cmd/commands.go b/cmd/commands.go index e5e1265e4..7e7af1c77 100644 --- a/cmd/commands.go +++ b/cmd/commands.go @@ -459,7 +459,8 @@ argument of --directory. If the directory does not exist, it will be created. if err := os.MkdirAll(dir, 0o755); err != nil { return caddy.ExitCodeFailedQuit, err } - if err := doc.GenManTree(rootCmd, &doc.GenManHeader{ + ccmd := defaultFactory.Build() + if err := doc.GenManTree(ccmd, &doc.GenManHeader{ Title: "Caddy", Section: "8", // https://en.wikipedia.org/wiki/Man_page#Manual_sections }, dir); err != nil { @@ -471,10 +472,11 @@ argument of --directory. If the directory does not exist, it will be created. }) // source: https://github.com/spf13/cobra/blob/main/shell_completions.md - rootCmd.AddCommand(&cobra.Command{ - Use: "completion [bash|zsh|fish|powershell]", - Short: "Generate completion script", - Long: fmt.Sprintf(`To load completions: + defaultFactory.Use(func(ccmd *cobra.Command) { + ccmd.AddCommand(&cobra.Command{ + Use: "completion [bash|zsh|fish|powershell]", + Short: "Generate completion script", + Long: fmt.Sprintf(`To load completions: Bash: @@ -512,24 +514,25 @@ argument of --directory. If the directory does not exist, it will be created. # To load completions for every new session, run: PS> %[1]s completion powershell > %[1]s.ps1 # and source this file from your PowerShell profile. - `, rootCmd.Root().Name()), - DisableFlagsInUseLine: true, - ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, - Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), - RunE: func(cmd *cobra.Command, args []string) error { - switch args[0] { - case "bash": - return cmd.Root().GenBashCompletion(os.Stdout) - case "zsh": - return cmd.Root().GenZshCompletion(os.Stdout) - case "fish": - return cmd.Root().GenFishCompletion(os.Stdout, true) - case "powershell": - return cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) - default: - return fmt.Errorf("unrecognized shell: %s", args[0]) - } - }, + `, defaultFactory.constructor().Name()), + DisableFlagsInUseLine: true, + ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, + Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), + RunE: func(cmd *cobra.Command, args []string) error { + switch args[0] { + case "bash": + return cmd.Root().GenBashCompletion(os.Stdout) + case "zsh": + return cmd.Root().GenZshCompletion(os.Stdout) + case "fish": + return cmd.Root().GenFishCompletion(os.Stdout, true) + case "powershell": + return cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) + default: + return fmt.Errorf("unrecognized shell: %s", args[0]) + } + }, + }) }) } @@ -563,7 +566,9 @@ func RegisterCommand(cmd Command) { if !commandNameRegex.MatchString(cmd.Name) { panic("invalid command name") } - rootCmd.AddCommand(caddyCmdToCobra(cmd)) + defaultFactory.Use(func(ccmd *cobra.Command) { + ccmd.AddCommand(caddyCmdToCobra(cmd)) + }) } var commandNameRegex = regexp.MustCompile(`^[a-z0-9]$|^([a-z0-9]+-?[a-z0-9]*)+[a-z0-9]$`) diff --git a/cmd/main.go b/cmd/main.go index 4526b26b6..6defac756 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -34,7 +34,6 @@ import ( "time" "github.com/caddyserver/certmagic" - "github.com/spf13/cobra" "github.com/spf13/pflag" "go.uber.org/automaxprocs/maxprocs" "go.uber.org/zap" @@ -72,7 +71,7 @@ func Main() { if err != nil { caddy.Log().Warn("failed to set GOMAXPROCS", zap.Error(err)) } - + rootCmd := defaultFactory.Build() if err := rootCmd.Execute(); err != nil { var exitError *exitError if errors.As(err, &exitError) { @@ -86,15 +85,9 @@ func Main() { func MainForTesting(args ...string) error { // create a root command for testing which will not pollute the global namespace, and does not // call os.Exit(). - tmpRootCmp := cobra.Command{ - Use: rootCmd.Use, - Long: rootCmd.Long, - Example: rootCmd.Example, - SilenceUsage: rootCmd.SilenceUsage, - Version: rootCmd.Version, - } - tmpRootCmp.SetArgs(args) - if err := tmpRootCmp.Execute(); err != nil { + rootCmd := defaultFactory.Build() + rootCmd.SetArgs(args) + if err := rootCmd.Execute(); err != nil { return err } return nil |