Skip to content

Commit

Permalink
Mitigate single dash long flags (#5)
Browse files Browse the repository at this point in the history
* go linter complaint

* added heuristic to catch long short flags

* tests

* added error catching if everything else fails

* naming things is hard

* changed a comment
  • Loading branch information
pballandras authored Feb 28, 2023
1 parent 9057817 commit 8069c86
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 3 deletions.
2 changes: 1 addition & 1 deletion app.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ func (a *Application) parseContext(ignoreDefault bool, args []string) (*ParseCon
// on.
func (a *Application) Parse(args []string) (command string, err error) {
context, parseErr := a.ParseContext(args)
selected := []string{}
var selected []string
var setValuesErr error

if context == nil {
Expand Down
7 changes: 6 additions & 1 deletion flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,12 @@ func (f *flagGroup) parse(context *ParseContext) (*FlagClause, error) {
context.Elements = context.Elements[:len(context.Elements)-pos]
for x := len(current) - pos - 1; x > 0; x-- {
// We skip all remaining elements of the group
context.Next()
purgedToken := context.Next()
// This error isn't supposed to be possible, but let's handle it anyway.
if purgedToken.Type == TokenLong {
err = fmt.Errorf("while skipping unmanaged shorts flags, skipped long flag '%s' from '%s'", purgedToken.Value, current)
return nil, err
}
}
}
context.appUnmanagedArgs.Unmanaged = append(context.appUnmanagedArgs.Unmanaged, current)
Expand Down
2 changes: 1 addition & 1 deletion parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (p *ParseContext) Next() *Token {
return p.Next()
}

if strings.HasPrefix(arg, "--") {
if strings.HasPrefix(arg, "--") || (strings.HasPrefix(arg, "-") && strings.Count(arg, "-") > 1) {
parts := strings.SplitN(arg[2:], "=", 2)
token := &Token{p.argi, TokenLong, parts[0]}
if len(parts) == 2 {
Expand Down
53 changes: 53 additions & 0 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,56 @@ func TestParseContextPush(t *testing.T) {
b = c.Next()
assert.Equal(t, "bar", b.Value)
}

func TestAppParseSingleThenDoubleDashFlags(t *testing.T) {
app := New("test", "")
app.allowUnmanaged = true
app.Command("foo", "")

_, err := app.ParseContext([]string{"foo", "-single-dash", "--double-dash"})
assert.Nil(t, err)
assert.Equal(t, []string{"-single-dash", "--double-dash"}, app.Unmanaged)
}

func TestAppParseTwoSingleDashFlags(t *testing.T) {
app := New("test", "")
app.allowUnmanaged = true
app.Command("foo", "")

_, err := app.ParseContext([]string{"foo", "-short-flag", "-verylongshort-flag"})
assert.Nil(t, err)
assert.Equal(t, []string{"-short-flag", "-verylongshort-flag"}, app.Unmanaged)
}

func TestAppParseDoubleThenSingleDashFlags(t *testing.T) {
app := New("test", "")
app.allowUnmanaged = true
app.Command("foo", "")

_, err := app.ParseContext([]string{"foo", "--double-dash", "-single-dash"})
assert.Nil(t, err)
assert.Equal(t, []string{"--double-dash", "-single-dash"}, app.Unmanaged)
}

func TestAppParseVerboseVarFlags(t *testing.T) {
app := New("test", "")
app.allowUnmanaged = true
app.Command("foo", "")
app.Flag("verbose", "").Short('v').Bool()

_, err := app.ParseContext([]string{"foo", "-v", "-var"})
assert.Nil(t, err)
assert.Equal(t, []string{"-var"}, app.Unmanaged)
}

func TestAppParseUnmanagedVarWithTwoManagedFlags(t *testing.T) {
app := New("test", "")
app.allowUnmanaged = true
app.Command("foo", "")
app.Flag("verbose", "").Short('v').Bool()
app.Flag("aflag", "").Short('a').Bool()

_, err := app.ParseContext([]string{"foo", "-var"})
assert.Nil(t, err)
assert.Equal(t, []string{"-var"}, app.Unmanaged)
}

0 comments on commit 8069c86

Please sign in to comment.