chore: optionally allow parsing of hyphen-prefixied flag parameters
This allows for eg. `foo --number -10`, `foo --flag -bar`. Fixes #478, #315.
This commit is contained in:
+1
-1
@@ -99,7 +99,7 @@ type Context struct {
|
||||
// This just constructs a new trace. To fully apply the trace you must call Reset(), Resolve(),
|
||||
// Validate() and Apply().
|
||||
func Trace(k *Kong, args []string) (*Context, error) {
|
||||
s := Scan(args...)
|
||||
s := Scan(args...).AllowHyphenPrefixedParameters(k.allowHyphenated)
|
||||
c := &Context{
|
||||
Kong: k,
|
||||
Args: args,
|
||||
|
||||
@@ -56,16 +56,17 @@ type Kong struct {
|
||||
registry *Registry
|
||||
ignoreFields []*regexp.Regexp
|
||||
|
||||
noDefaultHelp bool
|
||||
usageOnError usageOnError
|
||||
help HelpPrinter
|
||||
shortHelp HelpPrinter
|
||||
helpFormatter HelpValueFormatter
|
||||
helpOptions HelpOptions
|
||||
helpFlag *Flag
|
||||
groups []Group
|
||||
vars Vars
|
||||
flagNamer func(string) string
|
||||
noDefaultHelp bool
|
||||
allowHyphenated bool
|
||||
usageOnError usageOnError
|
||||
help HelpPrinter
|
||||
shortHelp HelpPrinter
|
||||
helpFormatter HelpValueFormatter
|
||||
helpOptions HelpOptions
|
||||
helpFlag *Flag
|
||||
groups []Group
|
||||
vars Vars
|
||||
flagNamer func(string) string
|
||||
|
||||
// Set temporarily by Options. These are applied after build().
|
||||
postBuildOptions []Option
|
||||
|
||||
+36
-9
@@ -1043,15 +1043,6 @@ func TestParentBindings(t *testing.T) {
|
||||
assert.Equal(t, "foo", cli.Command.value)
|
||||
}
|
||||
|
||||
func TestNumericParamErrors(t *testing.T) {
|
||||
var cli struct {
|
||||
Name string
|
||||
}
|
||||
parser := mustNew(t, &cli)
|
||||
_, err := parser.Parse([]string{"--name", "-10"})
|
||||
assert.EqualError(t, err, `--name: expected string value but got "-10" (short flag); perhaps try --name="-10"?`)
|
||||
}
|
||||
|
||||
func TestDefaultValueIsHyphen(t *testing.T) {
|
||||
var cli struct {
|
||||
Flag string `default:"-"`
|
||||
@@ -2677,3 +2668,39 @@ func TestProviderWithoutError(t *testing.T) {
|
||||
err = kctx.Run()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestParseHyphenParameter(t *testing.T) {
|
||||
type shortFlag struct {
|
||||
Flag string `short:"f"`
|
||||
Other string `short:"o"`
|
||||
Numeric int `short:"n"`
|
||||
}
|
||||
|
||||
t.Run("ShortFlag", func(t *testing.T) {
|
||||
actual := &shortFlag{}
|
||||
_, err := mustNew(t, actual, kong.WithHyphenPrefixedParameters(true)).Parse([]string{"-f", "-foo"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, &shortFlag{Flag: "-foo"}, actual)
|
||||
})
|
||||
|
||||
t.Run("LongFlag", func(t *testing.T) {
|
||||
actual := &shortFlag{}
|
||||
_, err := mustNew(t, actual, kong.WithHyphenPrefixedParameters(true)).Parse([]string{"--flag", "-foo"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, &shortFlag{Flag: "-foo"}, actual)
|
||||
})
|
||||
|
||||
t.Run("ParamMatchesFlag", func(t *testing.T) {
|
||||
actual := &shortFlag{}
|
||||
_, err := mustNew(t, actual, kong.WithHyphenPrefixedParameters(true)).Parse([]string{"--flag", "-oo"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, &shortFlag{Flag: "-oo"}, actual)
|
||||
})
|
||||
|
||||
t.Run("NegativeNumber", func(t *testing.T) {
|
||||
actual := &shortFlag{}
|
||||
_, err := mustNew(t, actual, kong.WithHyphenPrefixedParameters(true)).Parse([]string{"--numeric", "-10"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, &shortFlag{Numeric: -10}, actual)
|
||||
})
|
||||
}
|
||||
|
||||
+10
@@ -55,6 +55,16 @@ func Exit(exit func(int)) Option {
|
||||
})
|
||||
}
|
||||
|
||||
// WithHyphenPrefixedParameters enables or disables hyphen-prefixed parameters.
|
||||
//
|
||||
// These are disabled by default.
|
||||
func WithHyphenPrefixedParameters(enable bool) Option {
|
||||
return OptionFunc(func(k *Kong) error {
|
||||
k.allowHyphenated = enable
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
type embedded struct {
|
||||
strct any
|
||||
tags []string
|
||||
|
||||
+11
-2
@@ -111,7 +111,8 @@ func (t Token) IsValue() bool {
|
||||
//
|
||||
// [{FlagToken, "foo"}, {FlagValueToken, "bar"}]
|
||||
type Scanner struct {
|
||||
args []Token
|
||||
allowHyphenated bool
|
||||
args []Token
|
||||
}
|
||||
|
||||
// ScanAsType creates a new Scanner from args with the given type.
|
||||
@@ -133,6 +134,14 @@ func ScanFromTokens(tokens ...Token) *Scanner {
|
||||
return &Scanner{args: tokens}
|
||||
}
|
||||
|
||||
// AllowHyphenPrefixedParameters enables or disables hyphen-prefixed flag parameters on this Scanner.
|
||||
//
|
||||
// Disabled by default.
|
||||
func (s *Scanner) AllowHyphenPrefixedParameters(enable bool) *Scanner {
|
||||
s.allowHyphenated = enable
|
||||
return s
|
||||
}
|
||||
|
||||
// Len returns the number of input arguments.
|
||||
func (s *Scanner) Len() int {
|
||||
return len(s.args)
|
||||
@@ -162,7 +171,7 @@ func (e *expectedError) Error() string {
|
||||
// "context" is used to assist the user if the value can not be popped, eg. "expected <context> value but got <type>"
|
||||
func (s *Scanner) PopValue(context string) (Token, error) {
|
||||
t := s.Pop()
|
||||
if !t.IsValue() {
|
||||
if !s.allowHyphenated && !t.IsValue() {
|
||||
return t, &expectedError{context, t}
|
||||
}
|
||||
return t, nil
|
||||
|
||||
Reference in New Issue
Block a user