Unverified Commit 9b025d03 authored by Steven Allen's avatar Steven Allen Committed by GitHub

Merge pull request #186 from ipfs/fix/option-alias

fix: normalize options when parsing them
parents 0722d72b 7c76a735
...@@ -140,6 +140,7 @@ L: ...@@ -140,6 +140,7 @@ L:
if err != nil { if err != nil {
return err return err
} }
kvType, err := getOptType(k, optDefs) kvType, err := getOptType(k, optDefs)
if err != nil { if err != nil {
return err // shouldn't happen b/c k,v was parsed from optsDef return err // shouldn't happen b/c k,v was parsed from optsDef
...@@ -409,17 +410,17 @@ func splitkv(opt string) (k, v string, ok bool) { ...@@ -409,17 +410,17 @@ func splitkv(opt string) (k, v string, ok bool) {
} }
} }
func parseOpt(opt, value string, opts map[string]cmds.Option) (interface{}, error) { func parseOpt(opt, value string, opts map[string]cmds.Option) (string, interface{}, error) {
optDef, ok := opts[opt] optDef, ok := opts[opt]
if !ok { if !ok {
return nil, fmt.Errorf("unknown option %q", opt) return "", nil, fmt.Errorf("unknown option %q", opt)
} }
v, err := optDef.Parse(value) v, err := optDef.Parse(value)
if err != nil { if err != nil {
return nil, err return "", nil, err
} }
return v, nil return optDef.Name(), v, nil
} }
type kv struct { type kv struct {
...@@ -433,7 +434,7 @@ func (st *parseState) parseShortOpts(optDefs map[string]cmds.Option) ([]kv, erro ...@@ -433,7 +434,7 @@ func (st *parseState) parseShortOpts(optDefs map[string]cmds.Option) ([]kv, erro
if ok { if ok {
// split at = successful // split at = successful
v, err := parseOpt(k, vStr, optDefs) k, v, err := parseOpt(k, vStr, optDefs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -453,7 +454,7 @@ func (st *parseState) parseShortOpts(optDefs map[string]cmds.Option) ([]kv, erro ...@@ -453,7 +454,7 @@ func (st *parseState) parseShortOpts(optDefs map[string]cmds.Option) ([]kv, erro
case od.Type() == cmds.Bool: case od.Type() == cmds.Bool:
// single char flags for bools // single char flags for bools
kvs = append(kvs, kv{ kvs = append(kvs, kv{
Key: flag, Key: od.Name(),
Value: true, Value: true,
}) })
j++ j++
...@@ -462,23 +463,23 @@ func (st *parseState) parseShortOpts(optDefs map[string]cmds.Option) ([]kv, erro ...@@ -462,23 +463,23 @@ func (st *parseState) parseShortOpts(optDefs map[string]cmds.Option) ([]kv, erro
// single char flag for non-bools (use the rest of the flag as value) // single char flag for non-bools (use the rest of the flag as value)
rest := k[j+1:] rest := k[j+1:]
v, err := parseOpt(flag, rest, optDefs) k, v, err := parseOpt(flag, rest, optDefs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
kvs = append(kvs, kv{Key: flag, Value: v}) kvs = append(kvs, kv{Key: k, Value: v})
break LOOP break LOOP
case st.i < len(st.cmdline)-1: case st.i < len(st.cmdline)-1:
// single char flag for non-bools (use the next word as value) // single char flag for non-bools (use the next word as value)
st.i++ st.i++
v, err := parseOpt(flag, st.cmdline[st.i], optDefs) k, v, err := parseOpt(flag, st.cmdline[st.i], optDefs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
kvs = append(kvs, kv{Key: flag, Value: v}) kvs = append(kvs, kv{Key: k, Value: v})
break LOOP break LOOP
default: default:
...@@ -507,7 +508,7 @@ func (st *parseState) parseLongOpt(optDefs map[string]cmds.Option) (string, inte ...@@ -507,7 +508,7 @@ func (st *parseState) parseLongOpt(optDefs map[string]cmds.Option) (string, inte
} }
} }
optval, err := parseOpt(k, v, optDefs) k, optval, err := parseOpt(k, v, optDefs)
return k, optval, err return k, optval, err
} }
......
...@@ -80,6 +80,7 @@ func TestOptionParsing(t *testing.T) { ...@@ -80,6 +80,7 @@ func TestOptionParsing(t *testing.T) {
cmd := &cmds.Command{ cmd := &cmds.Command{
Options: []cmds.Option{ Options: []cmds.Option{
cmds.StringOption("string", "s", "a string"), cmds.StringOption("string", "s", "a string"),
cmds.StringOption("flag", "alias", "multiple long"),
cmds.BoolOption("bool", "b", "a bool"), cmds.BoolOption("bool", "b", "a bool"),
cmds.StringsOption("strings", "r", "strings array"), cmds.StringsOption("strings", "r", "strings array"),
}, },
...@@ -156,6 +157,11 @@ func TestOptionParsing(t *testing.T) { ...@@ -156,6 +157,11 @@ func TestOptionParsing(t *testing.T) {
test("defaults", kvs{"opt": "def"}, words{}) test("defaults", kvs{"opt": "def"}, words{})
test("defaults -o foo", kvs{"opt": "foo"}, words{}) test("defaults -o foo", kvs{"opt": "foo"}, words{})
test("--flag=foo", kvs{"flag": "foo"}, words{})
test("--alias=foo", kvs{"flag": "foo"}, words{})
testFail("--flag=bar --alias=foo")
testFail("--alias=bar --flag=foo")
testFail("--bad-flag") testFail("--bad-flag")
testFail("--bad-flag=") testFail("--bad-flag=")
testFail("--bad-flag=xyz") testFail("--bad-flag=xyz")
...@@ -636,7 +642,8 @@ func TestFileArgs(t *testing.T) { ...@@ -636,7 +642,8 @@ func TestFileArgs(t *testing.T) {
cmd: words{"fileOp", "--ignore", path.Base(tmpFile2.Name()), tmpDir1, tmpFile1.Name()}, f: nil, cmd: words{"fileOp", "--ignore", path.Base(tmpFile2.Name()), tmpDir1, tmpFile1.Name()}, f: nil,
args: words{tmpDir1, tmpFile1.Name(), tmpFile3.Name()}, args: words{tmpDir1, tmpFile1.Name(), tmpFile3.Name()},
parseErr: fmt.Errorf(notRecursiveFmtStr, tmpDir1, "r"), parseErr: fmt.Errorf(notRecursiveFmtStr, tmpDir1, "r"),
}, { },
{
cmd: words{"fileOp", tmpFile1.Name(), "--ignore", path.Base(tmpFile2.Name()), "--ignore"}, f: nil, cmd: words{"fileOp", tmpFile1.Name(), "--ignore", path.Base(tmpFile2.Name()), "--ignore"}, f: nil,
args: words{tmpDir1, tmpFile1.Name(), tmpFile3.Name()}, args: words{tmpDir1, tmpFile1.Name(), tmpFile3.Name()},
parseErr: fmt.Errorf("missing argument for option %q", "ignore"), parseErr: fmt.Errorf("missing argument for option %q", "ignore"),
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment