Skip to content

Commit 19f0644

Browse files
authored
Merge pull request #2419 from official-burak/fix-bare-dash-keeps-following-args
Keep arguments after a bare dash
2 parents e3f7e35 + df51685 commit 19f0644

2 files changed

Lines changed: 75 additions & 4 deletions

File tree

‎command_parse.go‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,9 @@ func (cmd *Command) parseFlags(args Args) (Args, error) {
122122
}
123123

124124
numMinuses := 1
125-
// this is same as firstArg == "-"
126-
if len(firstArg) == 1 {
127-
posArgs = append(posArgs, firstArg)
128-
break
125+
if firstArg == "-" {
126+
posArgs = append(posArgs, rargs[0])
127+
continue
129128
}
130129

131130
shortOptionHandling := cmd.useShortOptionHandling()

‎command_test.go‎

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,78 @@ func TestCommand_CommandWithDash(t *testing.T) {
11561156
require.Equal(t, "-", args.Get(1))
11571157
}
11581158

1159+
func TestCommand_BareDash(t *testing.T) {
1160+
cases := []struct {
1161+
name string
1162+
argv []string
1163+
option string
1164+
args []string
1165+
err string
1166+
}{
1167+
{
1168+
name: "arguments after a bare dash are kept",
1169+
argv: []string{"", "cmd", "-", "foo", "bar"},
1170+
args: []string{"-", "foo", "bar"},
1171+
},
1172+
{
1173+
name: "flags after a bare dash still parse",
1174+
argv: []string{"", "cmd", "-", "--option", "my-option", "foo"},
1175+
option: "my-option",
1176+
args: []string{"-", "foo"},
1177+
},
1178+
{
1179+
name: "terminator after a bare dash still stops flag parsing",
1180+
argv: []string{"", "cmd", "-", "--", "--option", "leftover"},
1181+
args: []string{"-", "--option", "leftover"},
1182+
},
1183+
{
1184+
name: "a bare dash with surrounding whitespace is passed through unchanged",
1185+
argv: []string{"", "cmd", " - ", "foo"},
1186+
args: []string{" - ", "foo"},
1187+
},
1188+
{
1189+
name: "an undefined flag after a bare dash is an error",
1190+
argv: []string{"", "cmd", "-", "--undefined"},
1191+
err: "flag provided but not defined: -undefined",
1192+
},
1193+
}
1194+
1195+
for _, tc := range cases {
1196+
t.Run(tc.name, func(t *testing.T) {
1197+
var parsedOption string
1198+
var args Args
1199+
1200+
cmd := &Command{
1201+
Writer: io.Discard,
1202+
ErrWriter: io.Discard,
1203+
Commands: []*Command{
1204+
{
1205+
Name: "cmd",
1206+
Flags: []Flag{
1207+
&StringFlag{Name: "option", Value: "", Usage: "some option"},
1208+
},
1209+
Action: func(_ context.Context, cmd *Command) error {
1210+
parsedOption = cmd.String("option")
1211+
args = cmd.Args()
1212+
return nil
1213+
},
1214+
},
1215+
},
1216+
}
1217+
1218+
err := cmd.Run(buildTestContext(t), tc.argv)
1219+
if tc.err != "" {
1220+
require.EqualError(t, err, tc.err)
1221+
return
1222+
}
1223+
require.NoError(t, err)
1224+
require.Equal(t, tc.option, parsedOption)
1225+
require.NotNil(t, args)
1226+
require.Equal(t, tc.args, args.Slice())
1227+
})
1228+
}
1229+
}
1230+
11591231
func TestCommand_PositionalArgsKeepWhitespace(t *testing.T) {
11601232
var args Args
11611233

0 commit comments

Comments
 (0)