@@ -44,50 +44,91 @@ func New(binaryName string, shortUsage string, longUsage, examples string) Comma
4444 }
4545}
4646
47- // ParseAndValidateFlags will parse flags registered in this instance of CLI from os.Args
48- // and then perform validation
49- func (cl * CommandLineInterface ) ParseAndValidateFlags () (map [string ]interface {}, error ) {
47+ // ParseFlags will parse flags registered in this instance of CLI from os.Args
48+ func (cl * CommandLineInterface ) ParseFlags () (map [string ]interface {}, error ) {
5049 cl .setUsageTemplate ()
5150 // Remove Suite Flags so that args only include Config and Filter Flags
52- cl .rootCmd .SetArgs (cl . removeIntersectingArgs (cl .suiteFlags ))
51+ cl .rootCmd .SetArgs (removeIntersectingArgs (cl .suiteFlags ))
5352 // This parses Config and Filter flags only
5453 err := cl .rootCmd .Execute ()
5554 if err != nil {
5655 return nil , err
5756 }
5857 // Remove Config and Filter flags so that only suite flags are parsed
59- err = cl .suiteFlags .Parse (cl . removeIntersectingArgs (cl .rootCmd .Flags ()))
58+ err = cl .suiteFlags .Parse (removeIntersectingArgs (cl .rootCmd .Flags ()))
6059 if err != nil {
6160 return nil , err
6261 }
6362 // Add suite flags to rootCmd flagset so that other processing can occur
6463 // This has to be done after usage is printed so that the flagsets can be grouped properly when printed
6564 cl .rootCmd .Flags ().AddFlagSet (cl .suiteFlags )
66- err = cl .SetUntouchedFlagValuesToNil ()
65+ err = cl .setUntouchedFlagValuesToNil ()
6766 if err != nil {
6867 return nil , err
6968 }
70- err = cl .ProcessRangeFilterFlags ()
69+ err = cl .processRangeFilterFlags ()
70+ if err != nil {
71+ return nil , err
72+ }
73+ return cl .Flags , nil
74+ }
75+
76+ // ParseAndValidateFlags will parse flags registered in this instance of CLI from os.Args
77+ // and then perform validation
78+ func (cl * CommandLineInterface ) ParseAndValidateFlags () (map [string ]interface {}, error ) {
79+ flags , err := cl .ParseFlags ()
7180 if err != nil {
7281 return nil , err
7382 }
7483 err = cl .ValidateFlags ()
7584 if err != nil {
7685 return nil , err
7786 }
78- return cl . Flags , nil
87+ return flags , nil
7988}
8089
81- func (cl * CommandLineInterface ) removeIntersectingArgs (flagSet * pflag.FlagSet ) []string {
82- newArgs := os .Args [1 :]
83- for i , arg := range newArgs {
84- if flagSet .Lookup (strings .Replace (arg , "--" , "" , 1 )) != nil || (len (arg ) == 2 && flagSet .ShorthandLookup (strings .Replace (arg , "-" , "" , 1 )) != nil ) {
85- newArgs = append (newArgs [:i ], newArgs [i + 1 :]... )
90+ // ValidateFlags iterates through any registered validators and executes them
91+ func (cl * CommandLineInterface ) ValidateFlags () error {
92+ for flagName , validationFn := range cl .validators {
93+ if validationFn == nil {
94+ continue
95+ }
96+ err := validationFn (cl .Flags [flagName ])
97+ if err != nil {
98+ return err
8699 }
87100 }
101+ return nil
102+ }
103+
104+ func removeIntersectingArgs (flagSet * pflag.FlagSet ) []string {
105+ newArgs := []string {}
106+ skipNext := false
107+ for i , arg := range os .Args {
108+ if skipNext {
109+ skipNext = false
110+ continue
111+ }
112+ arg = strings .Split (arg , "=" )[0 ]
113+ longFlag := strings .Replace (arg , "--" , "" , 1 )
114+ if flagSet .Lookup (longFlag ) != nil || shorthandLookup (flagSet , arg ) != nil {
115+ if len (os .Args ) > i + 1 && os .Args [i + 1 ][0 ] != '-' {
116+ skipNext = true
117+ }
118+ continue
119+ }
120+ newArgs = append (newArgs , os .Args [i ])
121+ }
88122 return newArgs
89123}
90124
125+ func shorthandLookup (flagSet * pflag.FlagSet , arg string ) * pflag.Flag {
126+ if len (arg ) == 2 && arg [0 ] == '-' && arg [1 ] != '-' {
127+ return flagSet .ShorthandLookup (strings .Replace (arg , "-" , "" , 1 ))
128+ }
129+ return nil
130+ }
131+
91132func (cl * CommandLineInterface ) setUsageTemplate () {
92133 transformedUsage := usageTemplate
93134 suiteFlagCount := 0
@@ -104,9 +145,9 @@ func (cl *CommandLineInterface) setUsageTemplate() {
104145 cl .rootCmd .Flags ().Usage = func () {}
105146}
106147
107- // SetUntouchedFlagValuesToNil iterates through all flags and sets their value to nil if they were not specifically set by the user
148+ // setUntouchedFlagValuesToNil iterates through all flags and sets their value to nil if they were not specifically set by the user
108149// This allows for a specified value, a negative value (like false or empty string), or an unspecified (nil) entry.
109- func (cl * CommandLineInterface ) SetUntouchedFlagValuesToNil () error {
150+ func (cl * CommandLineInterface ) setUntouchedFlagValuesToNil () error {
110151 defaultHandlerErrMsg := "Unable to find a default value handler for %v, marking as no default value. This could be an error"
111152 defaultHandlerFlags := []string {}
112153
@@ -141,8 +182,8 @@ func (cl *CommandLineInterface) SetUntouchedFlagValuesToNil() error {
141182 return nil
142183}
143184
144- // ProcessRangeFilterFlags sets min and max to the appropriate 0 or maxInt bounds based on the 3-tuple that a user specifies for base flag, min, and/or max
145- func (cl * CommandLineInterface ) ProcessRangeFilterFlags () error {
185+ // processRangeFilterFlags sets min and max to the appropriate 0 or maxInt bounds based on the 3-tuple that a user specifies for base flag, min, and/or max
186+ func (cl * CommandLineInterface ) processRangeFilterFlags () error {
146187 for flagName := range cl .intRangeFlags {
147188 rangeHelperMin := fmt .Sprintf ("%s-%s" , flagName , "min" )
148189 rangeHelperMax := fmt .Sprintf ("%s-%s" , flagName , "max" )
@@ -167,17 +208,3 @@ func (cl *CommandLineInterface) ProcessRangeFilterFlags() error {
167208 }
168209 return nil
169210}
170-
171- // ValidateFlags iterates through any registered validators and executes them
172- func (cl * CommandLineInterface ) ValidateFlags () error {
173- for flagName , validationFn := range cl .validators {
174- if validationFn == nil {
175- continue
176- }
177- err := validationFn (cl .Flags [flagName ])
178- if err != nil {
179- return err
180- }
181- }
182- return nil
183- }
0 commit comments