Skip to content
Draft
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
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ dependencies {
implementation 'io.seqera:lib-retry:1.1.0'
implementation 'io.seqera:lib-random:1.0.0'
implementation 'io.seqera:lib-activator:1.0.0'
implementation 'io.seqera:wave-api:0.16.0'
implementation 'io.seqera:wave-utils:1.0.0'
implementation 'io.seqera:wave-api:0.17.0-alpha.1'
implementation 'io.seqera:wave-utils:1.1.0-alpha.1'
implementation 'io.seqera:lib-crypto:1.0.0'
implementation 'io.seqera:jedis-lock:1.0.0'
implementation 'io.seqera:lib-data-queue-redis:1.1.0'
Expand Down
22 changes: 22 additions & 0 deletions src/main/groovy/io/seqera/wave/util/ContainerHelper.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import io.seqera.wave.api.PackagesSpec
import io.seqera.wave.api.SubmitContainerTokenRequest
import io.seqera.wave.api.SubmitContainerTokenResponse
import io.seqera.wave.config.CondaOpts
import io.seqera.wave.config.CranOpts
import io.seqera.wave.core.ContainerPlatform
import io.seqera.wave.exception.BadRequestException
import io.seqera.wave.service.builder.BuildFormat
Expand All @@ -41,6 +42,10 @@ import static io.seqera.wave.util.DockerHelper.condaFileToSingularityFile
import static io.seqera.wave.util.DockerHelper.condaPackagesToCondaYaml
import static io.seqera.wave.util.DockerHelper.condaPackagesToDockerFile
import static io.seqera.wave.util.DockerHelper.condaPackagesToSingularityFile
import static io.seqera.wave.util.CranHelper.cranPackagesToDockerFile
import static io.seqera.wave.util.CranHelper.cranPackagesToSingularityFile
import static io.seqera.wave.util.CranHelper.cranFileToDockerFile
import static io.seqera.wave.util.CranHelper.cranFileToSingularityFile
/**
* Container helper methods
*
Expand Down Expand Up @@ -78,6 +83,23 @@ class ContainerHelper {
return result
}

if( spec.type == PackagesSpec.Type.CRAN ) {
if( !spec.cranOpts )
spec.cranOpts = new CranOpts()
def result
if ( spec.entries ) {
final String packages = spec.entries.join(' ')
result = formatSingularity
? cranPackagesToSingularityFile(packages, spec.channels, spec.cranOpts)
: cranPackagesToDockerFile(packages, spec.channels, spec.cranOpts)
} else {
result = formatSingularity
? cranFileToSingularityFile(spec.cranOpts)
: cranFileToDockerFile(spec.cranOpts)
}
return result
}

throw new BadRequestException("Unexpected packages spec type: $spec.type")
}

Expand Down
70 changes: 70 additions & 0 deletions src/test/groovy/io/seqera/wave/util/ContainerHelperTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import io.seqera.wave.api.ImageNameStrategy
import io.seqera.wave.api.PackagesSpec
import io.seqera.wave.api.SubmitContainerTokenRequest
import io.seqera.wave.config.CondaOpts
import io.seqera.wave.config.CranOpts
import io.seqera.wave.exception.BadRequestException
import io.seqera.wave.service.request.ContainerRequest
import io.seqera.wave.service.builder.BuildFormat
Expand Down Expand Up @@ -603,4 +604,73 @@ class ContainerHelperTest extends Specification {

}

def 'should create cran docker file with packages'() {
given:
def REPOSITORIES = ['cran', 'bioconductor']
def CRAN_OPTS = new CranOpts([rImage: 'rocker/r-ver:4.4.1', basePackages: 'littler r-cran-docopt'])
def PACKAGES = ['dplyr', 'ggplot2', 'bioc::GenomicRanges']
def packages = new PackagesSpec(type: PackagesSpec.Type.CRAN, entries: PACKAGES, channels: REPOSITORIES, cranOpts: CRAN_OPTS)

when:
def result = ContainerHelper.containerFileFromPackages(packages, false)

then:
result.contains('FROM rocker/r-ver:4.4.1')
result.contains('install2.r')
result.contains('dplyr ggplot2 bioc::GenomicRanges')
result.contains('R_LIBS_USER="/usr/local/lib/R/site-library"')
}

def 'should create cran singularity file with packages'() {
given:
def REPOSITORIES = ['cran']
def CRAN_OPTS = new CranOpts([rImage: 'rocker/r-ver:4.4.1'])
def PACKAGES = ['tidyverse', 'data.table']
def packages = new PackagesSpec(type: PackagesSpec.Type.CRAN, entries: PACKAGES, channels: REPOSITORIES, cranOpts: CRAN_OPTS)

when:
def result = ContainerHelper.containerFileFromPackages(packages, true)

then:
result.contains('BootStrap: docker')
result.contains('From: rocker/r-ver:4.4.1')
result.contains('install2.r')
result.contains('tidyverse data.table')
result.contains('export R_LIBS_USER="/usr/local/lib/R/site-library"')
}

def 'should create cran docker file without packages (file mode)'() {
given:
def CRAN_OPTS = new CranOpts([rImage: 'rocker/r-ver:4.4.1'])
def packages = new PackagesSpec(type: PackagesSpec.Type.CRAN, cranOpts: CRAN_OPTS)

when:
def result = ContainerHelper.containerFileFromPackages(packages, false)

then:
result.contains('FROM rocker/r-ver:4.4.1')
result.contains('COPY --from=wave_context_dir . .')
result.contains('renv.lock')
result.contains('install.R')
result.contains('R_LIBS_USER="/usr/local/lib/R/site-library"')
}

def 'should create cran singularity file without packages (file mode)'() {
given:
def CRAN_OPTS = new CranOpts([rImage: 'rocker/r-ver:4.4.1', basePackages: 'build-essential'])
def packages = new PackagesSpec(type: PackagesSpec.Type.CRAN, cranOpts: CRAN_OPTS)

when:
def result = ContainerHelper.containerFileFromPackages(packages, true)

then:
result.contains('BootStrap: docker')
result.contains('From: rocker/r-ver:4.4.1')
result.contains('%files')
result.contains('/opt/wave_context_dir')
result.contains('build-essential')
result.contains('renv.lock')
result.contains('export R_LIBS_USER="/usr/local/lib/R/site-library"')
}

}
14 changes: 0 additions & 14 deletions typespec/models/CondaPackages.tsp

This file was deleted.

6 changes: 3 additions & 3 deletions typespec/models/ContainerRequest.tsp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "./ContainerConfig.tsp";
import "./CondaPackages.tsp";
import "./PackagesSpec.tsp";
import "./ScanMode.tsp";
import "./ScanLevel.tsp";

Expand Down Expand Up @@ -39,8 +39,8 @@ model ContainerRequest {
@doc("The name strategy to be used to create the name of the container built by Wave. Its values can be `none`, `tagPrefix`, or `imageSuffix`. ")
nameStrategy?: "none" | "tagPrefix" | "imageSuffix";
mirror?: boolean;
@doc("Conda packages to be installed in the container.")
packages?: CondaPackages;
@doc("Packages to be installed in the container.")
packages?: PackagesSpec;
scanMode?: ScanMode;
scanLevels?: ScanLevel[];
@doc("Request submission timestamp using ISO-8601.")
Expand Down
Loading