Skip to content

Commit

Permalink
wip: Evalbool
Browse files Browse the repository at this point in the history
  • Loading branch information
ZauberNerd committed Dec 10, 2021
1 parent 5bec910 commit 3aea593
Showing 1 changed file with 6 additions and 40 deletions.
46 changes: 6 additions & 40 deletions pkg/runner/expression.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package runner

import (
"errors"
"fmt"
"reflect"
"regexp"
"strings"

"github.com/nektos/act/pkg/exprparser"
Expand Down Expand Up @@ -247,45 +245,13 @@ func (ee expressionEvaluator) toString(in interface{}) string {

// EvalBool evaluates an expression against given evaluator
func EvalBool(evaluator ExpressionEvaluator, expr string) (bool, error) {
if splitPattern == nil {
splitPattern = regexp.MustCompile(fmt.Sprintf(`%s|%s|\S+`, expressionPattern.String(), operatorPattern.String()))
}
if strings.HasPrefix(strings.TrimSpace(expr), "!") {
return false, errors.New("expressions starting with ! must be wrapped in ${{ }}")
expr = strings.Replace(expr, "${{", "", -1)
evaluated, _, err := evaluator.Evaluate(expr)
if err != nil {
return false, err
}
if expr != "" {
parts := splitPattern.FindAllString(expr, -1)
var evaluatedParts []string
for i, part := range parts {
if operatorPattern.MatchString(part) {
evaluatedParts = append(evaluatedParts, part)
continue
}

interpolatedPart, isString := evaluator.InterpolateWithStringCheck(part)

// This peculiar transformation has to be done because the GitHub parser
// treats false returned from contexts as a string, not a boolean.
// Hence env.SOMETHING will be evaluated to true in an if: expression
// regardless if SOMETHING is set to false, true or any other string.
// It also handles some other weirdness that I found by trial and error.
if (expressionPattern.MatchString(part) && // it is an expression
!strings.Contains(part, "!")) && // but it's not negated
interpolatedPart == "false" && // and the interpolated string is false
(isString || previousOrNextPartIsAnOperator(i, parts)) { // and it's of type string or has an logical operator before or after
interpolatedPart = fmt.Sprintf("'%s'", interpolatedPart) // then we have to quote the false expression
}

evaluatedParts = append(evaluatedParts, interpolatedPart)
}
log.Debugf("expression '%s' evaluated to '%s'", expr, evaluated)

joined := strings.Join(evaluatedParts, " ")
v, _, err := evaluator.Evaluate(fmt.Sprintf("Boolean(%s)", joined))
if err != nil {
return false, err
}
log.Debugf("expression '%s' evaluated to '%s'", expr, v)
return v == "true", nil
}
return true, nil
return evaluated == "true", nil
}

0 comments on commit 3aea593

Please sign in to comment.