Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -1569,7 +1569,11 @@ class TaskProcessor {
ResourcesBundle getModuleBundle() {
final script = this.getOwnerScript()
final meta = ScriptMeta.get(script)
return meta?.isModule() ? meta.getModuleBundle() : null
// Resolve the resources bundle whenever the owner script has a known path,
// not only when it was loaded as an included module. This allows module
// binaries to be picked up also when a module is launched directly as the
// entry script via `nextflow module run` -- see #7087
return meta?.getScriptPath() ? meta.getModuleBundle() : null
}

@Memoized
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import nextflow.script.BaseScript
import nextflow.script.BodyDef
import nextflow.script.ProcessConfig
import nextflow.script.ProcessConfigV1
import nextflow.script.ScriptMeta
import nextflow.script.ScriptType
import nextflow.script.bundle.ResourcesBundle
import nextflow.script.params.FileInParam
Expand Down Expand Up @@ -100,6 +101,41 @@ class TaskProcessorTest extends Specification {

}

def 'should resolve module bundle when script path is set regardless of isModule' () {
given:
def folder = Files.createTempDirectory('test')
def mod = folder.resolve('mod1'); mod.mkdir()
def bin = mod.resolve('resources/usr/bin'); bin.mkdirs()
def scriptPath = mod.resolve('main.nf'); Files.createFile(scriptPath)
Files.createFile(bin.resolve('echo.sh'))
and:
def script = Mock(BaseScript)
def meta = Mock(ScriptMeta) {
getScriptPath() >> scriptPath
// Simulate the failing case: script is loaded as the entry, not as an included module
isModule() >> false
getModuleBundle() >> ResourcesBundle.scan(mod.resolve('resources'))
}
and:
def session = Mock(Session) { getConfig() >> [:] }
def executor = Mock(Executor) {}
def processor = Spy(TaskProcessor, constructorArgs: [[session:session, executor:executor]])
processor.getOwnerScript() >> script

when:
ResourcesBundle bundle
GroovyMock(ScriptMeta, global: true)
ScriptMeta.get(script) >> meta
bundle = processor.getModuleBundle()

then:
bundle != null
bundle.getBinDirs() == [bin]

cleanup:
folder?.deleteDir()
}

@Unroll
def 'should add module bin paths to task env' () {
given:
Expand Down
Loading