-
Notifications
You must be signed in to change notification settings - Fork 0
/
cli.go
199 lines (186 loc) · 4.61 KB
/
cli.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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package enscli
import (
"flag"
"os"
"runtime"
"strings"
"github.com/EnsurityTechnologies/logger"
)
const (
StringType string = "string"
IntType string = "int"
Int64Type string = "int64"
UIntType string = "uint"
UInt64Type string = "uint64"
Float64Type string = "float64"
BoolType string = "bool"
)
type CommandHandler func() bool
type Function struct {
Handler CommandHandler
Title string
SuccessMsg string
FailureMsg string
}
type Option struct {
Type string
Flag string
Ptr interface{}
Default interface{}
Usage string
}
type EnsCli struct {
name string
version string
log logger.Logger
funcs map[string]*Function
options []*Option
}
func NewEnsCli(name string, log logger.Logger) (EnsCli, error) {
return EnsCli{name: name, version: "0.0.1", log: log, funcs: make(map[string]*Function), options: make([]*Option, 0)}, nil
}
func (cli *EnsCli) SetVersion(version string) {
cli.version = version
}
func (cli *EnsCli) AddCommand(cmd string, f *Function) {
cmd = strings.ToLower(cmd)
cli.funcs[cmd] = f
}
func (cli *EnsCli) AddOption(o *Option) {
o.Type = strings.ToLower(o.Type)
cli.options = append(cli.options, o)
}
func (cli *EnsCli) showHelp() {
msg := "Command line helper\n\n"
if runtime.GOOS == "windows" {
msg = msg + cli.name + ".exe <cmd>\n\n"
} else {
msg = msg + cli.name + " <cmd>\n\n"
}
msg = msg + "Use the following commands\n\n"
for k := range cli.funcs {
msg = msg + " " + k + "\n"
}
msg = msg + "\nSupported options\n\n"
for _, o := range cli.options {
msg = msg + " " + o.Flag + " <" + o.Type + ">" + " : " + o.Usage + "\n"
}
cli.log.Info(msg)
}
func (cli *EnsCli) Run() {
if len(os.Args) < 2 {
cli.showHelp()
return
}
cmd := strings.ToLower(os.Args[1])
if cmd == "-h" || cmd == "-help" {
cli.showHelp()
return
}
if cmd == "-v" {
cli.log.Info("Tool version : " + cli.version)
}
f, ok := cli.funcs[cmd]
if !ok {
cli.log.Error("Unsupported command, please check the helper")
cli.showHelp()
return
}
os.Args = os.Args[1:]
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
for _, o := range cli.options {
switch o.Type {
case StringType:
ptr, ok := o.Ptr.(*string)
if !ok {
cli.log.Error("invalid pointer, expected string pointer", "flag", o.Flag)
return
}
v, ok := o.Default.(string)
if !ok {
cli.log.Error("invalid default value, expected string", "flag", o.Flag)
return
}
flag.StringVar(ptr, o.Flag, v, o.Usage)
case IntType:
ptr, ok := o.Ptr.(*int)
if !ok {
cli.log.Error("invalid pointer, expected integer pointer", "flag", o.Flag)
return
}
v, ok := o.Default.(int)
if !ok {
cli.log.Error("invalid default value, expected integer", "flag", o.Flag)
return
}
flag.IntVar(ptr, o.Flag, v, o.Usage)
case Int64Type:
ptr, ok := o.Ptr.(*int64)
if !ok {
cli.log.Error("invalid pointer, expected integer 64 pointer", "flag", o.Flag)
return
}
v, ok := o.Default.(int64)
if !ok {
cli.log.Error("invalid default value, expected integer 64", "flag", o.Flag)
return
}
flag.Int64Var(ptr, o.Flag, v, o.Usage)
case UIntType:
ptr, ok := o.Ptr.(*uint)
if !ok {
cli.log.Error("invalid pointer, expected unsigned integer pointer", "flag", o.Flag)
return
}
v, ok := o.Default.(uint)
if !ok {
cli.log.Error("invalid default value, expected unsigned integer", "flag", o.Flag)
return
}
flag.UintVar(ptr, o.Flag, v, o.Usage)
case UInt64Type:
ptr, ok := o.Ptr.(*uint64)
if !ok {
cli.log.Error("invalid pointer, expected unsigned integer 64 pointer", "flag", o.Flag)
return
}
v, ok := o.Default.(uint64)
if !ok {
cli.log.Error("invalid default value, expected unsigned integer 64", "flag", o.Flag)
return
}
flag.Uint64Var(ptr, o.Flag, v, o.Usage)
case Float64Type:
ptr, ok := o.Ptr.(*float64)
if !ok {
cli.log.Error("invalid pointer, expected float 64 pointer", "flag", o.Flag)
return
}
v, ok := o.Default.(float64)
if !ok {
cli.log.Error("invalid default value, expected float 64", "flag", o.Flag)
return
}
flag.Float64Var(ptr, o.Flag, v, o.Usage)
case BoolType:
ptr, ok := o.Ptr.(*bool)
if !ok {
cli.log.Error("invalid pointer, expected boolean pointer", "flag", o.Flag)
return
}
v, ok := o.Default.(bool)
if !ok {
cli.log.Error("invalid default value, expected boolean", "flag", o.Flag)
return
}
flag.BoolVar(ptr, o.Flag, v, o.Usage)
}
}
flag.Parse()
cli.log.Info("Executing the command : " + f.Title)
if !f.Handler() {
cli.log.Error(f.FailureMsg)
} else {
cli.log.Info(f.SuccessMsg)
}
}