EVAL JavaScript
Evaluates a short piece of JavaScript and stores the result in one stash variable.
The palette lists it as SET JS EXPR, next to the other variable ops, because that is what it is: an
assignment whose right-hand side happens to be JavaScript.
Use it when a value needs a line or two of JavaScript to compute and you want the target variable visible in the tree. When the block grows past that, move it to Server CODE, which takes the same JavaScript, adds Perl as an option and gives you a real editor to work in. For the Perl equivalent of this op, see SET EXPR.
Fields¶
Variable¶
The stash variable that receives the result. Write the name on its own, with no ${} around it. The
field starts out holding myvar.
Clear the field and the op falls back to the node's name, lowercased, with spaces and punctuation
replaced by _. An op named Next build number then writes to next_build_number, and an op you
never renamed writes to set_js_expr. Rename the op afterwards and the variable name moves with it,
which breaks every later op that read the old name.
An existing variable of that name is overwritten. There is no append; use PUSH VAR for that.
ClaJS Expression¶
The JavaScript, in a syntax-highlighted editor. The value stored is whatever the last expression evaluates to.
The field is not empty when you open it. It arrives holding a worked sample:
// enter js code here
// variables in the stash are available as cla.stash("myvar")
// the last line will be returned into the receiving variable
parseInt(cla.stash("myvar")) + 1;
That text is the field's value, not a placeholder. Apply the form, save the rule, and the sample is
what runs: it reads myvar from the stash, adds one and writes the result back. With no myvar in
the stash the result is NaN, stored without complaint.
Reach the stash through cla.stash, described in cla/stash.
cla.stash('foo') reads, cla.stash('foo', 3) writes straight into the rule's stash, and
cla.stash() returns the whole stash. Nested values take a slash path, cla.stash('/topic/title');
a dotted name such as cla.stash('topic.title') returns nothing. The modules listed in
the Clarive JavaScript DSL are available through require.
Two habits from other JavaScript environments do not carry over here.
A declaration is not an expression, and the fallback in this case is not an empty value. Ending the
field with var total = a + b; stores the string use strict, because that is the last value the
engine produced. End with total; on a line of its own.
A top-level return is a syntax error, because the code is not wrapped in a function. The op fails
with a JavaScript error rather than returning anything.
${...} placeholders are not expanded in this field. Read stash values through cla.stash instead.
What lands in the variable¶
Strings and numbers arrive as you would expect. An array or an object arrives as a real structure
rather than as text, so a list computed here can be tested with HAS and IN in
IF var condition THEN and extended later with
PUSH VAR.
Each run gets a brand new JavaScript engine. Nothing carries over from a previous EVAL JavaScript
op or from a Server CODE block, and every require reloads. Inside a
loop that startup cost is paid on every iteration.
An error in the expression stops the rule. The message names JavaScript as the source and carries a
line number counted from the first line you typed in the field. Trap it with Error Handling on the
op's Options tab, or by wrapping the op in TRY statement and
CATCH statement.
The op writes one entry to the job log, its name, and nothing about the value it computed. To see the result, log it with LOG Message or from inside the expression.
Return Key on the Options tab has no role here. The Variable field is what decides where the
value lands.
Combining with other ops¶
The natural pairing is a condition op reading the variable straight after:
IF var condition THEN with the Numeric option ticked when the
value came out of arithmetic, because text ordering puts 9 after 10.
Inside WHILE condition, this op is the usual way to move the loop counter. A loop whose body never updates the variable it tests never ends.
For a value that does not need JavaScript at all, SET VAR takes a literal
or a ${...} template and reads better in the tree.
Examples¶
Advance a counter that a loop tests. The || 0 matters on the first pass, when the variable does not
exist yet.
Variable: attempt
ClaJS Expression:
(parseInt(cla.stash('attempt')) || 0) + 1;
Pick one value out of a structure another op put in the stash, with a fallback.
Variable: owner_email
ClaJS Expression:
var topic = cla.stash('topic') || {};
var owners = topic.owners || [];
owners.length ? owners[0].email : 'release-team';
Normalise a name before it is used to build a path.
Variable: safe_project
ClaJS Expression:
String(cla.stash('project') || '')
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-');