commands/cli: Refactored parsing to always get the command path at the beginning of the CLI input
Matt Bell committed
Oct 14, 2014 at 15:00 UTC
bb32633136813799957eb0a403533ac5342f258b
1 file changed
+34
-25
commands/cli/parse.go
+34
-25
@@ -8,12 +8,12 @@ import (
8
)
9
10
func Parse(input []string, root *commands.Command) ([]string, []string, map[string]string, error) {
11
- opts, input, err := parseOptions(input, root)
11
+ path, input, err := parsePath(input, root)
12
if err != nil {
13
return nil, nil, nil, err
14
}
15
16
- path, args, err := parsePath(input, root)
16
+ opts, args, err := parseOptions(input, path, root)
17
if err != nil {
18
return nil, nil, nil, err
19
}
@@ -21,11 +21,38 @@ func Parse(input []string, root *commands.Command) ([]string, []string, map[stri
21
return path, args, opts, nil
22
}
23
24
+
25
+// path gets the command path from the command line input
26
+func parsePath(input []string, root *commands.Command) ([]string, []string, error) {
27
+ cmd := root
28
+ i := 0
29
+
30
+ for _, blob := range input {
31
+ if strings.HasPrefix(blob, "-") {
32
+ break
33
+ }
34
+
35
+ cmd := cmd.Sub(blob)
36
+ if cmd == nil {
37
+ break
38
+ }
39
+
40
+ i++
41
+ }
42
+
43
+ return input[:i], input[i:], nil
44
+}
45
+
46
// options parses the raw string values of the given options
25
-// returns the parsed options as strings, along with the CLI input minus option blobs
26
-func parseOptions(input []string, root *commands.Command) (map[string]string, []string, error) {
47
+// returns the parsed options as strings, along with the CLI args
48
+func parseOptions(input, path []string, root *commands.Command) (map[string]string, []string, error) {
49
+ _, err := root.GetOptions(path)
50
+ if err != nil {
51
+ return nil, nil, err
52
+ }
53
+
54
opts := make(map[string]string)
28
- cleanInput := make([]string, 0)
55
+ args := make([]string, 0)
56
57
// TODO: error if one option is defined multiple times
58
@@ -89,27 +116,9 @@ func parseOptions(input []string, root *commands.Command) (map[string]string, []
116
// TODO: interpret next blob as value if the last option isn't a bool
117
118
} else {
92
- cleanInput = append(cleanInput, blob)
93
- }
94
- }
95
-
96
- return opts, cleanInput, nil
97
-}
98
-
99
-// path takes the command line (without options) and splits it into the command path and arguments
100
-func parsePath(input []string, root *commands.Command) ([]string, []string, error) {
101
- cmd := root
102
- i := 0
103
-
104
- for _, blob := range input {
105
- cmd := cmd.Sub(blob)
106
-
107
- if cmd == nil {
108
- break
119
+ args = append(args, blob)
120
}
110
-
111
- i++
121
}
122
114
- return input[:i], input[i:], nil
123
+ return opts, args, nil
124
}