JavaScript Expressions
Overview
Teaching: 10 min
Exercises: 0 minQuestions
What do I do when I want to create values dynamically and CWL doesn’t provide a built-in way of doing so?
Objectives
Learn how to insert JavaScript expressions into a CWL description.
If you need to manipulate input parameters, include the requirement
InlineJavascriptRequirement
and then anywhere a parameter reference is
legal you can provide a fragment of Javascript that will be evaluated by
the CWL runner.
Note: JavaScript expressions should only be used when absolutely necessary.
When manipulating file names, extensions, paths etc, consider whether one of the
built in File
properties like basename
, nameroot
, nameext
,
etc, could be used instead.
See the list of recommended practices.
expression.cwl
#!/usr/bin/env cwl-runner
cwlVersion: v1.0
class: CommandLineTool
baseCommand: echo
requirements:
InlineJavascriptRequirement: {}
inputs: []
outputs:
example_out:
type: stdout
stdout: output.txt
arguments:
- prefix: -A
valueFrom: $(1+1)
- prefix: -B
valueFrom: $("/foo/bar/baz".split('/').slice(-1)[0])
- prefix: -C
valueFrom: |
${
var r = [];
for (var i = 10; i >= 1; i--) {
r.push(i);
}
return r;
}
As this tool does not require any inputs
we can run it with an (almost) empty
job file:
empty.yml
{}
empty.yml
contains a description of an empty JSON object. JSON objects
descriptions are contained inside curly brackets {}
, so an empty object is
represented simply by a set of empty brackets.
We can then run expression.cwl
:
$ cwl-runner expression.cwl empty.yml
[job expression.cwl] /home/example$ echo \
-A \
2 \
-B \
baz \
-C \
10 \
9 \
8 \
7 \
6 \
5 \
4 \
3 \
2 \
1 > /home/example/output.txt
[job expression.cwl] completed success
{
"example_out": {
"location": "file:///home/example/output.txt",
"basename": "output.txt",
"class": "File",
"checksum": "sha1$a739a6ff72d660d32111265e508ed2fc91f01a7c",
"size": 36,
"path": "/home/example/output.txt"
}
}
Final process status is success
$ cat output.txt
-A 2 -B baz -C 10 9 8 7 6 5 4 3 2 1
Note that requirements can be provided with the map syntax, as in the example above:
requirements:
InlineJavascriptRequirement: {}
Or as an array, with each entry (in this case, only class: InlineJavascriptRequirement
) marked by a -
.
The same syntax is used to describe the additional command line arguments.
requirements:
- class: InlineJavascriptRequirement
Where are JavaScript expressions allowed?
Just like parameter references, you can use JavaScript Expressions only in certain fields. These are:
- From
CommandLineTool
arguments
valueFrom
stdin
stdout
stderr
- From CommandInputParameter
format
secondaryFiles
- From
inputBinding
valueFrom
- From CommandOutputParamater
format
secondaryFiles
- From CommandOutputBinding
glob
outputEval
- From
Workflow
- From InputParameter and WorkflowOutputParameter
format
secondaryFiles
- From
steps
- From WorkflowStepInput
valueFrom
- From ExpressionTool
expression
- From InputParameter and ExpressionToolOutputParameter
format
secondaryFiles
- From
ResourceRequirement
coresMin
coresMax
ramMin
ramMax
tmpdirMin
tmpdirMax
outdirMin
outdirMax
- From
InitialWorkDirRequirement
listing
- in Dirent
entry
entryname
- From
EnvVarRequirement
- From EnvironmentDef
envValue
Key Points
If
InlineJavascriptRequirement
is specified, you can include JavaScript expressions that will be evaluated by the CWL runner.Expressions are only valid in certain fields.
Expressions should only be used when no built in CWL solution exists.