Commit 54236b3f88

54236b3f88b1c12cca152c40b62ceecc823a22e7

parent: c2a6cbdbec

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-24 04:05 UTC

help: usage keeps required flags; owner/name as written

Ref #254
internal/control/help.go +6 −9
@@ -146,17 +146,14 @@ func (c *Ctx) helpVerb(w io.Writer, cmd Command, below []Command) {
146146 fmt.Fprintln(w, cmd.Summary)
147147 fmt.Fprintln(w)
148148 c.heading(w, "USAGE")
149 // Cutting at the first optional flag drops the rest of the usage
150 // syntax behind "[flags]" — safe only for what is actually optional.
151 // A required flag (repo delete --yes) or an alternative
152 // (notifications read <id>... | --all) has no " [--" to cut at, so
153 // the usage prints whole.
149154 shape := cmd.Usage
150155 if i := strings.Index(shape, " [--"); i >= 0 {
151 shape = shape[:i]
152 } else if i := strings.Index(shape, " --"); i >= 0 {
153 shape = shape[:i]
154 }
155 if c.Term.Cols > 0 {
156 shape = strings.Replace(shape, "<owner/name>", "[<owner/name>]", 1)
157 }
158 if len(cmd.Flags) > 0 {
159 shape += " [flags]"
156 shape = shape[:i] + " [flags]"
160157 }
161158 fmt.Fprintf(w, " %s %s\n", c.program(), shape)
162159 fmt.Fprintln(w)
internal/control/help_test.go +23 −1
@@ -25,7 +25,7 @@ func TestHelpVerb(t *testing.T) {
2525 out := helpOut(t, Term{Cols: 100}, "issue", "list")
2626 for _, want := range []string{
2727 "list issues\n",
28 "USAGE\n gitbay issue list [<owner/name>] [flags]\n",
28 "USAGE\n gitbay issue list <owner/name> [flags]\n",
2929 "FLAGS\n",
3030 " --state open|closed|all",
3131 "which issues (default open)\n",
@@ -45,6 +45,28 @@ func TestHelpVerb(t *testing.T) {
4545 }
4646}
4747
48// TestHelpVerbUsageKeepsRequiredFlags covers a usage line with no
49// optional flag to cut at: it prints whole, not truncated to "[flags]"
50// as though --yes were optional.
51func TestHelpVerbUsageKeepsRequiredFlags(t *testing.T) {
52 out := helpOut(t, Term{Cols: 100}, "repo", "delete")
53 if !strings.Contains(out, "USAGE\n gitbay repo delete <owner/name> --yes\n") {
54 t.Errorf("missing required --yes in usage:\n%s", out)
55 }
56 if strings.Contains(out, "[flags]") {
57 t.Errorf("repo delete has no optional flags; should not print [flags]:\n%s", out)
58 }
59}
60
61// TestHelpVerbUsageKeepsAlternative covers a usage line whose flag is
62// one side of a "|" alternative, not an optional extra.
63func TestHelpVerbUsageKeepsAlternative(t *testing.T) {
64 out := helpOut(t, Term{Cols: 100}, "notifications", "read")
65 if !strings.Contains(out, "USAGE\n gitbay notifications read <id>... | --all\n") {
66 t.Errorf("missing whole alternative in usage:\n%s", out)
67 }
68}
69
4870func TestHelpNoun(t *testing.T) {
4971 out := helpOut(t, Term{Cols: 100}, "issue")
5072 for _, want := range []string{"issues\n", "READ\n", "WRITE\n", " list ", " create ", "gitbay issue <verb> --help for flags.\n"} {