Skip to content

Commit 047c9ad

Browse files
committed
UserGuide: about nested workflow
1 parent 3b41eda commit 047c9ad

File tree

5 files changed

+181
-3
lines changed

5 files changed

+181
-3
lines changed

site/userguide-v1.0-input.json

+10
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,16 @@
144144
"basename": "tar-job.yml",
145145
"class": "File",
146146
"location": "../v1.0/examples/tar-job.yml"
147+
},
148+
{
149+
"basename": "empty.yml",
150+
"class": "File",
151+
"location": "../v1.0/examples/empty.yml"
152+
},
153+
{
154+
"basename": "nestedworkflows.cwl",
155+
"class": "File",
156+
"location": "../v1.0/examples/nestedworkflows.cwl"
147157
}
148158
]
149159
}

v1.0/UserGuide.yml

+117-2
Original file line numberDiff line numberDiff line change
@@ -666,8 +666,8 @@
666666
667667
*empty.yml*
668668
```
669-
- $include: examples/empty.yml
670-
- |
669+
{}
670+
|
671671
```
672672
673673
We can then run `expression.cwl`:
@@ -877,3 +877,118 @@
877877
connecting the input parameter `src` to the output parameter of `untar`
878878
using `untar/example_out`. The output of this step `classfile` is
879879
connected to the `outputs` section for the Workflow, described above.
880+
881+
- |
882+
## Nested workflows
883+
884+
Workflows are ways to combine multiple tools to perform a larger
885+
operations. We can also think of a workflow as being a tool itself;
886+
a CWL workflow can be used as a step in another CWL workflow, if the
887+
workflow engine supports the `SubworkflowFeatureRequirement`:
888+
889+
890+
```
891+
requirements:
892+
- class: SubworkflowFeatureRequirement
893+
```
894+
895+
Here's an example workflow that uses our `1st-workflow.cwl` as a
896+
nested workflow:
897+
898+
```
899+
- $include: examples/nestedworkflows.cwl
900+
- |
901+
```
902+
903+
A CWL `Workflow` can be used as a `step` just like a
904+
`CommandLineTool`, it's CWL file is included with `run`.
905+
The workflow inputs (`inp` and `ex`)
906+
and outputs (`classout`) then can be mapped to become the
907+
step's input/outputs.
908+
909+
```
910+
compile:
911+
run: 1st-workflow.cwl
912+
in:
913+
inp:
914+
source: create-tar/tar
915+
ex:
916+
default: "Hello.java"
917+
out: [classout]
918+
```
919+
920+
Our `1st-workflow.cwl` was parameterized with workflow inputs,
921+
so when running it we had to provide a job file to denote
922+
the tar file and `*.java` filename. This is generally best-practice,
923+
as it means it can be reused in multiple parent workflows,
924+
or even in multiple steps within the same workflow.
925+
926+
Here we use `default:` to hard-code
927+
`"Hello.java" as the `ex` input,
928+
however our workflow also requires a tar file at `inp`,
929+
which we will prepare in the `create-tar` step.
930+
At this point it is probably a good idea to refactor
931+
`1st-workflow.cwl` to have more specific input/output names,
932+
as those also appear in its usage as a tool.
933+
934+
It is also possible to do a less generic approach and avoid
935+
external dependencies in the job file. So in this workflow we can
936+
generate a hard-coded `Hello.java` file using the
937+
previously mentioned `InitialWorkDirRequirement` requirement, before
938+
adding it to a tar file.
939+
940+
```
941+
create-tar:
942+
requirements:
943+
- class: InitialWorkDirRequirement
944+
listing:
945+
- entryname: Hello.java
946+
entry: |
947+
public class Hello {
948+
public static void main(String[] argv) {
949+
System.out.println("Hello from Java");
950+
}
951+
}
952+
```
953+
954+
In this case our step can assume `Hello.java` rather than be
955+
parameterized, so we can use a simpler `arguments` form
956+
as long as the CWL workflow wngine supports the
957+
`ShellCommandRequirement`:
958+
959+
```
960+
run:
961+
class: CommandLineTool
962+
requirements:
963+
- class: ShellCommandRequirement
964+
arguments:
965+
- shellQuote: false
966+
valueFrom: >
967+
tar cf hello.tar Hello.java
968+
```
969+
970+
Note the use of `shellQuote: false` here, otherwise the shell will try
971+
to execute the quoted binary `"tar cf hello.tar Hello.java"`.
972+
973+
Here the `>` block means that newlines are stripped, so it's possible to write
974+
the single command on multiple lines. Similarly, the `|` we used above will
975+
preserve newlines, combined with `ShellCommandRequirement` this would
976+
allow embedding a shell script.
977+
Shell commands should however be used sparingly in CWL, as it
978+
means you "jump out" of the workflow and no longer get
979+
reusable components, provenance or scalability. For reproducibility
980+
and portability it is recommended to only use shell commands together
981+
with a `DockerRequirement` hint, so that
982+
the commands are executed in a predictable shell environment.
983+
984+
Did you notice that we didn't split out the `tar cf` tool to a separate
985+
file, but rather embedded it within the CWL Workflow file? This is generally
986+
not best practice, as the tool then can't be reused. The reason for doing it
987+
in this case is because the command line is hard-coded with filenames that
988+
only make sense within this workflow.
989+
990+
In this example we had to prepare a tar file outside, but only because
991+
our inner workflow was designed to take that as an input. A better
992+
refactoring of the inner workflow would be to take a list of
993+
Java files to compile, which would simplify its usage as a tool
994+
step in other workflows.

v1.0/examples/arguments.cwl

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ label: Example trivial wrapper for Java 7 compiler
44
baseCommand: javac
55
hints:
66
DockerRequirement:
7-
dockerPull: java:7
7+
dockerPull: java:7-jdk
88
baseCommand: javac
99
arguments: ["-d", $(runtime.outdir)]
1010
inputs:

v1.0/examples/empty.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

v1.0/examples/nestedworkflows.cwl

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
cwlVersion: v1.0
2+
class: Workflow
3+
4+
inputs: []
5+
6+
outputs:
7+
classout:
8+
type: File
9+
outputSource: compile/classout
10+
11+
requirements:
12+
- class: SubworkflowFeatureRequirement
13+
14+
steps:
15+
compile:
16+
run: 1st-workflow.cwl
17+
in:
18+
inp:
19+
source: create-tar/tar
20+
ex:
21+
default: "Hello.java"
22+
out: [classout]
23+
24+
create-tar:
25+
requirements:
26+
- class: InitialWorkDirRequirement
27+
listing:
28+
- entryname: Hello.java
29+
entry: |
30+
public class Hello {
31+
public static void main(String[] argv) {
32+
System.out.println("Hello from Java");
33+
}
34+
}
35+
in: []
36+
out: [tar]
37+
run:
38+
class: CommandLineTool
39+
requirements:
40+
- class: ShellCommandRequirement
41+
arguments:
42+
- shellQuote: false
43+
valueFrom: |
44+
date
45+
tar cf hello.tar Hello.java
46+
date
47+
inputs: []
48+
outputs:
49+
tar:
50+
type: File
51+
outputBinding:
52+
glob: "hello.tar"

0 commit comments

Comments
 (0)