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  }