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.

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:

Running 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: