Skip to content

Commit

Permalink
Merge pull request #22 from semaphoreci/handle-broken-when-syntax
Browse files Browse the repository at this point in the history
Handle broken when syntax
  • Loading branch information
shiroyasha authored Jan 28, 2021
2 parents 10cf6e3 + 1fb85cf commit f9d3ab4
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 40 deletions.
13 changes: 7 additions & 6 deletions .semaphore/semaphore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ global_job_config:
- export GO111MODULE=on
- export GOPATH=~/go
- 'export PATH=/home/semaphore/go/bin:$PATH'
- curl -LO https://github.com/renderedtext/when/releases/download/v0.0.3-alpha/when
- sudo mv when /usr/local/bin/when
- sudo chmod +x /usr/local/bin/when
- checkout
- go get ./...

Expand All @@ -30,9 +33,6 @@ blocks:
task:
prologue:
commands:
- curl -LO https://github.com/renderedtext/when/releases/download/v0.0.2-alpha/when
- sudo chmod +x when
- sudo mv when /usr/bin/when
- git config --global user.email "you@example.com"
- git config --global user.name "Your Name"
- unset SEMAPHORE_GIT_REF_TYPE
Expand All @@ -57,16 +57,17 @@ blocks:
- test/e2e/change_in_default_range.rb
- test/e2e/change_in_excluded_paths.rb
- test/e2e/change_in_glob.rb
- test/e2e/change_in_invalid_when.rb
- test/e2e/change_in_missing_branch.rb
- test/e2e/change_in_multiple_paths.rb
- test/e2e/change_in_on_tags.rb
- test/e2e/change_in_on_prs.rb
- test/e2e/change_in_on_forked_prs.rb
- test/e2e/change_in_on_prs.rb
- test/e2e/change_in_on_tags.rb
- test/e2e/change_in_performance.rb
- test/e2e/change_in_pipeline_file_tracking.rb
- test/e2e/change_in_relative_paths.rb
- test/e2e/change_in_simple.rb
- test/e2e/change_in_with_default_branch.rb
- test/e2e/change_in_performance.rb

commands:
- make build
Expand Down
4 changes: 4 additions & 0 deletions pkg/cli/evaluate.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ func check(err error) {
os.Exit(1)
}

if _, ok := err.(*logs.ErrorInvalidWhenExpression); ok {
os.Exit(1)
}

panic(err)
}

Expand Down
9 changes: 9 additions & 0 deletions pkg/logs/error_invalid_change_in.go → pkg/logs/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,12 @@ type ErrorChangeInMissingBranch struct {
func (e *ErrorChangeInMissingBranch) Error() string {
return e.Message
}

type ErrorInvalidWhenExpression struct {
Message string `json:"message"`
Location Location `json:"location"`
}

func (e *ErrorInvalidWhenExpression) Error() string {
return e.Message
}
36 changes: 34 additions & 2 deletions pkg/pipelines/extract_when_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package pipelines
import (
"strconv"

logs "github.com/semaphoreci/spc/pkg/logs"
when "github.com/semaphoreci/spc/pkg/when"
whencli "github.com/semaphoreci/spc/pkg/when/whencli"
)
Expand All @@ -29,18 +30,49 @@ func (e *whenExtractor) Parse() ([]when.WhenExpression, error) {
expressions = append(expressions, e.Expression)
}

res := []when.WhenExpression{}

requirments, err := whencli.ListInputs(expressions)
if err != nil {
return []when.WhenExpression{}, err
return res, err
}

err = e.verifyParsed(requirments)
if err != nil {
return res, err
}

for index := range e.list {
e.list[index].Requirments = requirments[index]
e.list[index].Requirments = requirments[index].Inputs
}

return e.list, nil
}

func (e *whenExtractor) verifyParsed(requirments []whencli.ListInputsResult) error {
var err error

for index, r := range requirments {
if r.Error != "" {
loc := logs.Location{
Path: e.list[index].Path,
File: e.pipeline.yamlPath,
}

logError := logs.ErrorInvalidWhenExpression{
Message: r.Error,
Location: loc,
}

logs.Log(logError)

err = &logError
}
}

return err
}

func (e *whenExtractor) ExtractAutoCancel() {
e.tryExtractingFromPath([]string{"auto_cancel", "queued", "when"})
e.tryExtractingFromPath([]string{"auto_cancel", "running", "when"})
Expand Down
21 changes: 0 additions & 21 deletions pkg/pipelines/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package pipelines

import (
"encoding/json"
"fmt"
"time"

gabs "github.com/Jeffail/gabs/v2"
Expand All @@ -25,30 +24,18 @@ var TotalEval int64
var TotalReduce int64

func (p *Pipeline) EvaluateChangeIns() error {
fmt.Println("Evaluating start.")

start1 := n()

list, err := p.ExtractWhenConditions()
if err != nil {
return err
}

TotalList = n() - start1

start2 := n()

for index := range list {
err := list[index].Eval()
if err != nil {
return err
}
}

TotalEval = n() - start2

start3 := n()

expressions := []string{}
inputs := []whencli.ReduceInputs{}

Expand All @@ -66,14 +53,6 @@ func (p *Pipeline) EvaluateChangeIns() error {
p.raw.Set(expressions[index], list[index].Path...)
}

TotalReduce = n() - start3

fmt.Println("Evaluating end.")

fmt.Printf("Parse When Expressions: %dms\n", TotalList)
fmt.Printf("Evaluated change_in: %dms\n", TotalEval)
fmt.Printf("Reduce When Expressions: %dms\n", TotalReduce)

return nil
}

Expand Down
41 changes: 31 additions & 10 deletions pkg/when/whencli/list_inputs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,46 @@ import (
gabs "github.com/Jeffail/gabs/v2"
)

func ListInputs(expressions []string) ([]*gabs.Container, error) {
type ListInputsResult struct {
Expression string
Inputs *gabs.Container
Error string
}

func ListInputs(expressions []string) ([]ListInputsResult, error) {
var err error
res := []ListInputsResult{}

inputPath := "/tmp/when-expressions"
outputPath := "/tmp/parsed-when-expressions"

err = ListInputsPrepareInputFile(inputPath, expressions)
if err != nil {
return []*gabs.Container{}, nil
return res, nil
}

output, err := exec.Command("when", "list-inputs", "--input", inputPath, "--output", outputPath).CombinedOutput()
if err != nil {
return []*gabs.Container{}, fmt.Errorf("unprecessable when expressions %s", string(output))
return res, fmt.Errorf("unprecessable when expressions %s", string(output))
}

result, err := ListInputsLoadResults(outputPath)
results, err := ListInputsLoadResults(outputPath)
if err != nil {
return result, fmt.Errorf("unprocessable when expressions %s, when CLI output: %s", err.Error(), output)
return res, fmt.Errorf("unprocessable when expressions %s, when CLI output: %s", err.Error(), output)
}

return prepareResults(expressions, results)
}

func prepareResults(expressions []string, results *gabs.Container) ([]ListInputsResult, error) {
result := []ListInputsResult{}

for index, el := range results.Children() {
result = append(result, ListInputsResult{
Expression: expressions[index],
Inputs: el.Search("inputs"),
Error: el.Search("error").Data().(string),
})
}

return result, nil
Expand All @@ -48,22 +69,22 @@ func ListInputsPrepareInputFile(path string, expressions []string) error {
return nil
}

func ListInputsLoadResults(path string) ([]*gabs.Container, error) {
func ListInputsLoadResults(path string) (*gabs.Container, error) {
file, err := os.Open(path)
if err != nil {
return []*gabs.Container{}, err
return nil, err
}
defer file.Close()

content, err := ioutil.ReadAll(file)
if err != nil {
return []*gabs.Container{}, err
return nil, err
}

inputs, err := gabs.ParseJSON(content)
if err != nil {
return []*gabs.Container{}, err
return nil, err
}

return inputs.Children(), nil
return inputs, nil
}
37 changes: 37 additions & 0 deletions pkg/when/whencli/list_inputs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package whencli

import (
"testing"

assert "github.com/stretchr/testify/assert"
)

func Test__ListInputs(t *testing.T) {
expressions := []string{
"branch = 'master'",
"change_in('lib')",
"branch = ",
}

results, err := ListInputs(expressions)

assert.Nil(t, err)
assert.Equal(t, len(expressions), len(results))
assert.Equal(t, []ListInputsResult{
ListInputsResult{
Expression: expressions[0],
Error: "",
Inputs: fromJSON(`[{"name": "branch", "type": "keyword"}]`),
},
ListInputsResult{
Expression: expressions[1],
Error: "",
Inputs: fromJSON(`[{"name": "change_in", "params": ["lib"], "type": "fun"}]`),
},
ListInputsResult{
Expression: expressions[2],
Error: "Invalid or incomplete expression at the end of the line.",
Inputs: fromJSON(`[]`),
},
}, results)
}
12 changes: 11 additions & 1 deletion pkg/when/whencli/reduce.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ func ReduceLoadOutput(path string) ([]string, error) {
return []string{}, err
}

fmt.Println(string(content))

inputs, err := gabs.ParseJSON(content)
if err != nil {
return []string{}, err
Expand All @@ -85,7 +87,15 @@ func ReduceLoadOutput(path string) ([]string, error) {
exprs := []string{}

for index := range inputs.Children() {
exprs = append(exprs, inputs.Children()[index].Data().(string))
el := inputs.Children()[index]
result := el.Search("result").Data().(string)
errString := el.Search("error").Data().(string)

if errString != "" {
return []string{}, fmt.Errorf("unprocessable when expression %s", errString)
}

exprs = append(exprs, result)
}

return exprs, nil
Expand Down
43 changes: 43 additions & 0 deletions pkg/when/whencli/reduce_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package whencli

import (
"testing"

assert "github.com/stretchr/testify/assert"
)

func Test__Reduce(t *testing.T) {
expressions := []string{
"branch = 'master'",
"change_in('lib')",
}

inputs := []ReduceInputs{
ReduceInputs{
Keywords: map[string]interface{}{
"branch": "master",
},
Functions: []interface{}{},
},
ReduceInputs{
Keywords: map[string]interface{}{},
Functions: []interface{}{
fromJSON(`{"name": "change_in", "params": ["lib"], "result": false}`),
},
},
ReduceInputs{
Keywords: map[string]interface{}{},
Functions: []interface{}{},
},
}

results, err := Reduce(expressions, inputs)

assert.Nil(t, err)
assert.Equal(t, len(expressions), len(results))

assert.Equal(t, []string{
"true",
"false",
}, results)
}
12 changes: 12 additions & 0 deletions pkg/when/whencli/test_main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package whencli

import gabs "github.com/Jeffail/gabs/v2"

func fromJSON(s string) *gabs.Container {
res, err := gabs.ParseJSON([]byte(s))
if err != nil {
panic(err)
}

return res
}
Loading

0 comments on commit f9d3ab4

Please sign in to comment.