add task variants
parent
481ebc30e0
commit
8fee228701
5
go.mod
5
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
|
||||
)
|
||||
|
|
8
go.sum
8
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=
|
||||
|
|
203
lib/run.go
203
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))
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
_, 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
|
||||
}
|
||||
|
||||
pi, _ := c.StdinPipe()
|
||||
|
||||
po, err := c.StdoutPipe()
|
||||
|
||||
if err != nil {
|
||||
log.Printf(err.Error())
|
||||
return err
|
||||
for k, v := range t.Vars {
|
||||
vars[k] = v
|
||||
}
|
||||
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"))
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
_, 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))
|
||||
}
|
||||
|
|
|
@ -8,11 +8,16 @@ type MkTask struct {
|
|||
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"`
|
||||
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"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue