main 98594d0

parser.go RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3package expr
4
5import "math"
6
7// FuncInfo describes a function that expressions may call besides the
8// built-in ones (case, contains, endsWith, format, fromJSON, join,
9// startsWith, toJSON). The parser checks names and argument counts against
10// it; the implementation is supplied at evaluation time in
11// [EvalContext.Funcs].
12type FuncInfo struct {
13	// Name is matched case-insensitively.
14	Name string
15	// MinArgs and MaxArgs bound the number of arguments. A negative MaxArgs
16	// means no upper bound.
17	MinArgs int
18	MaxArgs int
19}
20
21// builtinFuncs are the functions of ExpressionConstants.WellKnownFunctions, keyed
22// by upper-cased name (see foldKey). They take precedence over caller-supplied FuncInfo for
23// validation.
24var builtinFuncs = map[string]FuncInfo{
25	"CASE":       {"case", 3, math.MaxInt},
26	"CONTAINS":   {"contains", 2, 2},
27	"ENDSWITH":   {"endsWith", 2, 2},
28	"FORMAT":     {"format", 1, 255},
29	"FROMJSON":   {"fromJson", 1, 1},
30	"JOIN":       {"join", 1, 2},
31	"STARTSWITH": {"startsWith", 2, 2},
32	"TOJSON":     {"toJson", 1, 1},
33}
34
35// Parse parses the text of one expression (the inside of ${{ }}).
36//
37// contexts lists the context names the expression may reference, such as
38// "github" or "matrix"; funcs lists the extra functions it may call. Names
39// are case-insensitive. A reference to any other context or function is an
40// error, as is a call with a wrong number of arguments.
41//
42// The returned error is an [*Error]. An expression with no tokens, such as
43// "" or "  ", is not an error: the reference returns nothing for it, and Parse
44// returns a nil [Node], which [Evaluate] rejects.
45func Parse(expr string, contexts []string, funcs []FuncInfo) (Node, error) {
46	return parseRunner(expr, contexts, funcs)
47}
48
49// arityError reports whether argCount is wrong for f, and how. name is the
50// upper-cased function name (see foldKey): case also needs an odd number of arguments.
51func arityError(name string, f FuncInfo, argCount int) (ErrorType, bool) {
52	switch {
53	case argCount < f.MinArgs:
54		return ErrorTooFewParameters, true
55	case f.MaxArgs >= 0 && argCount > f.MaxArgs:
56		return ErrorTooManyParameters, true
57	case name == "CASE" && argCount%2 == 0:
58		return ErrorEvenParameters, true
59	}
60	return 0, false
61}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 3

↑↓ moveenter openesc close