diff options
| author | Alex Flint <[email protected]> | 2019-10-08 16:39:00 -0700 |
|---|---|---|
| committer | Alex Flint <[email protected]> | 2019-10-08 16:39:00 -0700 |
| commit | 0c952979908ba4db23086ffdbdfa3bca01f174e0 (patch) | |
| tree | ed7dc105f7e9e22736b43bafc3712c7a7bdd151d /parse.go | |
| parent | 873f3c2cf4ec11ac4cab84a6ebaf61f695ab8b68 (diff) | |
add support for default values in struct tags
Diffstat (limited to 'parse.go')
| -rw-r--r-- | parse.go | 39 |
1 files changed, 33 insertions, 6 deletions
@@ -54,6 +54,7 @@ type spec struct { help string env string boolean bool + defaultVal string // default value for this option, only if provided as a struct tag } // command represents a named subcommand, or the top-level command @@ -250,6 +251,11 @@ func cmdFromStruct(name string, dest path, t reflect.Type) (*command, error) { spec.help = help } + defaultVal, hasDefault := field.Tag.Lookup("default") + if hasDefault { + spec.defaultVal = defaultVal + } + // Look at the tag var isSubcommand bool // tracks whether this field is a subcommand if tag != "" { @@ -274,6 +280,11 @@ func cmdFromStruct(name string, dest path, t reflect.Type) (*command, error) { } spec.short = key[1:] case key == "required": + if hasDefault { + errs = append(errs, fmt.Sprintf("%s.%s: 'required' cannot be used when a default value is specified", + t.Name(), field.Name)) + return false + } spec.required = true case key == "positional": spec.positional = true @@ -328,6 +339,11 @@ func cmdFromStruct(name string, dest path, t reflect.Type) (*command, error) { t.Name(), field.Name, field.Type.String())) return false } + if spec.multiple && hasDefault { + errs = append(errs, fmt.Sprintf("%s.%s: default values are not supported for slice fields", + t.Name(), field.Name)) + return false + } } // if this was an embedded field then we already returned true up above @@ -570,15 +586,26 @@ func (p *Parser) process(args []string) error { return fmt.Errorf("too many positional arguments at '%s'", positionals[0]) } - // finally check that all the required args were provided + // fill in defaults and check that all the required args were provided for _, spec := range specs { - if spec.required && !wasPresent[spec] { - name := spec.long - if !spec.positional { - name = "--" + spec.long - } + if wasPresent[spec] { + continue + } + + name := spec.long + if !spec.positional { + name = "--" + spec.long + } + + if spec.required { return fmt.Errorf("%s is required", name) } + if spec.defaultVal != "" { + err := scalar.ParseValue(p.val(spec.dest), spec.defaultVal) + if err != nil { + return fmt.Errorf("error processing default value for %s: %v", name, err) + } + } } return nil |
