Skip to content

Commit

Permalink
added stages
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabian Simon committed Jan 10, 2023
1 parent 4d70753 commit 12db3a2
Show file tree
Hide file tree
Showing 18 changed files with 976 additions and 18 deletions.
32 changes: 32 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,38 @@ And all sprig functions ==> [Documentation](http://masterminds.github.io/sprig/)
# Use inside Pipeline
There is a [Dockerimage](https://hub.docker.com/r/fasibio/gomake)

# parallel execution

You can use same stage for different commands

```
buildDocker:
stage: stagename
color: "{{$root.Colors.red}}"
script:
- docker build -t {{$root.Vars.dockername}}:{{$root.Vars.version}} -f {{$root.Vars.dockerfile}} .
on_failure:
- docker rmi {{$root.Vars.dockername}}:{{$root.Vars.version}}
```
Now you can run by stagename instand of Command name with:

```
gomake srun stagename
```

**Hint** Color can help you make it better to read at

Possible Colors:
- black
- red
- green
- yellow
- purple
- magenta
- teal
- white



# Use Docker-Images

Expand Down
4 changes: 4 additions & 0 deletions command/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ type Operation struct {
Script []string
Image *DockerOperation
On_Failure []string
Stage string
Color string
}

type DockerOperation struct {
Expand Down Expand Up @@ -122,6 +124,8 @@ func (c *CommandHandler) GetExecutedCommandMakeScript(cmd string, data MakeStruc
Script: commands,
On_Failure: onFailer,
Image: data[cmd].Image,
Color: data[cmd].Color,
Stage: data[cmd].Stage,
}
return res, nil
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.19

require (
github.com/Masterminds/sprig/v3 v3.2.3
github.com/pkg/errors v0.9.1
github.com/schollz/closestmatch v2.1.0+incompatible
github.com/urfave/cli/v2 v2.23.7
gopkg.in/yaml.v2 v2.4.0
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBa
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
Expand All @@ -18,6 +19,9 @@ github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMK
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
Expand All @@ -29,6 +33,7 @@ github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/urfave/cli/v2 v2.23.7 h1:YHDQ46s3VghFHFf1DdF+Sh7H4RqhcM+t0TmZRJx4oJY=
github.com/urfave/cli/v2 v2.23.7/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
Expand Down
8 changes: 6 additions & 2 deletions gomake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ buildAll:
{{include "buildDocker"}}

build:
stage: b
color: "{{$root.Colors.purple}}"
script:
- mkdir {{.Vars.dist}}
{{- range $goosKey, $goos := splitList "|" $root.Vars.gooss}}
Expand All @@ -33,6 +35,8 @@ build:
- rm -rf {{.Vars.dist}}

buildDocker:
stage: b
color: "{{$root.Colors.red}}"
script:
- docker build -t {{$root.Vars.dockername}}:{{$root.Vars.version}} -f {{$root.Vars.dockerfile}} .
on_failure:
Expand All @@ -43,12 +47,12 @@ test:
- docker run --rm {{$root.Vars.dockername}}:{{$root.Vars.version}} --help
# Wrap build into a docker image
buildContainer:
color: {{$root.Colors.yellow}}
image:
name: golang:latest
name: alpine:latest
volumes:
- {{.Env.PWD}}:/build
script:
- cd /build
- ls
{{include "build"}}
on_failure:
15 changes: 10 additions & 5 deletions interpreter/dryRun.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ type DryRunOutput struct {
ExecutedCommand command.Operation
}

func (i Interpreter) printDryRun(command command.MakeStruct, variables map[string]map[string]any) error {
out, err := yaml.Marshal(DryRunOutput{
Vars: variables["vars"],
ExecutedCommand: command[i.ExecuteCommand],
})
type SDryRunOutput map[string]any

func (i Interpreter) printDryRun(command []StageOperationWrapper, variables map[string]map[string]any) error {

outPutData := make(SDryRunOutput)
outPutData["vars"] = variables["vars"]
for _, c := range command {
outPutData[c.Name] = c.Command
}
out, err := yaml.Marshal(outPutData)
if err != nil {
return err
}
Expand Down
155 changes: 145 additions & 10 deletions interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,44 @@ package interpreter
import (
"bytes"
"fmt"
"io"
"log"
"os"
"os/exec"
"strings"
"sync"
"text/template"

"github.com/Masterminds/sprig/v3"
"github.com/fasibio/gomake/command"
nearfinder "github.com/fasibio/gomake/nearFinder"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
)

var colorsMap map[string]string = map[string]string{
"black": "\033[1;30m%s\033[0m",
"red": "\033[1;31m%s\033[0m",
"green": "\033[1;32m%s\033[0m",
"yellow": "\033[1;33m%s\033[0m",
"purple": "\033[1;34m%s\033[0m",
"magenta": "\033[1;35m%s\033[0m",
"teal": "\033[1;36m%s\033[0m",
"white": "\033[1;37m%s\033[0m",
}

func getColorKeyMap() map[string]string {
res := make(map[string]string)
for k := range colorsMap {
res[k] = k
}
return res
}

type TemplateData struct {
Vars map[string]any
Env map[string]string
Vars map[string]any
Env map[string]string
Colors map[string]string
}

type Interpreter struct {
Expand Down Expand Up @@ -80,7 +103,7 @@ func (r *Interpreter) GetExecuteTemplate(file string, extraVariables map[string]
}
}

varStr, err := r.getParsedTemplate("gomake_vars", varCommandArr[0], TemplateData{Env: env, Vars: tempVar})
varStr, err := r.getParsedTemplate("gomake_vars", varCommandArr[0], TemplateData{Env: env, Vars: tempVar, Colors: getColorKeyMap()})

if err != nil {
return nil, nil, err
Expand All @@ -105,7 +128,7 @@ func (r *Interpreter) GetExecuteTemplate(file string, extraVariables map[string]
return nil, nil, err
}

b, err := r.getParsedTemplate("gomake", varCommandArr[1], TemplateData{Vars: v, Env: env})
b, err := r.getParsedTemplate("gomake", varCommandArr[1], TemplateData{Vars: v, Env: env, Colors: getColorKeyMap()})
return b, variables, err
}

Expand All @@ -128,7 +151,7 @@ func (r *Interpreter) Run() error {
return err
}
if r.DryRun {
return r.printDryRun(command, variables)
return r.printDryRun([]StageOperationWrapper{{Name: r.ExecuteCommand, Command: command[r.ExecuteCommand]}}, variables)
}

cmd := r.cmdHandler.SliceCommands(command[r.ExecuteCommand].Script)
Expand All @@ -137,23 +160,135 @@ func (r *Interpreter) Run() error {
cmd = getDockerCmd(cmd, image)
}

err = r.execCmd(executer, cmd)
err = r.execCmd(executer, cmd, log.Writer())
if err != nil {
if len(command[r.ExecuteCommand].On_Failure) > 0 {
fmt.Println("Script end with error so start onFailure Scripts ...")
err = r.execCmd(executer, r.cmdHandler.SliceCommands(command[r.ExecuteCommand].On_Failure))
err = r.execCmd(executer, r.cmdHandler.SliceCommands(command[r.ExecuteCommand].On_Failure), log.Writer())
} else {
fmt.Println("No onFailure Scripts found but got error")
}
}
return err
}

func (r *Interpreter) execCmd(executer, command string) error {
type StageOperationWrapper struct {
Name string
Command command.Operation
}

type StageOperationWrapperError struct {
StageOperationWrapper
error
}

func (w *StageOperationWrapper) Write(data []byte) (n int, err error) {

colorFunc := func(d ...interface{}) string { return fmt.Sprint(d...) }
if w.Command.Color != "" {
colorFunc = w.Color(colorsMap[w.Command.Color])

}
fmt.Print(colorFunc(w.Name + ":\t" + string(data)))
// fmt.Printf("%s:\t%s", w.ServiceName, string(data))
return len(data), nil
}

func (w *StageOperationWrapper) Color(colorString string) func(...interface{}) string {
sprint := func(args ...interface{}) string {
return fmt.Sprintf(colorString,
fmt.Sprint(args...))
}
return sprint
}

func (r *Interpreter) GetStageMap() (map[string][]StageOperationWrapper, command.MakeStruct, map[string]map[string]any, error) {
explizitMakeFile, variables, err := r.GetExecuteTemplate(string(r.commandFile), make(map[string]any))
if err != nil {
return nil, nil, nil, err
}
c1, err := r.getMakeScripts(explizitMakeFile)
if err != nil {
return nil, nil, nil, err
}
stagesMap := make(map[string][]StageOperationWrapper)
for k, c := range c1 {
if c.Stage != "" {
_, ok := stagesMap[c.Stage]
if !ok {
stagesMap[c.Stage] = make([]StageOperationWrapper, 0)
}
stagesMap[c.Stage] = append(stagesMap[c.Stage], StageOperationWrapper{Name: k, Command: c})
}
}
return stagesMap, c1, variables, nil
}

// Stage running
func (r *Interpreter) SRun() error {
stagesMap, c1, variables, err := r.GetStageMap()
if err != nil {
return err
}

if _, ok := stagesMap[r.ExecuteCommand]; !ok {
return fmt.Errorf("no command with stage %s found at makefile, did you mean \n%s", r.ExecuteCommand, nearfinder.ClosestMatch(r.ExecuteCommand, nearfinder.GetKeysOfMap(stagesMap), 2))
}

commands := make([]StageOperationWrapper, 0)
for _, c := range stagesMap[r.ExecuteCommand] {
tmpc, err := r.cmdHandler.GetExecutedCommandMakeScript(c.Name, c1)
if err != nil {
return err
}
commands = append(commands, StageOperationWrapper{Name: c.Name, Command: tmpc[c.Name]})
}

if r.DryRun {
return r.printDryRun(commands, variables)
}
w := sync.WaitGroup{}
errList := make([]StageOperationWrapperError, 0)
for _, c := range commands {
w.Add(1)
go func(operator StageOperationWrapper) {
cmd := r.cmdHandler.SliceCommands(operator.Command.Script)
if image := operator.Command.Image; image != nil {
cmd = getDockerCmd(cmd, image)
}
err := r.execCmd(r.executer, cmd, &operator)
if err != nil {
errList = append(errList, StageOperationWrapperError{
error: err,
StageOperationWrapper: operator,
})
}
w.Done()
}(c)
}
w.Wait()
var errres error = nil
if len(errList) > 0 {
for _, e := range errList {
if len(e.Command.On_Failure) > 0 {
e.Write([]byte(fmt.Sprintf("%s end with error so start onFailure Scripts ...", e.Name)))
err := r.execCmd(r.executer, r.cmdHandler.SliceCommands(e.Command.On_Failure), &e)
if err != nil {
errres = errors.Wrap(errres, err.Error())
}
} else {
e.Write([]byte(fmt.Sprintf("No OnFailer Script found but %s got error ", e.Name)))
}
}
}
return errres
}

func (r *Interpreter) execCmd(executer, command string, writer io.Writer) error {
cmd := exec.Command(executer, "-c", command)
cmd.Stdin = os.Stdin
cmd.Stdout = log.Writer()
cmd.Stderr = log.Writer()
cmd.Stdout = writer
cmd.Stderr = writer
return cmd.Run()
}

Expand Down
Loading

0 comments on commit 12db3a2

Please sign in to comment.