Declarations
A declaration reserves a name that can be referenced anywhere in the scope where it is declared. A declaration has a type, a name, and an optional initialization. Each declaration must be unique within its scope, may not collide with a reserved WDL keyword (e.g., workflow, or input), and may not have the same name as a visible struct or enum type.
A task or workflow may declare input parameters within its input section and output parameters within its output section. If a non-optional input declaration does not have an initialization, it is considered a "required" parameter, and its value must be provided by the user before the workflow or task may be run. Declarations may also appear in the body of a task or workflow. All non-input declarations must be initialized.
Example: declarations.wdl
version 1.3
workflow declarations {
input {
# these "unbound" declarations are only allowed in the input section
File? x # optional - defaults to None
Map[String, String] m # required
# this is a "bound" declaration
String y = "abc"
}
Int i = 1 + 2 # Private declarations must be bound
output {
Float pi = i + .14 # output declarations must also be bound
}
}Example input:
{
"declarations.m": {"a": "b"}
}
Example output:
{
"declarations.pi": 3.14
}A declaration may be initialized with an expression, which includes the ability to refer to elements that are outputs of tasks.
Example: task_outputs.wdl
version 1.3
task greet {
input {
String name
}
command <<<
printf "Hello ~{name}"
>>>
output {
String greeting = read_string(stdout())
}
}
task count_lines {
input {
Array[String] array
}
command <<<
wc -l < ~{write_lines(array)}
>>>
output {
Int line_count = read_int(stdout())
}
}
workflow task_outputs {
call greet as x {
name="John"
}
call greet as y {
name="Sarah"
}
Array[String] greetings = [x.greeting, y.greeting]
call count_lines {
array=greetings
}
output {
Int num_greetings = count_lines.line_count
}
}Example input:
{}
Example output:
{
"task_outputs.num_greetings": 2
}In this example, greetings is undefined until both call greet as x and call greet as y have successfully completed, at which point it is assigned the result of evaluating its expression. If either of the two tasks fail, the workflow would also fail and greetings would never be initialized.
It must be possible to organize all of the statements within a scope into a directed acyclic graph (DAG); thus, circular references between declarations are not allowed. The following example would result in an error due to the presence of a circular reference.
Example: circular.wdl
version 1.3
workflow circular {
Int i = j + 1
Int j = i - 2
}Example input:
{}
Example output:
{}
Test config:
{
"fail": true
}