JavaScript Expressions

Overview

Teaching: 10 min
Exercises: 0 min
Questions
  • 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:
  - class: 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 must be provided 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.

Where are JavaScript expressions allowed?

Just like parameter references, you can use JavaScript Expressions only in certain fields. These are:

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.