-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathcmd.go
165 lines (136 loc) · 3.89 KB
/
cmd.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
// Package cmd defines the cobra command structs and an execution method for adding an improved CLI to
// KrakenD based api gateways
package cmd
import (
"fmt"
"os"
"sync"
"time"
"github.com/luraproject/lura/v2/config"
"github.com/spf13/cobra"
)
// Executor defines the function that requires a service description
type Executor func(config.ServiceConfig)
// Execute sets up the cmd package with the received configuration parser and executor and delegates
// the CLI execution to the cobra lib
func Execute(configParser config.Parser, f Executor) {
ExecuteRoot(configParser, f, DefaultRoot)
}
func ExecuteRoot(configParser config.Parser, f Executor, root Root) {
root.Build()
root.Execute(configParser, f)
}
func GetConfigFlag() string {
return cfgFile
}
func GetDebugFlag() bool {
return debug > 0
}
func GetConfigParser() config.Parser {
return parser
}
type FlagBuilder func(*cobra.Command)
func StringFlagBuilder(dst *string, long, short, defaultValue, help string) FlagBuilder {
return func(cmd *cobra.Command) {
cmd.PersistentFlags().StringVarP(dst, long, short, defaultValue, help)
}
}
func BoolFlagBuilder(dst *bool, long, short string, defaultValue bool, help string) FlagBuilder {
return func(cmd *cobra.Command) {
cmd.PersistentFlags().BoolVarP(dst, long, short, defaultValue, help)
}
}
func DurationFlagBuilder(dst *time.Duration, long, short string, defaultValue time.Duration, help string) FlagBuilder {
return func(cmd *cobra.Command) {
cmd.PersistentFlags().DurationVarP(dst, long, short, defaultValue, help)
}
}
func Float64FlagBuilder(dst *float64, long, short string, defaultValue float64, help string) FlagBuilder {
return func(cmd *cobra.Command) {
cmd.PersistentFlags().Float64VarP(dst, long, short, defaultValue, help)
}
}
func IntFlagBuilder(dst *int, long, short string, defaultValue int, help string) FlagBuilder {
return func(cmd *cobra.Command) {
cmd.PersistentFlags().IntVarP(dst, long, short, defaultValue, help)
}
}
func CountFlagBuilder(dst *int, long, short, help string) FlagBuilder {
return func(cmd *cobra.Command) {
cmd.PersistentFlags().CountVarP(dst, long, short, help)
}
}
type ConstraintBuilder func(*cobra.Command)
func OneRequired(flags ...string) ConstraintBuilder {
return func(cmd *cobra.Command) {
cmd.MarkFlagsOneRequired(flags...)
}
}
func RequiredTogether(flags ...string) ConstraintBuilder {
return func(cmd *cobra.Command) {
cmd.MarkFlagsRequiredTogether(flags...)
}
}
func MutuallyExclusive(flags ...string) ConstraintBuilder {
return func(cmd *cobra.Command) {
cmd.MarkFlagsMutuallyExclusive(flags...)
}
}
type Command struct {
Cmd *cobra.Command
Flags []FlagBuilder
once *sync.Once
Constraints []ConstraintBuilder
}
func NewCommand(command *cobra.Command, flags ...FlagBuilder) Command {
return Command{Cmd: command, Flags: flags, once: new(sync.Once)}
}
func (c *Command) AddConstraint(r ConstraintBuilder) {
c.Constraints = append(c.Constraints, r)
}
func (c *Command) AddFlag(f FlagBuilder) {
c.Flags = append(c.Flags, f)
}
func (c *Command) BuildFlags() {
c.once.Do(func() {
for i := range c.Flags {
c.Flags[i](c.Cmd)
}
})
}
func (c *Command) AddSubCommand(cmd *cobra.Command) {
c.Cmd.AddCommand(cmd)
}
func NewRoot(root Command, subCommands ...Command) Root {
r := Root{Command: root, SubCommands: subCommands, once: new(sync.Once)}
return r
}
type Root struct {
Command
SubCommands []Command
once *sync.Once
}
func (r *Root) Build() {
r.once.Do(func() {
r.BuildFlags()
for i := range r.Constraints {
r.Constraints[i](r.Cmd)
}
for i := range r.SubCommands {
s := r.SubCommands[i]
s.BuildFlags()
for j := range s.Constraints {
s.Constraints[j](s.Cmd)
}
r.Cmd.AddCommand(s.Cmd)
}
})
}
func (r Root) Execute(configParser config.Parser, f Executor) {
parser = configParser
run = f
if err := r.Cmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(-1)
}
}