Skip to content

Workflow params #5929

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions docs/reference/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ A Nextflow script may contain the following top-level declarations:
- Shebang
- Feature flags
- Include declarations
- Parameter declarations
- Params block
- Parameter declarations (legacy)
- Workflow definitions
- Process definitions
- Function definitions
Expand Down Expand Up @@ -107,9 +108,22 @@ The following definitions can be included:
- Processes
- Named workflows

### Parameter
### Params block

A parameter declaration is an assignment. The target should be a pipeline parameter and the source should be an expression:
The params block consists of one or more *parameter declarations*. A parameter declaration consists of a name and an optional default value:

```nextflow
params {
input: Path
save_intermeds: Boolean = false
}
```

Only one params block may be defined in a script.

### Parameter (legacy)

A legacy parameter declaration is an assignment. The target should be a pipeline parameter and the source should be an expression:

```nextflow
params.message = 'Hello world!'
Expand Down
2 changes: 1 addition & 1 deletion docs/vscode.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The language server parses scripts and config files according to the {ref}`Nextf

When you hover over certain source code elements, such as variable names and function calls, the extension provides a tooltip with related information, such as the definition and/or documentation for the element.

If a [Javadoc](https://en.wikipedia.org/wiki/Javadoc) comment is defined above a workflow, process, or function, the extension will include the contents of the comment in hover hints. The following is an example Javadoc comment:
If a [Javadoc](https://en.wikipedia.org/wiki/Javadoc) comment is defined above a workflow, process, function, or parameter in a `params` block, the extension will include the contents of the comment in hover hints. The following is an example Javadoc comment:

```nextflow
/**
Expand Down
60 changes: 56 additions & 4 deletions docs/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,46 @@ workflow {
}
```

### Parameters
## Parameters

Parameters can be declared by assigning a `params` property to a default value:
Parameters can be declared in a Nextflow script with the `params` block or with *legacy* parameter declarations.

### Params block

:::{versionadded} 25.10.0
:::

:::{note}
This feature requires the {ref}`strict syntax <strict-syntax-page>` to be enabled (`NXF_SYNTAX_PARSER=v2`).
:::

A script can declare parameters using the `params` block:

```nextflow
params.input = '/some/data/file'
params.save_intermeds = false
params {
/**
* Path to input data.
*/
input: Path

/**
* Whether to save intermediate files.
*/
save_intermeds: Boolean = false
}
```

The following types can be used for parameters:

- Boolean
- Integer
- Number
- {ref}`stdlib-types-path`
- {ref}`stdlib-types-string`

Parameters can be used in the entry workflow:

```nextflow
workflow {
if( params.input )
analyze(params.input, params.save_intermeds)
Expand All @@ -44,6 +76,26 @@ As a best practice, params should be used only in the entry workflow and passed

The default value can be overridden by the command line, params file, or config file. Parameters from multiple sources are resolved in the order described in {ref}`cli-params`.

A parameter that doesn't specify a default value is a *required* param. If a required param is not given a value at runtime, the run will fail.

### Legacy parameters

Parameters can be declared by assigning a `params` property to a default value:

```nextflow
params.input = '/some/data/file'
params.save_intermeds = false

workflow {
if( params.input )
analyze(params.input, params.save_intermeds)
else
analyze(fake_input(), params.save_intermeds)
}
```

The default value can be overridden by the command line, params file, or config file. Parameters from multiple sources are resolved in the order described in {ref}`cli-params`.

## Named workflows

A *named workflow* is a workflow that can be called by other workflows:
Expand Down
14 changes: 13 additions & 1 deletion modules/nextflow/src/main/groovy/nextflow/Session.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ class Session implements ISession {
*/
ScriptBinding binding

/**
* Params that were specified on the command line.
*/
Map cliParams

/**
* Params that were specified in the configuration.
*/
Map configParams

/**
* Holds the configuration object
*/
Expand Down Expand Up @@ -418,7 +428,7 @@ class Session implements ISession {
/**
* Initialize the session workDir, libDir, baseDir and scriptName variables
*/
Session init( ScriptFile scriptFile, List<String> args=null ) {
Session init( ScriptFile scriptFile, List<String> args=null, Map<String,?> cliParams=null, Map<String,?> configParams=null ) {

if(!workDir.mkdirs()) throw new AbortOperationException("Cannot create work-dir: $workDir -- Make sure you have write permissions or specify a different directory by using the `-w` command line option")
log.debug "Work-dir: ${workDir.toUriString()} [${FileHelper.getPathFsType(workDir)}]"
Expand All @@ -445,6 +455,8 @@ class Session implements ISession {
this.workflowMetadata = new WorkflowMetadata(this, scriptFile)

// configure script params
this.cliParams = cliParams
this.configParams = configParams
binding.setParams( (Map)config.params )
binding.setArgs( new ScriptRunner.ArgsList(args) )

Expand Down
14 changes: 10 additions & 4 deletions modules/nextflow/src/main/groovy/nextflow/cli/CmdRun.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,18 @@ class CmdRun extends CmdBase implements HubOptions {
// -- specify the arguments
final scriptFile = getScriptFile(pipeline)

// -- load command line params
final baseDir = scriptFile.parent
final cliParams = parsedParams(ConfigBuilder.getConfigVars(baseDir))

// create the config object
final builder = new ConfigBuilder()
.setOptions(launcher.options)
.setCmdRun(this)
.setBaseDir(scriptFile.parent)
final config = builder .build()
.setBaseDir(baseDir)
.setCliParams(cliParams)
final config = builder.build()
final configParams = builder.getConfigParams()

// check DSL syntax in the config
launchInfo(config, scriptFile)
Expand Down Expand Up @@ -376,7 +382,7 @@ class CmdRun extends CmdBase implements HubOptions {
}

// -- run it!
runner.execute(scriptArgs, this.entryName)
runner.execute(scriptArgs, cliParams, configParams, this.entryName)
}

protected void printBanner() {
Expand Down Expand Up @@ -698,7 +704,7 @@ class CmdRun extends CmdBase implements HubOptions {
}

static protected parseParamValue(String str) {
if ( SysEnv.get('NXF_DISABLE_PARAMS_TYPE_DETECTION') )
if ( SysEnv.get('NXF_DISABLE_PARAMS_TYPE_DETECTION','true') != 'false' )
return str

if ( str == null ) return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class ConfigBuilder {

Path currentDir

Map<String,?> cliParams

boolean showAllProfiles

String profile = DEFAULT_PROFILE
Expand All @@ -81,9 +83,11 @@ class ConfigBuilder {

Map<String,String> env = new HashMap<>(System.getenv())

List<String> warnings = new ArrayList<>(10);
List<String> warnings = new ArrayList<>(10)

Map<String,Object> declaredParams = [:]

{
ConfigBuilder() {
setHomeDir(Const.APP_HOME_DIR)
setCurrentDir(Paths.get('.'))
}
Expand Down Expand Up @@ -114,6 +118,11 @@ class ConfigBuilder {
return this
}

ConfigBuilder setCliParams( Map<String,?> cliParams ) {
this.cliParams = cliParams
return this
}

ConfigBuilder setBaseDir( Path path ) {
this.baseDir = path.complete()
return this
Expand Down Expand Up @@ -162,6 +171,10 @@ class ConfigBuilder {
return this
}

Map<String,Object> getConfigParams() {
return declaredParams
}

static private wrapValue( value ) {
if( !value )
return ''
Expand Down Expand Up @@ -327,11 +340,11 @@ class ConfigBuilder {
// this is needed to make sure to reuse the same
// instance of the config vars across different instances of the ConfigBuilder
// and prevent multiple parsing of the same params file (which can even be remote resource)
return cacheableConfigVars(baseDir)
return getConfigVars(baseDir)
}

@Memoized
static private Map cacheableConfigVars(Path base) {
static Map getConfigVars(Path base) {
final binding = new HashMap(10)
binding.put('baseDir', base)
binding.put('projectDir', base)
Expand All @@ -351,8 +364,8 @@ class ConfigBuilder {
.setIgnoreIncludes(ignoreIncludes)
ConfigObject result = new ConfigObject()

if( cmdRun && (cmdRun.hasParams()) )
parser.setParams(cmdRun.parsedParams(configVars()))
if( cliParams )
parser.setParams(cliParams)

// add the user specified environment to the session env
env.sort().each { name, value -> result.env.put(name,value) }
Expand Down Expand Up @@ -383,7 +396,7 @@ class ConfigBuilder {
}

if( validateProfile ) {
checkValidProfile(parser.getProfiles())
checkValidProfile(parser.getDeclaredProfiles())
}

}
Expand Down Expand Up @@ -417,6 +430,7 @@ class ConfigBuilder {
final config = parse0(parser, entry)
if( NF.getSyntaxParserVersion() == 'v1' )
validate(config, entry)
declaredParams.putAll(parser.getDeclaredParams())
result.merge(config)
}

Expand Down Expand Up @@ -734,8 +748,8 @@ class ConfigBuilder {
}

// -- add the command line parameters to the 'taskConfig' object
if( cmdRun.hasParams() )
config.params = mergeMaps( (Map)config.params, cmdRun.parsedParams(configVars()), NF.strictMode )
if( cliParams )
config.params = mergeMaps( (Map)config.params, cliParams, NF.strictMode )

if( cmdRun.withoutDocker && config.docker instanceof Map ) {
// disable docker execution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ interface ConfigParser {
*/
ConfigParser setParams(Map vars)

/**
* Set the profiles that should be applied.
*/
ConfigParser setProfiles(List<String> profiles)

/**
* Parse a config object from the given source.
*/
Expand All @@ -75,13 +80,13 @@ interface ConfigParser {
ConfigObject parse(Path path)

/**
* Set the profiles that should be applied.
* Get the set of declared profiles.
*/
ConfigParser setProfiles(List<String> profiles)
Set<String> getDeclaredProfiles()

/**
* Get the set of available profiles.
* Get the map of declared params.
*/
Set<String> getProfiles()
Map<String,Object> getDeclaredParams()

}
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,15 @@ class ConfigParserV1 implements ConfigParser {
}

@Override
Set<String> getProfiles() {
Set<String> getDeclaredProfiles() {
Collections.unmodifiableSet(conditionalNames)
}

@Override
Map<String,Object> getDeclaredParams() {
[:]
}

private Grengine getGrengine() {
if( grengine ) {
return grengine
Expand Down
Loading
Loading