From 8fee228701f14a25399b942faef00b6504ff3e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Sima=CC=83o?= Date: Wed, 3 Nov 2021 13:25:44 -0300 Subject: [PATCH] add task variants --- go.mod | 7 +- go.sum | 8 ++ lib/run.go | 203 +++++++++++++++++++-------------------------------- lib/types.go | 29 +++++--- 4 files changed, 107 insertions(+), 140 deletions(-) diff --git a/go.mod b/go.mod index 1b13aae..787158d 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,10 @@ module go.digitalcircle.com.br/open/mk go 1.17 +replace ( + go.digitalcircle.com.br/open/shelly => ../shelly +) + require ( github.com/alecthomas/kong v0.2.17 github.com/fatih/color v1.13.0 @@ -10,4 +14,5 @@ require ( github.com/pkg/errors v0.9.1 // indirect golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b -) + go.digitalcircle.com.br/open/shelly v0.0.0-20211103011122-59a4e22ee8ce // indirect + ) diff --git a/go.sum b/go.sum index 4ba176b..b524f23 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,14 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +go.digitalcircle.com.br/open/shelly v0.0.0-20211030113731-e855d65d6014 h1:4WIAT2wEfG6Ype5PSscio8Ezd+nwFUb60ivVDl71fiU= +go.digitalcircle.com.br/open/shelly v0.0.0-20211030113731-e855d65d6014/go.mod h1:J4ZSPkhjtyQz1yDxFGTemtz+Z7Z3YkzLd7iw9Jqo1+E= +go.digitalcircle.com.br/open/shelly v0.0.0-20211103003803-2665d10c09c2 h1:X3s/yNZMW6lEl8AHuM5WScWZz5Aq0XkfObBow/Q/VJ8= +go.digitalcircle.com.br/open/shelly v0.0.0-20211103003803-2665d10c09c2/go.mod h1:J4ZSPkhjtyQz1yDxFGTemtz+Z7Z3YkzLd7iw9Jqo1+E= +go.digitalcircle.com.br/open/shelly v0.0.0-20211103004736-5ff5942b4ff3 h1:urFhugLuu02mir7lV2l9ifMNxcdE1risO3QQDvDFiBM= +go.digitalcircle.com.br/open/shelly v0.0.0-20211103004736-5ff5942b4ff3/go.mod h1:J4ZSPkhjtyQz1yDxFGTemtz+Z7Z3YkzLd7iw9Jqo1+E= +go.digitalcircle.com.br/open/shelly v0.0.0-20211103011122-59a4e22ee8ce h1:JJi0bh4gOhgklrdfht4hOnaeWwRWBnBPEamPmpfJ2Q4= +go.digitalcircle.com.br/open/shelly v0.0.0-20211103011122-59a4e22ee8ce/go.mod h1:J4ZSPkhjtyQz1yDxFGTemtz+Z7Z3YkzLd7iw9Jqo1+E= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/lib/run.go b/lib/run.go index 7dee832..4ea6198 100644 --- a/lib/run.go +++ b/lib/run.go @@ -1,10 +1,11 @@ package lib import ( - "bufio" + "encoding/json" "errors" "fmt" "github.com/fatih/color" + "go.digitalcircle.com.br/open/shelly" "gopkg.in/yaml.v3" "log" "os" @@ -13,7 +14,6 @@ import ( "runtime" "sort" "strings" - "sync" "time" ) @@ -83,17 +83,38 @@ func Log(i int, task string, stream string, b string) { } -func RunTask(name string, t *MkTask, l int) error { +func RunTask(name string, t *MkTask, variant string, l int) error { + cmd := t.Cmd + if len(t.Variants) > 0 && variant == "" { + for _, v := range t.Variants { + err := RunTask(name, t, v, l+1) + if err != nil { + return err + } + } + return nil + } - for k, v := range t.Env { - env[k] = v + if t.Model != "" { + cmd = model.Tasks[t.Model].Cmd + for k, v := range t.Vars { + cmd = strings.Replace(cmd, "${"+k+"}", v, -1) + } } for k, v := range t.Vars { - vars[k] = v + if strings.HasPrefix(k, variant+".") { + nk := strings.Replace(k, variant+".", "", 1) + cmd = strings.Replace(cmd, "${"+nk+"}", v, -1) + } + } + + if variant != "" { + Log(l, name, "**", fmt.Sprintf("Starting %s::%s", name, variant)) + } else { + Log(l, name, "**", fmt.Sprintf("Starting %s", name)) } - Log(l, name, "**", fmt.Sprintf("Starting %s", name)) if len(t.Pre) > 0 { Log(l, name, "**", fmt.Sprintf("Will run Pre tasks: [%s]", strings.Join(t.Pre, ","))) for _, v := range t.Pre { @@ -107,7 +128,7 @@ func RunTask(name string, t *MkTask, l int) error { pr, ok := model.Tasks[v] if ok { - err := RunTask(v, pr, l+1) + err := RunTask(v, pr, "", l+1) if err != nil { return err } @@ -116,125 +137,20 @@ func RunTask(name string, t *MkTask, l int) error { } } } - var c *exec.Cmd - if runtime.GOOS == "windows" { - c = exec.Command("cmd.exe") - } else { - c = exec.Command("sh") - } - for k, v := range env { - c.Env = append(c.Env, fmt.Sprintf("%s=%s", k, v)) - } - pi, _ := c.StdinPipe() - - po, err := c.StdoutPipe() - - if err != nil { - log.Printf(err.Error()) - return err - } - scannero := bufio.NewScanner(po) - - pe, err := c.StderrPipe() - if err != nil { - log.Printf(err.Error()) - return err - } - scannere := bufio.NewScanner(pe) - - wg := sync.WaitGroup{} - - wg.Add(2) - - ch := make(chan string) - - go func() { - time.Sleep(time.Millisecond * 100) - defer wg.Done() - for scannero.Scan() { - line := scannero.Text() - if strings.Contains(line, "__CMD_ENDED__:") { - ret := strings.Split(line, "__CMD_ENDED__:")[1] - if ret != "%errorlevel%" { - ch <- ret - } - } else { - Log(l+1, name, "O", line) - } - } - - }() - - go func() { - time.Sleep(time.Millisecond * 100) - defer wg.Done() - for scannere.Scan() { - Log(l+1, name, "E", scannere.Text()) - } - }() - - err = c.Start() - - if err != nil { - return err - } - - lines := bufio.NewScanner(strings.NewReader(t.Cmd)) - - //if runtime.GOOS == "windows" { - // pi.Write([]byte("@echo off\n")) - //} - - for lines.Scan() { - - txt := lines.Text() - - for k, v := range vars { - txt = strings.Replace(txt, fmt.Sprintf("${%s}", k), v, -1) - } - if strings.HasPrefix(txt, "@") { - txt = strings.TrimLeft(txt, "@") - } else { - Log(l+1, name, "I", txt) - } - - if strings.HasPrefix(txt, "mk:") { - txt = strings.Replace(txt, "mk:", "", 1) - txt = strings.TrimSpace(txt) - err = RunMkCmd(l+1, txt) - if err != nil { - log.Printf("Error running: %s", txt) - } - } else { - - _, err = pi.Write([]byte(txt + "\n")) - - if runtime.GOOS == "windows" { - _, err = pi.Write([]byte("echo __CMD_ENDED__:%errorlevel%" + "\n")) - } else { - _, err = pi.Write([]byte("echo __CMD_ENDED__:$?" + "\n")) + _, err := shelly.Exec(cmd, &shelly.Opts{ + Debug: model.Debug, + Trace: model.Trace, + SetupProc: func(cmd *exec.Cmd) { + for k, v := range t.Env { + env[k] = v } - ret := <-ch - if ret != "0" && t.Onerror == "skip" { - Log(l+1, name, "E", "Error Code: "+ret+" will continue, but watch out") - - } else if ret != "0" && t.Onerror != "skip" { - Log(l+1, name, "E", "Error Code is: "+ret+" ABORTING") - break + for k, v := range t.Vars { + vars[k] = v } - } - - } - _, err = pi.Write([]byte("exit\n")) - if err != nil { - return err - } - - wg.Wait() - err = c.Wait() - Log(l, name, "**", "End") + }, + }) return err } @@ -270,6 +186,15 @@ func DumpEnv() { } } +func jsonConvert(src interface{}, dst interface{}) error { + bs, err := json.Marshal(src) + if err != nil { + return err + } + err = json.Unmarshal(bs, dst) + return err +} + func Prepare() error { InitCli() @@ -306,9 +231,26 @@ func Prepare() error { if model.Default == "" { model.Default = "main" } + model.Tasks = make(map[string]*MkTask) - for k, v := range model.Tasks { - v.Name = k + for k, v := range model.RawTasks { + nv := &MkTask{} + nv.Name = k + nv.Vars = make(map[string]string) + switch v1 := v.(type) { + case string: + nv.Cmd = v1 + case map[string]interface{}: + err = jsonConvert(v1, nv) + if err != nil { + return err + } + } + + for k1, v1 := range model.Vars { + nv.Vars[k1] = v1 + } + model.Tasks[k] = nv } if CLI.List { @@ -384,9 +326,16 @@ func Run() error { DumpEnv() model.Stack = make(map[string]string) for _, v := range CLI.Tasks { - tasko := ResolveTask(v) + taskparts := strings.Split(v, ",") + tasko := ResolveTask(taskparts[0]) if tasko != nil { - err = RunTask(v, tasko, 0) + if len(taskparts) > 1 { + for i := 1; i < len(taskparts); i++ { + err = RunTask(taskparts[0], tasko, taskparts[1], 0) + } + } else { + err = RunTask(taskparts[0], tasko, "", 0) + } } else { return errors.New(fmt.Sprintf("No task named %s found", v)) } diff --git a/lib/types.go b/lib/types.go index 55a5b8a..d2c96e5 100644 --- a/lib/types.go +++ b/lib/types.go @@ -1,18 +1,23 @@ package lib type MkTask struct { - Name string - Help string - Cmd string `yaml:"cmd"` - Pre []string `yaml:"pre"` - Onerror string `yaml:"onerror"` - Env map[string]string `yaml:"env"` - Vars map[string]string `yaml:"vars"` + Name string + Help string + Cmd string `yaml:"cmd"` + Pre []string `yaml:"pre"` + Onerror string `yaml:"onerror"` + Env map[string]string `yaml:"env"` + Vars map[string]string `yaml:"vars"` + Model string `yaml:"model"` + Variants []string `yaml:"variants"` } type MkModel struct { - Env map[string]string `yaml:"env"` - Vars map[string]string `yaml:"vars"` - Tasks map[string]*MkTask `yaml:"tasks"` - Default string `yaml:"default"` - Stack map[string]string `yaml:"-"` + Env map[string]string `yaml:"env"` + Vars map[string]string `yaml:"vars"` + RawTasks map[string]interface{} `yaml:"tasks"` + Tasks map[string]*MkTask `yaml:"-"` + Default string `yaml:"default"` + Stack map[string]string `yaml:"-"` + Debug bool `yaml:"debug"` + Trace bool `yaml:"trace"` }