Allow using unabiguous long option prefixes
This commit is contained in:
parent
7d5849cc17
commit
74b1cac344
@ -347,6 +347,30 @@ func (self *Command) Add(s OptionSpec) *Option {
|
|||||||
return self.AddToGroup("", s)
|
return self.AddToGroup("", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Command) FindOptions(name_with_hyphens string) []*Option {
|
||||||
|
ans := make([]*Option, 0, 4)
|
||||||
|
for _, g := range self.OptionGroups {
|
||||||
|
x := g.FindOptions(name_with_hyphens)
|
||||||
|
if x != nil {
|
||||||
|
ans = append(ans, x...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
depth := 0
|
||||||
|
for p := self.Parent; p != nil; p = p.Parent {
|
||||||
|
depth++
|
||||||
|
x := p.FindOptions(name_with_hyphens)
|
||||||
|
if x != nil {
|
||||||
|
for _, po := range x {
|
||||||
|
if po.Depth >= depth {
|
||||||
|
ans = append(ans, po)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ans
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Command) FindOption(name_with_hyphens string) *Option {
|
func (self *Command) FindOption(name_with_hyphens string) *Option {
|
||||||
for _, g := range self.OptionGroups {
|
for _, g := range self.OptionGroups {
|
||||||
q := g.FindOption(name_with_hyphens)
|
q := g.FindOption(name_with_hyphens)
|
||||||
|
|||||||
@ -82,6 +82,19 @@ func (self *OptionGroup) AddOptionFromString(parent *Command, items ...string) (
|
|||||||
return ans, err
|
return ans, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *OptionGroup) FindOptions(prefix_with_hyphens string) []*Option {
|
||||||
|
is_short := !strings.HasPrefix(prefix_with_hyphens, "--")
|
||||||
|
option_name := NormalizeOptionName(prefix_with_hyphens)
|
||||||
|
ans := make([]*Option, 0, 4)
|
||||||
|
for _, q := range self.Options {
|
||||||
|
if q.MatchingAlias(option_name, is_short) != "" {
|
||||||
|
ans = append(ans, q)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ans
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (self *OptionGroup) FindOption(name_with_hyphens string) *Option {
|
func (self *OptionGroup) FindOption(name_with_hyphens string) *Option {
|
||||||
is_short := !strings.HasPrefix(name_with_hyphens, "--")
|
is_short := !strings.HasPrefix(name_with_hyphens, "--")
|
||||||
option_name := NormalizeOptionName(name_with_hyphens)
|
option_name := NormalizeOptionName(name_with_hyphens)
|
||||||
|
|||||||
@ -75,6 +75,15 @@ func (self *Option) needs_argument() bool {
|
|||||||
return self.OptionType != BoolOption && self.OptionType != CountOption
|
return self.OptionType != BoolOption && self.OptionType != CountOption
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Option) MatchingAlias(prefix_without_hyphens string, is_short bool) string {
|
||||||
|
for _, a := range self.Aliases {
|
||||||
|
if a.IsShort == is_short && strings.HasPrefix(a.NameWithoutHyphens, prefix_without_hyphens) {
|
||||||
|
return a.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Option) HasAlias(name_without_hyphens string, is_short bool) bool {
|
func (self *Option) HasAlias(name_without_hyphens string, is_short bool) bool {
|
||||||
for _, a := range self.Aliases {
|
for _, a := range self.Aliases {
|
||||||
if a.IsShort == is_short && a.NameWithoutHyphens == name_without_hyphens {
|
if a.IsShort == is_short && a.NameWithoutHyphens == name_without_hyphens {
|
||||||
|
|||||||
@ -20,9 +20,19 @@ func (self *Command) parse_args(ctx *Context, args []string) error {
|
|||||||
consume_arg := func() string { ans := args_to_parse[0]; args_to_parse = args_to_parse[1:]; return ans }
|
consume_arg := func() string { ans := args_to_parse[0]; args_to_parse = args_to_parse[1:]; return ans }
|
||||||
|
|
||||||
handle_option := func(opt_str string, has_val bool, opt_val string, val_not_allowed bool) error {
|
handle_option := func(opt_str string, has_val bool, opt_val string, val_not_allowed bool) error {
|
||||||
opt := self.FindOption(opt_str)
|
possible_options := self.FindOptions(opt_str)
|
||||||
if opt == nil {
|
var opt *Option
|
||||||
|
if len(possible_options) == 1 {
|
||||||
|
opt = possible_options[0]
|
||||||
|
opt_str = opt.MatchingAlias(NormalizeOptionName(opt_str), !strings.HasPrefix(opt_str, "--"))
|
||||||
|
} else if len(possible_options) == 0 {
|
||||||
return &ParseError{Message: fmt.Sprintf("Unknown option: :yellow:`%s`", opt_str)}
|
return &ParseError{Message: fmt.Sprintf("Unknown option: :yellow:`%s`", opt_str)}
|
||||||
|
} else {
|
||||||
|
ambi := make([]string, len(possible_options))
|
||||||
|
for i, o := range possible_options {
|
||||||
|
ambi[i] = o.MatchingAlias(NormalizeOptionName(opt_str), !strings.HasPrefix(opt_str, "--"))
|
||||||
|
}
|
||||||
|
return &ParseError{Message: fmt.Sprintf("Ambiguous option: :yellow:`%s` could be any of: %s", opt_str, strings.Join(ambi, ", "))}
|
||||||
}
|
}
|
||||||
opt.seen_option = opt_str
|
opt.seen_option = opt_str
|
||||||
needs_arg := opt.needs_argument()
|
needs_arg := opt.needs_argument()
|
||||||
|
|||||||
@ -85,8 +85,9 @@ func TestCLIParsing(t *testing.T) {
|
|||||||
)
|
)
|
||||||
rt(child1, "test child1", &options{})
|
rt(child1, "test child1", &options{})
|
||||||
rt(child1, "test child1 --set-me --simple-string=foo one", &options{SimpleString: "foo", SetMe: true}, "one")
|
rt(child1, "test child1 --set-me --simple-string=foo one", &options{SimpleString: "foo", SetMe: true}, "one")
|
||||||
|
rt(child1, "test child1 --set-me --simp=foo one", &options{SimpleString: "foo", SetMe: true}, "one")
|
||||||
rt(child1, "test child1 --set-me --simple-string= one", &options{SetMe: true}, "one")
|
rt(child1, "test child1 --set-me --simple-string= one", &options{SetMe: true}, "one")
|
||||||
rt(child1, "test child1 --int -3 --simple-string -s --float=3.3", &options{SimpleString: "-s", Int: -3, Float: 3.3})
|
rt(child1, "test child1 --int -3 --simple-s -s --float=3.3", &options{SimpleString: "-s", Int: -3, Float: 3.3})
|
||||||
rt(child1, "test child1 --list -3 -p --list one", &options{FromParent: 1, List: []string{"-3", "one"}})
|
rt(child1, "test child1 --list -3 -p --list one", &options{FromParent: 1, List: []string{"-3", "one"}})
|
||||||
rt(gc1, "test -p child1 -p gc1 xxx", &empty_options{}, "xxx")
|
rt(gc1, "test -p child1 -p gc1 xxx", &empty_options{}, "xxx")
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user