The ultimate --help & spelling suggester handler

- short command usage output now lists subcommands instead of flags for
  parent commands

- mistyping a subcommand now results in a non-zero exit status

- requesting `--help` or `-h` for any command now prints help docs on
  stdout and exits with 0
This commit is contained in:
Mislav Marohnić 2020-06-16 15:41:46 +02:00
parent ce59deb7b3
commit 311536433c
2 changed files with 45 additions and 22 deletions

View file

@ -56,6 +56,9 @@ func main() {
printError(os.Stderr, err, cmd, hasDebug)
os.Exit(1)
}
if command.HasFailed() {
os.Exit(1)
}
newRelease := <-updateMessageChan
if newRelease != nil {

View file

@ -12,6 +12,18 @@ import (
func rootUsageFunc(command *cobra.Command) error {
command.Printf("Usage: %s", command.UseLine())
subcommands := command.Commands()
if len(subcommands) > 0 {
command.Print("\n\nAvailable commands:\n")
for _, c := range subcommands {
if c.Hidden {
continue
}
command.Printf(" %s\n", c.Name())
}
return nil
}
flagUsages := command.LocalFlags().FlagUsages()
if flagUsages != "" {
command.Printf("\n\nFlags:\n%s", flagUsages)
@ -19,32 +31,40 @@ func rootUsageFunc(command *cobra.Command) error {
return nil
}
func rootHelpFunc(command *cobra.Command, args []string) {
// Display helpful error message in case subcommand name was mistyped.
// This matches Cobra's behavior for root command, which Cobra
// confusingly doesn't apply to nested commands.
if command != RootCmd {
if command.Parent() == RootCmd && len(args) >= 2 {
if command.SuggestionsMinimumDistance <= 0 {
command.SuggestionsMinimumDistance = 2
}
candidates := command.SuggestionsFor(args[1])
var hasFailed bool
errOut := command.OutOrStderr()
fmt.Fprintf(errOut, "unknown command %q for %q\n", args[1], "gh "+args[0])
// HasFailed signals that the main process should exit with non-zero status
func HasFailed() bool {
return hasFailed
}
if len(candidates) > 0 {
fmt.Fprint(errOut, "\nDid you mean this?\n")
for _, c := range candidates {
fmt.Fprintf(errOut, "\t%s\n", c)
}
fmt.Fprint(errOut, "\n")
}
// Display helpful error message in case subcommand name was mistyped.
// This matches Cobra's behavior for root command, which Cobra
// confusingly doesn't apply to nested commands.
func nestedSuggestFunc(command *cobra.Command, arg string) {
command.Printf("unknown command %q for `%s`\n", arg, command.UseLine())
oldOut := command.OutOrStdout()
command.SetOut(errOut)
defer command.SetOut(oldOut)
if command.SuggestionsMinimumDistance <= 0 {
command.SuggestionsMinimumDistance = 2
}
candidates := command.SuggestionsFor(arg)
if len(candidates) > 0 {
command.Print("\nDid you mean this?\n")
for _, c := range candidates {
command.Printf("\t%s\n", c)
}
command.Print("\n")
}
_ = rootUsageFunc(command)
}
func rootHelpFunc(command *cobra.Command, args []string) {
if command.Parent() == RootCmd && len(args) >= 2 && args[1] != "--help" && args[1] != "-h" {
nestedSuggestFunc(command, args[1])
hasFailed = true
return
}
coreCommands := []string{}