2.3. Expressions#
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.
Important
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 best practices.
#!/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
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
:
$ cwltool expression.cwl empty.yml
INFO /opt/hostedtoolcache/Python/3.9.13/x64/bin/cwltool 3.1.20220913185150
INFO Resolved 'expression.cwl' to 'file:///home/runner/work/user_guide/user_guide/src/_includes/cwl/expressions/expression.cwl'
INFO [job expression.cwl] /tmp/i0po119l$ echo \
-A \
2 \
-B \
baz \
-C \
10 \
9 \
8 \
7 \
6 \
5 \
4 \
3 \
2 \
1 > /tmp/i0po119l/output.txt
INFO [job expression.cwl] completed success
{
"example_out": {
"location": "file:///home/runner/work/user_guide/user_guide/src/_includes/cwl/expressions/output.txt",
"basename": "output.txt",
"class": "File",
"checksum": "sha1$a739a6ff72d660d32111265e508ed2fc91f01a7c",
"size": 36,
"path": "/home/runner/work/user_guide/user_guide/src/_includes/cwl/expressions/output.txt"
}
}
INFO Final process status is success
$ cat output.txt
Message is: Hello world!
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
-
format
secondaryFiles
From
inputBinding
valueFrom
-
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