feat: accept ls and rm for list and delete commands

Every list command also answers to ls and every delete command to rm,
as in gh. flagAliases lets a command accept old flag names for renamed
flags without listing them in help, so singular gh names such as
--add-label can become primary while the plural names keep working.

Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni committed 2026-10-11 22:55:26 +02:00
1 parent eb51dc8619
commit f6a0bcfa6a
2 files changed
+65

No files matched your search

+36
View File
@@ -192,3 +192,39 @@ func TestRawJSONCommandsKeepJQToThemselves(t *testing.T) {
root.SetArgs([]string{"raw", "--json"})
require.ErrorContains(t, root.Execute(), "raw prints text; --json is not supported")
}
func TestVerbAndFlagAliases(t *testing.T) {
deps, _, _ := testDeps(t)
root := NewRoot(deps)
for _, args := range [][]string{{"issue", "ls"}, {"label", "rm"}, {"pr", "review", "ls"}} {
cmd, _, err := root.Find(args)
require.NoError(t, err)
require.Equal(t, map[string]string{"ls": "list", "rm": "delete"}[args[len(args)-1]], cmd.Name(), args)
}
// Aliases never shadow a sibling command.
walkCommands(root, func(cmd *cobra.Command) {
names := map[string]string{}
for _, child := range cmd.Commands() {
for _, name := range append([]string{child.Name()}, child.Aliases...) {
require.Empty(t, names[name], "%s %s is both %s and %s", cmd.CommandPath(), name, names[name], child.Name())
names[name] = child.Name()
}
}
})
var labels []string
edit := &cobra.Command{Use: "edit", RunE: func(*cobra.Command, []string) error { return nil }}
edit.Flags().StringSliceVar(&labels, "add-label", nil, "Add labels")
flagAliases(edit, map[string]string{"add-labels": "add-label"})
edit.SetArgs([]string{"--add-labels", "bug", "--add-label", "docs"})
require.NoError(t, edit.Execute())
require.Equal(t, []string{"bug", "docs"}, labels)
require.NotContains(t, edit.UsageString(), "add-labels")
}
// walkCommands calls visit for cmd and each of its descendants.
func walkCommands(cmd *cobra.Command, visit func(*cobra.Command)) {
visit(cmd)
for _, child := range cmd.Commands() {
walkCommands(child, visit)
}
}