diff --git a/internal/app/app.go b/internal/app/app.go index d811f99a..c895fcc0 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -214,19 +214,34 @@ var rootGroups = map[string]string{ // Commands add other gh verbs, such as new, co, add and get, to their own Aliases. var verbAliases = map[string]string{"list": "ls", "delete": "rm"} -// addVerbAliases gives every list and delete command its short name. +// addVerbAliases gives every list and delete command its short name, and lets its flags be named +// in the plural. func addVerbAliases(cmd *cobra.Command) { if alias, ok := verbAliases[cmd.Name()]; ok && cmd.HasParent() && !slices.Contains(cmd.Aliases, alias) { cmd.Aliases = append(cmd.Aliases, alias) } + acceptPlurals(cmd) for _, child := range cmd.Commands() { addVerbAliases(child) } } +// acceptPlurals lets the flags of cmd be named in the plural, such as --add-labels for the gh name +// --add-label (D8), without showing the plural in help. +func acceptPlurals(cmd *cobra.Command) { + names := map[string]bool{} + cmd.Flags().VisitAll(func(flag *pflag.Flag) { names[flag.Name] = true }) + normalize := cmd.Flags().GetNormalizeFunc() + cmd.Flags().SetNormalizeFunc(func(flags *pflag.FlagSet, name string) pflag.NormalizedName { + if singular, ok := strings.CutSuffix(name, "s"); ok && !names[name] && names[singular] { + name = singular + } + return normalize(flags, name) + }) +} + // flagAliases makes the flags of cmd accept each key of aliases as another name of the flag it maps -// to, without showing it in help. Renamed flags keep their old names working this way, such as the -// plural --add-labels after the singular gh name --add-label became primary (D8). +// to, without showing it in help. Renamed flags keep their old names working this way. func flagAliases(cmd *cobra.Command, aliases map[string]string) { normalize := cmd.Flags().GetNormalizeFunc() cmd.Flags().SetNormalizeFunc(func(flags *pflag.FlagSet, name string) pflag.NormalizedName { diff --git a/internal/app/issues.go b/internal/app/issues.go index dee41f24..f49dd5e6 100644 --- a/internal/app/issues.go +++ b/internal/app/issues.go @@ -537,7 +537,6 @@ func (f *metadataFlags) register(cmd *cobra.Command) { flags.StringSliceVar(&f.addAssignees, "add-assignee", nil, "Add assignees by `login`; @me for yourself") flags.StringSliceVar(&f.removeAssignees, "remove-assignee", nil, "Remove assignees by `login`; @me for yourself") flags.StringSliceVar(&f.setAssignees, "set-assignees", nil, "Replace all assignees; an empty value clears them") - flagAliases(cmd, map[string]string{"add-labels": "add-label", "remove-labels": "remove-label", "add-assignees": "add-assignee", "remove-assignees": "remove-assignee"}) } // completeMetadataFlags completes the label and assignee flags of metadataFlags. diff --git a/internal/app/pull_edit.go b/internal/app/pull_edit.go index 10ae2fd9..686ede69 100644 --- a/internal/app/pull_edit.go +++ b/internal/app/pull_edit.go @@ -143,10 +143,7 @@ pull request, or mark it as a draft or ready for review.`, Annotations: pullArgu cmd.Flags().StringSliceVar(&reviewers.Remove.Users, "remove-reviewer", nil, "Withdraw review requests from users") cmd.Flags().StringSliceVar(&reviewers.Add.Teams, "add-reviewer-team", nil, "Request reviews from teams of the repository's organization") cmd.Flags().StringSliceVar(&reviewers.Remove.Teams, "remove-reviewer-team", nil, "Withdraw review requests from teams") - flagAliases(cmd, map[string]string{ - "milestone-name": "milestone", "add-reviewers": "add-reviewer", "remove-reviewers": "remove-reviewer", - "add-reviewer-teams": "add-reviewer-team", "remove-reviewer-teams": "remove-reviewer-team", - }) + flagAliases(cmd, map[string]string{"milestone-name": "milestone"}) for _, name := range []string{"add-reviewer", "remove-reviewer"} { _ = cmd.RegisterFlagCompletionFunc(name, a.completeUsers()) }