diff --git a/cli/parse.go b/cli/parse.go index ba35a0d694991db3d8d0ad1214b6d26ef8dad343..ae74d98741b495e1019f79ca4a669c342ba6439a 100644 --- a/cli/parse.go +++ b/cli/parse.go @@ -140,6 +140,7 @@ L: if err != nil { return err } + kvType, err := getOptType(k, optDefs) if err != nil { 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) { } } -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] if !ok { - return nil, fmt.Errorf("unknown option %q", opt) + return "", nil, fmt.Errorf("unknown option %q", opt) } v, err := optDef.Parse(value) if err != nil { - return nil, err + return "", nil, err } - return v, nil + return optDef.Name(), v, nil } type kv struct { @@ -433,7 +434,7 @@ func (st *parseState) parseShortOpts(optDefs map[string]cmds.Option) ([]kv, erro if ok { // split at = successful - v, err := parseOpt(k, vStr, optDefs) + k, v, err := parseOpt(k, vStr, optDefs) if err != nil { return nil, err } @@ -453,7 +454,7 @@ func (st *parseState) parseShortOpts(optDefs map[string]cmds.Option) ([]kv, erro case od.Type() == cmds.Bool: // single char flags for bools kvs = append(kvs, kv{ - Key: flag, + Key: od.Name(), Value: true, }) j++ @@ -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) rest := k[j+1:] - v, err := parseOpt(flag, rest, optDefs) + k, v, err := parseOpt(flag, rest, optDefs) if err != nil { return nil, err } - kvs = append(kvs, kv{Key: flag, Value: v}) + kvs = append(kvs, kv{Key: k, Value: v}) break LOOP case st.i < len(st.cmdline)-1: // single char flag for non-bools (use the next word as value) st.i++ - v, err := parseOpt(flag, st.cmdline[st.i], optDefs) + k, v, err := parseOpt(flag, st.cmdline[st.i], optDefs) if err != nil { return nil, err } - kvs = append(kvs, kv{Key: flag, Value: v}) + kvs = append(kvs, kv{Key: k, Value: v}) break LOOP default: @@ -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 } diff --git a/cli/parse_test.go b/cli/parse_test.go index 7fce8d30519eb8ebf19c897ac3182d2d8c1367bb..247e5a393e0af4b286c463e74a743d23cfde6bec 100644 --- a/cli/parse_test.go +++ b/cli/parse_test.go @@ -80,6 +80,7 @@ func TestOptionParsing(t *testing.T) { cmd := &cmds.Command{ Options: []cmds.Option{ cmds.StringOption("string", "s", "a string"), + cmds.StringOption("flag", "alias", "multiple long"), cmds.BoolOption("bool", "b", "a bool"), cmds.StringsOption("strings", "r", "strings array"), }, @@ -156,6 +157,11 @@ func TestOptionParsing(t *testing.T) { test("defaults", kvs{"opt": "def"}, 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=xyz") @@ -636,7 +642,8 @@ func TestFileArgs(t *testing.T) { cmd: words{"fileOp", "--ignore", path.Base(tmpFile2.Name()), tmpDir1, tmpFile1.Name()}, f: nil, args: words{tmpDir1, tmpFile1.Name(), tmpFile3.Name()}, parseErr: fmt.Errorf(notRecursiveFmtStr, tmpDir1, "r"), - }, { + }, + { cmd: words{"fileOp", tmpFile1.Name(), "--ignore", path.Base(tmpFile2.Name()), "--ignore"}, f: nil, args: words{tmpDir1, tmpFile1.Name(), tmpFile3.Name()}, parseErr: fmt.Errorf("missing argument for option %q", "ignore"),