diff --git a/pkg/cmd/root/completion.go b/pkg/cmd/completion/completion.go similarity index 98% rename from pkg/cmd/root/completion.go rename to pkg/cmd/completion/completion.go index a96b69840..3d3699b5d 100644 --- a/pkg/cmd/root/completion.go +++ b/pkg/cmd/completion/completion.go @@ -1,4 +1,4 @@ -package root +package completion import ( "errors" diff --git a/pkg/cmd/root/completion_test.go b/pkg/cmd/completion/completion_test.go similarity index 98% rename from pkg/cmd/root/completion_test.go rename to pkg/cmd/completion/completion_test.go index 505a65319..3ce03f9b6 100644 --- a/pkg/cmd/root/completion_test.go +++ b/pkg/cmd/completion/completion_test.go @@ -1,4 +1,4 @@ -package root +package completion import ( "strings" diff --git a/pkg/cmd/root/help.go b/pkg/cmd/root/help.go index 400be3834..ae57c1328 100644 --- a/pkg/cmd/root/help.go +++ b/pkg/cmd/root/help.go @@ -5,9 +5,11 @@ import ( "fmt" "strings" + "github.com/cli/cli/pkg/cmdutil" "github.com/cli/cli/pkg/text" "github.com/cli/cli/utils" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) func rootUsageFunc(command *cobra.Command) error { @@ -33,6 +35,13 @@ func rootUsageFunc(command *cobra.Command) error { return nil } +func rootFlagErrrorFunc(cmd *cobra.Command, err error) error { + if err == pflag.ErrHelp { + return err + } + return &cmdutil.FlagError{Err: err} +} + var hasFailed bool // HasFailed signals that the main process should exit with non-zero status diff --git a/pkg/cmd/root/root.go b/pkg/cmd/root/root.go index 334ee418d..7a82f0cbf 100644 --- a/pkg/cmd/root/root.go +++ b/pkg/cmd/root/root.go @@ -1,10 +1,7 @@ package root import ( - "fmt" "net/http" - "regexp" - "strings" "github.com/MakeNowJust/heredoc" "github.com/cli/cli/api" @@ -13,6 +10,7 @@ import ( aliasCmd "github.com/cli/cli/pkg/cmd/alias" apiCmd "github.com/cli/cli/pkg/cmd/api" authCmd "github.com/cli/cli/pkg/cmd/auth" + completionCmd "github.com/cli/cli/pkg/cmd/completion" configCmd "github.com/cli/cli/pkg/cmd/config" "github.com/cli/cli/pkg/cmd/factory" gistCmd "github.com/cli/cli/pkg/cmd/gist" @@ -21,9 +19,9 @@ import ( releaseCmd "github.com/cli/cli/pkg/cmd/release" repoCmd "github.com/cli/cli/pkg/cmd/repo" creditsCmd "github.com/cli/cli/pkg/cmd/repo/credits" + versionCmd "github.com/cli/cli/pkg/cmd/version" "github.com/cli/cli/pkg/cmdutil" "github.com/spf13/cobra" - "github.com/spf13/pflag" ) func NewCmdRoot(f *cmdutil.Factory, version, buildDate string) *cobra.Command { @@ -49,59 +47,31 @@ func NewCmdRoot(f *cmdutil.Factory, version, buildDate string) *cobra.Command { }, } - version = strings.TrimPrefix(version, "v") - if buildDate == "" { - cmd.Version = version - } else { - cmd.Version = fmt.Sprintf("%s (%s)", version, buildDate) - } - versionOutput := fmt.Sprintf("gh version %s\n%s\n", cmd.Version, changelogURL(version)) - cmd.AddCommand(&cobra.Command{ - Use: "version", - Hidden: true, - Run: func(cmd *cobra.Command, args []string) { - fmt.Print(versionOutput) - }, - }) - cmd.SetVersionTemplate(versionOutput) - cmd.Flags().Bool("version", false, "Show gh version") - cmd.SetOut(f.IOStreams.Out) cmd.SetErr(f.IOStreams.ErrOut) cmd.PersistentFlags().Bool("help", false, "Show help for command") cmd.SetHelpFunc(rootHelpFunc) cmd.SetUsageFunc(rootUsageFunc) + cmd.SetFlagErrorFunc(rootFlagErrrorFunc) - cmd.SetFlagErrorFunc(func(cmd *cobra.Command, err error) error { - if err == pflag.ErrHelp { - return err - } - return &cmdutil.FlagError{Err: err} - }) - - cmdutil.DisableAuthCheck(cmd) + formattedVersion := versionCmd.Format(version, buildDate) + cmd.SetVersionTemplate(formattedVersion) + cmd.Version = formattedVersion + cmd.Flags().Bool("version", false, "Show gh version") // Child commands + cmd.AddCommand(versionCmd.NewCmdVersion(f, version, buildDate)) cmd.AddCommand(aliasCmd.NewCmdAlias(f)) cmd.AddCommand(authCmd.NewCmdAuth(f)) cmd.AddCommand(configCmd.NewCmdConfig(f)) cmd.AddCommand(creditsCmd.NewCmdCredits(f, nil)) cmd.AddCommand(gistCmd.NewCmdGist(f)) - cmd.AddCommand(NewCmdCompletion(f.IOStreams)) - - // Help topics - cmd.AddCommand(NewHelpTopic("environment")) + cmd.AddCommand(completionCmd.NewCmdCompletion(f.IOStreams)) // the `api` command should not inherit any extra HTTP headers bareHTTPCmdFactory := *f - bareHTTPCmdFactory.HttpClient = func() (*http.Client, error) { - cfg, err := bareHTTPCmdFactory.Config() - if err != nil { - return nil, err - } - return factory.NewHTTPClient(bareHTTPCmdFactory.IOStreams, cfg, version, false), nil - } + bareHTTPCmdFactory.HttpClient = bareHTTPClient(f, version) cmd.AddCommand(apiCmd.NewCmdApi(&bareHTTPCmdFactory, nil)) @@ -114,9 +84,24 @@ func NewCmdRoot(f *cmdutil.Factory, version, buildDate string) *cobra.Command { cmd.AddCommand(releaseCmd.NewCmdRelease(&repoResolvingCmdFactory)) cmd.AddCommand(repoCmd.NewCmdRepo(&repoResolvingCmdFactory)) + // Help topics + cmd.AddCommand(NewHelpTopic("environment")) + + cmdutil.DisableAuthCheck(cmd) + return cmd } +func bareHTTPClient(f *cmdutil.Factory, version string) func() (*http.Client, error) { + return func() (*http.Client, error) { + cfg, err := f.Config() + if err != nil { + return nil, err + } + return factory.NewHTTPClient(f.IOStreams, cfg, version, false), nil + } +} + func resolvedBaseRepo(f *cmdutil.Factory) func() (ghrepo.Interface, error) { return func() (ghrepo.Interface, error) { httpClient, err := f.HttpClient() @@ -142,14 +127,3 @@ func resolvedBaseRepo(f *cmdutil.Factory) func() (ghrepo.Interface, error) { return baseRepo, nil } } - -func changelogURL(version string) string { - path := "https://github.com/cli/cli" - r := regexp.MustCompile(`^v?\d+\.\d+\.\d+(-[\w.]+)?$`) - if !r.MatchString(version) { - return fmt.Sprintf("%s/releases/latest", path) - } - - url := fmt.Sprintf("%s/releases/tag/v%s", path, strings.TrimPrefix(version, "v")) - return url -} diff --git a/pkg/cmd/version/version.go b/pkg/cmd/version/version.go new file mode 100644 index 000000000..040a3132e --- /dev/null +++ b/pkg/cmd/version/version.go @@ -0,0 +1,45 @@ +package version + +import ( + "fmt" + "regexp" + "strings" + + "github.com/cli/cli/pkg/cmdutil" + "github.com/spf13/cobra" +) + +func NewCmdVersion(f *cmdutil.Factory, version, buildDate string) *cobra.Command { + cmd := &cobra.Command{ + Use: "version", + Hidden: true, + Run: func(cmd *cobra.Command, args []string) { + fmt.Fprint(f.IOStreams.Out, Format(version, buildDate)) + }, + } + + cmdutil.DisableAuthCheck(cmd) + + return cmd +} + +func Format(version, buildDate string) string { + version = strings.TrimPrefix(version, "v") + + if buildDate != "" { + version = fmt.Sprintf("%s (%s)", version, buildDate) + } + + return fmt.Sprintf("gh version %s\n%s\n", version, changelogURL(version)) +} + +func changelogURL(version string) string { + path := "https://github.com/cli/cli" + r := regexp.MustCompile(`^v?\d+\.\d+\.\d+(-[\w.]+)?$`) + if !r.MatchString(version) { + return fmt.Sprintf("%s/releases/latest", path) + } + + url := fmt.Sprintf("%s/releases/tag/v%s", path, strings.TrimPrefix(version, "v")) + return url +} diff --git a/pkg/cmd/root/root_test.go b/pkg/cmd/version/version_test.go similarity index 98% rename from pkg/cmd/root/root_test.go rename to pkg/cmd/version/version_test.go index 714032ec3..9a1d49db3 100644 --- a/pkg/cmd/root/root_test.go +++ b/pkg/cmd/version/version_test.go @@ -1,4 +1,4 @@ -package root +package version import ( "testing"