diff --git a/modules/nextflow/src/main/groovy/nextflow/container/ContainerHandler.groovy b/modules/nextflow/src/main/groovy/nextflow/container/ContainerHandler.groovy index 676938fe6e..4ff70f5d72 100644 --- a/modules/nextflow/src/main/groovy/nextflow/container/ContainerHandler.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/container/ContainerHandler.groovy @@ -18,6 +18,7 @@ package nextflow.container import java.nio.file.Path import java.nio.file.Paths +import java.util.regex.Pattern import groovy.transform.PackageScope import nextflow.util.Escape @@ -62,8 +63,7 @@ class ContainerHandler { final normalizedImageName = normalizeSingularityImageName(imageName) if( !config.isEnabled() || !normalizedImageName ) return normalizedImageName - final formats = ['docker', 'docker-daemon', 'shub', 'library'] - final requiresCaching = formats.any { normalizedImageName.startsWith(it) } + final requiresCaching = normalizedImageName =~ IMAGE_URL_PREFIX final result = requiresCaching ? createCache(this.config, normalizedImageName) : normalizedImageName Escape.path(result) } @@ -157,6 +157,9 @@ class ContainerHandler { return imageName } + + public static final Pattern IMAGE_URL_PREFIX = ~/^[^\/:\. ]+:\/\/(.*)/ + /** * Normalize Singularity image name resolving the absolute path or * adding `docker://` prefix when required @@ -179,7 +182,7 @@ class ContainerHandler { } // check if matches a protocol scheme such as `docker://xxx` - if( img =~ '^[^/:\\. ]+://(.*)' ) { + if( img =~ IMAGE_URL_PREFIX ) { return img } diff --git a/modules/nextflow/src/test/groovy/nextflow/container/ContainerHandlerTest.groovy b/modules/nextflow/src/test/groovy/nextflow/container/ContainerHandlerTest.groovy index 5be51bc675..8e929d13d5 100644 --- a/modules/nextflow/src/test/groovy/nextflow/container/ContainerHandlerTest.groovy +++ b/modules/nextflow/src/test/groovy/nextflow/container/ContainerHandlerTest.groovy @@ -108,6 +108,8 @@ class ContainerHandlerTest extends Specification { 'foo.img' | 'docker://foo.img' 'quay.io/busybox' | 'docker://quay.io/busybox' 'library://library/default/debian:7' | 'library://library/default/debian:7' + 'http://reg.io/v1/alpine:latest' | 'http://reg.io/v1/alpine:latest' + 'https://reg.io/v1/alpine:latest' | 'https://reg.io/v1/alpine:latest' } def 'test singularity relative path exists' () { @@ -226,4 +228,25 @@ class ContainerHandlerTest extends Specification { 1 * handler.createCache(_,IMAGE) >> '/some/path/foo.img' result == '/some/path/foo.img' } + + def 'should invoke singularity cache' () { + given: + def handler = Spy(ContainerHandler,constructorArgs:[[engine: 'singularity', enabled: true]]) + + when: + def result = handler.normalizeImageName(IMG) + then: + TIMES * handler.createCache(_, NORM) >> EXPECTED + + then: + result == EXPECTED + + where: + IMG | NORM | TIMES | EXPECTED + 'foo' | 'docker://foo' | 1 | '/local/img/foo' + 'library://foo:latest' | 'library://foo:latest'| 1 | '/local/img/foo.img' + 'http://bar:latest' | 'http://bar:latest' | 1 | '/local/http/foo.img' + 'https://bar:latest' | 'https://bar:latest' | 1 | '/local/https/foo.img' + '/some/container.img' | '/some/container.img' | 0 | '/some/container.img' + } }