flag duplicate check

This commit is contained in:
Benjamin Levesque 2025-08-20 20:00:30 +02:00
parent 6e6c09e6b1
commit faa0e2c26b
No known key found for this signature in database
GPG key ID: 765E3CB147AA4D4A
3 changed files with 60 additions and 12 deletions

View file

@ -17,7 +17,6 @@ import (
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
type authEntry struct {
@ -172,15 +171,7 @@ func NewCmdStatus(f *cmdutil.Factory, runF func(*StatusOptions) error) *cobra.Co
cmd.Flags().BoolVarP(&opts.ShowToken, "show-token", "t", false, "Display the auth token")
cmd.Flags().BoolVarP(&opts.Active, "active", "a", false, "Display the active account only")
// Add JSON flags for exporting, but ignore the default `-t` abbreviation that conflicts with show-token.
tmpCmd := &cobra.Command{}
cmdutil.AddJSONFlags(tmpCmd, &opts.Exporter, authFields)
tmpCmd.Flags().VisitAll(func(f *pflag.Flag) {
if f.Name == "template" {
f.Shorthand = ""
}
cmd.Flags().AddFlag(f)
})
cmdutil.AddJSONFlags(cmd, &opts.Exporter, authFields)
cmd.MarkFlagsMutuallyExclusive("show-token", "json")

View file

@ -26,8 +26,8 @@ type JSONFlagError struct {
func AddJSONFlags(cmd *cobra.Command, exportTarget *Exporter, fields []string) {
f := cmd.Flags()
f.StringSlice("json", nil, "Output JSON with the specified `fields`")
f.StringP("jq", "q", "", "Filter JSON output using a jq `expression`")
f.StringP("template", "t", "", "Format JSON output using a Go template; see \"gh help formatting\"")
addStringFlagWithSafeShorthand(f, "jq", "q", "", "Filter JSON output using a jq `expression`")
addStringFlagWithSafeShorthand(f, "template", "t", "", "Format JSON output using a Go template; see \"gh help formatting\"")
_ = cmd.RegisterFlagCompletionFunc("json", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
var results []string
@ -94,6 +94,15 @@ func AddJSONFlags(cmd *cobra.Command, exportTarget *Exporter, fields []string) {
cmd.Annotations["help:json-fields"] = strings.Join(fields, ",")
}
// addStringFlagWithSafeShorthand only adds the flag with shorthand if the shorthand is not already used by another flag.
func addStringFlagWithSafeShorthand(f *pflag.FlagSet, name, shorthand, value, usage string) {
if f.ShorthandLookup(shorthand) != nil {
f.String(name, value, usage)
} else {
f.StringP(name, shorthand, value, usage)
}
}
func checkJSONFlags(cmd *cobra.Command) (*jsonExporter, error) {
f := cmd.Flags()
jsonFlag := f.Lookup("json")

View file

@ -119,6 +119,54 @@ func TestAddJSONFlags(t *testing.T) {
}
}
func TestAddJSONFlagsNoDuplicateShorthand(t *testing.T) {
tests := []struct {
name string
setFlags func(cmd *cobra.Command)
wantFlags map[string]string
}{
{
name: "no conflicting flags",
setFlags: func(cmd *cobra.Command) {
cmd.Flags().StringP("web", "w", "", "")
},
wantFlags: map[string]string{
"web": "w",
"jq": "q",
"template": "t",
"json": "",
},
},
{
name: "conflicting flags",
setFlags: func(cmd *cobra.Command) {
cmd.Flags().StringP("token", "t", "", "")
},
wantFlags: map[string]string{
"token": "t",
"jq": "q",
"template": "", // no shorthand
"json": "",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cmd := &cobra.Command{Run: func(*cobra.Command, []string) {}}
tt.setFlags(cmd)
AddJSONFlags(cmd, nil, []string{})
for f, shorthand := range tt.wantFlags {
flag := cmd.Flags().Lookup(f)
require.NotNil(t, flag)
require.Equal(t, shorthand, flag.Shorthand)
}
})
}
}
// TestAddJSONFlagsSetsAnnotations asserts that `AddJSONFlags` function adds the
// appropriate annotation to the command, which could later be used by doc
// generator functions.