Skip to content

Commit 7b90614

Browse files
authored
Merge branch 'main' into issue_2292
2 parents b4f42d3 + 41c4f5f commit 7b90614

3 files changed

Lines changed: 102 additions & 18 deletions

File tree

command.go

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -582,19 +582,14 @@ func (cmd *Command) NArg() int {
582582

583583
func (cmd *Command) runFlagActions(ctx context.Context) error {
584584
tracef("runFlagActions")
585-
for fl := range cmd.setFlags {
586-
/*tracef("checking %v:%v", fl.Names(), fl.IsSet())
587-
if !fl.IsSet() {
588-
continue
589-
}*/
590-
591-
//if pf, ok := fl.(LocalFlag); ok && !pf.IsLocal() {
592-
// continue
593-
//}
594-
595-
if af, ok := fl.(ActionableFlag); ok {
596-
if err := af.RunAction(ctx, cmd); err != nil {
597-
return err
585+
// run the flag actions in the same order that they are defined
586+
// to maintain consistency.
587+
for _, fl := range cmd.appliedFlags {
588+
if _, inSet := cmd.setFlags[fl]; inSet {
589+
if af, ok := fl.(ActionableFlag); ok {
590+
if err := af.RunAction(ctx, cmd); err != nil {
591+
return err
592+
}
598593
}
599594
}
600595
}

command_parse.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ func (cmd *Command) parseFlags(args Args) (Args, error) {
164164

165165
tracef("processing non bool flag (fName=%[1]q)", flagName)
166166
// not a bool flag so need to get the next arg
167-
if flagVal == "" {
168-
if len(rargs) == 1 || valFromEqual {
167+
if flagVal == "" && !valFromEqual {
168+
if len(rargs) == 1 {
169169
return &stringSliceArgs{posArgs}, fmt.Errorf("%s%s", argumentNotProvidedErrMsg, firstArg)
170170
}
171171
flagVal = rargs[1]

command_test.go

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,6 +2185,54 @@ func TestCommand_OrderOfOperations(t *testing.T) {
21852185
})
21862186
}
21872187

2188+
func TestFlagActionOrder(t *testing.T) {
2189+
tests := []struct {
2190+
Name string
2191+
Args []string
2192+
}{
2193+
{
2194+
Name: "abc",
2195+
Args: []string{"", "--a", "--b", "--c"},
2196+
},
2197+
{
2198+
Name: "bca",
2199+
Args: []string{"", "--b", "--c", "--a"},
2200+
},
2201+
{
2202+
Name: "cba",
2203+
Args: []string{"", "--c", "--b", "--a"},
2204+
},
2205+
}
2206+
for _, tt := range tests {
2207+
t.Run(tt.Name, func(t *testing.T) {
2208+
str := ""
2209+
action := func(name string) func(context.Context, *Command, bool) error {
2210+
return func(_ context.Context, _ *Command, _ bool) error {
2211+
str += name
2212+
return nil
2213+
}
2214+
}
2215+
cmd := &Command{
2216+
Flags: []Flag{
2217+
&BoolFlag{Name: "a", Action: action("a")},
2218+
&BoolFlag{Name: "b", Action: action("b")},
2219+
&BoolFlag{Name: "c", Action: action("c")},
2220+
},
2221+
Action: func(_ context.Context, cmd *Command) error {
2222+
return nil
2223+
},
2224+
}
2225+
2226+
err := cmd.Run(buildTestContext(t), tt.Args)
2227+
require.NoError(t, err)
2228+
2229+
if str != "abc" {
2230+
t.Errorf("expected 'abc' got '%s'", str)
2231+
}
2232+
})
2233+
}
2234+
}
2235+
21882236
func TestCommand_Run_CommandWithSubcommandHasHelpTopic(t *testing.T) {
21892237
subcommandHelpTopics := [][]string{
21902238
{"foo", "--help"},
@@ -2801,12 +2849,12 @@ func TestFlagAction(t *testing.T) {
28012849
{
28022850
name: "flag_string_error",
28032851
args: []string{"app", "--f_string="},
2804-
err: "flag needs an argument: --f_string=",
2852+
err: "empty string",
28052853
},
28062854
{
28072855
name: "flag_string_error2",
28082856
args: []string{"app", "--f_string=", "--f_bool"},
2809-
err: "flag needs an argument: --f_string=",
2857+
err: "empty string",
28102858
},
28112859
{
28122860
name: "flag_string_slice",
@@ -5614,5 +5662,46 @@ func TestEmptyPositionalArgs(t *testing.T) {
56145662
assert.NoError(t, err)
56155663
assert.Equal(t, tc.Expected, args)
56165664
})
5617-
}
5665+
}
5666+
5667+
func TestFlagEqualsEmptyValue(t *testing.T) {
5668+
t.Run("--flag= sets empty string", func(t *testing.T) {
5669+
var val string
5670+
5671+
cmd := &Command{
5672+
Flags: []Flag{
5673+
&StringFlag{
5674+
Name: "name",
5675+
Destination: &val,
5676+
},
5677+
},
5678+
}
5679+
5680+
err := cmd.Run(buildTestContext(t), []string{"app", "--name="})
5681+
assert.NoError(t, err)
5682+
assert.Equal(t, "", val)
5683+
})
5684+
5685+
t.Run("--flag= does not consume next positional arg", func(t *testing.T) {
5686+
var val string
5687+
var args []string
5688+
5689+
cmd := &Command{
5690+
Flags: []Flag{
5691+
&StringFlag{
5692+
Name: "name",
5693+
Destination: &val,
5694+
},
5695+
},
5696+
Action: func(_ context.Context, cmd *Command) error {
5697+
args = cmd.Args().Slice()
5698+
return nil
5699+
},
5700+
}
5701+
5702+
err := cmd.Run(buildTestContext(t), []string{"app", "--name=", "positional"})
5703+
assert.NoError(t, err)
5704+
assert.Equal(t, "", val)
5705+
assert.Equal(t, []string{"positional"}, args)
5706+
})
56185707
}

0 commit comments

Comments
 (0)