Documentation
¶
Overview ¶
Package exprlang evaluates the expression form of a resource type's check/in/out — the JSON-over-HTTP alternative to writing those three as shell commands.
It is a leaf: it knows nothing of pipelines, resources, or the store. Everything context-specific (which env names are allowed, which directory file() may read, the source/version/params in scope) arrives in an Input, so the only thing this package decides is what the language can do.
The language is expr-lang/expr, chosen for what it CANNOT do. It has no statements, no loops, no assignment, and no I/O except through the functions handed to it here — so a resource type written this way cannot run a shell command, cannot outlive its call, and cannot be made to by any amount of cleverness in a pipeline file. Adding a scripting engine with those capabilities would have meant owning a sandbox; this way there is nothing to sandbox.
What the expression form buys over shell, concretely: no dependency on curl/jq being installed, no quoting hazard (values are values, never text spliced into a command), errors that propagate instead of being swallowed by a pipeline's exit status, and HTTP that can be concurrent and rate-limit-aware because steps owns the fan-out (see http.go).
Index ¶
- func CloseIdleConnections()
- func Compile(slot Slot, src string) error
- func RunCheck(ctx context.Context, src string, in Input) ([]map[string]any, error)
- func RunIn(ctx context.Context, src string, in Input) (map[string]string, error)
- func RunOut(ctx context.Context, src string, in Input) (map[string]any, error)
- func Webhook(src string, wantBool bool) (func(env WebhookEnv) (any, error), error)
- type Input
- type Slot
- type WebhookEnv
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CloseIdleConnections ¶
func CloseIdleConnections()
CloseIdleConnections releases the keep-alive connections a run left behind. Called when an evaluation finishes so a test's goroutine leak check sees a quiet package, and so a long watch loop does not hold sockets to an API it polls every few minutes.
func Compile ¶
Compile parses and type-checks one slot's expression without running it, so a syntax error is reported by `steps validate` and by preflight rather than halfway through a watch loop.
It cannot be reported at LOAD time: internal/config depends on nothing internal and imports no third-party code but the YAML parser (enforced by depguard), which is what keeps the config types a leaf everything else can agree on. A syntax error is therefore a validate-time fact, not a parse-time one — see resource.CompileExprPrograms for where that is wired.
func RunCheck ¶
RunCheck evaluates a check expression and returns the versions it produced, oldest first — the same contract, and the same caller responsibility for ordering, as a shell check's stdout.
func RunIn ¶
RunIn evaluates an in expression and returns the files it produced, as a map of artifact-relative path to contents.
Returning a file map rather than handing the language a write() builtin is what keeps an expression pure: no side effects means the result is a function of its inputs, which is the property the resource cache is already built on. The caller writes the files (see resource.exprRunIn), and is also where the path guard lives.
func RunOut ¶
RunOut evaluates an out expression and returns the version it published, or nil when it published nothing versionable — the same tolerance a shell out: gets for printing no JSON.
Types ¶
type Input ¶
type Input struct {
// Source is the resource's source: block. Always in scope.
Source map[string]any
// Version is the version being fetched (in), or the check cursor — the
// last version this pipeline recorded (check). Never in scope for out,
// which produces a version rather than consuming one.
Version map[string]any
// Params are the get's or put's params:. In scope for in and out.
Params map[string]any
// EnvAllow is the resource type's env: list, and the complete set of
// names env() will resolve. See envFunc for why there is no baseline.
EnvAllow []string
// Dir is the put's read view, the only directory file() may read from.
// Out slot only.
Dir string
// Inputs are the put's input names, sorted: the complete set version()
// will answer for. Out slot only.
Inputs []string
// Versions are what this build's gets fetched, by get name, restricted
// to Inputs. Out slot only.
Versions map[string]map[string]any
}
Input is everything an expression evaluates against.
type Slot ¶
type Slot string
Slot names one of the three lifecycle stages an expression can implement. The stages differ in what they see and what they may do, so the slot is a parameter to everything here rather than a caller convention.
type WebhookEnv ¶
type WebhookEnv struct {
Provider string `expr:"provider"`
Event string `expr:"event"`
Method string `expr:"method"`
Headers map[string]string `expr:"headers"`
Query map[string]string `expr:"query"`
Body string `expr:"body"`
Payload any `expr:"payload"`
}
WebhookEnv is what a webhook expression reads. A struct rather than a map so payload is typed any: a JSON body can be an object, an array, or absent.