github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zcli/var.go (about) 1 package zcli 2 3 import ( 4 "flag" 5 "os" 6 "strings" 7 8 "github.com/sohaha/zlsgo/zlog" 9 "github.com/sohaha/zlsgo/ztype" 10 ) 11 12 type ( 13 cmdCont struct { 14 command Cmd 15 name string 16 desc string 17 Supplement string 18 requiredFlags []string 19 } 20 runFunc func() 21 // Cmd represents a subCommand 22 Cmd interface { 23 Flags(subcommand *Subcommand) 24 Run(args []string) 25 } 26 errWrite struct { 27 } 28 v struct { 29 name string 30 usage string 31 shorts []string 32 } 33 // Subcommand sub command 34 Subcommand struct { 35 CommandLine *flag.FlagSet 36 Name string 37 Desc string 38 Supplement string 39 Parameter string 40 cmdCont 41 } 42 ) 43 44 const cliPrefix = "" 45 46 var ( 47 // BuildTime Build Time 48 BuildTime = "" 49 // BuildGoVersion Build Go Version 50 BuildGoVersion = "" 51 // BuildGitCommitID Build Git CommitID 52 BuildGitCommitID = "" 53 // Log cli logger 54 Log *zlog.Logger 55 // FirstParameter First Parameter 56 FirstParameter = os.Args[0] 57 flagHelp = new(bool) 58 flagDetach = new(bool) 59 flagVersion = new(bool) 60 osExit = os.Exit 61 cmds = make(map[string]*cmdCont) 62 cmdsKey []string 63 matchingCmd *cmdCont 64 args []string 65 requiredFlags = make([]string, 0) 66 defaultLang = "en" 67 unknownCommandFn = func(name string) { 68 Error("unknown Command: %s", errorText(name)) 69 } 70 Logo string 71 Name string 72 Version string 73 HideHelp bool 74 EnableDetach bool 75 HidePrompt bool 76 Lang = defaultLang 77 varsKey = map[string]*v{} 78 varShortsKey = make([]string, 0) 79 ShortValues = map[string]interface{}{} 80 langs = map[string]map[string]string{ 81 "en": { 82 "command_empty": "Command name cannot be empty", 83 "help": "Show Command help", 84 "version": "View version", 85 "detach": "Running in the background", 86 "test": "Test", 87 "restart": "Restart service", 88 "stop": "Stop service", 89 "start": "Start service", 90 "status": "Service status", 91 "uninstall": "Uninstall service", 92 "install": "Install service", 93 }, 94 "zh": { 95 "command_empty": "命令名不能为空", 96 "help": "显示帮助信息", 97 "version": "查看版本信息", 98 "detach": "后台运行", 99 "restart": "重启服务", 100 "stop": "停止服务", 101 "start": "开始服务", 102 "status": "服务状态", 103 "uninstall": "卸载服务", 104 "install": "安装服务", 105 }, 106 } 107 ) 108 109 func SetLangText(lang, key, value string) { 110 l, ok := langs[lang] 111 if !ok { 112 l = map[string]string{} 113 } 114 l[key] = value 115 langs[lang] = l 116 } 117 118 func GetLangText(key string, def ...string) string { 119 if lang, ok := langs[Lang][key]; ok { 120 return lang 121 } 122 123 if lang, ok := langs[defaultLang][key]; ok { 124 return lang 125 } 126 if len(def) > 0 { 127 return def[0] 128 } 129 return key 130 } 131 132 func (e *errWrite) Write(p []byte) (n int, err error) { 133 Error(strings.Replace(ztype.ToString(p), cliPrefix, "", 1)) 134 return 1, nil 135 } 136 137 func SetVar(name, usage string) *v { 138 v := &v{ 139 name: cliPrefix + name, 140 usage: usage, 141 } 142 varsKey[name] = v 143 return v 144 } 145 146 func (v *v) short(short string) *v { 147 v.shorts = append(v.shorts, short) 148 // todo prevent duplicate addition 149 varShortsKey = append(varShortsKey, short) 150 return v 151 } 152 153 // Required Set flag to be required 154 func (v *v) Required() *v { 155 if matchingCmd != nil { 156 matchingCmd.requiredFlags = append(matchingCmd.requiredFlags, v.name) 157 } else { 158 requiredFlags = append(requiredFlags, v.name) 159 } 160 return v 161 } 162 163 func (v *v) String(def ...string) *string { 164 var value string 165 if len(def) > 0 { 166 value = def[0] 167 } 168 v.setFlagbind(func(name string) { 169 ShortValues[name] = setFlags(v, value, func() interface{} { 170 return flag.String(name, value, v.usage) 171 }).(*string) 172 }) 173 return setFlags(v, value, func() interface{} { 174 return flag.String(v.name, value, v.usage) 175 }).(*string) 176 } 177 178 func (v *v) Int(def ...int) *int { 179 var value int 180 if len(def) > 0 { 181 value = def[0] 182 } 183 v.setFlagbind(func(name string) { 184 ShortValues[name] = setFlags(v, value, func() interface{} { 185 return flag.Int(name, value, v.usage) 186 }).(*int) 187 }) 188 return setFlags(v, value, func() interface{} { 189 return flag.Int(v.name, value, v.usage) 190 }).(*int) 191 } 192 193 func (v *v) Bool(def ...bool) *bool { 194 var value bool 195 if len(def) > 0 { 196 value = def[0] 197 } 198 v.setFlagbind(func(name string) { 199 ShortValues[name] = setFlags(v, value, func() interface{} { 200 return flag.Bool(name, value, v.usage) 201 }).(*bool) 202 }) 203 return setFlags(v, value, func() interface{} { 204 return flag.Bool(v.name, value, v.usage) 205 }).(*bool) 206 } 207 208 var flags = map[string]interface{}{} 209 210 func setFlags(v *v, value interface{}, fn func() interface{}) (p interface{}) { 211 p, ok := flags[v.name] 212 if !ok { 213 flags[v.name] = fn() 214 return flags[v.name] 215 } 216 217 switch val := value.(type) { 218 case bool: 219 b, ok := p.(*bool) 220 if !ok { 221 Error("flag %s type error, it needs to be an bool", v.name) 222 } 223 *b = val 224 return b 225 case string: 226 s, ok := p.(*string) 227 if !ok { 228 Error("flag %s type error, it needs to be an string", v.name) 229 } 230 *s = val 231 return s 232 case int: 233 i, ok := p.(*int) 234 if !ok { 235 Error("flag %s type error, it needs to be an int", v.name) 236 } 237 *i = val 238 return i 239 } 240 return nil 241 } 242 243 func (v *v) setFlagbind(fn func(name string)) { 244 for _, s := range v.shorts { 245 fn(s) 246 } 247 }