summaryrefslogtreecommitdiff
path: root/parse.go
diff options
context:
space:
mode:
authorKenneth Shaw <[email protected]>2017-03-03 19:12:17 +0700
committerKenneth Shaw <[email protected]>2017-03-04 09:13:12 +0700
commitd4c2b35b2ef5b67c3ec6f904cea0dff806d51e2c (patch)
tree7c7b0944f564159efb512ceca0c562c475249960 /parse.go
parent8488cf10ceffaa0c78f84ce82b38374c3e546940 (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.go14
1 files changed, 10 insertions, 4 deletions
diff --git a/parse.go b/parse.go
index 60f35ee..4f62c60 100644
--- a/parse.go
+++ b/parse.go
@@ -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)
}