Render help through command aliases

This commit is contained in:
2026-10-19 19:40:55 +00:00
parent 451a0c483f
commit a504efbad7
10 changed files with 391 additions and 11 deletions

View File

@@ -347,7 +347,123 @@ func TestAliasOnlyPrefixProducesDiscoveryRoute(t *testing.T) {
if got, want := result.enteredPath.String(), "list"; got != want {
t.Fatalf("entered path = %q, want %q", got, want)
}
if !reflect.DeepEqual(result.args, []string{"list", "--help"}) {
t.Fatalf("discovery args = %q, want [list --help]", result.args)
if !reflect.DeepEqual(result.args, []string{"--help"}) {
t.Fatalf("discovery args = %q, want [--help]", result.args)
}
}
func TestAliasHelpTargetsGroupsAndDiscoveryViews(t *testing.T) {
var inputBuilds, promptRuns int
showPrompt := NewCommand(CommandSpec[struct{}]{
Name: "prompt",
NewInput: func() struct{} {
inputBuilds++
return struct{}{}
},
Flags: []Flag[struct{}]{ValueFlag(FlagMeta{Name: "format"}, (*string)(nil),
func(value string) (string, error) { return value, nil },
func(*struct{}, Supplied[string]) {},
)},
Run: func(Invocation, struct{}) Outcome {
promptRuns++
return Success()
},
})
commands := Group("promptkit", "PromptKit",
Group("list", "List", simpleRunnable("collections")),
Group("show", "Show", showPrompt),
)
app, err := New(Identity{Name: "example"}, commands,
Alias("list collections", "promptkit list collections"),
Alias("promptkit list bundles", "promptkit list collections"),
Alias("pk", "promptkit"),
Alias("pk list bundles", "promptkit show prompt"),
FlagAlias("--hlep", "--help"),
FlagAliasFor("promptkit show prompt", "--fmt", "--format"),
)
if err != nil {
t.Fatal(err)
}
for _, test := range []struct {
name string
args []string
want []string
omit []string
}{
{
name: "explicit command help resolves entered target",
args: []string{"help", "list", "collections"},
want: []string{"Usage:\n example list collections", "Alias for: example promptkit list collections"},
},
{
name: "aliased help flag uses entered command path",
args: []string{"list", "collections", "--hlep"},
want: []string{"Usage:\n example list collections", "Alias for: example promptkit list collections", "--hlep → --help"},
},
{
name: "canonical group shows direct aliases",
args: []string{"help", "promptkit", "list"},
want: []string{"Command Aliases:", "bundles → promptkit list collections"},
},
{
name: "group shortcut shows more-specific override",
args: []string{"pk", "--help"},
want: []string{"Usage:\n example pk [flags]", "Alias for: example promptkit", "list bundles → promptkit show prompt"},
omit: []string{"list bundles → promptkit list collections"},
},
{
name: "explicit discovery target",
args: []string{"help", "list"},
want: []string{"Usage:\n example list [command]", "Available Aliases:", "collections → promptkit list collections", "--hlep → --help"},
omit: []string{"--fmt"},
},
{
name: "discovery help flag",
args: []string{"list", "--hlep"},
want: []string{"Usage:\n example list [command]", "collections → promptkit list collections"},
},
{
name: "scoped flag alias appears on canonical command help",
args: []string{"promptkit", "show", "prompt", "--hlep"},
want: []string{"--fmt → --format"},
},
{
name: "group excludes descendant scoped flag aliases",
args: []string{"promptkit", "--help"},
want: []string{"Command Aliases:"},
omit: []string{"--fmt → --format"},
},
{
name: "root lists explicit command aliases separately",
args: []string{"--help"},
want: []string{"Available Commands:", "Command Aliases:", "list collections → promptkit list collections", "pk → promptkit"},
},
} {
t.Run(test.name, func(t *testing.T) {
var output bytes.Buffer
outcome := app.Execute(context.Background(), test.args, Streams{Out: &output, Err: io.Discard})
if outcome.Kind != OutcomeSuccess {
t.Fatalf("Execute(%q) = %#v; output %q", test.args, outcome, output.String())
}
for _, fragment := range test.want {
if !strings.Contains(output.String(), fragment) {
t.Errorf("help output %q does not contain %q", output.String(), fragment)
}
}
for _, fragment := range test.omit {
if strings.Contains(output.String(), fragment) {
t.Errorf("help output %q unexpectedly contains %q", output.String(), fragment)
}
}
})
}
var diagnostics bytes.Buffer
outcome := app.Execute(context.Background(), []string{"list"}, Streams{Out: io.Discard, Err: &diagnostics})
if outcome.Kind != OutcomeUsage || !strings.Contains(outcome.Cause.Error(), "--help") {
t.Fatalf("bare discovery prefix = %#v, diagnostics %q; want usage pointing to list --help", outcome, diagnostics.String())
}
if inputBuilds != 0 || promptRuns != 0 {
t.Fatalf("help built %d inputs and ran %d commands", inputBuilds, promptRuns)
}
}