1
Fork 0
mirror of https://github.com/caddyserver/caddy.git synced 2024-12-16 21:56:40 -05:00
This commit is contained in:
a 2024-06-18 21:57:46 -05:00
parent edf4168c8e
commit 7bc7e1680e
No known key found for this signature in database
GPG key ID: 374BC539FE795AF0
4 changed files with 76 additions and 46 deletions

View file

@ -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 {

28
cmd/commandfactory.go Normal file
View file

@ -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
}

View file

@ -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]$`)

View file

@ -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