@cryptotaxi247 / kubo / commits / 116041c5e

commands: Fixed argument value/definition mapping

Matt Bell committed Nov 4, 2014 at 17:41 UTC 116041c5ec52335bbafe1755c05f3f30bbe2a70d
3 files changed +85 -19
commands/cli/parse.go
+42 -9
@@ -117,25 +117,58 @@ func parseOptions(input []string) (map[string]interface{}, []string, error) {
117 }
118
119 func parseArgs(stringArgs []string, cmd *cmds.Command) ([]interface{}, error) {
120 - var argDef cmds.Argument
121 - args := make([]interface{}, len(stringArgs))
120 + args := make([]interface{}, 0)
121
123 - for i, arg := range stringArgs {
124 - if i < len(cmd.Arguments) {
125 - argDef = cmd.Arguments[i]
122 + // count required argument definitions
123 + lenRequired := 0
124 + for _, argDef := range cmd.Arguments {
125 + if argDef.Required {
126 + lenRequired++
127 }
128 + }
129
128 - if argDef.Type == cmds.ArgString {
129 - args[i] = arg
130 + j := 0
131 + for _, argDef := range cmd.Arguments {
132 + // skip optional argument definitions if there aren't sufficient remaining values
133 + if len(stringArgs)-j <= lenRequired && !argDef.Required {
134 + continue
135 + }
136
137 + if j >= len(stringArgs) {
138 + break
139 + }
140 +
141 + if argDef.Variadic {
142 + for _, arg := range stringArgs[j:] {
143 + var err error
144 + args, err = appendArg(args, argDef, arg)
145 + if err != nil {
146 + return nil, err
147 + }
148 + }
149 } else {
132 - in, err := os.Open(arg)
150 + var err error
151 + args, err = appendArg(args, argDef, stringArgs[j])
152 if err != nil {
153 return nil, err
154 }
136 - args[i] = in
155 }
156 +
157 + j++
158 }
159
160 return args, nil
161 }
162 +
163 +func appendArg(args []interface{}, argDef cmds.Argument, value string) ([]interface{}, error) {
164 + if argDef.Type == cmds.ArgString {
165 + return append(args, value), nil
166 +
167 + } else {
168 + in, err := os.Open(value)
169 + if err != nil {
170 + return nil, err
171 + }
172 + return append(args, in), nil
173 + }
174 +}
commands/command.go
+19 -5
@@ -149,13 +149,27 @@ func (c *Command) CheckArguments(req Request) error {
149 return fmt.Errorf("Expected %v arguments, got %v", len(argDefs), len(args))
150 }
151
152 + // count required argument definitions
153 + lenRequired := 0
154 + for _, argDef := range c.Arguments {
155 + if argDef.Required {
156 + lenRequired++
157 + }
158 + }
159 +
160 // iterate over the arg definitions
153 - for i, argDef := range c.Arguments {
161 + j := 0
162 + for _, argDef := range c.Arguments {
163 + // skip optional argument definitions if there aren't sufficient remaining values
164 + if len(args)-j <= lenRequired && !argDef.Required {
165 + continue
166 + }
167
168 // the value for this argument definition. can be nil if it wasn't provided by the caller
169 var v interface{}
157 - if i < len(args) {
158 - v = args[i]
170 + if j < len(args) {
171 + v = args[j]
172 + j++
173 }
174
175 err := checkArgValue(v, argDef)
@@ -164,8 +178,8 @@ func (c *Command) CheckArguments(req Request) error {
178 }
179
180 // any additional values are for the variadic arg definition
167 - if argDef.Variadic && i < len(args)-1 {
168 - for _, val := range args[i+1:] {
181 + if argDef.Variadic && j < len(args)-1 {
182 + for _, val := range args[j+1:] {
183 err := checkArgValue(val, argDef)
184 if err != nil {
185 return err
commands/http/parse.go
+24 -5
@@ -39,13 +39,32 @@ func Parse(r *http.Request, root *cmds.Command) (cmds.Request, error) {
39 opts, stringArgs2 := parseOptions(r)
40 stringArgs = append(stringArgs, stringArgs2...)
41
42 - // Note that the argument handling here is dumb, it does not do any error-checking.
43 - // (Arguments are further processed when the request is passed to the command to run)
42 args := make([]interface{}, 0)
43
46 - for _, arg := range cmd.Arguments {
47 - if arg.Type == cmds.ArgString {
48 - if arg.Variadic {
44 + // count required argument definitions
45 + lenRequired := 0
46 + for _, argDef := range cmd.Arguments {
47 + if argDef.Required {
48 + lenRequired++
49 + }
50 + }
51 +
52 + // count the number of provided argument values
53 + valCount := len(stringArgs)
54 + // TODO: add total number of parts in request body (instead of just 1 if body is present)
55 + if r.Body != nil {
56 + valCount += 1
57 + }
58 +
59 + for _, argDef := range cmd.Arguments {
60 + // skip optional argument definitions if there aren't sufficient remaining values
61 + if valCount <= lenRequired && !argDef.Required {
62 + continue
63 + }
64 + valCount--
65 +
66 + if argDef.Type == cmds.ArgString {
67 + if argDef.Variadic {
68 for _, s := range stringArgs {
69 args = append(args, s)
70 }