diff --git a/docs/process.md b/docs/process.md index 373ff47d48..44ed080d34 100644 --- a/docs/process.md +++ b/docs/process.md @@ -800,6 +800,45 @@ In general, multiple input channels should be used to process *combinations* of See also: {ref}`channel-types`. +(process-input-default-values)= + +### Inputs with default values + +:::{versionadded} 23.06.0-edge +::: + +Process inputs can be defined with a default value, so that they don't have to be specified when calling the process. Default values are useful for process inputs that aren't always used. For example: + +```groovy +process foo { + input: + val metadata + path ('star/*'), defaultValue: [] + path ('hisat2/*'), defaultValue: [] + path ('salmon/*'), defaultValue: [] + output: + stdout + script: + """ + echo 'metadata: ${metadata}' + [[ -d star ]] && ls star || echo 'skipping star directory' + [[ -d hisat2 ]] && ls hisat2 || echo 'skipping hisat2 directory' + [[ -d salmon ]] && ls salmon || echo 'skipping salmon directory' + """ +} + +workflow { + metadata = Channel.of('foo') + foo(metadata) | view +} +``` + +There are a few important caveats to keep in mind when using default values: + +- Inputs with a default value must be declared after inputs without a default value. + +- If you provide a value for an input, then you must also provide values for all inputs that precede it, even if those inputs have default values. In the example above, if you wanted to provide a value for the `salmon` input, you would have to provide values for the `star` and `hisat2` inputs as well, regardless of whether you use the default values for those inputs. + (process-output)= ## Outputs diff --git a/modules/nextflow/src/main/groovy/nextflow/script/ProcessDef.groovy b/modules/nextflow/src/main/groovy/nextflow/script/ProcessDef.groovy index 7cfc6309cc..a131d8dc9e 100644 --- a/modules/nextflow/src/main/groovy/nextflow/script/ProcessDef.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/script/ProcessDef.groovy @@ -169,17 +169,27 @@ class ProcessDef extends BindableDef implements IterableDef, ChainableDef { // get params final params = ChannelOut.spread(args) + // sanity check - if( params.size() != declaredInputs.size() ) + if( params.size() > declaredInputs.size() ) throw new ScriptRuntimeException(missMatchErrMessage(processName, declaredInputs.size(), params.size())) // set input channels for( int i=0; i