-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathargs.go
180 lines (148 loc) · 4.01 KB
/
args.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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package cli
import (
"fmt"
"github.com/posener/complete"
)
// Arguments is used to validate and complete positional arguments.
// Use `Args()` to create an instance from functions.
type Arguments interface {
Validator
complete.Predictor
}
// Validator checks that arguments have the expected form
type Validator interface {
// Validate receives the arguments of the command (without flags) and shall
// return an error if they are unexpected.
Validate(args []string) error
}
// Args bundles user-supplied implementations of the respective interfaces into
// an Arguments implementation.
type Args struct {
Validator
complete.Predictor
}
// ValidateFunc allows to use an ordinary func as an Validator
type ValidateFunc func(args []string) error
// Validate wrap the underlying function
func (v ValidateFunc) Validate(args []string) error {
return v(args)
}
// PredictFunc allows to use an ordinary func as an Predictor
type PredictFunc = complete.PredictFunc
// ---
// Common Argument implementations
// ---
// No Arguments
// ArgsNone checks that no arguments were given, and disables predictions.
func ArgsNone() Arguments {
return Args{
Validator: ValidateNone(),
Predictor: PredictNone(),
}
}
// ValidateNone checks for no arguments at all
func ValidateNone() ValidateFunc {
return ValidateExact(0)
}
// PredictNone predicts exactly nothing
func PredictNone() complete.Predictor {
return PredictFunc(func(args complete.Args) []string {
return nil
})
}
// Exact arguments
// ArgsExact checks for exactly n arguments, predicting anything
func ArgsExact(n int) Arguments {
return Args{
Validator: ValidateExact(n),
Predictor: PredictAny(),
}
}
// ValidateExact checks that exactly n arguments were given
func ValidateExact(n int) ValidateFunc {
return func(args []string) error {
if len(args) != n {
return fmt.Errorf("accepts %v arg, received %v", n, len(args))
}
return nil
}
}
// Minimum arguments
// ArgsMin checks for at least n arguments, predicting anything
func ArgsMin(n int) Arguments {
return Args{
Validator: ValidateMin(n),
Predictor: PredictAny(),
}
}
// ValidateMin checks that at least n arguments were given
func ValidateMin(n int) ValidateFunc {
return func(args []string) error {
if len(args) < n {
return fmt.Errorf("expects at least %v arg, received %v", n, len(args))
}
return nil
}
}
// Argument range
// ArgsRange checks for between n and m arguments (inclusive), predicting anything
func ArgsRange(n, m int) Arguments {
return Args{
Validator: ValidateRange(n, m),
Predictor: PredictAny(),
}
}
// ValidateRange checks that between n and m arguments (inclusive) were given
func ValidateRange(n, m int) ValidateFunc {
return func(args []string) error {
if len(args) < n || len(args) > m {
return fmt.Errorf("accepts between %v and %v args, received %v", n, m, len(args))
}
return nil
}
}
// Any arguments
// ArgsAny allows any number of arguments with any value
func ArgsAny() Arguments {
return Args{
Validator: ValidateAny(),
Predictor: PredictAny(),
}
}
// PredictAny predicts any files/directories
func PredictAny() complete.Predictor {
return complete.PredictFiles("*")
}
// ValidateAny always approves
func ValidateAny() ValidateFunc {
return func(args []string) error {
return nil
}
}
// Predefined arguments
// ArgsSet check the given argument is in the predefined set of options. Only
// these options are predicted. Only a single argument is assumed.
func ArgsSet(set ...string) Arguments {
return Args{
Validator: ValidateSet(set...),
Predictor: PredictSet(set...),
}
}
// PredictSet predicts the values from the given set
func PredictSet(set ...string) complete.Predictor {
return complete.PredictSet(set...)
}
// ValidateSet checks that the given single argument is part of the set.
func ValidateSet(set ...string) ValidateFunc {
return func(args []string) error {
if err := ValidateExact(1)(args); err != nil {
return err
}
for _, s := range set {
if args[0] == s {
return nil
}
}
return fmt.Errorf("only accepts %v", set)
}
}