Allow "-" as a positional or flag argument.

See #70.

There are some more elaborate ideas in that issue, but I think this is
sufficient for now.
This commit is contained in:
Alec Thomas
2020-04-27 09:06:10 +10:00
parent 860aaac388
commit 407c8229a6
4 changed files with 39 additions and 19 deletions
+6 -7
View File
@@ -279,6 +279,12 @@ func (c *Context) trace(node *Node) (err error) { // nolint: gocyclo
case string: case string:
switch { switch {
case v == "-":
fallthrough
default: // nolint
c.scan.Pop()
c.scan.PushTyped(token.Value, PositionalArgumentToken)
// Indicates end of parsing. All remaining arguments are treated as positional arguments only. // Indicates end of parsing. All remaining arguments are treated as positional arguments only.
case v == "--": case v == "--":
c.scan.Pop() c.scan.Pop()
@@ -305,9 +311,6 @@ func (c *Context) trace(node *Node) (err error) { // nolint: gocyclo
} }
c.scan.PushTyped(parts[0], FlagToken) c.scan.PushTyped(parts[0], FlagToken)
case v == "-":
return errors.New("expected short flag")
// Short flag. // Short flag.
case strings.HasPrefix(v, "-"): case strings.HasPrefix(v, "-"):
c.scan.Pop() c.scan.Pop()
@@ -316,10 +319,6 @@ func (c *Context) trace(node *Node) (err error) { // nolint: gocyclo
c.scan.PushTyped(tail, ShortFlagTailToken) c.scan.PushTyped(tail, ShortFlagTailToken)
} }
c.scan.PushTyped(v[1:2], ShortFlagToken) c.scan.PushTyped(v[1:2], ShortFlagToken)
default:
c.scan.Pop()
c.scan.PushTyped(token.Value, PositionalArgumentToken)
} }
default: default:
c.scan.Pop() c.scan.Pop()
+16
View File
@@ -863,3 +863,19 @@ func TestMultipleDefaultCommands(t *testing.T) {
_, err := p.Parse([]string{}) _, err := p.Parse([]string{})
require.EqualError(t, err, "can't have more than one default command under <command>") require.EqualError(t, err, "can't have more than one default command under <command>")
} }
func TestLoneHpyhen(t *testing.T) {
var cli struct {
Flag string
Arg string `arg:"" optional:""`
}
p := mustNew(t, &cli)
_, err := p.Parse([]string{"-"})
require.NoError(t, err)
require.Equal(t, "-", cli.Arg)
_, err = p.Parse([]string{"--flag", "-"})
require.NoError(t, err)
require.Equal(t, "-", cli.Flag)
}
+10 -7
View File
@@ -78,13 +78,16 @@ func (t TokenType) IsAny(types ...TokenType) bool {
// InferredType tries to infer the type of a token. // InferredType tries to infer the type of a token.
func (t Token) InferredType() TokenType { func (t Token) InferredType() TokenType {
if t.Type == UntypedToken { if t.Type != UntypedToken {
if v, ok := t.Value.(string); ok { return t.Type
if strings.HasPrefix(v, "--") { }
return FlagToken if v, ok := t.Value.(string); ok {
} else if strings.HasPrefix(v, "-") { if strings.HasPrefix(v, "--") { // nolint: gocritic
return ShortFlagToken return FlagToken
} } else if v == "-" {
return PositionalArgumentToken
} else if strings.HasPrefix(v, "-") {
return ShortFlagToken
} }
} }
return t.Type return t.Type
+7 -5
View File
@@ -7,11 +7,13 @@ import (
) )
func TestScannerTake(t *testing.T) { func TestScannerTake(t *testing.T) {
s := Scan("a", "b", "c") s := Scan("a", "b", "c", "-")
require.Equal(t, s.Pop().Value, "a") require.Equal(t, "a", s.Pop().Value)
require.Equal(t, s.Pop().Value, "b") require.Equal(t, "b", s.Pop().Value)
require.Equal(t, s.Pop().Value, "c") require.Equal(t, "c", s.Pop().Value)
require.Equal(t, s.Pop().Type, EOLToken) hyphen := s.Pop()
require.Equal(t, PositionalArgumentToken, hyphen.InferredType())
require.Equal(t, EOLToken, s.Pop().Type)
} }
func TestScannerPeek(t *testing.T) { func TestScannerPeek(t *testing.T) {