From a2aff072f0573065ce348864c0e20b85851c612e Mon Sep 17 00:00:00 2001 From: Erin McAuley Date: Wed, 15 Apr 2026 10:27:15 -0400 Subject: [PATCH 1/8] feat: parsnp module --- modules/nf-core/parsnp/environment.yml | 7 ++ modules/nf-core/parsnp/main.nf | 55 ++++++++ modules/nf-core/parsnp/meta.yml | 118 ++++++++++++++++++ modules/nf-core/parsnp/tests/main.nf.test | 68 ++++++++++ .../nf-core/parsnp/tests/main.nf.test.snap | 108 ++++++++++++++++ 5 files changed, 356 insertions(+) create mode 100644 modules/nf-core/parsnp/environment.yml create mode 100644 modules/nf-core/parsnp/main.nf create mode 100644 modules/nf-core/parsnp/meta.yml create mode 100644 modules/nf-core/parsnp/tests/main.nf.test create mode 100644 modules/nf-core/parsnp/tests/main.nf.test.snap diff --git a/modules/nf-core/parsnp/environment.yml b/modules/nf-core/parsnp/environment.yml new file mode 100644 index 000000000000..cdbf8a5b550a --- /dev/null +++ b/modules/nf-core/parsnp/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::parsnp=2.1.5" diff --git a/modules/nf-core/parsnp/main.nf b/modules/nf-core/parsnp/main.nf new file mode 100644 index 000000000000..d84e0a2d3bb2 --- /dev/null +++ b/modules/nf-core/parsnp/main.nf @@ -0,0 +1,55 @@ +process PARSNP { + tag "$meta.id" + label 'process_high' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'oras://community.wave.seqera.io/library/parsnp:2.1.5--0605933fc69e7b20': + 'community.wave.seqera.io/library/parsnp:2.1.5--2c7f64ad14a79523' }" + + input: + tuple val(meta), path(genomes, stageAs: "genomes") + path reference + + output: + tuple val(meta), path("*.xmfa") , emit: xmfa + tuple val(meta), path("*.ggr") , emit: ggr + tuple val(meta), path("*.snps.mblocks"), emit: snps_mblocks, optional: true + tuple val(meta), path("*.tree") , emit: tree + tuple val(meta), path("partition") , emit: partition, optional: true + tuple val("${task.process}"), val('parsnp'), eval("parsnp --version 2>/dev/null | tail -n 1 | sed 's/parsnp //'"), topic: versions, emit: versions_parsnp + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + parsnp \\ + -r "${reference}" \\ + -d "${genomes}" \\ + -o parsnp_out \\ + -p ${task.cpus} \\ + ${args} + + mv parsnp_out/parsnp.xmfa ${prefix}.xmfa + mv parsnp_out/parsnp.ggr ${prefix}.ggr + if [ -f parsnp_out/parsnp.snps.mblocks ]; then + mv parsnp_out/parsnp.snps.mblocks "${prefix}.snps.mblocks" + fi + mv parsnp_out/parsnp.tree ${prefix}.tree + if [ -d parsnp_out/partition ]; then + mv parsnp_out/partition . + fi + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.xmfa + touch ${prefix}.ggr + touch ${prefix}.snps.mblocks + touch ${prefix}.tree + """ +} diff --git a/modules/nf-core/parsnp/meta.yml b/modules/nf-core/parsnp/meta.yml new file mode 100644 index 000000000000..9755fcf0a9b5 --- /dev/null +++ b/modules/nf-core/parsnp/meta.yml @@ -0,0 +1,118 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "parsnp" +description: "Parsnp is a command-line-tool for efficient microbial core genome alignment and SNP detection." +keywords: + - alignment + - bacteria + - phylogeny + - microbial genomics + - core genome + - SNP + +tools: + - "parsnp": + description: "Parsnp is a command-line-tool for efficient microbial core genome alignment and SNP detection." + homepage: "https://harvest.readthedocs.io/en/latest/content/parsnp/tutorial.html" + documentation: "https://harvest.readthedocs.io/en/latest/content/parsnp/tutorial.html" + tool_dev_url: "https://github.com/marbl/parsnp" + doi: "10.1093/bioinformatics/btae311" + licence: ["custom; see https://raw.githubusercontent.com/marbl/parsnp/master/LICENSE"] + identifier: biotools:parsnp + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - genomes: + type: directory + description: Directory containing genome assemblies in FASTA format to be aligned + - reference: + type: file + description: Reference genome in FASTA format + pattern: "*.{fasta,fa,fna}" + ontologies: + - edam: "http://edamontology.org/format_1929" # FASTA + +output: + xmfa: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.xmfa": + type: file + description: Core-genome multiple sequence alignment in XMFA format + pattern: "*.xmfa" + ggr: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.ggr": + type: file + description: Compressed binary representation of the alignment generated by the Harvest toolkit, used for visualization with Gingr + pattern: "*.ggr" + snps_mblocks: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.snps.mblocks": + type: file + description: Core-SNP signature of each sequence in FASTA format, used to generate the phylogeny. Absent when no SNPs are detected. + pattern: "*.snps.mblocks" + ontologies: + - edam: "http://edamontology.org/format_1929" # FASTA + tree: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.tree": + type: file + description: Resulting phylogeny in Newick format + pattern: "*.tree" + ontologies: + - edam: "http://edamontology.org/format_1910" # Newick + partition: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "partition": + type: directory + description: Output directory from partition mode containing results of each partitioned run. Only present when --partition is specified. + pattern: "partition" + versions_parsnp: + - - ${task.process}: + type: string + description: The name of the process + - parsnp: + type: string + description: The name of the tool + - "parsnp --version 2>/dev/null | tail -n 1 | sed 's/parsnp //'": + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process + - parsnp: + type: string + description: The tool name + - parsnp --version 2>/dev/null | tail -n 1 | sed 's/parsnp //': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@emmcauley" +maintainers: + - "@emmcauley" diff --git a/modules/nf-core/parsnp/tests/main.nf.test b/modules/nf-core/parsnp/tests/main.nf.test new file mode 100644 index 000000000000..25eac0655004 --- /dev/null +++ b/modules/nf-core/parsnp/tests/main.nf.test @@ -0,0 +1,68 @@ +nextflow_process { + + name "Test Process PARSNP" + script "../main.nf" + process "PARSNP" + + tag "modules" + tag "modules_nfcore" + tag "parsnp" + + test("candidatus_portiera_aleyrodidarum - fasta") { + when { + params { + modules_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' + } + process { + def dir = file("${outputDir}/genomes") + dir.mkdirs() + def genomeText = new URL(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta').text + new File(dir, "portiera_1.fa").text = genomeText + new File(dir, "portiera_2.fa").text = genomeText + """ + input[0] = [[ id:'test' ], file("${outputDir}/genomes")] + input[1] = file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + + } + + test("candidatus_portiera_aleyrodidarum - fasta - stub") { + + options "-stub" + + when { + params { + modules_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' + } + process { + def dir = file("${outputDir}/genomes") + dir.mkdirs() + def genomeText = new URL(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta').text + new File(dir, "portiera_1.fa").text = genomeText + new File(dir, "portiera_2.fa").text = genomeText + """ + input[0] = [[ id:'test' ], file("${outputDir}/genomes")] + input[1] = file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + + } + +} diff --git a/modules/nf-core/parsnp/tests/main.nf.test.snap b/modules/nf-core/parsnp/tests/main.nf.test.snap new file mode 100644 index 000000000000..b736ae69b07a --- /dev/null +++ b/modules/nf-core/parsnp/tests/main.nf.test.snap @@ -0,0 +1,108 @@ +{ + "candidatus_portiera_aleyrodidarum - fasta - stub": { + "content": [ + { + "ggr": [ + [ + { + "id": "test" + }, + "test.ggr:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "partition": [ + + ], + "snps_mblocks": [ + [ + { + "id": "test" + }, + "test.snps.mblocks:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tree": [ + [ + { + "id": "test" + }, + "test.tree:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_parsnp": [ + [ + "PARSNP", + "parsnp", + "2.1.5" + ] + ], + "xmfa": [ + [ + { + "id": "test" + }, + "test.xmfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-04-15T10:59:34.624721" + }, + "candidatus_portiera_aleyrodidarum - fasta": { + "content": [ + { + "ggr": [ + [ + { + "id": "test" + }, + "test.ggr:md5,98585d7f9ffae110bbcf37b139887d1b" + ] + ], + "partition": [ + + ], + "snps_mblocks": [ + [ + { + "id": "test" + }, + "test.snps.mblocks:md5,5cdabd01f303fc480d81a352661e802d" + ] + ], + "tree": [ + [ + { + "id": "test" + }, + "test.tree:md5,e73585947555491eec4092429f3331bf" + ] + ], + "versions_parsnp": [ + [ + "PARSNP", + "parsnp", + "2.1.5" + ] + ], + "xmfa": [ + [ + { + "id": "test" + }, + "test.xmfa:md5,5b07a37b1e4dfb96582cede2a2763f0c" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-04-15T10:59:13.628388" + } +} \ No newline at end of file From 811e177f552acb14862e5a09a84e0b77f6b6bd3f Mon Sep 17 00:00:00 2001 From: Erin McAuley Date: Mon, 20 Apr 2026 22:22:15 -0400 Subject: [PATCH 2/8] tests: remove redundant params --- modules/nf-core/parsnp/tests/main.nf.test | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/modules/nf-core/parsnp/tests/main.nf.test b/modules/nf-core/parsnp/tests/main.nf.test index 25eac0655004..bd9eb5a5cbbe 100644 --- a/modules/nf-core/parsnp/tests/main.nf.test +++ b/modules/nf-core/parsnp/tests/main.nf.test @@ -10,13 +10,10 @@ nextflow_process { test("candidatus_portiera_aleyrodidarum - fasta") { when { - params { - modules_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' - } process { def dir = file("${outputDir}/genomes") dir.mkdirs() - def genomeText = new URL(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta').text + def genomeText = new URL('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta').text new File(dir, "portiera_1.fa").text = genomeText new File(dir, "portiera_2.fa").text = genomeText """ @@ -40,13 +37,10 @@ nextflow_process { options "-stub" when { - params { - modules_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' - } process { def dir = file("${outputDir}/genomes") dir.mkdirs() - def genomeText = new URL(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta').text + def genomeText = new URL('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta').text new File(dir, "portiera_1.fa").text = genomeText new File(dir, "portiera_2.fa").text = genomeText """ From 7fd07f3a1b9f65b3f4ce2d2baea896caea9813dd Mon Sep 17 00:00:00 2001 From: Erin McAuley Date: Tue, 21 Apr 2026 17:30:12 -0400 Subject: [PATCH 3/8] fix: reviewer comments and update tests --- modules/nf-core/parsnp/main.nf | 19 ++++++++++--------- modules/nf-core/parsnp/meta.yml | 10 ++++++++++ .../nf-core/parsnp/tests/main.nf.test.snap | 11 +++++++++-- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/modules/nf-core/parsnp/main.nf b/modules/nf-core/parsnp/main.nf index d84e0a2d3bb2..c4918e356e99 100644 --- a/modules/nf-core/parsnp/main.nf +++ b/modules/nf-core/parsnp/main.nf @@ -1,22 +1,22 @@ process PARSNP { - tag "$meta.id" + tag "${meta.id}" label 'process_high' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'oras://community.wave.seqera.io/library/parsnp:2.1.5--0605933fc69e7b20': - 'community.wave.seqera.io/library/parsnp:2.1.5--2c7f64ad14a79523' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community.wave.seqera.io/library/parsnp:2.1.5--0605933fc69e7b20' + : 'community.wave.seqera.io/library/parsnp:2.1.5--2c7f64ad14a79523'}" input: - tuple val(meta), path(genomes, stageAs: "genomes") + tuple val(meta), path(genomes, stageAs: "genomes/*") path reference output: - tuple val(meta), path("*.xmfa") , emit: xmfa - tuple val(meta), path("*.ggr") , emit: ggr + tuple val(meta), path("*.xmfa"), emit: xmfa + tuple val(meta), path("*.ggr"), emit: ggr tuple val(meta), path("*.snps.mblocks"), emit: snps_mblocks, optional: true - tuple val(meta), path("*.tree") , emit: tree - tuple val(meta), path("partition") , emit: partition, optional: true + tuple val(meta), path("*.tree"), emit: tree + tuple val(meta), path("partition"), emit: partition, optional: true tuple val("${task.process}"), val('parsnp'), eval("parsnp --version 2>/dev/null | tail -n 1 | sed 's/parsnp //'"), topic: versions, emit: versions_parsnp when: @@ -51,5 +51,6 @@ process PARSNP { touch ${prefix}.ggr touch ${prefix}.snps.mblocks touch ${prefix}.tree + mkdir partition """ } diff --git a/modules/nf-core/parsnp/meta.yml b/modules/nf-core/parsnp/meta.yml index 9755fcf0a9b5..77855845a454 100644 --- a/modules/nf-core/parsnp/meta.yml +++ b/modules/nf-core/parsnp/meta.yml @@ -25,9 +25,11 @@ input: description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` + ontologies: [] - genomes: type: directory description: Directory containing genome assemblies in FASTA format to be aligned + ontologies: [] - reference: type: file description: Reference genome in FASTA format @@ -42,26 +44,31 @@ output: description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` + ontologies: [] - "*.xmfa": type: file description: Core-genome multiple sequence alignment in XMFA format pattern: "*.xmfa" + ontologies: [] ggr: - - meta: type: map description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` + ontologies: [] - "*.ggr": type: file description: Compressed binary representation of the alignment generated by the Harvest toolkit, used for visualization with Gingr pattern: "*.ggr" + ontologies: [] snps_mblocks: - - meta: type: map description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` + ontologies: [] - "*.snps.mblocks": type: file description: Core-SNP signature of each sequence in FASTA format, used to generate the phylogeny. Absent when no SNPs are detected. @@ -74,6 +81,7 @@ output: description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` + ontologies: [] - "*.tree": type: file description: Resulting phylogeny in Newick format @@ -86,10 +94,12 @@ output: description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` + ontologies: [] - "partition": type: directory description: Output directory from partition mode containing results of each partitioned run. Only present when --partition is specified. pattern: "partition" + ontologies: [] versions_parsnp: - - ${task.process}: type: string diff --git a/modules/nf-core/parsnp/tests/main.nf.test.snap b/modules/nf-core/parsnp/tests/main.nf.test.snap index b736ae69b07a..aad4b6b364d2 100644 --- a/modules/nf-core/parsnp/tests/main.nf.test.snap +++ b/modules/nf-core/parsnp/tests/main.nf.test.snap @@ -11,7 +11,14 @@ ] ], "partition": [ - + [ + { + "id": "test" + }, + [ + + ] + ] ], "snps_mblocks": [ [ @@ -50,7 +57,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-04-15T10:59:34.624721" + "timestamp": "2026-04-21T16:30:51.174502" }, "candidatus_portiera_aleyrodidarum - fasta": { "content": [ From fe0f60a0e64087bc3412334f1251f87e65fcf2b1 Mon Sep 17 00:00:00 2001 From: Erin McAuley Date: Thu, 23 Apr 2026 23:00:38 -0400 Subject: [PATCH 4/8] fix: reviewer comments --- modules/nf-core/parsnp/main.nf | 2 +- modules/nf-core/parsnp/meta.yml | 10 -------- modules/nf-core/parsnp/tests/main.nf.test | 25 +++++++------------ .../nf-core/parsnp/tests/main.nf.test.snap | 12 ++++----- 4 files changed, 16 insertions(+), 33 deletions(-) diff --git a/modules/nf-core/parsnp/main.nf b/modules/nf-core/parsnp/main.nf index c4918e356e99..306b005e09a7 100644 --- a/modules/nf-core/parsnp/main.nf +++ b/modules/nf-core/parsnp/main.nf @@ -28,7 +28,7 @@ process PARSNP { """ parsnp \\ -r "${reference}" \\ - -d "${genomes}" \\ + -d genomes/ \\ -o parsnp_out \\ -p ${task.cpus} \\ ${args} diff --git a/modules/nf-core/parsnp/meta.yml b/modules/nf-core/parsnp/meta.yml index 77855845a454..9755fcf0a9b5 100644 --- a/modules/nf-core/parsnp/meta.yml +++ b/modules/nf-core/parsnp/meta.yml @@ -25,11 +25,9 @@ input: description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` - ontologies: [] - genomes: type: directory description: Directory containing genome assemblies in FASTA format to be aligned - ontologies: [] - reference: type: file description: Reference genome in FASTA format @@ -44,31 +42,26 @@ output: description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` - ontologies: [] - "*.xmfa": type: file description: Core-genome multiple sequence alignment in XMFA format pattern: "*.xmfa" - ontologies: [] ggr: - - meta: type: map description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` - ontologies: [] - "*.ggr": type: file description: Compressed binary representation of the alignment generated by the Harvest toolkit, used for visualization with Gingr pattern: "*.ggr" - ontologies: [] snps_mblocks: - - meta: type: map description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` - ontologies: [] - "*.snps.mblocks": type: file description: Core-SNP signature of each sequence in FASTA format, used to generate the phylogeny. Absent when no SNPs are detected. @@ -81,7 +74,6 @@ output: description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` - ontologies: [] - "*.tree": type: file description: Resulting phylogeny in Newick format @@ -94,12 +86,10 @@ output: description: | Groovy Map containing sample information e.g. `[ id:'sample1' ]` - ontologies: [] - "partition": type: directory description: Output directory from partition mode containing results of each partitioned run. Only present when --partition is specified. pattern: "partition" - ontologies: [] versions_parsnp: - - ${task.process}: type: string diff --git a/modules/nf-core/parsnp/tests/main.nf.test b/modules/nf-core/parsnp/tests/main.nf.test index bd9eb5a5cbbe..c2e9f463739e 100644 --- a/modules/nf-core/parsnp/tests/main.nf.test +++ b/modules/nf-core/parsnp/tests/main.nf.test @@ -11,25 +11,21 @@ nextflow_process { test("candidatus_portiera_aleyrodidarum - fasta") { when { process { - def dir = file("${outputDir}/genomes") - dir.mkdirs() - def genomeText = new URL('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta').text - new File(dir, "portiera_1.fa").text = genomeText - new File(dir, "portiera_2.fa").text = genomeText """ - input[0] = [[ id:'test' ], file("${outputDir}/genomes")] - input[1] = file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) + def genome = file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) + def genome2 = genome.copyTo('portiera_2.fa') + + input[0] = [[ id:'test' ], [genome, genome2]] + input[1] = genome """ } } - then { assertAll( { assert process.success }, { assert snapshot(sanitizeOutput(process.out)).match() } ) } - } test("candidatus_portiera_aleyrodidarum - fasta - stub") { @@ -38,14 +34,11 @@ nextflow_process { when { process { - def dir = file("${outputDir}/genomes") - dir.mkdirs() - def genomeText = new URL('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta').text - new File(dir, "portiera_1.fa").text = genomeText - new File(dir, "portiera_2.fa").text = genomeText """ - input[0] = [[ id:'test' ], file("${outputDir}/genomes")] - input[1] = file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) + def genome = file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) + def genome2 = genome.copyTo('portiera_2.fa') + input[0] = [[ id:'test' ], [genome, genome2]] + input[1] = genome """ } } diff --git a/modules/nf-core/parsnp/tests/main.nf.test.snap b/modules/nf-core/parsnp/tests/main.nf.test.snap index aad4b6b364d2..f95f79e44d24 100644 --- a/modules/nf-core/parsnp/tests/main.nf.test.snap +++ b/modules/nf-core/parsnp/tests/main.nf.test.snap @@ -57,7 +57,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-04-21T16:30:51.174502" + "timestamp": "2026-04-23T21:49:54.901811" }, "candidatus_portiera_aleyrodidarum - fasta": { "content": [ @@ -67,7 +67,7 @@ { "id": "test" }, - "test.ggr:md5,98585d7f9ffae110bbcf37b139887d1b" + "test.ggr:md5,11bb67383eeed4e2607abf54b38bc332" ] ], "partition": [ @@ -78,7 +78,7 @@ { "id": "test" }, - "test.snps.mblocks:md5,5cdabd01f303fc480d81a352661e802d" + "test.snps.mblocks:md5,e1f403db7a9fb5ea7fac96fb5410f454" ] ], "tree": [ @@ -86,7 +86,7 @@ { "id": "test" }, - "test.tree:md5,e73585947555491eec4092429f3331bf" + "test.tree:md5,e56cd53de993f7437fac3be08a442c0d" ] ], "versions_parsnp": [ @@ -101,7 +101,7 @@ { "id": "test" }, - "test.xmfa:md5,5b07a37b1e4dfb96582cede2a2763f0c" + "test.xmfa:md5,c6418a3584d1a7e0d265cb007766fa54" ] ] } @@ -110,6 +110,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-04-15T10:59:13.628388" + "timestamp": "2026-04-23T22:04:35.831479" } } \ No newline at end of file From 7051840b232eb7a1f6251b68d2bd30365f7a4112 Mon Sep 17 00:00:00 2001 From: Erin McAuley Date: Sat, 25 Apr 2026 10:20:20 -0400 Subject: [PATCH 5/8] fix: https breaks singularity image, need to use oras --- modules/nf-core/parsnp/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nf-core/parsnp/main.nf b/modules/nf-core/parsnp/main.nf index 306b005e09a7..ab47e98a3f43 100644 --- a/modules/nf-core/parsnp/main.nf +++ b/modules/nf-core/parsnp/main.nf @@ -4,7 +4,7 @@ process PARSNP { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'https://community.wave.seqera.io/library/parsnp:2.1.5--0605933fc69e7b20' + ? 'oras://community.wave.seqera.io/library/parsnp:2.1.5--0605933fc69e7b20' : 'community.wave.seqera.io/library/parsnp:2.1.5--2c7f64ad14a79523'}" input: From 806eddb1b0e31bd815383154105474fb279ea3fd Mon Sep 17 00:00:00 2001 From: Erin McAuley Date: Mon, 4 May 2026 18:18:09 -0400 Subject: [PATCH 6/8] fix: reviewer comments --- modules/nf-core/parsnp/main.nf | 2 +- modules/nf-core/parsnp/meta.yml | 2 + modules/nf-core/parsnp/tests/main.nf.test | 52 ++++++++ .../nf-core/parsnp/tests/main.nf.test.snap | 113 ++++++++++++++++++ modules/nf-core/parsnp/tests/nextflow.config | 5 + 5 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 modules/nf-core/parsnp/tests/nextflow.config diff --git a/modules/nf-core/parsnp/main.nf b/modules/nf-core/parsnp/main.nf index ab47e98a3f43..fdc591f954be 100644 --- a/modules/nf-core/parsnp/main.nf +++ b/modules/nf-core/parsnp/main.nf @@ -4,7 +4,7 @@ process PARSNP { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'oras://community.wave.seqera.io/library/parsnp:2.1.5--0605933fc69e7b20' + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/78/78d7fff752adf0b7ff156545536bbe58f8e6e8c5e1b1513f9a726747ee686900/data' : 'community.wave.seqera.io/library/parsnp:2.1.5--2c7f64ad14a79523'}" input: diff --git a/modules/nf-core/parsnp/meta.yml b/modules/nf-core/parsnp/meta.yml index 9755fcf0a9b5..864cfd276a78 100644 --- a/modules/nf-core/parsnp/meta.yml +++ b/modules/nf-core/parsnp/meta.yml @@ -46,6 +46,7 @@ output: type: file description: Core-genome multiple sequence alignment in XMFA format pattern: "*.xmfa" + ontologies: [] ggr: - - meta: type: map @@ -56,6 +57,7 @@ output: type: file description: Compressed binary representation of the alignment generated by the Harvest toolkit, used for visualization with Gingr pattern: "*.ggr" + ontologies: [] snps_mblocks: - - meta: type: map diff --git a/modules/nf-core/parsnp/tests/main.nf.test b/modules/nf-core/parsnp/tests/main.nf.test index c2e9f463739e..bb2f64844e57 100644 --- a/modules/nf-core/parsnp/tests/main.nf.test +++ b/modules/nf-core/parsnp/tests/main.nf.test @@ -52,4 +52,56 @@ nextflow_process { } + test("candidatus_portiera_aleyrodidarum - fasta - partition") { + + when { + params { + module_args = '--partition 1' + } + process { + """ + def genome = file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) + def genome2 = genome.copyTo('portiera_2.fa') + input[0] = [[ id:'test' ], [genome, genome2]] + input[1] = genome + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + + } + + test("candidatus_portiera_aleyrodidarum - fasta - partition - stub") { + + options "-stub" + + when { + params { + module_args = '--partition 1' + } + process { + """ + def genome = file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) + def genome2 = genome.copyTo('portiera_2.fa') + input[0] = [[ id:'test' ], [genome, genome2]] + input[1] = genome + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + + } + } diff --git a/modules/nf-core/parsnp/tests/main.nf.test.snap b/modules/nf-core/parsnp/tests/main.nf.test.snap index f95f79e44d24..37947213be63 100644 --- a/modules/nf-core/parsnp/tests/main.nf.test.snap +++ b/modules/nf-core/parsnp/tests/main.nf.test.snap @@ -111,5 +111,118 @@ "nextflow": "25.10.2" }, "timestamp": "2026-04-23T22:04:35.831479" + }, + "candidatus_portiera_aleyrodidarum - fasta - partition": { + "content": [ + { + "ggr": [ + [ + { + "id": "test" + }, + "test.ggr:md5,11bb67383eeed4e2607abf54b38bc332" + ] + ], + "partition": [ + + ], + "snps_mblocks": [ + [ + { + "id": "test" + }, + "test.snps.mblocks:md5,e1f403db7a9fb5ea7fac96fb5410f454" + ] + ], + "tree": [ + [ + { + "id": "test" + }, + "test.tree:md5,e56cd53de993f7437fac3be08a442c0d" + ] + ], + "versions_parsnp": [ + [ + "PARSNP", + "parsnp", + "2.1.5" + ] + ], + "xmfa": [ + [ + { + "id": "test" + }, + "test.xmfa:md5,c6418a3584d1a7e0d265cb007766fa54" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-05-04T16:58:34.782251" + }, + "candidatus_portiera_aleyrodidarum - fasta - partition - stub": { + "content": [ + { + "ggr": [ + [ + { + "id": "test" + }, + "test.ggr:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "partition": [ + [ + { + "id": "test" + }, + [ + + ] + ] + ], + "snps_mblocks": [ + [ + { + "id": "test" + }, + "test.snps.mblocks:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tree": [ + [ + { + "id": "test" + }, + "test.tree:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_parsnp": [ + [ + "PARSNP", + "parsnp", + "2.1.5" + ] + ], + "xmfa": [ + [ + { + "id": "test" + }, + "test.xmfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-05-04T17:01:12.136804" } } \ No newline at end of file diff --git a/modules/nf-core/parsnp/tests/nextflow.config b/modules/nf-core/parsnp/tests/nextflow.config new file mode 100644 index 000000000000..1ca024e48704 --- /dev/null +++ b/modules/nf-core/parsnp/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'PARSNP' { + ext.args = params.module_args ?: '' + } +} From bebcfadd8e7be8a4acff25f8de2d4980585ca729 Mon Sep 17 00:00:00 2001 From: Erin McAuley Date: Wed, 6 May 2026 13:38:51 -0400 Subject: [PATCH 7/8] fix: reviewer comments, partition outputs --- modules/nf-core/parsnp/tests/main.nf.test | 33 +++++-- .../nf-core/parsnp/tests/main.nf.test.snap | 89 +++++++++---------- modules/nf-core/parsnp/tests/nextflow.config | 2 +- 3 files changed, 68 insertions(+), 56 deletions(-) diff --git a/modules/nf-core/parsnp/tests/main.nf.test b/modules/nf-core/parsnp/tests/main.nf.test index bb2f64844e57..29e777c8e6d0 100644 --- a/modules/nf-core/parsnp/tests/main.nf.test +++ b/modules/nf-core/parsnp/tests/main.nf.test @@ -3,13 +3,18 @@ nextflow_process { name "Test Process PARSNP" script "../main.nf" process "PARSNP" + config "./nextflow.config" tag "modules" tag "modules_nfcore" tag "parsnp" test("candidatus_portiera_aleyrodidarum - fasta") { + config './nextflow.config' when { + params { + module_args = '' + } process { """ def genome = file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) @@ -29,10 +34,13 @@ nextflow_process { } test("candidatus_portiera_aleyrodidarum - fasta - stub") { - + config './nextflow.config' options "-stub" when { + params { + module_args = '' + } process { """ def genome = file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) @@ -53,16 +61,17 @@ nextflow_process { } test("candidatus_portiera_aleyrodidarum - fasta - partition") { - + config './nextflow.config' when { params { - module_args = '--partition 1' + module_args = '--min-partition-size 1' } process { """ def genome = file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) def genome2 = genome.copyTo('portiera_2.fa') - input[0] = [[ id:'test' ], [genome, genome2]] + def genome3 = genome.copyTo('portiera_3.fa') + input[0] = [[ id:'test' ], [genome, genome2, genome3]] input[1] = genome """ } @@ -71,25 +80,33 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(sanitizeOutput(process.out)).match() } + { assert process.out.partition }, + { assert snapshot( + process.out.xmfa, + process.out.ggr, + process.out.snps_mblocks, + process.out.tree, + process.out.versions_parsnp + ).match() } ) } } test("candidatus_portiera_aleyrodidarum - fasta - partition - stub") { - + config './nextflow.config' options "-stub" when { params { - module_args = '--partition 1' + module_args = '--min-partition-size 1' } process { """ def genome = file('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true) def genome2 = genome.copyTo('portiera_2.fa') - input[0] = [[ id:'test' ], [genome, genome2]] + def genome3 = genome.copyTo('portiera_3.fa') + input[0] = [[ id:'test' ], [genome, genome2, genome3]] input[1] = genome """ } diff --git a/modules/nf-core/parsnp/tests/main.nf.test.snap b/modules/nf-core/parsnp/tests/main.nf.test.snap index 37947213be63..8ad411c88f2f 100644 --- a/modules/nf-core/parsnp/tests/main.nf.test.snap +++ b/modules/nf-core/parsnp/tests/main.nf.test.snap @@ -57,7 +57,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-04-23T21:49:54.901811" + "timestamp": "2026-05-05T11:25:57.496665" }, "candidatus_portiera_aleyrodidarum - fasta": { "content": [ @@ -110,60 +110,55 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-04-23T22:04:35.831479" + "timestamp": "2026-05-05T11:25:43.191941" }, "candidatus_portiera_aleyrodidarum - fasta - partition": { "content": [ - { - "ggr": [ - [ - { - "id": "test" - }, - "test.ggr:md5,11bb67383eeed4e2607abf54b38bc332" - ] - ], - "partition": [ - - ], - "snps_mblocks": [ - [ - { - "id": "test" - }, - "test.snps.mblocks:md5,e1f403db7a9fb5ea7fac96fb5410f454" - ] - ], - "tree": [ - [ - { - "id": "test" - }, - "test.tree:md5,e56cd53de993f7437fac3be08a442c0d" - ] - ], - "versions_parsnp": [ - [ - "PARSNP", - "parsnp", - "2.1.5" - ] - ], - "xmfa": [ - [ - { - "id": "test" - }, - "test.xmfa:md5,c6418a3584d1a7e0d265cb007766fa54" - ] + [ + [ + { + "id": "test" + }, + "test.xmfa:md5,9254c3e2a3b0f42b9959bf989a397b51" ] - } + ], + [ + [ + { + "id": "test" + }, + "test.ggr:md5,320ae37a8df8d427041d86fca0c40e4c" + ] + ], + [ + [ + { + "id": "test" + }, + "test.snps.mblocks:md5,b476ad8ee2ce9150a40033b2d419613e" + ] + ], + [ + [ + { + "id": "test" + }, + "test.tree:md5,7d7b3090aa9dec54124f80e202ef5576" + ] + ], + [ + [ + "PARSNP", + "parsnp", + "2.1.5" + ] + ] ], "meta": { "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-05-04T16:58:34.782251" + "timestamp": "2026-05-06T13:35:34.655406" }, "candidatus_portiera_aleyrodidarum - fasta - partition - stub": { "content": [ @@ -223,6 +218,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-05-04T17:01:12.136804" + "timestamp": "2026-05-05T11:26:28.884401" } } \ No newline at end of file diff --git a/modules/nf-core/parsnp/tests/nextflow.config b/modules/nf-core/parsnp/tests/nextflow.config index 1ca024e48704..ebb6a2e7ac81 100644 --- a/modules/nf-core/parsnp/tests/nextflow.config +++ b/modules/nf-core/parsnp/tests/nextflow.config @@ -1,5 +1,5 @@ process { withName: 'PARSNP' { - ext.args = params.module_args ?: '' + ext.args = params.module_args } } From 25fb13f5f546fcccb72d3054442d9664f90d2df7 Mon Sep 17 00:00:00 2001 From: Erin McAuley Date: Thu, 7 May 2026 13:32:26 -0400 Subject: [PATCH 8/8] fix: more fixes --- modules/nf-core/parsnp/main.nf | 4 +++- modules/nf-core/parsnp/tests/main.nf.test | 8 ++------ modules/nf-core/parsnp/tests/main.nf.test.snap | 14 +++----------- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/modules/nf-core/parsnp/main.nf b/modules/nf-core/parsnp/main.nf index fdc591f954be..dfeecf485b6b 100644 --- a/modules/nf-core/parsnp/main.nf +++ b/modules/nf-core/parsnp/main.nf @@ -45,12 +45,14 @@ process PARSNP { """ stub: + def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" + def partition_cmd = args.contains("partition") ? "mkdir partition" : "" """ touch ${prefix}.xmfa touch ${prefix}.ggr touch ${prefix}.snps.mblocks touch ${prefix}.tree - mkdir partition + ${partition_cmd} """ } diff --git a/modules/nf-core/parsnp/tests/main.nf.test b/modules/nf-core/parsnp/tests/main.nf.test index 29e777c8e6d0..c375e927f4ab 100644 --- a/modules/nf-core/parsnp/tests/main.nf.test +++ b/modules/nf-core/parsnp/tests/main.nf.test @@ -10,7 +10,6 @@ nextflow_process { tag "parsnp" test("candidatus_portiera_aleyrodidarum - fasta") { - config './nextflow.config' when { params { module_args = '' @@ -34,7 +33,6 @@ nextflow_process { } test("candidatus_portiera_aleyrodidarum - fasta - stub") { - config './nextflow.config' options "-stub" when { @@ -61,7 +59,6 @@ nextflow_process { } test("candidatus_portiera_aleyrodidarum - fasta - partition") { - config './nextflow.config' when { params { module_args = '--min-partition-size 1' @@ -80,13 +77,13 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert process.out.partition }, { assert snapshot( process.out.xmfa, process.out.ggr, process.out.snps_mblocks, process.out.tree, - process.out.versions_parsnp + process.out.versions_parsnp, + file(process.out.partition[0][1]).name ).match() } ) } @@ -94,7 +91,6 @@ nextflow_process { } test("candidatus_portiera_aleyrodidarum - fasta - partition - stub") { - config './nextflow.config' options "-stub" when { diff --git a/modules/nf-core/parsnp/tests/main.nf.test.snap b/modules/nf-core/parsnp/tests/main.nf.test.snap index 8ad411c88f2f..d49047ea3206 100644 --- a/modules/nf-core/parsnp/tests/main.nf.test.snap +++ b/modules/nf-core/parsnp/tests/main.nf.test.snap @@ -10,16 +10,7 @@ "test.ggr:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "partition": [ - [ - { - "id": "test" - }, - [ - - ] - ] - ], + "partition": [], "snps_mblocks": [ [ { @@ -152,7 +143,8 @@ "parsnp", "2.1.5" ] - ] + ], + "partition" ], "meta": { "nf-test": "0.9.3",