Skip to content

Commit 295f173

Browse files
authored
Enable v2 syntax parser by default (#6643)
1 parent 16d1ff9 commit 295f173

File tree

65 files changed

+2132
-3890
lines changed

Some content is hidden

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

65 files changed

+2132
-3890
lines changed

docs/reference/feature-flags.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Feature flags with the `nextflow.preview` prefix can cause pipelines run with ne
2323
: When `true`, enables the use of modules with binary scripts. See {ref}`module-binaries` for more information.
2424

2525
`nextflow.enable.strict`
26+
: :::{deprecated} 26.04.0
27+
:::
2628
: When `true`, executes the pipeline in "strict" mode, which introduces the following rules:
2729

2830
- When reading a params file, Nextflow will fail if a dynamic param value references an undefined variable

docs/strict-syntax.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ export NXF_SYNTAX_PARSER=v2
1616
```
1717
:::
1818

19+
:::{versionchanged} 26.04.0
20+
The strict syntax is enabled by default. You can disable it by setting the environment variable `NXF_SYNTAX_PARSER=v1`.
21+
:::
22+
1923
## Overview
2024

2125
The strict syntax is a subset of DSL2. While DSL2 allows any Groovy syntax, the strict syntax allows only a subset of Groovy syntax for Nextflow scripts and config files. This new specification enables more specific error reporting, ensures more consistent code, and will allow the Nextflow language to evolve independently of Groovy.

modules/nextflow/src/main/groovy/nextflow/NF.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class NF {
3333
}
3434

3535
static String getSyntaxParserVersion() {
36-
return SysEnv.get('NXF_SYNTAX_PARSER', 'v1')
36+
return SysEnv.get('NXF_SYNTAX_PARSER', 'v2')
3737
}
3838

3939
static boolean isSyntaxParserV2() {

modules/nextflow/src/main/groovy/nextflow/cli/CmdRun.groovy

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,8 +492,9 @@ class CmdRun extends CmdBase implements HubOptions {
492492
}
493493

494494
static void detectStrictFeature(ConfigMap config, Map sysEnv) {
495+
if( NF.isSyntaxParserV2() )
496+
return
495497
final defStrict = sysEnv.get('NXF_ENABLE_STRICT') ?: false
496-
log
497498
final strictMode = config.navigate('nextflow.enable.strict', defStrict)
498499
if( strictMode ) {
499500
log.debug "Enabling nextflow strict mode"
@@ -522,8 +523,10 @@ class CmdRun extends CmdBase implements HubOptions {
522523
}
523524

524525
static String detectDslMode(ConfigMap config, String scriptText, Map sysEnv) {
525-
// -- try determine DSL version from config file
526+
if( NF.isSyntaxParserV2() )
527+
return DSL2
526528

529+
// -- try determine DSL version from config file
527530
final dsl = config.navigate('nextflow.enable.dsl') as String
528531

529532
// -- script can still override the DSL version

modules/nextflow/src/main/groovy/nextflow/config/ConfigBuilder.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class ConfigBuilder {
8585

8686
List<String> warnings = new ArrayList<>(10)
8787

88-
Map<String,Object> declaredParams = [:]
88+
Map<String,Object> declaredParams
8989

9090
ConfigBuilder() {
9191
setHomeDir(Const.APP_HOME_DIR)
@@ -407,6 +407,7 @@ class ConfigBuilder {
407407
checkValidProfile(parser.getDeclaredProfiles())
408408
}
409409

410+
this.declaredParams = parser.getDeclaredParams()
410411
}
411412

412413
// guarantee top scopes
@@ -438,7 +439,6 @@ class ConfigBuilder {
438439
final config = parse0(parser, entry)
439440
if( NF.getSyntaxParserVersion() == 'v1' )
440441
validate(config, entry)
441-
declaredParams.putAll(parser.getDeclaredParams())
442442
result.merge(config)
443443
}
444444

modules/nextflow/src/main/groovy/nextflow/config/parser/v2/ConfigDsl.groovy

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package nextflow.config.parser.v2
1919
import java.nio.file.NoSuchFileException
2020
import java.nio.file.Path
2121

22+
import groovy.transform.CompileDynamic
2223
import groovy.transform.CompileStatic
2324
import groovy.transform.Memoized
2425
import groovy.util.logging.Slf4j
@@ -42,13 +43,15 @@ class ConfigDsl extends Script {
4243

4344
private boolean strict
4445

46+
private boolean stripSecrets
47+
4548
private Path configPath
4649

47-
private Map paramOverrides
50+
private Map cliParams
4851

4952
private List<String> profiles
5053

51-
private Map target = [:]
54+
private Map target = [params: [:]]
5255

5356
private Set<String> declaredProfiles = []
5457

@@ -66,13 +69,21 @@ class ConfigDsl extends Script {
6669
this.strict = value
6770
}
6871

72+
void setStripSecrets(boolean value) {
73+
this.stripSecrets = value
74+
}
75+
6976
void setConfigPath(Path path) {
7077
this.configPath = path
7178
}
7279

73-
void setParams(Map paramOverrides) {
74-
this.paramOverrides = paramOverrides
75-
target.params = paramOverrides
80+
void setParams(Map params) {
81+
this.cliParams = params
82+
(target.params as Map).putAll(params)
83+
}
84+
85+
void setConfigParams(Map params) {
86+
(target.params as Map).putAll(params)
7687
}
7788

7889
void setProfiles(List<String> profiles) {
@@ -120,7 +131,7 @@ class ConfigDsl extends Script {
120131
void assign(List<String> names, Object value) {
121132
if( names.size() == 2 && names.first() == 'params' ) {
122133
declareParam(names.last(), value)
123-
if( paramOverrides.containsKey(names.last()) )
134+
if( cliParams.containsKey(names.last()) )
124135
return
125136
}
126137
navigate(names.init()).put(names.last(), value)
@@ -195,8 +206,10 @@ class ConfigDsl extends Script {
195206
.setIgnoreIncludes(ignoreIncludes)
196207
.setRenderClosureAsString(renderClosureAsString)
197208
.setStrict(strict)
209+
.setStripSecrets(stripSecrets)
198210
.setBinding(binding.getVariables())
199-
.setParams(target.params as Map)
211+
.setParams(cliParams)
212+
.setConfigParams(target.params as Map)
200213
.setProfiles(profiles)
201214
final config = parser.parse(configText, includePath)
202215
declaredProfiles.addAll(parser.getDeclaredProfiles())
@@ -213,6 +226,7 @@ class ConfigDsl extends Script {
213226
* @param includePath
214227
*/
215228
@Memoized
229+
@CompileDynamic // required to support ProviderPath::getText() over NioExtensions::getText()
216230
protected static String readConfigFile(Path includePath) {
217231
try {
218232
return includePath.getText()

modules/nextflow/src/main/groovy/nextflow/config/parser/v2/ConfigParserV2.groovy

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package nextflow.config.parser.v2
1818

1919
import java.nio.file.Path
2020

21+
import groovy.transform.CompileDynamic
2122
import groovy.transform.CompileStatic
2223
import nextflow.config.ConfigParser
2324
import nextflow.exception.ConfigParseException
@@ -36,7 +37,9 @@ class ConfigParserV2 implements ConfigParser {
3637

3738
private Map bindingVars = [:]
3839

39-
private Map paramOverrides = [:]
40+
private Map cliParams = [:]
41+
42+
private Map configParams = [:]
4043

4144
private boolean ignoreIncludes = false
4245

@@ -48,9 +51,9 @@ class ConfigParserV2 implements ConfigParser {
4851

4952
private List<String> appliedProfiles
5053

51-
private Set<String> declaredProfiles
54+
private Set<String> declaredProfiles = []
5255

53-
private Map<String,Object> declaredParams
56+
private Map<String,Object> declaredParams = [:]
5457

5558
private GroovyShell groovyShell
5659

@@ -79,7 +82,7 @@ class ConfigParserV2 implements ConfigParser {
7982
}
8083

8184
@Override
82-
ConfigParser setStripSecrets(boolean value) {
85+
ConfigParserV2 setStripSecrets(boolean value) {
8386
this.stripSecrets = value
8487
return this
8588
}
@@ -91,10 +94,15 @@ class ConfigParserV2 implements ConfigParser {
9194
}
9295

9396
@Override
94-
ConfigParserV2 setParams(Map vars) {
95-
// deep clone the map to prevent side-effect
97+
ConfigParserV2 setParams(Map params) {
98+
// deep clone the map to prevent side effects with nested params
9699
// see https://github.com/nextflow-io/nextflow/issues/1923
97-
this.paramOverrides = Bolts.deepClone(vars)
100+
this.cliParams = Bolts.deepClone(params)
101+
return this
102+
}
103+
104+
ConfigParserV2 setConfigParams(Map params) {
105+
this.configParams = params
98106
return this
99107
}
100108

@@ -127,14 +135,17 @@ class ConfigParserV2 implements ConfigParser {
127135
if( path )
128136
script.setConfigPath(path)
129137
script.setIgnoreIncludes(ignoreIncludes)
130-
script.setParams(paramOverrides)
131-
script.setProfiles(appliedProfiles)
132138
script.setRenderClosureAsString(renderClosureAsString)
139+
script.setStrict(strict)
140+
script.setStripSecrets(stripSecrets)
141+
script.setParams(cliParams)
142+
script.setConfigParams(configParams)
143+
script.setProfiles(appliedProfiles)
133144
script.run()
134145

135146
final target = script.getTarget()
136-
declaredProfiles = script.getDeclaredProfiles()
137-
declaredParams = script.getDeclaredParams()
147+
declaredProfiles.addAll(script.getDeclaredProfiles())
148+
declaredParams.putAll(script.getDeclaredParams())
138149
return Bolts.toConfigObject(target)
139150
}
140151
catch( CompilationFailedException e ) {
@@ -168,8 +179,9 @@ class ConfigParserV2 implements ConfigParser {
168179
}
169180

170181
@Override
182+
@CompileDynamic // required to support ProviderPath::getText() over NioExtensions::getText()
171183
ConfigObject parse(Path path) {
172-
return parse(path.text, path)
184+
return parse(path.getText(), path)
173185
}
174186

175187
private ConfigCompiler compiler

modules/nextflow/src/main/groovy/nextflow/scm/ProviderPath.groovy

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import java.nio.file.LinkOption
2020
import java.nio.file.Path
2121
import java.nio.file.Paths
2222

23+
import groovy.transform.CompileStatic
2324
import groovy.transform.EqualsAndHashCode
2425
import groovy.transform.Memoized
2526
import groovy.transform.PackageScope
@@ -39,6 +40,7 @@ import groovy.util.logging.Slf4j
3940
*/
4041
@EqualsAndHashCode
4142
@Slf4j
43+
@CompileStatic
4244
class ProviderPath implements Path {
4345

4446
@PackageScope
@@ -59,18 +61,27 @@ class ProviderPath implements Path {
5961
this.delegate = path
6062
}
6163

64+
@Override
65+
Path relativize(Path other) {
66+
new ProviderPath(provider, delegate.relativize(other))
67+
}
68+
69+
@Override
6270
Path resolveSibling(Path other) {
6371
new ProviderPath(provider, delegate.resolveSibling(other.toString()))
6472
}
6573

74+
@Override
6675
Path resolveSibling(String other) {
6776
new ProviderPath(provider, delegate.resolveSibling(other))
6877
}
6978

79+
@Override
7080
Path resolve(Path other) {
7181
new ProviderPath(provider, delegate.resolve(other.toString()))
7282
}
7383

84+
@Override
7485
Path resolve(String other) {
7586
new ProviderPath(provider, delegate.resolve(other))
7687
}
@@ -97,10 +108,16 @@ class ProviderPath implements Path {
97108
provider.readText(delegate.toString())
98109
}
99110

111+
@Override
112+
URI toUri() {
113+
URI.create(toUriString())
114+
}
115+
100116
String toUriString() {
101117
provider.getContentUrl(delegate.toString())
102118
}
103119

120+
@Override
104121
String toString() {
105122
final base = provider.getRepositoryUrl()
106123
final file = delegate.toString()
@@ -110,20 +127,23 @@ class ProviderPath implements Path {
110127
/**
111128
* @return the path itself because it's absolute by definition being a remote file
112129
*/
130+
@Override
113131
Path toAbsolutePath() {
114132
return this
115133
}
116134

117135
/**
118136
* @return {@code true} because it's absolute by definition being a remote file
119137
*/
138+
@Override
120139
boolean isAbsolute() {
121140
return true
122141
}
123142

124143
/**
125144
* @return the path itself because it's absolute by definition being a remote file
126145
*/
146+
@Override
127147
Path normalize() {
128148
return this
129149
}

modules/nextflow/src/main/groovy/nextflow/script/BaseScript.groovy

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,12 @@ abstract class BaseScript extends Script implements ExecutionContext {
4040

4141
private Session session
4242

43-
private ProcessFactory processFactory
44-
4543
private ScriptMeta meta
4644

4745
private WorkflowDef entryFlow
4846

4947
private OutputDef publisher
5048

51-
@Lazy InputStream stdin = { System.in }()
52-
5349
BaseScript() {
5450
meta = ScriptMeta.register(this)
5551
}
@@ -90,7 +86,6 @@ abstract class BaseScript extends Script implements ExecutionContext {
9086
private void setup() {
9187
binding.owner = this
9288
session = binding.getSession()
93-
processFactory = session.newProcessFactory(this)
9489

9590
binding.setVariable( 'baseDir', session.baseDir )
9691
binding.setVariable( 'projectDir', session.baseDir )

modules/nextflow/src/main/groovy/nextflow/script/BaseScriptConsts.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ class BaseScriptConsts {
2525

2626
public static Object[] EMPTY_ARGS = [] as Object[]
2727

28-
public static List<String> PRIVATE_NAMES = ['session','processFactory','taskProcessor','meta','entryFlow', 'publisher']
28+
public static List<String> PRIVATE_NAMES = ['session','meta','entryFlow', 'publisher']
2929
}

0 commit comments

Comments
 (0)