add task variants
parent
481ebc30e0
commit
8fee228701
7
go.mod
7
go.mod
|
@ -2,6 +2,10 @@ module go.digitalcircle.com.br/open/mk
|
||||||
|
|
||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
|
replace (
|
||||||
|
go.digitalcircle.com.br/open/shelly => ../shelly
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alecthomas/kong v0.2.17
|
github.com/alecthomas/kong v0.2.17
|
||||||
github.com/fatih/color v1.13.0
|
github.com/fatih/color v1.13.0
|
||||||
|
@ -10,4 +14,5 @@ require (
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
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/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 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
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-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-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
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
|
package lib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
|
"go.digitalcircle.com.br/open/shelly"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
@ -13,7 +14,6 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"time"
|
"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 {
|
if t.Model != "" {
|
||||||
env[k] = v
|
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 {
|
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 {
|
if len(t.Pre) > 0 {
|
||||||
Log(l, name, "**", fmt.Sprintf("Will run Pre tasks: [%s]", strings.Join(t.Pre, ",")))
|
Log(l, name, "**", fmt.Sprintf("Will run Pre tasks: [%s]", strings.Join(t.Pre, ",")))
|
||||||
for _, v := range 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]
|
pr, ok := model.Tasks[v]
|
||||||
if ok {
|
if ok {
|
||||||
err := RunTask(v, pr, l+1)
|
err := RunTask(v, pr, "", l+1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -116,125 +137,20 @@ func RunTask(name string, t *MkTask, l int) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var c *exec.Cmd
|
|
||||||
if runtime.GOOS == "windows" {
|
_, err := shelly.Exec(cmd, &shelly.Opts{
|
||||||
c = exec.Command("cmd.exe")
|
Debug: model.Debug,
|
||||||
} else {
|
Trace: model.Trace,
|
||||||
c = exec.Command("sh")
|
SetupProc: func(cmd *exec.Cmd) {
|
||||||
}
|
for k, v := range t.Env {
|
||||||
for k, v := range env {
|
env[k] = v
|
||||||
c.Env = append(c.Env, fmt.Sprintf("%s=%s", k, v))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pi, _ := c.StdinPipe()
|
for k, v := range t.Vars {
|
||||||
|
vars[k] = v
|
||||||
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"))
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
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 {
|
func Prepare() error {
|
||||||
|
|
||||||
InitCli()
|
InitCli()
|
||||||
|
@ -306,9 +231,26 @@ func Prepare() error {
|
||||||
if model.Default == "" {
|
if model.Default == "" {
|
||||||
model.Default = "main"
|
model.Default = "main"
|
||||||
}
|
}
|
||||||
|
model.Tasks = make(map[string]*MkTask)
|
||||||
|
|
||||||
for k, v := range model.Tasks {
|
for k, v := range model.RawTasks {
|
||||||
v.Name = k
|
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 {
|
if CLI.List {
|
||||||
|
@ -384,9 +326,16 @@ func Run() error {
|
||||||
DumpEnv()
|
DumpEnv()
|
||||||
model.Stack = make(map[string]string)
|
model.Stack = make(map[string]string)
|
||||||
for _, v := range CLI.Tasks {
|
for _, v := range CLI.Tasks {
|
||||||
tasko := ResolveTask(v)
|
taskparts := strings.Split(v, ",")
|
||||||
|
tasko := ResolveTask(taskparts[0])
|
||||||
if tasko != nil {
|
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 {
|
} else {
|
||||||
return errors.New(fmt.Sprintf("No task named %s found", v))
|
return errors.New(fmt.Sprintf("No task named %s found", v))
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,16 @@ type MkTask struct {
|
||||||
Onerror string `yaml:"onerror"`
|
Onerror string `yaml:"onerror"`
|
||||||
Env map[string]string `yaml:"env"`
|
Env map[string]string `yaml:"env"`
|
||||||
Vars map[string]string `yaml:"vars"`
|
Vars map[string]string `yaml:"vars"`
|
||||||
|
Model string `yaml:"model"`
|
||||||
|
Variants []string `yaml:"variants"`
|
||||||
}
|
}
|
||||||
type MkModel struct {
|
type MkModel struct {
|
||||||
Env map[string]string `yaml:"env"`
|
Env map[string]string `yaml:"env"`
|
||||||
Vars map[string]string `yaml:"vars"`
|
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"`
|
Default string `yaml:"default"`
|
||||||
Stack map[string]string `yaml:"-"`
|
Stack map[string]string `yaml:"-"`
|
||||||
|
Debug bool `yaml:"debug"`
|
||||||
|
Trace bool `yaml:"trace"`
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue