Skip to content

Commit 814d40c

Browse files
committed
Typed processes
Signed-off-by: Ben Sherman <[email protected]>
1 parent a830125 commit 814d40c

File tree

94 files changed

+7526
-3281
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+7526
-3281
lines changed

docs/migrations/25-10.md

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ The `params` block is a new way to declare pipeline parameters in a Nextflow scr
1616

1717
```nextflow
1818
params {
19-
// Path to input data.
20-
input: Path
19+
// Path to input data.
20+
input: Path
2121
22-
// Whether to save intermediate files.
23-
save_intermeds: Boolean = false
22+
// Whether to save intermediate files.
23+
save_intermeds: Boolean = false
2424
}
2525
2626
workflow {
27-
println "params.input = ${params.input}"
28-
println "params.save_intermeds = ${params.save_intermeds}"
27+
println "params.input = ${params.input}"
28+
println "params.save_intermeds = ${params.save_intermeds}"
2929
}
3030
```
3131

@@ -39,33 +39,73 @@ Type annotations are a way to denote the *type* of a variable. They help documen
3939

4040
```nextflow
4141
workflow RNASEQ {
42-
take:
43-
reads: Channel<Path>
44-
index: Value<Path>
42+
take:
43+
reads: Channel<Path>
44+
index: Value<Path>
4545
46-
main:
47-
samples_ch = QUANT( reads, index )
46+
main:
47+
samples_ch = QUANT( reads, index )
4848
49-
emit:
50-
samples: Channel<Path> = samples_ch
49+
emit:
50+
samples: Channel<Path> = samples_ch
5151
}
5252
5353
def isSraId(id: String) -> Boolean {
54-
return id.startsWith('SRA')
54+
return id.startsWith('SRA')
55+
}
56+
57+
// feature flag required for typed processes
58+
nextflow.preview.types = true
59+
60+
process fastqc {
61+
input:
62+
(id, fastq_1, fastq_2): Tuple<String,Path,Path>
63+
64+
output:
65+
logs = tuple(id, file('fastqc_logs'))
66+
67+
script:
68+
"""
69+
mkdir fastqc_logs
70+
fastqc -o fastqc_logs -f fastq -q ${fastq_1} ${fastq_2}
71+
"""
5572
}
5673
```
5774

5875
The following declarations can be annotated with types:
5976

6077
- Pipeline parameters (the `params` block)
6178
- Workflow takes and emits
79+
- Process inputs and outputs
6280
- Function parameters and returns
6381
- Local variables
6482
- Closure parameters
6583
- Workflow outputs (the `output` block)
6684

6785
Type annotations can refer to any of the {ref}`standard types <stdlib-types>`.
6886

87+
Some types have *generic type parameters*, which allow them to be reused in a type-safe manner with different types of data. For example:
88+
89+
- The generic type `E` in `List<E>` and `Channel<E>` refers to the type of the elements in the list or channel
90+
91+
- The generic types `K` and `V` in `Map<K,V>` refer to the types of keys and values in the map
92+
93+
Here are some concrete examples of types that use type parameters:
94+
95+
```nextflow
96+
// List<E> where E is String
97+
def sequences: List<String> = ['ATCG', 'GCTA', 'TTAG']
98+
99+
// List<E> where E is Path
100+
def fastqs: List<Path> = [file('sample1.fastq'), file('sample2.fastq')]
101+
102+
// Map<K,V> where K is String and V is Integer
103+
def readCounts: Map<String,Integer> = [sample1: 1000, sample2: 1500]
104+
105+
// Channel<E> where E is Path
106+
def ch_bams: Channel<Path> = channel.fromPath('*.bam')
107+
```
108+
69109
Type annotations can be appended with `?` to denote that the value can be `null`:
70110

71111
```nextflow
@@ -78,6 +118,8 @@ In the type system, queue channels are represented as `Channel`, while value cha
78118
Nextflow supports Groovy-style type annotations using the `<type> <name>` syntax, but this approach is deprecated in {ref}`strict syntax <strict-syntax-page>`. While Groovy-style annotations remain valid for functions and local variables, the language server and `nextflow lint` automatically convert them to Nextflow-style annotations during code formatting.
79119
:::
80120

121+
See {ref}`migrating-static-types` for details.
122+
81123
## Enhancements
82124

83125
<h3>Nextflow plugin registry</h3>
@@ -113,7 +155,7 @@ workflow {
113155

114156
This syntax is simpler and easier to use with the {ref}`strict syntax <strict-syntax-page>`. See {ref}`workflow-handlers` for details.
115157

116-
<h3>Improved handling of dynamic directives</h3>
158+
<h3>Simpler syntax for dynamic directives</h3>
117159

118160
The {ref}`strict syntax <strict-syntax-page>` allows dynamic process directives to be specified without a closure:
119161

@@ -131,6 +173,8 @@ process hello {
131173
}
132174
```
133175

176+
Dynamic process settings in configuration files must still be specified with closures.
177+
134178
See {ref}`dynamic-directives` for details.
135179

136180
<h3>Configurable date formatting</h3>

docs/process-typed.md

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
(process-typed-page)=
2+
3+
# Processes (typed)
4+
5+
:::{versionadded} 25.10.0
6+
:::
7+
8+
:::{note}
9+
This feature requires the {ref}`strict syntax <strict-syntax-page>` to be enabled (`NXF_SYNTAX_PARSER=v2`).
10+
:::
11+
12+
:::{note}
13+
Typed processes require the `nextflow.preview.types` feature flag to be enabled in every script that uses them.
14+
:::
15+
16+
Typed processes use a new syntax for inputs and outputs that is based on static types:
17+
18+
```nextflow
19+
process hello {
20+
input:
21+
message: String
22+
23+
output:
24+
file('hello.txt')
25+
26+
script:
27+
"""
28+
echo '${message}' > hello.txt
29+
"""
30+
}
31+
```
32+
33+
See {ref}`syntax-process-typed` for a full description of the process syntax. See {ref}`migrating-static-types` for more information on migrating existing code to static types.
34+
35+
## Inputs
36+
37+
The `input:` section is used to declare the inputs of a process. An input declaration in a typed process consists of a name and a type:
38+
39+
```nextflow
40+
process fastqc {
41+
input:
42+
(meta, fastq): Tuple<Map,Path>
43+
extra_args: String
44+
45+
script:
46+
"""
47+
echo 'meta: ${meta}`
48+
echo 'fastq: ${fastq}'
49+
echo 'extra_args: ${extra_args}'
50+
"""
51+
}
52+
```
53+
54+
Any of the {ref}`standard types <stdlib-types>` can be used as type annotations, except for the dataflow types (`Channel` and `Value`) which can only be used in workflows.
55+
56+
### File inputs
57+
58+
Inputs of type `Path` or a collection of `Path` (e.g. `Set<Path>`) are automatically staged into the task directory.
59+
60+
By default, the task will fail if any input receives a `null` value. You can mark an input as nullable by appending `?` to the type annotation:
61+
62+
```nextflow
63+
process cat_opt {
64+
input:
65+
input: Path?
66+
67+
stage:
68+
stageAs 'input.txt', input
69+
70+
output:
71+
stdout()
72+
73+
script:
74+
'''
75+
[[ -f input.txt ]] && cat input.txt || echo 'empty input'
76+
'''
77+
}
78+
```
79+
80+
### Stage directives
81+
82+
The `stage:` section can be specified after the `input:` section. You can use it to specify custom staging behavior using *stage directives*. These directives serve the same purpose as input qualifiers such as `env` and `stdin` in the legacy syntax.
83+
84+
The `env` directive declares an environment variable in terms of task inputs:
85+
86+
```nextflow
87+
process echo_env {
88+
input:
89+
hello: String
90+
91+
stage:
92+
env 'HELLO', hello
93+
94+
script:
95+
'''
96+
echo "$HELLO world!"
97+
'''
98+
}
99+
```
100+
101+
The `stdin` directive defines the standard input of the task script:
102+
103+
```nextflow
104+
process cat {
105+
input:
106+
message: String
107+
108+
stage:
109+
stdin message
110+
111+
script:
112+
"""
113+
cat -
114+
"""
115+
}
116+
```
117+
118+
The `stageAs` directive stages an input file (or files) under a custom file pattern:
119+
120+
```nextflow
121+
process blast {
122+
input:
123+
fasta: Path
124+
125+
stage:
126+
stageAs 'query.fa', fasta
127+
128+
script:
129+
"""
130+
blastp -query query.fa -db nr
131+
"""
132+
}
133+
```
134+
135+
The file pattern can also reference task inputs:
136+
137+
```nextflow
138+
process grep {
139+
input:
140+
id: String
141+
fasta: Path
142+
143+
stage:
144+
stageAs "${id}.fa", fasta
145+
146+
script:
147+
"""
148+
cat ${id}.fa | grep '>'
149+
"""
150+
}
151+
```
152+
153+
See {ref}`process-reference-typed` for the set of available stage directives.
154+
155+
## Outputs
156+
157+
The `output:` section is used to declare the outputs of a typed process. An output declaration in a typed process consists of a name, an optional type, and an output value:
158+
159+
```nextflow
160+
process echo {
161+
input:
162+
message: String
163+
164+
output:
165+
out_env: String = env('MESSAGE')
166+
out_file: Path = file('message.txt')
167+
out_std: String = stdout()
168+
169+
script:
170+
"""
171+
export MESSAGE='${message}'
172+
173+
echo \$MESSAGE > message.txt
174+
175+
cat message.txt
176+
"""
177+
}
178+
```
179+
180+
When there is only one output, the name can be omitted:
181+
182+
```nextflow
183+
process echo {
184+
input:
185+
message: String
186+
187+
output:
188+
stdout()
189+
190+
script:
191+
"""
192+
echo '${message}'
193+
"""
194+
}
195+
```
196+
197+
See {ref}`process-reference-typed` for the set of available output functions.
198+
199+
### File outputs
200+
201+
You can use the `file()` and `files()` functions in the `output:` section to get a single file or collection of files from the task directory.
202+
203+
By default, the `file()` function will fail if the specified file is not present in the task directory. You can specify `optional: true` to allow the file to be missing, in which case the `file()` function will return `null`. For example:
204+
205+
```nextflow
206+
process foo {
207+
output:
208+
file('output.txt', optional: true)
209+
210+
script:
211+
"""
212+
exit 0
213+
"""
214+
}
215+
```
216+
217+
## Topics
218+
219+
The `topic:` section is used to emit values to a {ref}`topic channel <channel-topic>`. A topic emission consists of an output value and a topic name:
220+
221+
```nextflow
222+
process cat {
223+
input:
224+
message: Path
225+
226+
output:
227+
stdout()
228+
229+
topic:
230+
tuple('bash', eval('bash --version')) >> 'versions'
231+
tuple('cat', eval('cat --version')) >> 'versions'
232+
233+
script:
234+
"""
235+
cat ${message}
236+
"""
237+
}
238+
```
239+
240+
Topic emissions can use the same {ref}`output functions <process-reference-typed>` that are available in the `output:` section.
241+
242+
## Script
243+
244+
The `script:` and `exec:` sections behave the same way as {ref}`legacy processes <process-script>`.
245+
246+
## Stub
247+
248+
The `stub:` section behaves the same way as {ref}`legacy processes <process-stub>`.
249+
250+
## Directives
251+
252+
Directives behave the same way as {ref}`legacy processes <process-directives>`.

docs/reference/feature-flags.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,9 @@ Feature flags are used to introduce experimental or other opt-in features. They
6060
This feature flag is no longer required to use topic channels.
6161
:::
6262
: When `true`, enables {ref}`topic channels <channel-topic>` feature.
63+
64+
`nextflow.preview.types`
65+
: :::{versionadded} 25.10.0
66+
:::
67+
: When `true`, enables the use of {ref}`typed processes <process-typed-page>`.
68+
: This feature flag must be enabled in every script that uses typed processes. Legacy processes can not be defined in scripts that enable this feature flag.

0 commit comments

Comments
 (0)