Check required after parsing
diff --git a/command_private.go b/command_private.go
index bd97cc7..7c7c53c 100644
--- a/command_private.go
+++ b/command_private.go
@@ -11,7 +11,6 @@
shortNames map[string]*Option
longNames map[string]*Option
- required map[*Option]bool
commands map[string]*Command
}
@@ -104,17 +103,11 @@
ret := lookup{
shortNames: make(map[string]*Option),
longNames: make(map[string]*Option),
-
- required: make(map[*Option]bool),
commands: make(map[string]*Command),
}
c.eachGroup(func(g *Group) {
for _, option := range g.options {
- if option.Required && option.canCli() {
- ret.required[option] = true
- }
-
if option.ShortName != 0 {
ret.shortNames[string(option.ShortName)] = option
}
diff --git a/parser.go b/parser.go
index b6889cf..8fe4f78 100644
--- a/parser.go
+++ b/parser.go
@@ -162,15 +162,14 @@
}
var err error
- var options []*Option
prefix, optname, islong := stripOptionPrefix(arg)
optname, argument := splitOption(prefix, optname, islong)
if islong {
- options, err = p.parseLong(s, optname, argument)
+ err = p.parseLong(s, optname, argument)
} else {
- options, err = p.parseShort(s, optname, argument)
+ err = p.parseShort(s, optname, argument)
}
if err != nil {
@@ -185,10 +184,6 @@
if ignoreUnknown {
s.retargs = append(s.retargs, arg)
}
- } else {
- for _, option := range options {
- delete(s.lookup.required, option)
- }
}
}
@@ -205,7 +200,7 @@
})
}, true)
- s.checkRequired()
+ s.checkRequired(p)
}
var reterr error
diff --git a/parser_private.go b/parser_private.go
index 47fbd4e..23b0ee9 100644
--- a/parser_private.go
+++ b/parser_private.go
@@ -42,8 +42,22 @@
return p.args[0]
}
-func (p *parseState) checkRequired() error {
- required := p.lookup.required
+func (p *parseState) checkRequired(parser *Parser) error {
+ c := parser.Command
+
+ required := make([]*Option, 0)
+
+ for c != nil {
+ c.eachGroup(func (g *Group) {
+ for _, option := range g.options {
+ if !option.isSet && option.Required {
+ required = append(required, option)
+ }
+ }
+ })
+
+ c = c.Active
+ }
if len(required) == 0 {
return nil
@@ -51,7 +65,7 @@
names := make([]string, 0, len(required))
- for k := range required {
+ for _, k := range required {
names = append(names, "`"+k.String()+"'")
}
@@ -155,20 +169,16 @@
return err
}
-func (p *Parser) parseLong(s *parseState, name string, argument *string) (options []*Option, err error) {
+func (p *Parser) parseLong(s *parseState, name string, argument *string) error {
if option := s.lookup.longNames[name]; option != nil {
- options = append(options, option)
-
// Only long options that are required can consume an argument
// from the argument list
canarg := !option.OptionalArgument
- err := p.parseOption(s, name, option, canarg, argument)
-
- return options, err
+ return p.parseOption(s, name, option, canarg, argument)
}
- return nil, newError(ErrUnknownFlag, fmt.Sprintf("unknown flag `%s'", name))
+ return newError(ErrUnknownFlag, fmt.Sprintf("unknown flag `%s'", name))
}
func (p *Parser) splitShortConcatArg(s *parseState, optname string) (string, *string) {
@@ -188,7 +198,7 @@
return optname, nil
}
-func (p *Parser) parseShort(s *parseState, optname string, argument *string) (options []*Option, err error) {
+func (p *Parser) parseShort(s *parseState, optname string, argument *string) error {
if argument == nil {
optname, argument = p.splitShortConcatArg(s, optname)
}
@@ -197,17 +207,15 @@
shortname := string(c)
if option := s.lookup.shortNames[shortname]; option != nil {
- options = append(options, option)
-
// Only the last short argument can consume an argument from
// the arguments list, and only if it's non optional
canarg := (i+utf8.RuneLen(c) == len(optname)) && !option.OptionalArgument
if err := p.parseOption(s, shortname, option, canarg, argument); err != nil {
- return options, err
+ return err
}
} else {
- return nil, newError(ErrUnknownFlag, fmt.Sprintf("unknown flag `%s'", shortname))
+ return newError(ErrUnknownFlag, fmt.Sprintf("unknown flag `%s'", shortname))
}
// Only the first option can have a concatted argument, so just
@@ -215,15 +223,11 @@
argument = nil
}
- return options, nil
+ return nil
}
func (p *Parser) parseNonOption(s *parseState) error {
if cmd := s.lookup.commands[s.arg]; cmd != nil {
- if err := s.checkRequired(); err != nil {
- return err
- }
-
s.command.Active = cmd
s.command = cmd