diff --git a/ui/colors.go b/ui/colors.go new file mode 100644 index 0000000..524628d --- /dev/null +++ b/ui/colors.go @@ -0,0 +1,306 @@ +package ui + +import ( + "fmt" + "os" + "runtime" + "strings" +) + +const ( + // Reset ... + Reset = "\x1b[0m" + // Bright ... + Bright = "\x1b[1m" + // Dim ... + Dim = "\x1b[2m" + // Underscore ... + Underscore = "\x1b[4m" + // Blink ... + Blink = "\x1b[5m" + // Reverse ... + Reverse = "\x1b[7m" + // Hidden ... + Hidden = "\x1b[8m" +) + +const ( + // FgBlack - Black foreground + FgBlack = "\x1b[30m" + // FgRed - Red foreground + FgRed = "\x1b[91m" + // FgGreen - Green foreground + FgGreen = "\x1b[92m" + // FgYellow - Yellow foreground + FgYellow = "\x1b[93m" + // FgBlue - Blue foreground + FgBlue = "\x1b[94m" + // FgMagenta - Magenta foreground + FgMagenta = "\x1b[95m" + // FgCyan - Cyan foreground + FgCyan = "\x1b[96m" + // FgWhite - White foreground + FgWhite = "\x1b[97m" + // FgOrange - Orange foreground + FgOrange = "\x1b[33m" +) + +const ( + // BgBlack - Black background + BgBlack = "\x1b[40m" + // BgRed - Red background + BgRed = "\x1b[41m" + // BgGreen - Green background + BgGreen = "\x1b[42m" + // BgYellow - Yellow background + BgYellow = "\x1b[43m" + // BgBlue - Blue background + BgBlue = "\x1b[44m" + // BgMagenta - Magenta background + BgMagenta = "\x1b[45m" + // BgCyan - Cyan background + BgCyan = "\x1b[46m" + // BgWhite - White background + BgWhite = "\x1b[47m" +) + +// Color ... +type Color struct { + nocolor bool +} + +// NewColor ... +func NewColor(nocolor bool) *Color { + return &Color{nocolor} +} + +// color ... +func (c *Color) color(color string, msg ...interface{}) { + if !c.nocolor && colorterm() { + fmt.Print(color) + msg = append(msg, Reset) + } + fmt.Print(msg...) +} + +// colorln ... +func (c *Color) colorln(color string, msg ...interface{}) { + if !c.nocolor && colorterm() { + fmt.Print(color) + msg = append(msg, Reset) + } + fmt.Println(msg...) +} + +// colorf ... +func (c *Color) colorf(color, format string, i ...interface{}) { + if !c.nocolor && colorterm() { + fmt.Print(color) + format += Reset + } + fmt.Printf(format, i...) +} + +// scolorf ... +func (c *Color) scolorf(color, format string, i ...interface{}) string { + if !c.nocolor && colorterm() { + format = color + format + format += Reset + } + return fmt.Sprintf(format, i...) +} + +// colorterm +func colorterm() (supportscolor bool) { + term := os.Getenv("TERM") + supportscolor = true // going to assume yes + if len(term) > 0 { + if !(strings.Contains(term, "xterm-color") || strings.Contains(term, "256color")) { + supportscolor = false + } + } + if runtime.GOOS == "windows" { + supportscolor = false + } + return +} + +// Black ... +func (c *Color) Black(msg ...interface{}) { + c.color(FgBlack, msg...) +} + +// Blackln ... +func (c *Color) Blackln(msg ...interface{}) { + c.colorln(FgBlack, msg...) +} + +// Blackf ... +func (c *Color) Blackf(format string, i ...interface{}) { + c.colorf(FgBlack, format, i...) +} + +// Sblackf ... +func (c *Color) Sblackf(format string, i ...interface{}) { + c.scolorf(FgBlack, format, i...) +} + +// Red ... +func (c *Color) Red(msg ...interface{}) { + c.color(FgRed, msg...) +} + +// Redln ... +func (c *Color) Redln(msg ...interface{}) { + c.colorln(FgRed, msg...) +} + +// Redf ... +func (c *Color) Redf(format string, i ...interface{}) { + c.colorf(FgRed, format, i...) +} + +// Sredf ... +func (c *Color) Sredf(format string, i ...interface{}) string { + return c.scolorf(FgRed, format, i...) +} + +// Green ... +func (c *Color) Green(msg ...interface{}) { + c.color(FgGreen, msg...) +} + +// Greenln ... +func (c *Color) Greenln(msg ...interface{}) { + c.colorln(FgGreen, msg...) +} + +// Greenf ... +func (c *Color) Greenf(format string, i ...interface{}) { + c.colorf(FgGreen, format, i...) +} + +// Sgreenf ... +func (c *Color) Sgreenf(format string, i ...interface{}) string { + return c.scolorf(FgGreen, format, i...) +} + +// Yellow ... +func (c *Color) Yellow(msg ...interface{}) { + c.color(FgYellow, msg...) +} + +// Yellowln ... +func (c *Color) Yellowln(msg ...interface{}) { + c.colorln(FgYellow, msg...) +} + +// Yellowf ... +func (c *Color) Yellowf(format string, i ...interface{}) { + c.colorf(FgYellow, format, i...) +} + +// Syellowf ... +func (c *Color) Syellowf(format string, i ...interface{}) string { + return c.scolorf(FgYellow, format, i...) +} + +// Blue ... +func (c *Color) Blue(msg ...interface{}) { + c.color(FgBlue, msg...) +} + +// Blueln ... +func (c *Color) Blueln(msg ...interface{}) { + c.colorln(FgBlue, msg...) +} + +// Bluef ... +func (c *Color) Bluef(format string, i ...interface{}) { + c.colorf(FgBlue, format, i...) +} + +// Sbluef ... +func (c *Color) Sbluef(format string, i ...interface{}) string { + return c.scolorf(FgBlue, format, i...) +} + +// Magenta ... +func (c *Color) Magenta(msg ...interface{}) { + c.color(FgMagenta, msg...) +} + +// Magentaln ... +func (c *Color) Magentaln(msg ...interface{}) { + c.colorln(FgMagenta, msg...) +} + +// Magentaf ... +func (c *Color) Magentaf(format string, i ...interface{}) { + c.colorf(FgMagenta, format, i...) +} + +// Smagentaf ... +func (c *Color) Smagentaf(format string, i ...interface{}) string { + return c.scolorf(FgMagenta, format, i...) +} + +// Cyan ... +func (c *Color) Cyan(msg ...interface{}) { + c.color(FgCyan, msg...) +} + +// Cyanln ... +func (c *Color) Cyanln(msg ...interface{}) { + c.colorln(FgCyan, msg...) +} + +// Cyanf ... +func (c *Color) Cyanf(format string, i ...interface{}) { + c.colorf(FgCyan, format, i...) +} + +// Scyanf ... +func (c *Color) Scyanf(format string, i ...interface{}) string { + return c.scolorf(FgCyan, format, i...) +} + +// Orange ... +func (c *Color) Orange(msg ...interface{}) { + c.color(FgOrange, msg...) +} + +// Orangeln ... +func (c *Color) Orangeln(msg ...interface{}) { + c.colorln(FgOrange, msg...) +} + +// Orangef ... +func (c *Color) Orangef(format string, i ...interface{}) { + c.colorf(FgOrange, format, i...) +} + +// Sorangef ... +func (c *Color) Sorangef(format string, i ...interface{}) string { + return c.scolorf(FgOrange, format, i...) +} + +// White ... +func (c *Color) White(msg ...interface{}) { + c.color(FgWhite, msg...) +} + +// Whiteln ... +func (c *Color) Whiteln(msg ...interface{}) { + c.colorln(FgWhite, msg...) +} + +// Whitef ... +func (c *Color) Whitef(format string, i ...interface{}) { + c.colorf(FgWhite, format, i...) +} + +// Swhitef ... +func (c *Color) Swhitef(format string, i ...interface{}) string { + return c.scolorf(FgWhite, format, i...) +} diff --git a/ui/gitinit.sh b/ui/gitinit.sh new file mode 100755 index 0000000..c928b05 --- /dev/null +++ b/ui/gitinit.sh @@ -0,0 +1,15 @@ +#!/bin/bash +GITSVR="cdmnky.web" +VERSION="v3" +PROJECT="ui" +ssh $GITSVR "mkdir -p ./gitrepos/cdmnky.go/$VERSION/$PROJECT; cd ./gitrepos/cdmnky.go/$VERSION/$PROJECT; git init --bare" + +#git config --global user.email "brian@bcnewman.com" +#git config --global user.name "Brian Newman" + + +git init +git add . +git commit -m "Initial commit" +git remote add origin $GITSVR:gitrepos/cdmnky.go/$VERSION/$PROJECT +git push -u origin master diff --git a/ui/ui.go b/ui/ui.go new file mode 100644 index 0000000..eeca44b --- /dev/null +++ b/ui/ui.go @@ -0,0 +1,484 @@ +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") +}