diff options
| author | Kenneth Shaw <[email protected]> | 2017-03-03 19:12:17 +0700 |
|---|---|---|
| committer | Kenneth Shaw <[email protected]> | 2017-03-04 09:13:12 +0700 |
| commit | d4c2b35b2ef5b67c3ec6f904cea0dff806d51e2c (patch) | |
| tree | 7c7b0944f564159efb512ceca0c562c475249960 /parse.go | |
| parent | 8488cf10ceffaa0c78f84ce82b38374c3e546940 (diff) | |
Adding separate tag option
As outlined in #49, there is a need to mimic the behavior of other
applications by interweaving positional and non-positional parameters.
This change adds the 'separate' option that will force a arg of type
[]string to only read the next supplied value.
For example, when dealing with the following arg type:
var MyArgs struct {
Pos []string `arg:"positional"`
Separate []string `arg:"-s,separate"`
}
This commit will parse the following command line:
./app pos1 pos2 -s=separate1 -s=separate2 pos3 -s=separate3 pos4
Such that MyArgs.Pos will be [pos1 pos2 pos3 pos4] and MyArgs.Separate
will be [separate1 separate2 separate3].
Unit tests for the above have also been written and are included in this
commit, as well as the addition of a section to README.md and an example
func in example_test.go.
Fixes #49
Diffstat (limited to 'parse.go')
| -rw-r--r-- | parse.go | 14 |
1 files changed, 10 insertions, 4 deletions
@@ -20,6 +20,7 @@ type spec struct { multiple bool required bool positional bool + separate bool help string env string wasPresent bool @@ -189,6 +190,8 @@ func NewParser(config Config, dests ...interface{}) (*Parser, error) { spec.required = true case key == "positional": spec.positional = true + case key == "separate": + spec.separate = true case key == "help": spec.help = value case key == "env": @@ -314,11 +317,14 @@ func process(specs []*spec, args []string) error { for i+1 < len(args) && !isFlag(args[i+1]) { values = append(values, args[i+1]) i++ + if spec.separate { + break + } } } else { values = append(values, value) } - err := setSlice(spec.dest, values) + err := setSlice(spec.dest, values, !spec.separate) if err != nil { return fmt.Errorf("error processing %s: %v", arg, err) } @@ -350,7 +356,7 @@ func process(specs []*spec, args []string) error { for _, spec := range specs { if spec.positional { if spec.multiple { - err := setSlice(spec.dest, positionals) + err := setSlice(spec.dest, positionals, true) if err != nil { return fmt.Errorf("error processing %s: %v", spec.long, err) } @@ -388,7 +394,7 @@ func validate(spec []*spec) error { } // parse a value as the appropriate type and store it in the struct -func setSlice(dest reflect.Value, values []string) error { +func setSlice(dest reflect.Value, values []string, trunc bool) error { if !dest.CanSet() { return fmt.Errorf("field is not writable") } @@ -401,7 +407,7 @@ func setSlice(dest reflect.Value, values []string) error { } // Truncate the dest slice in case default values exist - if !dest.IsNil() { + if trunc && !dest.IsNil() { dest.SetLen(0) } |
