@cryptotaxi247 / kubo / commits / bc6938dc0

commands: Cleaned up argument validation

Matt Bell committed Nov 3, 2014 at 18:34 UTC bc6938dc0899c4f37b4afa1f7b32c8bc7cdfb618
1 file changed +49 -26
commands/command.go
+49 -26
@@ -140,40 +140,37 @@ func (c *Command) GetOptions(path []string) (map[string]Option, error) {
140 }
141
142 func (c *Command) CheckArguments(req Request) error {
143 - var argDef Argument
143 args := req.Arguments()
144 + argDefs := c.Arguments
145
146 - var length int
147 - if len(args) > len(c.Arguments) {
148 - length = len(args)
149 - } else {
150 - length = len(c.Arguments)
146 + // if we have more arg values provided than argument definitions,
147 + // and the last arg definition is not variadic (or there are no definitions), return an error
148 + notVariadic := len(argDefs) == 0 || !argDefs[len(argDefs)-1].Variadic
149 + if notVariadic && len(args) > len(argDefs) {
150 + return fmt.Errorf("Expected %v arguments, got %v", len(argDefs), len(args))
151 }
152
153 - for i := 0; i < length; i++ {
154 - var arg interface{}
155 - if len(args) > i {
156 - arg = args[i]
157 - }
153 + // iterate over the arg definitions
154 + for i, argDef := range c.Arguments {
155
159 - if i < len(c.Arguments) {
160 - argDef = c.Arguments[i]
161 - } else if !argDef.Variadic {
162 - return fmt.Errorf("Expected %v arguments, got %v", len(c.Arguments), len(args))
156 + // the value for this argument definition. can be nil if it wasn't provided by the caller
157 + var v interface{}
158 + if i < len(args) {
159 + v = args[i]
160 }
161
165 - if argDef.Required && arg == nil {
166 - return fmt.Errorf("Argument '%s' is required", argDef.Name)
162 + err := checkArgValue(v, argDef)
163 + if err != nil {
164 + return err
165 }
168 - if argDef.Type == ArgFile {
169 - _, ok := arg.(io.Reader)
170 - if !ok {
171 - return fmt.Errorf("Argument '%s' isn't valid", argDef.Name)
172 - }
173 - } else if argDef.Type == ArgString {
174 - _, ok := arg.(string)
175 - if !ok {
176 - return fmt.Errorf("Argument '%s' must be a string", argDef.Name)
166 +
167 + // any additional values are for the variadic arg definition
168 + if argDef.Variadic && i < len(args)-1 {
169 + for _, val := range args[i+1:] {
170 + err := checkArgValue(val, argDef)
171 + if err != nil {
172 + return err
173 + }
174 }
175 }
176 }
@@ -185,3 +182,29 @@ func (c *Command) CheckArguments(req Request) error {
182 func (c *Command) Subcommand(id string) *Command {
183 return c.Subcommands[id]
184 }
185 +
186 +// checkArgValue returns an error if a given arg value is not valid for the given Argument
187 +func checkArgValue(v interface{}, def Argument) error {
188 + if v == nil {
189 + if def.Required {
190 + return fmt.Errorf("Argument '%s' is required", def.Name)
191 + }
192 +
193 + return nil
194 + }
195 +
196 + if def.Type == ArgFile {
197 + _, ok := v.(io.Reader)
198 + if !ok {
199 + return fmt.Errorf("Argument '%s' isn't valid", def.Name)
200 + }
201 +
202 + } else if def.Type == ArgString {
203 + _, ok := v.(string)
204 + if !ok {
205 + return fmt.Errorf("Argument '%s' must be a string", def.Name)
206 + }
207 + }
208 +
209 + return nil
210 +}