1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-19 18:05:32 +08:00

commands: Check argument validity when running commands

This commit is contained in:
Matt Bell
2014-11-02 20:26:27 -08:00
committed by Juan Batiz-Benet
parent ee2c76992a
commit e8d0cbff1d
2 changed files with 44 additions and 0 deletions

View File

@ -19,6 +19,12 @@ type Function func(Response, Request)
// MAYBE_TODO: maybe this should be a io.Reader instead of a string?
type Formatter func(Response) (string, error)
// TODO: check Argument definitions when creating a Command
// (might need to use a Command constructor)
// * make sure any variadic args are at the end
// * make sure there aren't duplicate names
// * make sure optional arguments aren't followed by required arguments
// Command is a runnable command, with input arguments and options (flags).
// It can also have Subcommands, to group units of work into sets.
type Command struct {
@ -52,6 +58,12 @@ func (c *Command) Call(req Request) Response {
return res
}
err = req.CheckArguments(cmd.Arguments)
if err != nil {
res.SetError(err, ErrClient)
return res
}
options, err := c.GetOptions(req.Path())
if err != nil {
res.SetError(err, ErrClient)

View File

@ -2,6 +2,7 @@ package commands
import (
"fmt"
"io"
"reflect"
"strconv"
@ -28,6 +29,7 @@ type Request interface {
SetContext(Context)
Command() *Command
CheckArguments(args []Argument) error
ConvertOptions(options map[string]Option) error
}
@ -101,6 +103,36 @@ var converters = map[reflect.Kind]converter{
},
}
// MAYBE_TODO: maybe this should be a Command method? (taking a Request as a param)
func (r *request) CheckArguments(args []Argument) error {
var argDef Argument
for i, arg := range r.arguments {
if i < len(args) {
argDef = args[i]
} else if !argDef.Variadic {
return fmt.Errorf("Expected %v arguments, got %v", len(args), len(r.arguments))
}
if argDef.Required && arg == nil {
return fmt.Errorf("Argument '%s' is required", argDef.Name)
}
if argDef.Type == ArgFile {
_, ok := arg.(io.Reader)
if !ok {
return fmt.Errorf("Argument '%s' isn't valid", argDef.Name)
}
} else if argDef.Type == ArgString {
_, ok := arg.(string)
if !ok {
return fmt.Errorf("Argument '%s' must be a string", argDef.Name)
}
}
}
return nil
}
func (r *request) ConvertOptions(options map[string]Option) error {
converted := make(map[string]interface{})