-
Notifications
You must be signed in to change notification settings - Fork 454
Expand file tree
/
Copy pathtypes.go
More file actions
285 lines (252 loc) · 6.74 KB
/
Copy pathtypes.go
File metadata and controls
285 lines (252 loc) · 6.74 KB
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
package cli
import (
"fmt"
"reflect"
"strconv"
"strings"
"github.com/pkg/errors"
"github.com/ovh/cds/sdk"
)
// FlagType for cli flag.
type FlagType string
// Flags types
const (
FlagString FlagType = "string"
FlagBool FlagType = "bool"
FlagSlice FlagType = "slice"
FlagArray FlagType = "array"
)
// Flag represents a command flag.
type Flag struct {
Name string
ShortHand string
Usage string
Default string
Type FlagType
IsValid func(string) bool
}
// Values represents commands flags and args values accessible with their name
type Values map[string][]string
// GetString returns a string.
func (v *Values) GetString(s string) string {
r := (*v)[s]
if len(r) == 0 {
return ""
}
return r[0]
}
// GetInt64 returns a int64.
func (v *Values) GetInt64(s string) (int64, error) {
ns := v.GetString(s)
if ns == "" {
return 0, nil
}
n, err := strconv.ParseInt(ns, 10, 64)
if err != nil {
return -1, fmt.Errorf("%s invalid: not a integer", s)
}
return n, nil
}
// GetBool returns a string.
func (v *Values) GetBool(s string) bool {
r := strings.ToLower(v.GetString(s))
return r == "true" || r == "yes" || r == "y" || r == "1"
}
// GetStringSlice returns a string slice.
func (v *Values) GetStringSlice(s string) []string {
if strings.TrimSpace(v.GetString(s)) == "" {
return nil
}
res := strings.Split(v.GetString(s), "||")
if len(res) == 1 && strings.Contains(res[0], ",") {
return strings.Split(res[0], ",")
}
return res
}
// GetStringArray returns a string array.
func (v *Values) GetStringArray(s string) []string {
return (*v)[s]
}
// Arg represent a command argument
type Arg struct {
Name string `json:"name"`
IsValid func(string) bool `json:"-"`
AllowEmpty bool `json:"-"`
}
// Command represents the way to instantiate a cobra.Command
type Command struct {
Name string
Ctx []Arg
Args []Arg
OptionalArgs []Arg
VariadicArgs Arg
Short string
Long string
Example string
Flags []Flag
Aliases []string
Hidden bool
PreRun func(c *Command, args *[]string) error
Mcp bool
}
// CommandModifier is a function type to extend a command
type CommandModifier func(*Command, interface{})
// CommandWithoutExtraFlags to avoid add extra flags
func CommandWithoutExtraFlags(c *Command, run interface{}) {}
// CommandWithExtraFlags to add common extra flags
func CommandWithExtraFlags(c *Command, run interface{}) {
var extraFlags = []Flag{}
switch run.(type) {
case RunGetFunc:
extraFlags = []Flag{
{
Name: "format",
Default: "plain",
Usage: "Output format: plain|json|yaml",
Type: FlagString,
},
{
Name: "verbose",
Usage: "Display all object fields",
Type: FlagBool,
},
{
Name: "quiet",
ShortHand: "q",
Default: "",
Usage: "Only display object's key",
Type: FlagBool,
},
{
Name: "fields",
Default: "",
Usage: "Only display specified object fields. 'empty' will display all fields, 'all' will display all object fields, 'field1,field2' to select multiple fields",
Type: FlagString,
},
}
case RunListFunc:
extraFlags = []Flag{
{
Name: "filter",
Default: "",
Usage: "Filter output based on conditions provided",
Type: FlagString,
},
{
Name: "format",
Default: "table",
Usage: "Output format: table|json|yaml",
Type: FlagString,
},
{
Name: "quiet",
ShortHand: "q",
Default: "",
Usage: "Only display object's key",
Type: FlagBool,
},
{
Name: "fields",
Default: "",
Usage: "Only display specified object fields. 'empty' will display all fields, 'all' will display all object fields, 'field1,field2' to select multiple fields",
Type: FlagString,
},
{
Name: "verbose",
Usage: "Display all object fields",
Type: FlagBool,
},
}
case RunDeleteFunc:
extraFlags = []Flag{
{
Name: "force",
Default: "false",
Usage: "Force delete without confirmation and exit 0 if resource does not exist",
Type: FlagBool,
},
}
}
c.Flags = append(c.Flags, extraFlags...)
}
// CommandWithExtraAliases to add common extra alias
func CommandWithExtraAliases(c *Command, run interface{}) {
var extraAliases []string
switch run.(type) {
case RunListFunc:
extraAliases = []string{"ls"}
case RunDeleteFunc:
extraAliases = []string{"rm", "remove", "del"}
}
c.Aliases = append(c.Aliases, extraAliases...)
}
// CommandWithPreRun to add pre run function
func CommandWithPreRun(f func(c *Command, args *[]string) error) func(c *Command, run interface{}) {
return func(c *Command, run interface{}) {
c.PreRun = f
}
}
// ErrWrongUsage is a common error
var ErrWrongUsage = &Error{Code: 1, Err: fmt.Errorf("Wrong usage")}
// Error implements error
type Error struct {
Message string
Code int
Err error
}
// Error implements error
func (e *Error) Error() string {
if e.Message == "" {
return e.Err.Error()
}
return e.Message + ": " + e.Err.Error()
}
func NewError(format string, args ...interface{}) error {
return &Error{
Code: 50,
Err: errors.WithStack(fmt.Errorf(format, args...)),
}
}
func WrapError(err error, format string, args ...interface{}) error {
msg := fmt.Sprintf(format, args...)
return &Error{
Code: 50,
Message: msg,
Err: errors.WithStack(err),
}
}
// ListResult is the result type for command function which returns list. Use AsListResult to compute this
type ListResult []interface{}
// RunFunc is the most basic run function for a command. It returns only an error
type RunFunc func(Values) error
// RunGetFunc is a run function for a command. It returns an object value (not a pointer) and an error.
type RunGetFunc func(Values) (interface{}, error)
// RunDeleteFunc is a run function for a command. It returns an error.
type RunDeleteFunc func(Values) error
// RunListFunc is a run function for a command. It returns an objects list and an error
type RunListFunc func(Values) (ListResult, error)
// AsListResult compute any slice to ListResult
func AsListResult(i interface{}) ListResult {
s := reflect.ValueOf(i)
if s.Kind() != reflect.Slice {
panic("AsListResult() given a non-slice type")
}
res := ListResult{}
for i := 0; i < s.Len(); i++ {
v := s.Index(i).Interface()
res = append(res, v)
}
return res
}
// ParsePath returns group and itme name from given path.
func ParsePath(path string) (string, string, error) {
pathSplit := strings.Split(path, "/")
// if no group name given suppose that is a shared.infra item
if len(pathSplit) == 1 {
return sdk.SharedInfraGroupName, pathSplit[0], nil
}
if len(pathSplit) != 2 {
return "", "", fmt.Errorf("invalid given path")
}
return pathSplit[0], pathSplit[1], nil
}