Skip to content

Commit

Permalink
Merge pull request #65 from nextflow-io/fix/multiple-samplesheetToList
Browse files Browse the repository at this point in the history
Fix using `samplesheetToList` multiple times in channel operators
  • Loading branch information
nvnieuwk authored Oct 22, 2024
2 parents b3d2cd4 + fb6a525 commit 9f6c2b2
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 20 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

## Bug fixes

1. Fixed a bug in `samplesheetToList` that caused output mixing when the function was used more than once in channel operators.

## Improvements

# Version 2.1.2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,10 @@ import nextflow.Nextflow
@CompileStatic
class SamplesheetConverter {

private static Path samplesheetFile
private static Path schemaFile
private static ValidationConfig config
private static Map options

SamplesheetConverter(Path samplesheetFile, Path schemaFile, ValidationConfig config, Map options) {
this.samplesheetFile = samplesheetFile
this.schemaFile = schemaFile
SamplesheetConverter(ValidationConfig config) {
this.config = config
this.options = options
}

private static List<Map> rows = []
Expand Down Expand Up @@ -67,34 +61,38 @@ class SamplesheetConverter {
/*
Convert the samplesheet to a list of entries based on a schema
*/
public static List validateAndConvertToList() {
public static List validateAndConvertToList(
Path samplesheetFile,
Path schemaFile,
Map options
) {

def colors = Utils.logColours(config.monochromeLogs)

// Some checks before validating
if(!this.schemaFile.exists()) {
def msg = "${colors.red}JSON schema file ${this.schemaFile.toString()} does not exist\n${colors.reset}\n"
if(!schemaFile.exists()) {
def msg = "${colors.red}JSON schema file ${schemaFile.toString()} does not exist\n${colors.reset}\n"
throw new SchemaValidationException(msg)
}

if(!this.samplesheetFile.exists()) {
def msg = "${colors.red}Samplesheet file ${this.samplesheetFile.toString()} does not exist\n${colors.reset}\n"
if(!samplesheetFile.exists()) {
def msg = "${colors.red}Samplesheet file ${samplesheetFile.toString()} does not exist\n${colors.reset}\n"
throw new SchemaValidationException(msg)
}

// Validate
final validator = new JsonSchemaValidator(config)
def JSONArray samplesheet = Utils.fileToJsonArray(this.samplesheetFile, this.schemaFile)
def List<String> validationErrors = validator.validate(samplesheet, this.schemaFile.text)
def JSONArray samplesheet = Utils.fileToJsonArray(samplesheetFile, schemaFile)
def List<String> validationErrors = validator.validate(samplesheet, schemaFile.text)
if (validationErrors) {
def msg = "${colors.red}The following errors have been detected in ${this.samplesheetFile.toString()}:\n\n" + validationErrors.join('\n').trim() + "\n${colors.reset}\n"
def msg = "${colors.red}The following errors have been detected in ${samplesheetFile.toString()}:\n\n" + validationErrors.join('\n').trim() + "\n${colors.reset}\n"
log.error("Validation of samplesheet failed!")
throw new SchemaValidationException(msg, validationErrors)
}

// Convert
def LinkedHashMap schemaMap = new JsonSlurper().parseText(this.schemaFile.text) as LinkedHashMap
def List samplesheetList = Utils.fileToList(this.samplesheetFile, this.schemaFile)
def LinkedHashMap schemaMap = new JsonSlurper().parseText(schemaFile.text) as LinkedHashMap
def List samplesheetList = Utils.fileToList(samplesheetFile, schemaFile)

this.rows = []

Expand All @@ -110,7 +108,7 @@ class SamplesheetConverter {
}
return result
}
logUnusedHeadersWarning(this.samplesheetFile.toString())
logUnusedHeadersWarning(samplesheetFile.toString())
return channelFormat
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,9 @@ class SchemaValidator extends PluginExtensionPoint {
final Path schema,
final Map options = null
) {
def SamplesheetConverter converter = new SamplesheetConverter(samplesheet, schema, config, options)
return converter.validateAndConvertToList()
def SamplesheetConverter converter = new SamplesheetConverter(config)
def List output = converter.validateAndConvertToList(samplesheet, schema, options)
return output
}

//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,4 +537,42 @@ class SamplesheetConverterTest extends Dsl2Spec{
stdout.contains("[[string1:dependentRequired, string2:dependentRequired, integer1:10, integer2:10, boolean1:true, boolean2:true], string1, 25, false, [], [], [], unique2, 1, itDoesExist]")
stdout.contains("[[string1:extraField, string2:extraField, integer1:10, integer2:10, boolean1:true, boolean2:true], string1, 25, false, ${getRootString()}/src/testResources/test.txt, ${getRootString()}/src/testResources/testDir, ${getRootString()}/src/testResources/testDir, unique3, 1, itDoesExist]" as String)
}

def 'samplesheetToList - usage in channels' () {
given:
def SCRIPT_TEXT = '''
include { samplesheetToList } from 'plugin/nf-schema'
Channel.of("src/testResources/correct.csv")
.flatMap { it ->
samplesheetToList(it, "src/testResources/schema_input.json")
}
.map { it -> println("first: ${it}") }
Channel.of("src/testResources/correct_arrays.json")
.flatMap { it ->
samplesheetToList(it, "src/testResources/schema_input_with_arrays.json")
}
.map { it -> println("second: ${it}") }
'''

when:
dsl_eval(SCRIPT_TEXT)
def stdout = capture
.toString()
.readLines()
.findResults {it.startsWith('first') || it.startsWith('second') ? it : null }

then:
noExceptionThrown()
stdout.contains("first: [[string1:fullField, string2:fullField, integer1:10, integer2:10, boolean1:true, boolean2:true], string1, 25.12, false, ${getRootString()}/src/testResources/test.txt, ${getRootString()}/src/testResources/testDir, ${getRootString()}/src/testResources/test.txt, unique1, 1, itDoesExist]" as String)
stdout.contains("first: [[string1:value, string2:value, integer1:0, integer2:0, boolean1:true, boolean2:true], string1, 25.08, false, [], [], [], [], [], itDoesExist]")
stdout.contains("first: [[string1:dependentRequired, string2:dependentRequired, integer1:10, integer2:10, boolean1:true, boolean2:true], string1, 25, false, [], [], [], unique2, 1, itDoesExist]")
stdout.contains("first: [[string1:extraField, string2:extraField, integer1:10, integer2:10, boolean1:true, boolean2:true], string1, 25, false, ${getRootString()}/src/testResources/test.txt, ${getRootString()}/src/testResources/testDir, ${getRootString()}/src/testResources/testDir, unique3, 1, itDoesExist]" as String)
stdout.contains("second: [[array_meta:[]], [${getRootString()}/src/testResources/testDir/testFile.txt, ${getRootString()}/src/testResources/testDir2/testFile2.txt], [${getRootString()}/src/testResources/testDir, ${getRootString()}/src/testResources/testDir2], [${getRootString()}/src/testResources/testDir, ${getRootString()}/src/testResources/testDir2/testFile2.txt], [string1, string2], [25, 26], [25, 26.5], [false, true], [1, 2, 3], [true], [${getRootString()}/src/testResources/testDir/testFile.txt], [[${getRootString()}/src/testResources/testDir/testFile.txt]]]" as String)
stdout.contains("second: [[array_meta:[look, an, array, in, meta]], [], [], [], [string1, string2], [25, 26], [25, 26.5], [], [1, 2, 3], [false, true, false], [${getRootString()}/src/testResources/testDir/testFile.txt], [[${getRootString()}/src/testResources/testDir/testFile.txt]]]" as String)
stdout.contains("second: [[array_meta:[]], [], [], [], [string1, string2], [25, 26], [25, 26.5], [], [1, 2, 3], [false, true, false], [${getRootString()}/src/testResources/testDir/testFile.txt], [[${getRootString()}/src/testResources/testDir/testFile.txt], [${getRootString()}/src/testResources/testDir/testFile.txt, ${getRootString()}/src/testResources/testDir2/testFile2.txt]]]" as String)

}
}

0 comments on commit 9f6c2b2

Please sign in to comment.