package ui import ( "bufio" "fmt" "os" "sort" "strconv" "strings" "time" ) type UI struct { appname string version string build string usage string Params Param Other []string debug bool nocolor bool } // Returns a new UI object func New(appname, version, build string) *UI { return &UI{ appname: appname, version: version, build: build, usage: "", Params: Param{ params: map[string]map[string]Arg{ "--debug": {"descr": {"enable debug messages"}, "value": {"false"}, "envvar": {}, "required": {"false"}}, "--help": {"descr": {"show this screen"}, "value": {"false"}, "envvar": {}, "required": {"false"}}, "--nocolor": {"descr": {"disable color output"}, "value": {"false"}, "envvar": {}, "required": {"false"}}, }, }, Other: []string{}, debug: false, nocolor: false, } } type Arg []string type Param struct { params map[string]map[string]Arg } // Adds a new parameter to the UI parameter stack func (x *Param) Add(name, descr, value, envvar, required string) { wrk1 := Arg{} if len(value) > 0 { wrk1 = Arg{value} } wrk2 := Arg{} if len(envvar) > 0 { wrk2 = Arg{envvar} } wrk3 := Arg{"false"} if len(required) > 0 { wrk3 = Arg{required} } x.params[name] = map[string]Arg{"descr": {descr}, "value": wrk1, "envvar": wrk2, "required": wrk3} } // IsNocolor... func (x *UI) IsNocolor() bool { return x.nocolor } // IsDebug... func (x *UI) IsDebug() bool { return x.debug } // Usage... func (x *UI) Usage(msg ...interface{}) { if len(msg) > 0 { x.usage = fmt.Sprintf("%v", msg...) x.usage = strings.Replace(x.usage, "[appname]", x.appname, -1) } else { x.Outln(x.usage) } } func (x *UI) Help() { if len(x.usage) > 0 { x.Outln("USAGE") x.Outf(" %s \n", x.usage) x.Outln() } x.Outln("PARAMETERS") sortedKeys := []string{} for key := range x.Params.params { sortedKeys = append(sortedKeys, key) } sort.Strings(sortedKeys) for _, key := range sortedKeys { p := x.Params.params[key] if key == "--debug" || key == "--nocolor" || key == "--help" { continue } wrk1 := "" if len(p["required"]) > 0 { wrk1 = " required... " + p["required"][0] } if len(p["value"]) > 0 { wrk1 += "\n default.... " + p["value"][0] } if len(p["envvar"]) > 0 { wrk1 += "\n env var.... " + p["envvar"][0] } name := key + " ..............................................................................." x.Outf(" %s %s\n", name[:80-len(p["descr"][0])-3], p["descr"][0]) x.Outln(wrk1) } x.Outln() for key := range x.Params.params { p := x.Params.params[key] if key == "--debug" || key == "--nocolor" || key == "--help" { wrk1 := "" if len(p["required"]) > 0 { wrk1 = " required... " + p["required"][0] } if len(p["value"]) > 0 { wrk1 += "\n default.... " + p["value"][0] } if len(p["envvar"]) > 0 { wrk1 += "\n env var.... " + p["envvar"][0] } name := key + " ..............................................................................." x.Outf(" %s %s\n", name[:80-len(p["descr"][0])-3], p["descr"][0]) x.Outln(wrk1) } } x.Outln() } func (x *UI) Parse(args []string) (err error) { // parse default variables tmp := []string{} for idx, arg := range args { if idx == 0 { continue } if arg == "--help" { x.Help() os.Exit(0) } if arg == "--debug" { x.debug = true x.Params.params["--debug"]["value"] = Arg{"true"} continue } if arg == "--nocolor" { x.nocolor = true x.Params.params["--nocolor"]["value"] = Arg{"true"} continue } tmp = append(tmp, arg) } args = tmp var required = map[string]bool{} // determine required for key := range x.Params.params { if x.Params.params[key]["required"][0] == "true" { required[key] = true } } var isBool = map[string]bool{} // determine if parameter is a bool for key := range x.Params.params { wrk := x.Params.params[key]["value"] if len(wrk) > 0 && (wrk[0] == "true" || wrk[0] == "false") { isBool[key] = true } } // parse bool parameters tmp = []string{} for _, arg := range args { if isBool[arg] { x.Params.params[arg]["value"] = Arg{"true"} continue } tmp = append(tmp, arg) } args = tmp // parse environment variables for key := range x.Params.params { wrk := x.Params.params[key]["envvar"] if len(wrk) > 0 { tmp := os.Getenv(wrk[0]) if len(tmp) > 0 { x.Params.params[key]["value"] = Arg{tmp} } } } // parse everything else ... for idx := 0; idx < len(args); idx++ { name := args[idx] if n := x.Params.params[name]; n != nil { idx++ if len(args) > (idx) { x.Params.params[name]["value"] = append(x.Params.params[name]["value"], args[idx]) } } else { x.Other = append(x.Other, args[idx]) } } // make sure requred arguments were supplied errcnt := 0 errmsg := "" for key := range required { param := x.Params.params[key] if len(param["value"]) == 0 { if errcnt > 0 { errmsg += ", " } errmsg += key errcnt++ } } if len(errmsg) > 0 { return fmt.Errorf("missing required arguments: %s", errmsg) } return nil } func (x *UI) Banner() { print := NewColor(x.nocolor) print.Yellowf("%s, version %s, build %s \n", x.appname, x.version, x.build) } func (x *UI) String(arg string) (val string) { val = "" wrk := x.Params.params[arg]["value"] if len(wrk) > 0 { val = wrk[len(wrk)-1] } return } func (x *UI) Strings(arg string) (val []string) { val = []string{} for _, wrk := range x.Params.params[arg]["value"] { if len(wrk) > 0 { val = append(val, wrk) } } return } func (x *UI) Bool(arg string) (val bool) { val = false wrk := x.Params.params[arg]["value"] if len(wrk) > 0 { val = wrk[len(wrk)-1] == "true" } return } // Int ... func (x *UI) Int(name string) (val int) { var err error if wrk := x.Params.params[name]; wrk != nil { tmp := 0 tmp, err = strconv.Atoi(wrk["value"][0]) if err != nil { tmp = -999 } val = tmp } return } // Int32 ... func (x *UI) Int32(name string) (val int32) { var err error if wrk := x.Params.params[name]; wrk != nil { tmp := 0 tmp, err = strconv.Atoi(wrk["value"][0]) if err != nil { tmp = -999 } val = int32(tmp) } return } // Int64 ... func (x *UI) Int64(name string) (val int64) { var err error if wrk := x.Params.params[name]; wrk != nil { tmp := 0 tmp, err = strconv.Atoi(wrk["value"][0]) if err != nil { tmp = -999 } val = int64(tmp) } return } // Ints ... func (x *UI) Ints(name string) (val []int) { var err error if wrk := x.Params.params[name]; wrk != nil { tmp := 0 for _, wrk1 := range wrk["value"] { tmp, err = strconv.Atoi(wrk1) if err != nil { tmp = -999 } val = append(val, tmp) } } return } // Ints32 ... func (x *UI) Ints32(name string) (val []int32) { var err error if wrk := x.Params.params[name]; wrk != nil { tmp := 0 for _, wrk1 := range wrk["value"] { tmp, err = strconv.Atoi(wrk1) if err != nil { tmp = -999 } val = append(val, int32(tmp)) } } return } // Ints64 ... func (x *UI) Ints64(name string) (val []int64) { var err error if wrk := x.Params.params[name]; wrk != nil { tmp := 0 for _, wrk1 := range wrk["value"] { tmp, err = strconv.Atoi(wrk1) if err != nil { tmp = -999 } val = append(val, int64(tmp)) } } return } // Out ... func (x *UI) Out(msg ...interface{}) { fmt.Print(msg...) } // Outln ... func (x *UI) Outln(msg ...interface{}) { fmt.Println(msg...) } // Outf ... func (x *UI) Outf(format string, i ...interface{}) { fmt.Printf(format, i...) } // Info ... func (x *UI) Info(msg ...interface{}) { fmt.Print(NewColor(x.nocolor).Sgreenf("[info] ")) fmt.Print(msg...) } // Infoln ... func (x *UI) Infoln(msg ...interface{}) { fmt.Print(NewColor(x.nocolor).Sgreenf("[info] ")) fmt.Println(msg...) } // Infof ... func (x *UI) Infof(format string, i ...interface{}) { fmt.Print(NewColor(x.nocolor).Sgreenf("[info] ")) fmt.Printf(format, i...) } // Error ... func (x *UI) Error(msg ...interface{}) { fmt.Print(NewColor(x.nocolor).Sredf("[error] ")) fmt.Print(msg...) } // Errorln ... func (x *UI) Errorln(msg ...interface{}) { fmt.Print(NewColor(x.nocolor).Sredf("[error] ")) fmt.Println(msg...) } // Errorf ... func (x *UI) Errorf(format string, i ...interface{}) { fmt.Print(NewColor(x.nocolor).Sredf("[error] ")) fmt.Printf(format, i...) } // Debug ... func (x *UI) Debug(msg ...interface{}) { if x.debug { fmt.Print(NewColor(x.nocolor).Syellowf("[debug] ")) fmt.Print(msg...) } } // Debugln ... func (x *UI) Debugln(msg ...interface{}) { if x.debug { fmt.Print(NewColor(x.nocolor).Syellowf("[debug] ")) fmt.Println(msg...) } } // Debugf ... func (x *UI) Debugf(format string, i ...interface{}) { if x.debug { fmt.Print(NewColor(x.nocolor).Syellowf("[debug] ")) fmt.Printf(format, i...) } } // Log ... func (x *UI) Log(msg ...interface{}) { ts := time.Now().Format("2006.01.02 03:04:05PM") fmt.Print("[" + ts + "] ") fmt.Print(msg...) } // Logln ... func (x *UI) Logln(msg ...interface{}) { ts := time.Now().Format("2006.01.02 03:04:05PM") fmt.Print("[" + ts + "] ") fmt.Println(msg...) } // Logf ... func (x *UI) Logf(format string, i ...interface{}) { ts := time.Now().Format("2006.01.02 03:04:05PM") fmt.Print("[" + ts + "] ") fmt.Printf(format, i...) } // Prompt ... func (x *UI) Prompt(msg ...interface{}) string { r := bufio.NewReader(os.Stdin) fmt.Print(NewColor(x.nocolor).Sredf("%s", msg...)) //fmt.Print(msg...) line, _, err := r.ReadLine() if err != nil { return err.Error() } return string(line) } // Clear ... func (x *UI) Clear() { fmt.Printf("\033[2J\033[1;1H") }