From 0d1fbaa1a93bb9c9e8f1a78f80f99ff742c70723 Mon Sep 17 00:00:00 2001 From: yougg Date: Mon, 29 Aug 2022 11:49:19 +0800 Subject: [PATCH 1/3] correct match parsed flag when it has same shortname with subcommand --- parser.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/parser.go b/parser.go index 08a23bf..79a846c 100644 --- a/parser.go +++ b/parser.go @@ -6,7 +6,6 @@ import ( "os" "strconv" "strings" - "text/template" ) @@ -94,7 +93,8 @@ func findArgsNotInParsedValues(args []string, parsedValues []parsedValue) []stri // if the final argument (--) is seen, then we stop checking because all // further values are trailing arguments. - if determineArgType(a) == argIsFinal { + argType := determineArgType(a) + if argType == argIsFinal { return argsNotUsed } @@ -122,10 +122,10 @@ func findArgsNotInParsedValues(args []string, parsedValues []parsedValue) []stri // search all args for a corresponding parsed value for _, pv := range parsedValues { - // this argumenet was a key + // this argument was a key // debugPrint(pv.Key, "==", arg) debugPrint(pv.Key + "==" + arg + " || (" + strconv.FormatBool(pv.IsPositional) + " && " + pv.Value + " == " + arg + ")") - if pv.Key == arg || (pv.IsPositional && pv.Value == arg) { + if pv.Key == arg || (argType == argIsPositional && pv.IsPositional && pv.Value == arg) { debugPrint("Found matching parsed arg for " + pv.Key) foundArgUsed = true // the arg was used in this parsedValues set // if the value is not a positional value and the parsed value had a From e64624f2dc647ada2c7e62a745ff83c66c1a4f02 Mon Sep 17 00:00:00 2001 From: yougg Date: Fri, 16 Sep 2022 17:15:04 +0800 Subject: [PATCH 2/3] print help arguments with original flag and args --- parser.go | 2 +- subCommand.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/parser.go b/parser.go index 79a846c..15bf97f 100644 --- a/parser.go +++ b/parser.go @@ -145,7 +145,7 @@ func findArgsNotInParsedValues(args []string, parsedValues []parsedValue) []stri // if the arg was not used in any parsed values, then we add it to the slice // of arguments not used if !foundArgUsed { - argsNotUsed = append(argsNotUsed, arg) + argsNotUsed = append(argsNotUsed, a) } } diff --git a/subCommand.go b/subCommand.go index c82c081..9d46c2b 100644 --- a/subCommand.go +++ b/subCommand.go @@ -162,7 +162,7 @@ func (sc *Subcommand) parseAllFlagsFromArgs(p *Parser, args []string) ([]string, // if the next arg was not found, then show a Help message if !nextArgExists { - p.ShowHelpWithMessage("Expected a following arg for flag " + a + ", but it did not exist.") + p.ShowHelpWithMessage("Expected a following arg for flag " + args[i] + ", but it did not exist.") exitOrPanic(2) } valueSet, err := setValueForParsers(a, nextArg, p, sc) From 30da54c9700e68b371d54c3be807554da2b2c746 Mon Sep 17 00:00:00 2001 From: yougg Date: Tue, 27 Sep 2022 10:32:41 +0800 Subject: [PATCH 3/3] support user defined slice flag value separator --- flag.go | 23 ++++++++++++++--------- flag_test.go | 11 +++++++++++ flaggy.go | 4 ++-- subCommand.go | 9 ++++++--- subcommand_test.go | 10 ++++++++++ 5 files changed, 43 insertions(+), 14 deletions(-) diff --git a/flag.go b/flag.go index cdd4491..7c0b611 100644 --- a/flag.go +++ b/flag.go @@ -12,14 +12,15 @@ import ( // Flag holds the base methods for all flag types type Flag struct { - ShortName string - LongName string - Description string - rawValue string // the value as a string before being parsed - Hidden bool // indicates this flag should be hidden from help and suggestions - AssignmentVar interface{} - defaultValue string // the value (as a string), that was set by default before any parsing and assignment - parsed bool // indicates that this flag has already been parsed + ShortName string + LongName string + Description string + rawValue string // the value as a string before being parsed + Hidden bool // indicates this flag should be hidden from help and suggestions + AssignmentVar interface{} + ValueSeparator string + defaultValue string // the value (as a string), that was set by default before any parsing and assignment + parsed bool // indicates that this flag has already been parsed } // HasName indicates that this flag's short or long name matches the @@ -62,7 +63,11 @@ func (f *Flag) identifyAndAssignValue(value string) error { *v = value case *[]string: v := f.AssignmentVar.(*[]string) - splitString := strings.Split(value, ",") + sep := `,` + if f.ValueSeparator != `` { + sep = f.ValueSeparator + } + splitString := strings.Split(value, sep) new := append(*v, splitString...) *v = new case *bool: diff --git a/flag_test.go b/flag_test.go index 5c2c7ae..1dfe925 100644 --- a/flag_test.go +++ b/flag_test.go @@ -94,6 +94,11 @@ func TestInputParsing(t *testing.T) { inputArgs = append(inputArgs, "-ssf", "one", "-ssf", "two") var stringSliceFlagExpected = []string{"one", "two"} + var stringSlicePipeFlag []string + StringSlice(&stringSlicePipeFlag, "sspf", "stringSlice1", "string slice flag", `|`) + inputArgs = append(inputArgs, "-sspf", "one|two|three") + var stringSlicePipeFlagExpected = []string{"one", "two", "three"} + var boolFlag bool Bool(&boolFlag, "bf", "bool", "bool flag") inputArgs = append(inputArgs, "-bf") @@ -306,6 +311,12 @@ func TestInputParsing(t *testing.T) { } } + for i, f := range stringSlicePipeFlagExpected { + if stringSlicePipeFlag[i] != f { + t.Fatal("stringSlice value incorrect", stringSlicePipeFlag[i], f) + } + } + if boolFlag != boolFlagExpected { t.Fatal("bool flag incorrect", boolFlag, boolFlagExpected) } diff --git a/flaggy.go b/flaggy.go index e850823..c9d3aa2 100644 --- a/flaggy.go +++ b/flaggy.go @@ -85,8 +85,8 @@ func String(assignmentVar *string, shortName string, longName string, descriptio // StringSlice adds a new slice of strings flag // Specify the flag multiple times to fill the slice -func StringSlice(assignmentVar *[]string, shortName string, longName string, description string) { - DefaultParser.add(assignmentVar, shortName, longName, description) +func StringSlice(assignmentVar *[]string, shortName, longName, description string, separator ...string) { + DefaultParser.add(assignmentVar, shortName, longName, description, separator...) } // Bool adds a new bool flag diff --git a/subCommand.go b/subCommand.go index 9d46c2b..0c843a3 100644 --- a/subCommand.go +++ b/subCommand.go @@ -430,7 +430,7 @@ func (sc *Subcommand) AttachSubcommand(newSC *Subcommand, relativePosition int) // add is a "generic" to add flags of any type. Checks the supplied parent // parser to ensure that the user isn't setting version or help flags that // conflict with the built-in help and version flag behavior. -func (sc *Subcommand) add(assignmentVar interface{}, shortName string, longName string, description string) { +func (sc *Subcommand) add(assignmentVar interface{}, shortName, longName, description string, separator ...string) { // if the flag is already used, throw an error for _, existingFlag := range sc.Flags { @@ -448,6 +448,9 @@ func (sc *Subcommand) add(assignmentVar interface{}, shortName string, longName LongName: longName, Description: description, } + if len(separator) > 0 { + newFlag.ValueSeparator = separator[0] + } sc.Flags = append(sc.Flags, &newFlag) } @@ -458,8 +461,8 @@ func (sc *Subcommand) String(assignmentVar *string, shortName string, longName s // StringSlice adds a new slice of strings flag // Specify the flag multiple times to fill the slice -func (sc *Subcommand) StringSlice(assignmentVar *[]string, shortName string, longName string, description string) { - sc.add(assignmentVar, shortName, longName, description) +func (sc *Subcommand) StringSlice(assignmentVar *[]string, shortName, longName, description string, separator ...string) { + sc.add(assignmentVar, shortName, longName, description, separator...) } // Bool adds a new bool flag diff --git a/subcommand_test.go b/subcommand_test.go index d47c3ee..9cb9dbf 100644 --- a/subcommand_test.go +++ b/subcommand_test.go @@ -385,6 +385,11 @@ func TestSCInputParsing(t *testing.T) { inputArgs = append(inputArgs, "-sscf", "one,two") var stringSliceCommaFlagExpected = []string{"one", "two"} + var stringSlicePipeFlag []string + sc.StringSlice(&stringSlicePipeFlag, "sspf", "stringSlice1", "string slice flag", `|`) + inputArgs = append(inputArgs, "-sspf", "one|two|three") + var stringSlicePipeFlagExpected = []string{"one", "two", "three"} + var boolFlag bool sc.Bool(&boolFlag, "bf", "bool", "bool flag") inputArgs = append(inputArgs, "-bf") @@ -601,6 +606,11 @@ func TestSCInputParsing(t *testing.T) { t.Fatal("stringSlice value incorrect", stringSliceCommaFlag[i], f) } } + for i, f := range stringSlicePipeFlagExpected { + if stringSlicePipeFlag[i] != f { + t.Fatal("stringSlice value incorrect", stringSlicePipeFlag[i], f) + } + } if boolFlag != boolFlagExpected { t.Fatal("bool flag incorrect", boolFlag, boolFlagExpected)