expr

package
v1.26.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package expr evaluates the expressions and {{ }} templates of a workflow.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CallsTemplate

func CallsTemplate(v any) bool

CallsTemplate reports whether a template in v calls template, whose argument is evaluated as templates once it runs, so that what it reads cannot be known before then. v is as Refs takes it.

func Parse

func Parse(input string) error

Parse reports whether input is an expression that parses, without evaluating it, so that a workflow can be checked before it runs.

func Reads

func Reads(input, name string) [][]string

Reads returns the constant keys that input, an expression, reads from the object name, as chains: outputs.auth.token is read as [auth token], and as [auth] too. A key read in a way that cannot be known before it runs, such as name[k], is not returned. An expression that does not parse reads nothing here.

func ReadsNothing

func ReadsNothing(input string) bool

ReadsNothing reports whether input, an expression that parses, reads no variable, so that it evaluates the same whatever it is evaluated against, as true or 1 == 1 does. A function it calls, such as now(), is not a variable.

func Refs

func Refs(v any, name string) (keys []string, dynamic bool)

Refs returns the names that the templates in v read from the object name, as name.key or name['key']. v is a string, or a map or array of them at any depth, as a value under vars is. dynamic is true when a template reads the object in a way whose key cannot be known before it runs, such as name[k] or the object as a whole, so that it may read any key. keys come in the order they are first read, a map's values in the order of its sorted keys.

An expression that does not parse reads nothing here; evaluating it reports the error.

func ReplaceTemplates

func ReplaceTemplates(s, repl string) string

ReplaceTemplates returns s with repl in place of each {{ }} template in it, for what is written around the templates to be read without them.

func TemplateExprs

func TemplateExprs(s string) []string

TemplateExprs returns the expressions of the {{ }} templates in s, in the order they come.

Types

type Clause

type Clause struct {
	// Expr is the condition, as the parser writes it back: res.code == 200.
	Expr string
	// Operands are what the condition compares, with what each evaluated
	// to. A literal, such as the 200 above, is left out, as it says what it
	// is.
	Operands []Operand
}

Clause is one of the conditions an expression joins with &&, as each line of a test usually is.

type Expr

type Expr struct {
	// BeforeTemplate, when it is set, is called with the text template() is
	// about to expand, at any depth. An error it returns stops the
	// evaluation, and is found in the error returned with errors.As.
	BeforeTemplate func(text string) error
	// contains filtered or unexported fields
}

Expr evaluates expressions and templates against an environment such as a step's context.

func (*Expr) Eval

func (e *Expr) Eval(input string, env any) (any, error)

func (*Expr) EvalOrEvalTemplate

func (e *Expr) EvalOrEvalTemplate(input string, env any) (string, error)

func (*Expr) EvalTemplate

func (e *Expr) EvalTemplate(input string, env any) (string, error)

EvalTemplate replaces each {{ }} template in input with the value of its expression. A template that does not compile or fails to run is an error naming the template, and no string is returned: a value with the error written into it would otherwise be sent on, as a URL or a header, as if it were right.

func (*Expr) EvalTemplateMap

func (e *Expr) EvalTemplateMap(input map[string]any, env any) (map[string]any, error)

EvalTemplateMap evaluates every template in the keys and values of input, at any depth, keeping the type of a value that is a single template and evaluating a key as text. The errors of all the keys and values that could not be evaluated are joined, each as a *FieldError naming the value by its keys as written. A key that comes to the same key as another is an error too. The map is returned with the errors, so that a caller can still see what could be evaluated, such as credentials to hide from the errors: it holds nil where a value could not be evaluated, and leaves out a key that could not be, or that came to a key taken.

func (*Expr) EvalTemplateWithTypePreservation

func (e *Expr) EvalTemplateWithTypePreservation(input string, env any) (any, error)

func (*Expr) FalseClause

func (e *Expr) FalseClause(input string, env any) (Clause, bool)

FalseClause returns the first of the conditions input joins with && that is not true against env, so that a test of several conditions that failed can say which one did. An expression that joins none is one condition.

The conditions are evaluated again, each on its own, after the expression was found false as a whole. One that calls a function that returns another value each time, such as random_int, could then be told as true, or with a value it did not have, so nothing is told of an expression that calls one.

It reports false when no condition can be told: input does not parse, calls such a function, or a condition cannot be evaluated on its own.

func (*Expr) Options

func (e *Expr) Options(env any) []ex.Option

Options builds the expr options used to compile every workflow expression.

Two guards that used to live here have been removed because neither did anything. ex.DisableBuiltin had no effect on all / any / one / filter / map / count: expr's parser recognises those as predicate builtins before it looks at the disabled set (parser.go, the `predicates` table), so the calls were dead and the functions have always been reachable. A per-key blocklist that filtered the environment was equally inert, because the filtered copy only ever reached the type checker while ex.Run receives the caller's env, and enforcing it would have broken the documented way of reading credentials into `vars`.

What still bounds an expression is the length check in validateExpression, the evaluation timeout in executeWithTimeout, and the argument limits on the functions registered below.

type FieldError

type FieldError struct {
	Path string
	// EvaluatedPath is Path with the keys that hold templates as they were
	// evaluated, which is what tells a value such as a header named by a
	// template apart. It is empty where it is not known.
	EvaluatedPath string
	Err           error
}

FieldError is an error in the value under a key of a map evaluated by EvalTemplateMap. Path names the value from the top of that map, as in headers.authorization or items[0].name.

func (*FieldError) Error

func (e *FieldError) Error() string

func (*FieldError) Unwrap

func (e *FieldError) Unwrap() error

type Operand

type Operand struct {
	Expr  string
	Value any
}

Operand is a part of a condition and what it evaluated to.

type TemplateError

type TemplateError struct {
	Template string // The template as written, braces included
	Err      error  // Why it could not be evaluated
}

TemplateError is a {{ }} template that could not be evaluated.

func (*TemplateError) Error

func (e *TemplateError) Error() string

func (*TemplateError) Unwrap

func (e *TemplateError) Unwrap() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL