cli: help forwards to the server for a prefix or --json !179

merged merged by cmc on 2026-09-03 00:53 UTC · krz/gitbay:stack-9-help into main

2 files changed, +30 −2

Layout: unified · split

cmd/gitbay/coverage_test.go +3 −2
@@ -13,7 +13,6 @@ import (
13// registry must be reachable by typing it, or the CLI is not the 13// registry must be reachable by typing it, or the CLI is not the
14// complete interface the design claims. 14// complete interface the design claims.
15var notInCLI = map[string]string{ 15var notInCLI = map[string]string{
16 "help": "cobra owns `gitbay help`; the registry's is reached by `<cmd> --help`",
17 "runner next": "the CI runner's wire protocol, not for humans", 16 "runner next": "the CI runner's wire protocol, not for humans",
18 "runner done": "the CI runner's wire protocol, not for humans", 17 "runner done": "the CI runner's wire protocol, not for humans",
19 "runner log": "the CI runner's wire protocol, not for humans", 18 "runner log": "the CI runner's wire protocol, not for humans",
@@ -36,7 +35,9 @@ func TestEveryCommandIsReachable(t *testing.T) {
36 walk(sub) 35 walk(sub)
37 } 36 }
38 } 37 }
39 walk(newRoot()) 38 root := newRoot()
39 root.InitDefaultHelpCmd() // attaches the help command the way Execute does
40 walk(root)
40 41
41 for _, cmd := range control.Commands() { 42 for _, cmd := range control.Commands() {
42 path := strings.Join(cmd.Path, " ") 43 path := strings.Join(cmd.Path, " ")
cmd/gitbay/main.go +27
@@ -32,6 +32,7 @@ func newRoot() *cobra.Command {
32 SilenceUsage: true, 32 SilenceUsage: true,
33 SilenceErrors: true, 33 SilenceErrors: true,
34 } 34 }
35 root.SetHelpCommand(helpCmd(root))
35 36
36 root.AddCommand( 37 root.AddCommand(
37 authCmd(), 38 authCmd(),
@@ -576,3 +577,29 @@ func manCmd(root *cobra.Command) *cobra.Command {
576 cmd.Flags().StringVar(&dir, "dir", "man", "output directory") 577 cmd.Flags().StringVar(&dir, "dir", "man", "output directory")
577 return cmd 578 return cmd
578} 579}
580
581// helpCmd is `gitbay help`. Bare, it is cobra's tree of local commands.
582// With anything after it — a prefix such as `mr`, or --json — it is the
583// server's help: the registry is the only place flags are written down,
584// and its JSON is the contract. Cobra's built-in help used to swallow
585// both forms, so `gitbay help --json` failed on an unknown flag.
586func helpCmd(root *cobra.Command) *cobra.Command {
587 return &cobra.Command{
588 Use: "help [<prefix>...] [--json]",
589 Short: "this list, or the server's command reference for a prefix",
590 Annotations: map[string]string{serverPath: "help", stdinMode: "none"},
591 DisableFlagParsing: true,
592 RunE: func(cmd *cobra.Command, args []string) error {
593 if len(args) == 0 {
594 return root.Help()
595 }
596 t, err := resolveTarget()
597 if err != nil {
598 fmt.Fprintln(os.Stderr, "gitbay:", err)
599 os.Exit(protocol.ExitFailure)
600 }
601 os.Exit(runSSH(t, append([]string{"help"}, args...), strings.NewReader("")))
602 return nil
603 },
604 }
605}