Skip to content
Merged
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
40 changes: 0 additions & 40 deletions modules/nextflow/src/main/groovy/nextflow/Session.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ import nextflow.util.NameGenerator
import nextflow.util.SysHelper
import nextflow.util.ThreadPoolManager
import nextflow.util.Threads
import nextflow.util.VersionNumber
import org.apache.commons.lang3.exception.ExceptionUtils
import sun.misc.Signal
import sun.misc.SignalHandler
Expand Down Expand Up @@ -686,7 +685,6 @@ class Session implements ISession {
throw new IllegalStateException("Not a valid config env object: $config.env")
}

@Memoized
Manifest getManifest() {
if( !config.manifest )
return new Manifest()
Expand Down Expand Up @@ -890,13 +888,6 @@ class Session implements ISession {

ExecutorService getExecService() { execService }

/**
* Check preconditions before run the main script
*/
protected void validate() {
checkVersion()
}

@PackageScope void checkConfig() {
final enabled = config.navigate('nextflow.enable.configProcessNamesValidation', true) as boolean
if( enabled ) {
Expand All @@ -918,36 +909,6 @@ class Session implements ISession {
config.navigate('workflow.failOnIgnore', false) as boolean
}

@PackageScope VersionNumber getCurrentVersion() {
new VersionNumber(BuildInfo.version)
}

@PackageScope void checkVersion() {
def version = manifest.getNextflowVersion()?.trim()
if( !version )
return

// when the version string is prefix with a `!`
// an exception is thrown is the version does not match
boolean important = false
if( version.startsWith('!') ) {
important = true
version = version.substring(1).trim()
}

if( !getCurrentVersion().matches(version) ) {
important ? showVersionError(version) : showVersionWarning(version)
}
}

@PackageScope void showVersionError(String ver) {
throw new AbortOperationException("Nextflow version $BuildInfo.version does not match workflow required version: $ver")
}

@PackageScope void showVersionWarning(String ver) {
log.warn "Nextflow version $BuildInfo.version does not match workflow required version: $ver -- Execution will continue, but things may break!"
}

/**
* Validate the config file
*
Expand Down Expand Up @@ -1090,7 +1051,6 @@ class Session implements ISession {
}

void notifyBeforeWorkflowExecution() {
validate()
}

void notifyAfterWorkflowExecution() {
Expand Down
44 changes: 44 additions & 0 deletions modules/nextflow/src/main/groovy/nextflow/cli/CmdRun.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import nextflow.SysEnv
import nextflow.config.ConfigBuilder
import nextflow.config.ConfigMap
import nextflow.config.ConfigValidator
import nextflow.config.Manifest
import nextflow.exception.AbortOperationException
import nextflow.file.FileHelper
import nextflow.plugin.Plugins
Expand All @@ -49,6 +50,7 @@ import nextflow.secret.SecretsLoader
import nextflow.util.CustomPoolFactory
import nextflow.util.Duration
import nextflow.util.HistoryFile
import nextflow.util.VersionNumber
import org.apache.commons.lang3.StringUtils
import org.fusesource.jansi.AnsiConsole
import org.yaml.snakeyaml.Yaml
Expand Down Expand Up @@ -360,6 +362,9 @@ class CmdRun extends CmdBase implements HubOptions {
ConfigMap config = builder.build()
Map configParams = builder.getConfigParams()

// -- Check Nextflow version
checkVersion(config)

// -- Load plugins (may register secret providers)
Plugins.load(config)

Expand Down Expand Up @@ -677,6 +682,45 @@ class CmdRun extends CmdBase implements HubOptions {
return result
}

/**
* Check the Nextflow version against the version required by
* the pipeline via `manifest.nextflowVersion`.
*
* When the version spec is prefixed with '!', the run will fail
* if the Nextflow version does not match.
*
* @param config
*/
protected void checkVersion(Map config) {
final manifest = new Manifest(config.manifest as Map ?: Collections.emptyMap())
String version = manifest.nextflowVersion?.trim()
if( !version )
return

final important = version.startsWith('!')
if( important )
version = version.substring(1).trim()

if( !getCurrentVersion().matches(version) ) {
if( important )
showVersionError(version)
else
showVersionWarning(version)
}
}

protected VersionNumber getCurrentVersion() {
return new VersionNumber(BuildInfo.version)
}

protected void showVersionError(String ver) {
throw new AbortOperationException("Nextflow version ${BuildInfo.version} does not match version required by pipeline: ${ver}")
}

protected void showVersionWarning(String ver) {
log.warn "Nextflow version ${BuildInfo.version} does not match version required by pipeline: ${ver} -- execution will continue, but things might break!"
}

@Memoized // <-- avoid parse multiple times the same file and params
Map parsedParams(Map configVars) {

Expand Down
45 changes: 1 addition & 44 deletions modules/nextflow/src/test/groovy/nextflow/SessionTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ class SessionTest extends Specification {
when:
def session = new Session([manifest: MAN])
then:
session.manifest.with {
session.getManifest().with {
author == 'pablo'
nextflowVersion == '1.2.3'
name == 'foo'
Expand Down Expand Up @@ -401,49 +401,6 @@ class SessionTest extends Specification {
session.fetchContainers() == 'ngi/rnaseq:1.2'
}


def 'should validate version'() {

given:
def manifest = Mock(Manifest)
def session = Spy(Session)

when:
session.checkVersion()
then:
session.getManifest() >> manifest
1 * session.getCurrentVersion() >> new VersionNumber('1.1')
1 * manifest.getNextflowVersion() >> '>= 1.0'
0 * session.showVersionWarning(_)

when:
session.checkVersion()
then:
session.getManifest() >> manifest
1 * session.getCurrentVersion() >> new VersionNumber('1.1')
1 * manifest.getNextflowVersion() >> '>= 1.2'
1 * session.showVersionWarning('>= 1.2')

when:
session.checkVersion()
then:
session.getManifest() >> manifest
1 * session.getCurrentVersion() >> new VersionNumber('1.1')
1 * manifest.getNextflowVersion() >> '! >= 1.2'
1 * session.showVersionError('>= 1.2')
thrown(AbortOperationException)

when:
session.checkVersion()
then:
session.getManifest() >> manifest
1 * manifest.getNextflowVersion() >> null
0 * session.getCurrentVersion() >> null
0 * session.showVersionWarning(_)
0 * session.showVersionError(_)

}

@Unroll
def 'should get module binaries status'() {
given:
Expand Down
34 changes: 34 additions & 0 deletions modules/nextflow/src/test/groovy/nextflow/cli/CmdRunTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import nextflow.NextflowMeta
import nextflow.SysEnv
import nextflow.config.ConfigMap
import nextflow.exception.AbortOperationException
import nextflow.util.VersionNumber
import spock.lang.Specification
import spock.lang.Unroll

Expand Down Expand Up @@ -438,4 +439,37 @@ class CmdRunTest extends Specification {
true | [:] | [NXF_ENABLE_STRICT: true ] | true

}

def 'should validate Nextflow version against version required by pipeline'() {

given:
def cmd = Spy(new CmdRun())

when:
cmd.checkVersion([manifest: [nextflowVersion: '>= 1.0']])
then:
1 * cmd.getCurrentVersion() >> new VersionNumber('1.1')
0 * cmd.showVersionWarning(_)

when:
cmd.checkVersion([manifest: [nextflowVersion: '>= 1.2']])
then:
1 * cmd.getCurrentVersion() >> new VersionNumber('1.1')
1 * cmd.showVersionWarning('>= 1.2')

when:
cmd.checkVersion([manifest: [nextflowVersion: '! >= 1.2']])
then:
1 * cmd.getCurrentVersion() >> new VersionNumber('1.1')
1 * cmd.showVersionError('>= 1.2')
thrown(AbortOperationException)

when:
cmd.checkVersion([:])
then:
0 * cmd.getCurrentVersion()
0 * cmd.showVersionWarning(_)
0 * cmd.showVersionError(_)
}

}
Loading