forked from keybase/bot-sshca
-
Notifications
You must be signed in to change notification settings - Fork 0
/
flags.go
65 lines (57 loc) · 2.16 KB
/
flags.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package kssh
import "fmt"
type CLIArgument struct {
// The name of the flag eg "--foo"
Name string
// HasArgument:true if an argument comes after it (eg "--foo bar") false if it is a boolean flag (eg "--help")
HasArgument bool
// Preserve:true if you wish to preserve this argument into the list of remaining arguments even if found
// eg if your command takes in a `-v` flag and the subcommand also takes in a `-v` flag
// incompatible with HasArgument: true but only because that has not been built
Preserve bool
}
type ParsedCLIArgument struct {
// The CLIArgument that was found and parsed
Argument CLIArgument
// The value associated with it if HasArgument:true. Otherwise an empty string.
Value string
}
// ParseArgs parses os.Args for use with kssh. This is handwritten rather than using go's flag library (or
// any other CLI argument parsing library) since we want to have custom arguments and access any other remaining
// arguments. See this Github discussion for a longer discussion of why this is implemented this way:
// https://github.com/atvenu/bot-sshca/pull/3#discussion_r302740696
//
// Returns: a list of the remaining unparsed arguments, a list of the parsed arguments, error
func ParseArgs(args []string, cliArguments []CLIArgument) ([]string, []ParsedCLIArgument, error) {
for _, cliArg := range cliArguments {
if cliArg.Preserve && cliArg.HasArgument {
return nil, nil, fmt.Errorf("cannot specify Preserve and HasArgument for argument %s", cliArg.Name)
}
}
remainingArguments := []string{}
found := []ParsedCLIArgument{}
OUTER:
for i := 0; i < len(args); i++ {
arg := args[i]
for _, cliArg := range cliArguments {
if cliArg.Name == arg {
parsed := ParsedCLIArgument{Argument: cliArg}
if cliArg.HasArgument {
if i+1 == len(args) {
return nil, nil, fmt.Errorf("argument %s requires a value", cliArg.Name)
}
nextArg := args[i+1]
parsed.Value = nextArg
i++
}
found = append(found, parsed)
if cliArg.Preserve {
remainingArguments = append(remainingArguments, arg)
}
continue OUTER
}
}
remainingArguments = append(remainingArguments, arg)
}
return remainingArguments, found, nil
}