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:
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.
case v == "--":
c.scan.Pop()
@@ -305,9 +311,6 @@ func (c *Context) trace(node *Node) (err error) { // nolint: gocyclo
}
c.scan.PushTyped(parts[0], FlagToken)
case v == "-":
return errors.New("expected short flag")
// Short flag.
case strings.HasPrefix(v, "-"):
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(v[1:2], ShortFlagToken)
default:
c.scan.Pop()
c.scan.PushTyped(token.Value, PositionalArgumentToken)
}
default:
c.scan.Pop()
+16
View File
@@ -863,3 +863,19 @@ func TestMultipleDefaultCommands(t *testing.T) {
_, err := p.Parse([]string{})
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.
func (t Token) InferredType() TokenType {
if t.Type == UntypedToken {
if v, ok := t.Value.(string); ok {
if strings.HasPrefix(v, "--") {
return FlagToken
} else if strings.HasPrefix(v, "-") {
return ShortFlagToken
}
if t.Type != UntypedToken {
return t.Type
}
if v, ok := t.Value.(string); ok {
if strings.HasPrefix(v, "--") { // nolint: gocritic
return FlagToken
} else if v == "-" {
return PositionalArgumentToken
} else if strings.HasPrefix(v, "-") {
return ShortFlagToken
}
}
return t.Type
+7 -5
View File
@@ -7,11 +7,13 @@ import (
)
func TestScannerTake(t *testing.T) {
s := Scan("a", "b", "c")
require.Equal(t, s.Pop().Value, "a")
require.Equal(t, s.Pop().Value, "b")
require.Equal(t, s.Pop().Value, "c")
require.Equal(t, s.Pop().Type, EOLToken)
s := Scan("a", "b", "c", "-")
require.Equal(t, "a", s.Pop().Value)
require.Equal(t, "b", s.Pop().Value)
require.Equal(t, "c", s.Pop().Value)
hyphen := s.Pop()
require.Equal(t, PositionalArgumentToken, hyphen.InferredType())
require.Equal(t, EOLToken, s.Pop().Type)
}
func TestScannerPeek(t *testing.T) {