diff --git a/CHANGELOG.md b/CHANGELOG.md index 1358d556..974abdf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#223](https://github.com/nf-core/seqinspector/pull/223) Workflow output for the rest of the pipeline - [#235](https://github.com/nf-core/seqinspector/pull/235) Update MultiQC and other dependencies - [#237](https://github.com/nf-core/seqinspector/pull/237) Improved citation system to dynamically build tool citations based on selected tools +- [#241](https://github.com/nf-core/seqinspector/pull/241) Remove vendored nf-core utils subworkflows, use plugin imports from nf-core-utils and nf-schema ### `Dependencies` diff --git a/modules.json b/modules.json index 49de1c2f..e74a82eb 100644 --- a/modules.json +++ b/modules.json @@ -146,25 +146,6 @@ "installed_by": ["modules"] } } - }, - "subworkflows": { - "nf-core": { - "utils_nextflow_pipeline": { - "branch": "master", - "git_sha": "1a545fcbd762911c21a64ced3dbef99b2b51ac75", - "installed_by": ["subworkflows"] - }, - "utils_nfcore_pipeline": { - "branch": "master", - "git_sha": "a3fb7351b1fdb2b1de282b765816bbea190e86a8", - "installed_by": ["subworkflows"] - }, - "utils_nfschema_plugin": { - "branch": "master", - "git_sha": "a7b27fd25bfa8dcc07d299e88bd790585901a436", - "installed_by": ["subworkflows"] - } - } } } } diff --git a/modules/nf-core/bwamem2/index/meta.yml b/modules/nf-core/bwamem2/index/meta.yml index 12074860..27e2354f 100644 --- a/modules/nf-core/bwamem2/index/meta.yml +++ b/modules/nf-core/bwamem2/index/meta.yml @@ -12,6 +12,12 @@ tools: a large reference genome, such as the human genome. homepage: https://github.com/bwa-mem2/bwa-mem2 documentation: https://github.com/bwa-mem2/bwa-mem2#usage + doi: "10.1109/IPDPS.2019.00041" + publication: + author: "Vasimuddin Md, Misra Sanchit, Li Heng & Aluru Srinivas" + year: 2018 + source: "IEEE International Parallel and Distributed Processing Symposium (IPDPS)" + title: "Efficient Architecture-Aware Acceleration of BWA-MEM for Multicore Systems" licence: - "MIT" identifier: "biotools:bwa-mem2" diff --git a/modules/nf-core/bwamem2/mem/meta.yml b/modules/nf-core/bwamem2/mem/meta.yml index a60d6788..8d052e2d 100644 --- a/modules/nf-core/bwamem2/mem/meta.yml +++ b/modules/nf-core/bwamem2/mem/meta.yml @@ -14,8 +14,13 @@ tools: BWA-mem2 is a software package for mapping DNA sequences against a large reference genome, such as the human genome. homepage: https://github.com/bwa-mem2/bwa-mem2 - documentation: http://www.htslib.org/doc/samtools.html - arxiv: arXiv:1303.3997 + documentation: https://github.com/bwa-mem2/bwa-mem2#usage + doi: "10.1109/IPDPS.2019.00041" + publication: + author: "Vasimuddin Md, Misra Sanchit, Li Heng & Aluru Srinivas" + year: 2018 + source: "IEEE International Parallel and Distributed Processing Symposium (IPDPS)" + title: "Efficient Architecture-Aware Acceleration of BWA-MEM for Multicore Systems" licence: - "MIT" identifier: "biotools:bwa-mem2" diff --git a/modules/nf-core/checkqc/meta.yml b/modules/nf-core/checkqc/meta.yml index d979c0d1..f791932b 100644 --- a/modules/nf-core/checkqc/meta.yml +++ b/modules/nf-core/checkqc/meta.yml @@ -12,6 +12,11 @@ tools: homepage: "https://github.com/Molmed/checkQC" documentation: "http://checkqc.readthedocs.io/en/latest/" doi: "10.21105/joss.00556" + publication: + author: "Åslin M., Brandt M. & Dahlberg J." + title: "CheckQC: Quick quality control of Illumina sequencing runs" + year: 2018 + source: "Journal of Open Source Software" licence: - "GPL v3" identifier: "" diff --git a/modules/nf-core/fastp/meta.yml b/modules/nf-core/fastp/meta.yml index a67be395..9e7ff588 100644 --- a/modules/nf-core/fastp/meta.yml +++ b/modules/nf-core/fastp/meta.yml @@ -10,6 +10,11 @@ tools: A tool designed to provide fast all-in-one preprocessing for FastQ files. This tool is developed in C++ with multithreading supported to afford high performance. documentation: https://github.com/OpenGene/fastp doi: 10.1093/bioinformatics/bty560 + publication: + author: "Chen S., Zhou Y., Chen Y. & Gu J." + title: "fastp: an ultra-fast all-in-one FASTQ preprocessor" + year: 2018 + source: "Bioinformatics" licence: ["MIT"] identifier: biotools:fastp input: diff --git a/modules/nf-core/fastqe/meta.yml b/modules/nf-core/fastqe/meta.yml index 52c9c759..8ecd8477 100644 --- a/modules/nf-core/fastqe/meta.yml +++ b/modules/nf-core/fastqe/meta.yml @@ -12,7 +12,12 @@ tools: homepage: "https://github.com/fastqe/fastqe" documentation: "https://github.com/fastqe/fastqe#readme" tool_dev_url: "https://github.com/fastqe/fastqe" - doi: "10.21105/joss.02400" + doi: "10.25334/Q4D172" + publication: + author: "StJacques R., Maza M., Robertson S., Lu G., Lonsdale A. & Enke R.A." + year: 2019 + source: "Journal of Open Source Education" + title: "A Fun Introductory Command Line Exercise: Next Generation Sequencing Quality Analysis with Emoji!" licence: - "MIT" identifier: "biotools:fastqe" diff --git a/modules/nf-core/kraken2/kraken2/meta.yml b/modules/nf-core/kraken2/kraken2/meta.yml index b60868de..66953d0d 100644 --- a/modules/nf-core/kraken2/kraken2/meta.yml +++ b/modules/nf-core/kraken2/kraken2/meta.yml @@ -12,6 +12,11 @@ tools: homepage: https://ccb.jhu.edu/software/kraken2/ documentation: https://github.com/DerrickWood/kraken2/wiki/Manual doi: 10.1186/s13059-019-1891-0 + publication: + author: "Wood Derrick E, Lu Jennifer & Langmead Ben" + title: "Improved metagenomic analysis with Kraken 2" + year: 2019 + source: "Genome Biology" licence: ["MIT"] identifier: biotools:kraken2 input: diff --git a/modules/nf-core/krona/ktimporttaxonomy/meta.yml b/modules/nf-core/krona/ktimporttaxonomy/meta.yml index ef86961f..4677ed06 100644 --- a/modules/nf-core/krona/ktimporttaxonomy/meta.yml +++ b/modules/nf-core/krona/ktimporttaxonomy/meta.yml @@ -15,6 +15,11 @@ tools: homepage: https://github.com/marbl/Krona/wiki/KronaTools documentation: http://manpages.ubuntu.com/manpages/impish/man1/ktImportTaxonomy.1.html doi: 10.1186/1471-2105-12-385 + publication: + author: "Ondov Brian D, Bergman Nicholas H & Phillippy Adam M" + year: 2011 + source: "BMC Bioinformatics" + title: "Interactive metagenomic visualization in a Web browser" identifier: biotools:krona input: - - meta: diff --git a/modules/nf-core/krona/ktupdatetaxonomy/meta.yml b/modules/nf-core/krona/ktupdatetaxonomy/meta.yml index b58ba6d6..2ce2b460 100644 --- a/modules/nf-core/krona/ktupdatetaxonomy/meta.yml +++ b/modules/nf-core/krona/ktupdatetaxonomy/meta.yml @@ -11,10 +11,14 @@ tools: Bioinformatics tools as well as from text and XML files. homepage: https://github.com/marbl/Krona/wiki/KronaTools documentation: https://github.com/marbl/Krona/wiki/Installing - doi: - 10.1186/1471-2105-12-385 - # There is no input. This module downloads a pre-built taxonomy database for use with Krona Tools. + doi: 10.1186/1471-2105-12-385 + publication: + author: "Ondov Brian D, Bergman Nicholas H & Phillippy Adam M" + year: 2011 + source: "BMC Bioinformatics" + title: "Interactive metagenomic visualization in a Web browser" identifier: biotools:krona + # There is no input. This module downloads a pre-built taxonomy database for use with Krona Tools. output: db: - taxonomy/taxonomy.tab: diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml index 27ce18d8..87d0b2c0 100644 --- a/modules/nf-core/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -10,8 +10,14 @@ tools: description: | MultiQC searches a given directory for analysis logs and compiles a HTML report. It's a general use tool, perfect for summarising the output from numerous bioinformatics tools. - homepage: https://multiqc.info/ - documentation: https://multiqc.info/docs/ + homepage: https://seqera.io/multiqc/ + documentation: https://docs.seqera.io/multiqc/ + doi: "10.1093/bioinformatics/btw354" + publication: + author: "Ewels P., Magnusson M., Lundin S. & Käller M." + year: 2016 + source: "Bioinformatics" + title: "MultiQC: summarize analysis results for multiple tools and samples in a single report" licence: - "GPL-3.0-or-later" identifier: biotools:multiqc diff --git a/modules/nf-core/multiqcsav/meta.yml b/modules/nf-core/multiqcsav/meta.yml index 7c3130ad..f84f0bd3 100644 --- a/modules/nf-core/multiqcsav/meta.yml +++ b/modules/nf-core/multiqcsav/meta.yml @@ -13,8 +13,8 @@ tools: description: | MultiQC searches a given directory for analysis logs and compiles a HTML report. It's a general use tool, perfect for summarising the output from numerous bioinformatics tools. - homepage: https://multiqc.info/ - documentation: https://multiqc.info/docs/ + homepage: https://github.com/MultiQC/MultiQC_SAV + documentation: https://docs.seqera.io/multiqc/ licence: - "GPL-3.0-or-later" identifier: biotools:multiqc diff --git a/modules/nf-core/samtools/faidx/meta.yml b/modules/nf-core/samtools/faidx/meta.yml index 529f7a26..fb199d79 100644 --- a/modules/nf-core/samtools/faidx/meta.yml +++ b/modules/nf-core/samtools/faidx/meta.yml @@ -15,6 +15,11 @@ tools: homepage: http://www.htslib.org/ documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 + publication: + author: "Li Heng, Handsaker Bob, Wysoker Alec, Fennell Tim, Ruan Jue, Homer Nils, Marth Gabor, Abecasis Goncalo, Durbin Richard, 1000 Genome Project Data Processing Subgroup" + year: 2009 + source: "Bioinformatics" + title: "The Sequence Alignment/Map format and SAMtools" licence: - "MIT" identifier: biotools:samtools diff --git a/modules/nf-core/samtools/index/meta.yml b/modules/nf-core/samtools/index/meta.yml index d4938bcd..56b9972c 100644 --- a/modules/nf-core/samtools/index/meta.yml +++ b/modules/nf-core/samtools/index/meta.yml @@ -14,6 +14,11 @@ tools: homepage: http://www.htslib.org/ documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 + publication: + author: "Li Heng, Handsaker Bob, Wysoker Alec, Fennell Tim, Ruan Jue, Homer Nils, Marth Gabor, Abecasis Goncalo, Durbin Richard, 1000 Genome Project Data Processing Subgroup" + year: 2009 + source: "Bioinformatics" + title: "The Sequence Alignment/Map format and SAMtools" licence: - "MIT" identifier: biotools:samtools diff --git a/modules/nf-core/seqfu/stats/meta.yml b/modules/nf-core/seqfu/stats/meta.yml index 856e6f79..e195a5c6 100644 --- a/modules/nf-core/seqfu/stats/meta.yml +++ b/modules/nf-core/seqfu/stats/meta.yml @@ -12,6 +12,11 @@ tools: documentation: "https://telatin.github.io/seqfu2/" tool_dev_url: "https://github.com/telatin/seqfu2" doi: "10.3390/bioengineering8050059" + publication: + author: "Telatin Andrea, Fariselli Piero & Birolo Giovanni" + year: 2021 + source: "Bioengineering" + title: "SeqFu: A Suite of Utilities for the Robust and Reproducible Manipulation of Sequence Files" licence: - "GPL v3" identifier: biotools:seqfu diff --git a/modules/nf-core/seqkit/stats/meta.yml b/modules/nf-core/seqkit/stats/meta.yml index 3143449e..601b5ebd 100644 --- a/modules/nf-core/seqkit/stats/meta.yml +++ b/modules/nf-core/seqkit/stats/meta.yml @@ -12,6 +12,11 @@ tools: documentation: https://bioinf.shenwei.me/seqkit/usage/ tool_dev_url: https://github.com/shenwei356/seqkit/ doi: "10.1371/journal.pone.0163962" + publication: + author: "Shen Wei, Le Shuai, Li Yan& Hu Fuquan" + year: 2016 + source: "PLOS ONE" + title: "SeqKit: A Cross-Platform and Ultrafast Toolkit for FASTA/Q File Manipulation" licence: ["MIT"] identifier: biotools:seqkit input: diff --git a/modules/nf-core/sequali/meta.yml b/modules/nf-core/sequali/meta.yml index 8c4dcf4f..3cdd47cd 100644 --- a/modules/nf-core/sequali/meta.yml +++ b/modules/nf-core/sequali/meta.yml @@ -10,7 +10,12 @@ tools: homepage: "https://github.com/rhpvorderman/sequali" documentation: "https://sequali.readthedocs.io/en/latest/" tool_dev_url: "https://github.com/rhpvorderman/sequali" - doi: "10.5281/zenodo.10854010" + doi: "10.1093/bioadv/vbaf010" + publication: + author: "Vorderman Ruben HP" + year: 2025 + source: "Bioinformatics Advances" + title: "Sequali: efficient and comprehensive quality control of short- and long-read sequencing data" licence: - "AGPL v3-or-later" identifier: biotools:sequali diff --git a/nextflow.config b/nextflow.config index ef269b00..f57f5438 100644 --- a/nextflow.config +++ b/nextflow.config @@ -456,7 +456,7 @@ manifest { // Nextflow plugins plugins { - id 'nf-core-utils@0.4.0' // nf-core-utils is a collection of utilities for Nextflow pipelines + id 'nf-core-utils@0.6.0' // nf-core-utils is a collection of utilities for Nextflow pipelines id 'nf-schema@2.6.1' // Validation of pipeline parameters and creation of an input channel from a sample sheet } diff --git a/nf-test.config b/nf-test.config index 443f01ce..c19e6f25 100644 --- a/nf-test.config +++ b/nf-test.config @@ -34,6 +34,6 @@ config { // load the necessary plugins plugins { load "nft-bam@0.4.0" - load "nft-utils@0.0.9" + load "nft-utils@1.0.0" } } diff --git a/subworkflows/local/utils_nfcore_seqinspector_pipeline/main.nf b/subworkflows/local/utils_nfcore_seqinspector_pipeline/main.nf index 151b1982..565e355f 100644 --- a/subworkflows/local/utils_nfcore_seqinspector_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_seqinspector_pipeline/main.nf @@ -8,14 +8,18 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' -include { paramsSummaryMap } from 'plugin/nf-schema' -include { samplesheetToList } from 'plugin/nf-schema' -include { paramsHelp } from 'plugin/nf-schema' -include { completionEmail } from '../../nf-core/utils_nfcore_pipeline' -include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' -include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' -include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +include { checkCondaChannels } from 'plugin/nf-core-utils' +include { checkConfigProvided } from 'plugin/nf-core-utils' +include { checkProfileProvided } from 'plugin/nf-core-utils' +include { completionEmail } from 'plugin/nf-core-utils' +include { completionSummary } from 'plugin/nf-core-utils' +include { dumpParametersToJSON } from 'plugin/nf-core-utils' +include { getWorkflowVersion } from 'plugin/nf-core-utils' +include { paramsHelp } from 'plugin/nf-schema' +include { paramsSummaryLog } from 'plugin/nf-schema' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { validateParameters } from 'plugin/nf-schema' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -45,12 +49,16 @@ workflow PIPELINE_INITIALISATION { // // Print version and exit if required and dump pipeline parameters to JSON file // - UTILS_NEXTFLOW_PIPELINE( - version, - true, - outdir, - workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1, - ) + if (version) { + log.info("${workflow.manifest.name} ${getWorkflowVersion()}") + System.exit(0) + } + if (outdir) { + dumpParametersToJSON(outdir, params) + } + if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { + checkCondaChannels() + } // // Validate parameters and generate parameter summary to stdout @@ -80,20 +88,31 @@ workflow PIPELINE_INITIALISATION { before_text = before_text.replaceAll(/\033\[[0-9;]*m/, '') } - command = "nextflow run ${workflow.manifest.name} -profile --input samplesheet.csv --outdir " - - UTILS_NFSCHEMA_PLUGIN( - workflow, - validate_params, - null, - help, - help_full, - show_hidden, - before_text, - after_text, - command, - null, - ) + def command = "nextflow run ${workflow.manifest.name} -profile --input samplesheet.csv --outdir " + + if (help || help_full) { + log.info( + paramsHelp( + [ + beforeText: before_text, + afterText: after_text, + command: command, + showHidden: show_hidden, + fullHelp: help_full, + ], + (help instanceof String && help != "true") ? help : "", + ) + ) + System.exit(0) + } + + log.info(before_text) + log.info(paramsSummaryLog(workflow, parameters_schema: "nextflow_schema.json")) + log.info(after_text) + + if (validate_params) { + validateParameters(parameters_schema: "nextflow_schema.json") + } extra_text = """ \033[1;37mExtra informations\033[0m @@ -110,7 +129,8 @@ workflow PIPELINE_INITIALISATION { // // Check config provided to the pipeline // - UTILS_NFCORE_PIPELINE(nextflow_cli_args) + checkConfigProvided() + checkProfileProvided(nextflow_cli_args, monochrome_logs) // // Custom validation for pipeline parameters @@ -260,90 +280,6 @@ def genomeExistsError() { // Generate methods description for MultiQC // -def toolReferencesMap() { - return [ - 'bbmap': ['name': 'BBMap', 'authors': 'Bushnell B. (2014).', 'authors_short': 'Bushnell 2014', 'description': 'BBMap: A Fast, Accurate, Splice-Aware Aligner.', 'url': 'https://bbmap.org/'], - 'bwamem2': ['name': 'BWAMEM2', 'authors': 'Vasimuddin Md., Misra S., Li H, & Aluru S. (2019).', 'authors_short': 'Vasimuddin et al. 2019', 'description': 'Efficient Architecture-Aware Acceleration of BWA-MEM for Multicore Systems.', 'doi': '10.1109/IPDPS.2019.00041'], - 'checkqc': ['name': 'checkQC', 'authors': 'Åslin et al., (2018).', 'authors_short': 'Åslin et al. 2018', 'description': 'CheckQC: Quick quality control of Illumina sequencing runs. Journal of Open Source Software, 3(22), 556.', 'doi': '10.21105/joss.00556'], - 'fastp': ['name': 'Fastp', 'authors': 'Chen S., Zhou Y., Chen Y., & Gu J. (2018).', 'authors_short': 'Chen et al. 2018', 'description': 'fastp: an ultra-fast all-in-one FASTQ preprocessor. Bioinformatics, 34(17), i884-i890.', 'doi': '10.1093/bioinformatics/bty560'], - 'fastqc': ['name': 'FastQC', 'authors': '', 'authors_short': '', 'description': 'Quality control application for high throughput sequence data.', 'url': 'https://www.bioinformatics.babraham.ac.uk/projects/fastqc/'], - 'fastqe': ['name': 'FASTQE', 'authors': '', 'authors_short': '', 'description': 'FASTQ sequence quality visualisation with Emoji.', 'url': 'https://github.com/fastqe/fastqe'], - 'fastqscreen': ['name': 'FastQ Screen', 'authors': 'Wingett SW., & Andrews S. (2018).', 'authors_short': 'Wingett & Andrews 2018', 'description': 'FastQ Screen: A tool for multi-genome mapping and quality control. F1000Res. 2018 Aug 24 [revised 2018 Jan 1];7:1338.', 'doi': '10.12688/f1000research.15931.2'], - 'fq': ['name': 'FQ', 'authors': '', 'authors_short': '', 'description': 'A library to generate and validate FASTQ file pairs.', 'url': 'https://github.com/stjude-rust-labs/fq'], - 'kraken2': ['name': 'Kraken2', 'authors': 'Wood D.E., Lu J., & Langmead B. (2019).', 'authors_short': 'Wood et al. 2019', 'description': 'Improved metagenomic analysis with Kraken 2. Genome Biology, 20(1), 257.', 'doi': '10.1186/s13059-019-1891-0'], - 'krona': ['name': 'Krona', 'authors': 'Ondov BD, Bergman NH, & Phillippy AM. (2011).', 'authors_short': 'Ondov et al. 2011', 'description': 'Interactive metagenomic visualization in a Web browser. BMC Bioinformatics, 12, 385.', 'doi': '10.1186/1471-2105-12-385'], - 'multiqc': ['name': 'MultiQC', 'authors': 'Ewels P., Magnusson M., Lundin S., & Käller M. (2016).', 'authors_short': 'Ewels et al. 2016', 'description': 'MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics, 32(19), 3047–3048.', 'doi': '10.1093/bioinformatics/btw354'], - 'multiqcsav': ['name': 'MultiQC SAV', 'authors': '', 'authors_short': '', 'description': 'MultiQC plugin for Illumina Sequencing Analysis Viewer.', 'url': 'https://github.com/MultiQC/MultiQC_SAV/'], - 'picard': ['name': 'Picard', 'authors': '', 'authors_short': '', 'description': 'Command line tools for manipulating high-throughput sequencing (HTS) data.', 'url': 'https://broadinstitute.github.io/picard/'], - 'pigz': ['name': 'pigz', 'authors': 'Adler M.', 'authors_short': 'Adler 2005', 'description': 'Parallel implementation of gzip.', 'url': 'https://zlib.net/pigz/'], - 'python': ['name': 'Python', 'authors': '', 'authors_short': '', 'description': 'Programming language.', 'url': 'https://www.python.org/'], - 'pyyaml': ['name': 'PyYAML', 'authors': '', 'authors_short': '', 'description': 'YAML parser and emitter for Python.', 'url': 'https://pyyaml.org/'], - 'rundirparser': ['name': 'Rundirparser', 'authors': '', 'authors_short': '', 'description': 'Parse Illumina run directory metadata for MultiQC.', 'url': 'https://github.com/nf-core/seqinspector'], - 'samtools': ['name': 'SAMTOOLS', 'authors': 'Danecek P., Bonfield JK., Liddle J., & al. (2021).', 'authors_short': 'Danecek et al. 2021', 'description': 'Twelve years of SAMtools and BCFtools.', 'doi': '10.1093/gigascience/giab008'], - 'seqfu': ['name': 'SeqFu', 'authors': 'Telatin A., Fariselli P., & Birolo G. (2021).', 'authors_short': 'Telatin et al. 2021', 'description': 'SeqFu: A Suite of Utilities for the Robust and Reproducible Manipulation of Sequence Files. Bioengineering, 8, 59.', 'doi': '10.3390/bioengineering8050059'], - 'seqkit': ['name': 'SeqKit', 'authors': 'Shen W., Sipos B., & Zhao L. (2024).', 'authors_short': 'Shen et al. 2024', 'description': 'SeqKit2: A Swiss Army Knife for Sequence and Alignment Processing. iMeta, e191.', 'doi': '10.1002/imt2.191'], - 'seqtk': ['name': 'Seqtk', 'authors': 'Li H.', 'authors_short': 'Li 2013', 'description': 'Toolkit for processing FASTA and FASTQ files.', 'url': 'https://github.com/lh3/seqtk'], - 'sequali': ['name': 'Sequali', 'authors': 'Vorderman R. (2025).', 'authors_short': 'Vorderman 2025', 'description': 'Sequali: efficient and comprehensive quality control of short- and long-read sequencing data. Bioinformatics Advances.', 'doi': '10.1093/bioadv/vbaf010'], - 'toulligqc': ['name': 'ToulligQC', 'authors': '', 'authors_short': '', 'description': 'Post sequencing QC tool for Oxford Nanopore sequencers.', 'url': 'https://github.com/GenomiqueENS/toulligQC'], - 'untar': ['name': 'untar', 'authors': '', 'authors_short': '', 'description': 'GNU tar archive utility.', 'url': 'https://www.gnu.org/software/tar/'], - ] -} - -def toolReferencesText(type, tools) { - def references = [] - def map = toolReferencesMap() - - tools.each { tool -> - if (tool in map) { - def entry = map[tool] - if (type == 'citation') { - references << "${entry.name} (${entry.doi ? "${entry.authors_short}" : "${entry.url}"})" - } - else { - def link = entry.doi ? "doi: ${entry.doi}" : "url: ${entry.url}" - references << "${entry.authors ?: entry.name + ':'} ${entry.description} ${link}".trim() - } - } - } - - return references.sort() -} - -def methodsDescriptionText(mqc_methods_yaml, tool_list) { - // Convert to a named map so can be used as with familiar NXF ${workflow} variable syntax in the MultiQC YML file - def meta = [:] - meta.workflow = workflow.toMap() - meta["manifest_map"] = workflow.manifest.toMap() - - // Pipeline DOI - if (meta.manifest_map.doi) { - // Using a loop to handle multiple DOIs - // Removing `https://doi.org/` to handle pipelines using DOIs vs DOI resolvers - // Removing ` ` since the manifest.doi is a string and not a proper list - def temp_doi_ref = "" - def manifest_doi = meta.manifest_map.doi.tokenize(",") - manifest_doi.each { doi_ref -> - temp_doi_ref += "( ${doi_ref.replace("https://doi.org/", "").replace(" ", "")}), " - } - meta["doi_text"] = temp_doi_ref.substring(0, temp_doi_ref.length() - 2) - } - else { - meta["doi_text"] = "" - } - meta["nodoi_text"] = meta.manifest_map.doi ? "" : "
  • If available, make sure to update the text to include the Zenodo DOI of version of the pipeline used.
  • " - - // Tool references - dynamically built from tools list - meta["tool_citations"] = 'Tools used in the workflow included: ' + toolReferencesText('citation', tool_list).join(', ') + '.' - meta["tool_bibliography"] = toolReferencesText('bibliography', tool_list).collect { bibliography -> "
  • ${bibliography}
  • " }.join('\n ') - - def methods_text = mqc_methods_yaml.text - - def engine = new groovy.text.SimpleTemplateEngine() - def description_html = engine.createTemplate(methods_text).make(meta) - - return description_html.toString() -} - def defineToolsList(input_bundle, input_tools, input_skip, sample_size) { // Any tools in skip_tools will override any selection made via tools or tools_bundle diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf deleted file mode 100644 index 37939acd..00000000 --- a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf +++ /dev/null @@ -1,138 +0,0 @@ -// -// Subworkflow with functionality that may be useful for any Nextflow pipeline -// - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - SUBWORKFLOW DEFINITION -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -workflow UTILS_NEXTFLOW_PIPELINE { - take: - print_version // boolean: print version - dump_parameters // boolean: dump parameters - outdir // path: base directory used to publish pipeline results - check_conda_channels // boolean: check conda channels - - main: - - // - // Print workflow version and exit on --version - // - if (print_version) { - log.info("${workflow.manifest.name} ${getWorkflowVersion()}") - System.exit(0) - } - - // - // Dump pipeline parameters to a JSON file - // - if (dump_parameters && outdir) { - dumpParametersToJSON(outdir) - } - - // - // When running with Conda, warn if channels have not been set-up appropriately - // - if (check_conda_channels) { - checkCondaChannels() - } - - emit: - dummy_emit = true -} - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - FUNCTIONS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -// -// Generate version string -// -def getWorkflowVersion() { - def version_string = "" as String - if (workflow.manifest.version) { - def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : '' - version_string += "${prefix_v}${workflow.manifest.version}" - } - - if (workflow.commitId) { - def git_shortsha = workflow.commitId.substring(0, 7) - version_string += "-g${git_shortsha}" - } - - return version_string -} - -// -// Dump pipeline parameters to a JSON file -// -def dumpParametersToJSON(outdir) { - def timestamp = new java.util.Date().format('yyyy-MM-dd_HH-mm-ss') - def filename = "params_${timestamp}.json" - def temp_pf = workflow.launchDir.resolve(".${filename}") - def jsonGenerator = new groovy.json.JsonGenerator.Options() - .excludeNulls() - .addConverter(Path) { Path path -> path.toUriString() } - .addConverter(Duration) { Duration duration -> duration.toMillis() } - .addConverter(MemoryUnit) { MemoryUnit memory -> memory.toBytes() } - .addConverter(nextflow.script.types.VersionNumber) { nextflow.script.types.VersionNumber version -> version.toString() } - .build() - def jsonStr = jsonGenerator.toJson(params) - temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr) - if (outdir instanceof Path) { - temp_pf.copyTo(outdir.resolve("pipeline_info/${filename}")) - } else if (outdir instanceof String) { - temp_pf.copyTo("${outdir}/pipeline_info/params_${timestamp}.json") - } else { - log.warn("Could not determine type of outdir, parameters JSON file will not be copied to output directory!") - } - temp_pf.delete() -} - -// -// When running with -profile conda, warn if channels have not been set-up appropriately -// -def checkCondaChannels() { - def parser = new org.yaml.snakeyaml.Yaml() - def channels = [] - try { - def config = parser.load("conda config --show channels".execute().text) - channels = config.channels - } - catch (NullPointerException e) { - log.debug(e) - log.warn("Could not verify conda channel configuration.") - return null - } - catch (IOException e) { - log.debug(e) - log.warn("Could not verify conda channel configuration.") - return null - } - - // Check that all channels are present - // This channel list is ordered by required channel priority. - def required_channels_in_order = ['conda-forge', 'bioconda'] - def channels_missing = ((required_channels_in_order as Set) - (channels as Set)) as Boolean - - // Check that they are in the right order - def channel_priority_violation = required_channels_in_order != channels.findAll { ch -> ch in required_channels_in_order } - - if (channels_missing | channel_priority_violation) { - log.warn """\ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - There is a problem with your Conda configuration! - You will need to set-up the conda-forge and bioconda channels correctly. - Please refer to https://bioconda.github.io/ - The observed channel order is - ${channels} - but the following channel order is required: - ${required_channels_in_order} - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - """.stripIndent(true) - } -} diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/meta.yml b/subworkflows/nf-core/utils_nextflow_pipeline/meta.yml deleted file mode 100644 index e5c3a0a8..00000000 --- a/subworkflows/nf-core/utils_nextflow_pipeline/meta.yml +++ /dev/null @@ -1,38 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json -name: "UTILS_NEXTFLOW_PIPELINE" -description: Subworkflow with functionality that may be useful for any Nextflow pipeline -keywords: - - utility - - pipeline - - initialise - - version -components: [] -input: - - print_version: - type: boolean - description: | - Print the version of the pipeline and exit - - dump_parameters: - type: boolean - description: | - Dump the parameters of the pipeline to a JSON file - - output_directory: - type: directory - description: Path to output dir to write JSON file to. - pattern: "results/" - - check_conda_channel: - type: boolean - description: | - Check if the conda channel priority is correct. -output: - - dummy_emit: - type: boolean - description: | - Dummy emit to make nf-core subworkflows lint happy -authors: - - "@adamrtalbot" - - "@drpatelh" -maintainers: - - "@adamrtalbot" - - "@drpatelh" - - "@maxulysse" diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf deleted file mode 100644 index afca5439..00000000 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ /dev/null @@ -1,355 +0,0 @@ -// -// Subworkflow with utility functions specific to the nf-core pipeline template -// - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - SUBWORKFLOW DEFINITION -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -workflow UTILS_NFCORE_PIPELINE { - take: - nextflow_cli_args - - main: - valid_config = checkConfigProvided() - checkProfileProvided(nextflow_cli_args) - - emit: - valid_config = valid_config -} - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - FUNCTIONS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -// -// Warn if a -profile or Nextflow config has not been provided to run the pipeline -// -def checkConfigProvided() { - def valid_config = true as Boolean - if (workflow.profile == 'standard' && workflow.configFiles.size() <= 1) { - log.warn( - "[${workflow.manifest.name}] You are attempting to run the pipeline without any custom configuration!\n\n" + "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + " (1) Using an existing pipeline profile e.g. `-profile docker` or `-profile singularity`\n" + " (2) Using an existing nf-core/configs for your Institution e.g. `-profile crick` or `-profile uppmax`\n" + " (3) Using your own local custom config e.g. `-c /path/to/your/custom.config`\n\n" + "Please refer to the quick start section and usage docs for the pipeline.\n " - ) - valid_config = false - } - return valid_config -} - -// -// Exit pipeline if --profile contains spaces -// -def checkProfileProvided(nextflow_cli_args) { - if (workflow.profile.endsWith(',')) { - error( - "The `-profile` option cannot end with a trailing comma, please remove it and re-run the pipeline!\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" - ) - } - if (nextflow_cli_args[0]) { - log.warn( - "nf-core pipelines do not accept positional arguments. The positional argument `${nextflow_cli_args[0]}` has been detected.\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" - ) - } -} - -// -// Generate workflow version string -// -def getWorkflowVersion() { - def version_string = "" as String - if (workflow.manifest.version) { - def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : '' - version_string += "${prefix_v}${workflow.manifest.version}" - } - - if (workflow.commitId) { - def git_shortsha = workflow.commitId.substring(0, 7) - version_string += "-g${git_shortsha}" - } - - return version_string -} - -// -// Get software versions for pipeline -// -def processVersionsFromYAML(yaml_file) { - def yaml = new org.yaml.snakeyaml.Yaml() - def versions = yaml.load(yaml_file).collectEntries { k, v -> [k.tokenize(':')[-1], v] } - return yaml.dumpAsMap(versions).trim() -} - -// -// Get workflow version for pipeline -// -def workflowVersionToYAML() { - return """ - Workflow: - ${workflow.manifest.name}: ${getWorkflowVersion()} - Nextflow: ${workflow.nextflow.version} - """.stripIndent().trim() -} - -// -// Get channel of software versions used in pipeline in YAML format -// -def softwareVersionsToYAML(ch_versions) { - return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(channel.of(workflowVersionToYAML())) -} - -// -// Get workflow summary for MultiQC -// -def paramsSummaryMultiqc(summary_params) { - def summary_section = '' - summary_params - .keySet() - .each { group -> - def group_params = summary_params.get(group) - // This gets the parameters of that particular group - if (group_params) { - summary_section += "

    ${group}

    \n" - summary_section += "
    \n" - group_params - .keySet() - .sort() - .each { param -> - summary_section += "
    ${param}
    ${group_params.get(param) ?: 'N/A'}
    \n" - } - summary_section += "
    \n" - } - } - - def yaml_file_text = "id: '${workflow.manifest.name.replace('/', '-')}-summary'\n" as String - yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" - yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" - yaml_file_text += "section_href: 'https://github.com/${workflow.manifest.name}'\n" - yaml_file_text += "plot_type: 'html'\n" - yaml_file_text += "data: |\n" - yaml_file_text += "${summary_section}" - - return yaml_file_text -} - -// -// ANSII colours used for terminal logging -// -def logColours(monochrome_logs=true) { - def colorcodes = [:] as Map - - // Reset / Meta - colorcodes['reset'] = monochrome_logs ? '' : "\033[0m" - colorcodes['bold'] = monochrome_logs ? '' : "\033[1m" - colorcodes['dim'] = monochrome_logs ? '' : "\033[2m" - colorcodes['underlined'] = monochrome_logs ? '' : "\033[4m" - colorcodes['blink'] = monochrome_logs ? '' : "\033[5m" - colorcodes['reverse'] = monochrome_logs ? '' : "\033[7m" - colorcodes['hidden'] = monochrome_logs ? '' : "\033[8m" - - // Regular Colors - colorcodes['black'] = monochrome_logs ? '' : "\033[0;30m" - colorcodes['red'] = monochrome_logs ? '' : "\033[0;31m" - colorcodes['green'] = monochrome_logs ? '' : "\033[0;32m" - colorcodes['yellow'] = monochrome_logs ? '' : "\033[0;33m" - colorcodes['blue'] = monochrome_logs ? '' : "\033[0;34m" - colorcodes['purple'] = monochrome_logs ? '' : "\033[0;35m" - colorcodes['cyan'] = monochrome_logs ? '' : "\033[0;36m" - colorcodes['white'] = monochrome_logs ? '' : "\033[0;37m" - - // Bold - colorcodes['bblack'] = monochrome_logs ? '' : "\033[1;30m" - colorcodes['bred'] = monochrome_logs ? '' : "\033[1;31m" - colorcodes['bgreen'] = monochrome_logs ? '' : "\033[1;32m" - colorcodes['byellow'] = monochrome_logs ? '' : "\033[1;33m" - colorcodes['bblue'] = monochrome_logs ? '' : "\033[1;34m" - colorcodes['bpurple'] = monochrome_logs ? '' : "\033[1;35m" - colorcodes['bcyan'] = monochrome_logs ? '' : "\033[1;36m" - colorcodes['bwhite'] = monochrome_logs ? '' : "\033[1;37m" - - // Underline - colorcodes['ublack'] = monochrome_logs ? '' : "\033[4;30m" - colorcodes['ured'] = monochrome_logs ? '' : "\033[4;31m" - colorcodes['ugreen'] = monochrome_logs ? '' : "\033[4;32m" - colorcodes['uyellow'] = monochrome_logs ? '' : "\033[4;33m" - colorcodes['ublue'] = monochrome_logs ? '' : "\033[4;34m" - colorcodes['upurple'] = monochrome_logs ? '' : "\033[4;35m" - colorcodes['ucyan'] = monochrome_logs ? '' : "\033[4;36m" - colorcodes['uwhite'] = monochrome_logs ? '' : "\033[4;37m" - - // High Intensity - colorcodes['iblack'] = monochrome_logs ? '' : "\033[0;90m" - colorcodes['ired'] = monochrome_logs ? '' : "\033[0;91m" - colorcodes['igreen'] = monochrome_logs ? '' : "\033[0;92m" - colorcodes['iyellow'] = monochrome_logs ? '' : "\033[0;93m" - colorcodes['iblue'] = monochrome_logs ? '' : "\033[0;94m" - colorcodes['ipurple'] = monochrome_logs ? '' : "\033[0;95m" - colorcodes['icyan'] = monochrome_logs ? '' : "\033[0;96m" - colorcodes['iwhite'] = monochrome_logs ? '' : "\033[0;97m" - - // Bold High Intensity - colorcodes['biblack'] = monochrome_logs ? '' : "\033[1;90m" - colorcodes['bired'] = monochrome_logs ? '' : "\033[1;91m" - colorcodes['bigreen'] = monochrome_logs ? '' : "\033[1;92m" - colorcodes['biyellow'] = monochrome_logs ? '' : "\033[1;93m" - colorcodes['biblue'] = monochrome_logs ? '' : "\033[1;94m" - colorcodes['bipurple'] = monochrome_logs ? '' : "\033[1;95m" - colorcodes['bicyan'] = monochrome_logs ? '' : "\033[1;96m" - colorcodes['biwhite'] = monochrome_logs ? '' : "\033[1;97m" - - return colorcodes -} - -// Return a single report from an object that may be a Path or List -// -def getSingleReport(multiqc_reports) { - if (multiqc_reports instanceof Path) { - return multiqc_reports - } else if (multiqc_reports instanceof List) { - if (multiqc_reports.size() == 0) { - log.warn("[${workflow.manifest.name}] No reports found from process 'MULTIQC'") - return null - } else if (multiqc_reports.size() == 1) { - return multiqc_reports.first() - } else { - log.warn("[${workflow.manifest.name}] Found multiple reports from process 'MULTIQC', will use only one") - return multiqc_reports.first() - } - } else { - return null - } -} - -// -// Construct and send completion email -// -def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdir, monochrome_logs=true, multiqc_report=null) { - - // Set up the e-mail variables - def subject = "[${workflow.manifest.name}] Successful: ${workflow.runName}" - if (!workflow.success) { - subject = "[${workflow.manifest.name}] FAILED: ${workflow.runName}" - } - - def summary = [:] - summary_params - .keySet() - .sort() - .each { group -> - summary << summary_params[group] - } - - def misc_fields = [:] - misc_fields['Date Started'] = workflow.start - misc_fields['Date Completed'] = workflow.complete - misc_fields['Pipeline script file path'] = workflow.scriptFile - misc_fields['Pipeline script hash ID'] = workflow.scriptId - if (workflow.repository) { - misc_fields['Pipeline repository Git URL'] = workflow.repository - } - if (workflow.commitId) { - misc_fields['Pipeline repository Git Commit'] = workflow.commitId - } - if (workflow.revision) { - misc_fields['Pipeline Git branch/tag'] = workflow.revision - } - misc_fields['Nextflow Version'] = workflow.nextflow.version - misc_fields['Nextflow Build'] = workflow.nextflow.build - misc_fields['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp - - def email_fields = [:] - email_fields['version'] = getWorkflowVersion() - email_fields['runName'] = workflow.runName - email_fields['success'] = workflow.success - email_fields['dateComplete'] = workflow.complete - email_fields['duration'] = workflow.duration - email_fields['exitStatus'] = workflow.exitStatus - email_fields['errorMessage'] = (workflow.errorMessage ?: 'None') - email_fields['errorReport'] = (workflow.errorReport ?: 'None') - email_fields['commandLine'] = workflow.commandLine - email_fields['projectDir'] = workflow.projectDir - email_fields['summary'] = summary << misc_fields - - // On success try attach the multiqc report - def mqc_report = getSingleReport(multiqc_report) - - // Check if we are only sending emails on failure - def email_address = email - if (!email && email_on_fail && !workflow.success) { - email_address = email_on_fail - } - - // Render the TXT template - def engine = new groovy.text.GStringTemplateEngine() - def tf = new File("${workflow.projectDir}/assets/email_template.txt") - def txt_template = engine.createTemplate(tf).make(email_fields) - def email_txt = txt_template.toString() - - // Render the HTML template - def hf = new File("${workflow.projectDir}/assets/email_template.html") - def html_template = engine.createTemplate(hf).make(email_fields) - def email_html = html_template.toString() - - // Render the sendmail template - def max_multiqc_email_size = (params.containsKey('max_multiqc_email_size') ? params.max_multiqc_email_size : 0) as MemoryUnit - def smail_fields = [email: email_address, subject: subject, email_txt: email_txt, email_html: email_html, projectDir: "${workflow.projectDir}", mqcFile: mqc_report, mqcMaxSize: max_multiqc_email_size.toBytes()] - def sf = new File("${workflow.projectDir}/assets/sendmail_template.txt") - def sendmail_template = engine.createTemplate(sf).make(smail_fields) - def sendmail_html = sendmail_template.toString() - - // Send the HTML e-mail - def colors = logColours(monochrome_logs) as Map - if (email_address) { - try { - if (plaintext_email) { - new org.codehaus.groovy.GroovyException('Send plaintext e-mail, not HTML') - } - // Try to send HTML e-mail using sendmail - def sendmail_tf = new File(workflow.launchDir.toString(), ".sendmail_tmp.html") - sendmail_tf.withWriter { w -> w << sendmail_html } - ['sendmail', '-t'].execute() << sendmail_html - log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (sendmail)-") - } - catch (Exception msg) { - log.debug(msg.toString()) - log.debug("Trying with mail instead of sendmail") - // Catch failures and try with plaintext - def mail_cmd = ['mail', '-s', subject, '--content-type=text/html', email_address] - mail_cmd.execute() << email_html - log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (mail)-") - } - } - - // Write summary e-mail HTML to a file - def output_hf = new File(workflow.launchDir.toString(), ".pipeline_report.html") - output_hf.withWriter { w -> w << email_html } - nextflow.extension.FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html") - output_hf.delete() - - // Write summary e-mail TXT to a file - def output_tf = new File(workflow.launchDir.toString(), ".pipeline_report.txt") - output_tf.withWriter { w -> w << email_txt } - nextflow.extension.FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt") - output_tf.delete() -} - -// -// Print pipeline summary on completion -// -def completionSummary(monochrome_logs=true) { - def colors = logColours(monochrome_logs) as Map - if (workflow.success) { - if (workflow.stats.ignoredCount == 0) { - log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Pipeline completed successfully${colors.reset}-") - } - else { - log.info("-${colors.purple}[${workflow.manifest.name}]${colors.yellow} Pipeline completed successfully, but with errored process(es) ${colors.reset}-") - } - } - else { - log.info("-${colors.purple}[${workflow.manifest.name}]${colors.red} Pipeline completed with errors${colors.reset}-") - } -} diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/meta.yml b/subworkflows/nf-core/utils_nfcore_pipeline/meta.yml deleted file mode 100644 index d08d2434..00000000 --- a/subworkflows/nf-core/utils_nfcore_pipeline/meta.yml +++ /dev/null @@ -1,24 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json -name: "UTILS_NFCORE_PIPELINE" -description: Subworkflow with utility functions specific to the nf-core pipeline template -keywords: - - utility - - pipeline - - initialise - - version -components: [] -input: - - nextflow_cli_args: - type: list - description: | - Nextflow CLI positional arguments -output: - - success: - type: boolean - description: | - Dummy output to indicate success -authors: - - "@adamrtalbot" -maintainers: - - "@adamrtalbot" - - "@maxulysse" diff --git a/subworkflows/nf-core/utils_nfschema_plugin/main.nf b/subworkflows/nf-core/utils_nfschema_plugin/main.nf deleted file mode 100644 index 9ff0681f..00000000 --- a/subworkflows/nf-core/utils_nfschema_plugin/main.nf +++ /dev/null @@ -1,77 +0,0 @@ -// -// Subworkflow that uses the nf-schema plugin to validate parameters and render the parameter summary -// - -include { paramsSummaryLog } from 'plugin/nf-schema' -include { validateParameters } from 'plugin/nf-schema' -include { paramsHelp } from 'plugin/nf-schema' - -workflow UTILS_NFSCHEMA_PLUGIN { - - take: - input_workflow // workflow: the workflow object used by nf-schema to get metadata from the workflow - validate_params // boolean: validate the parameters - parameters_schema // string: path to the parameters JSON schema. - // this has to be the same as the schema given to `validation.parametersSchema` - // when this input is empty it will automatically use the configured schema or - // "${projectDir}/nextflow_schema.json" as default. This input should not be empty - // for meta pipelines - help // boolean: show help message - help_full // boolean: show full help message - show_hidden // boolean: show hidden parameters in help message - before_text // string: text to show before the help message and parameters summary - after_text // string: text to show after the help message and parameters summary - command // string: an example command of the pipeline - cli_typecast // boolean: whether to perform typecasting of CLI parameters. Set this to `null` to use the default behaviour - - main: - - if(help || help_full) { - help_options = [ - beforeText: before_text, - afterText: after_text, - command: command, - showHidden: show_hidden, - fullHelp: help_full, - ] - if(parameters_schema) { - help_options << [parameters_schema: parameters_schema] - } - log.info paramsHelp( - help_options, - (help instanceof String && help != "true") ? help : "", - ) - exit 0 - } - - // - // Print parameter summary to stdout. This will display the parameters - // that differ from the default given in the JSON schema - // - - summary_options = [:] - if(parameters_schema) { - summary_options << [parameters_schema: parameters_schema] - } - log.info before_text - log.info paramsSummaryLog(summary_options, input_workflow) - log.info after_text - - // - // Validate the parameters using nextflow_schema.json or the schema - // given via the validation.parametersSchema configuration option - // - if(validate_params) { - validateOptions = [:] - if(parameters_schema) { - validateOptions << [parameters_schema: parameters_schema] - } - if(cli_typecast != null) { - validateOptions << [cast_cli_params: cli_typecast] - } - validateParameters(validateOptions) - } - - emit: - dummy_emit = true -} diff --git a/subworkflows/nf-core/utils_nfschema_plugin/meta.yml b/subworkflows/nf-core/utils_nfschema_plugin/meta.yml deleted file mode 100644 index 1d8c75a9..00000000 --- a/subworkflows/nf-core/utils_nfschema_plugin/meta.yml +++ /dev/null @@ -1,59 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json -name: "utils_nfschema_plugin" -description: Run nf-schema to validate parameters and create a summary of changed parameters -keywords: - - validation - - JSON schema - - plugin - - parameters - - summary -components: [] -input: - - input_workflow: - type: object - description: | - The workflow object of the used pipeline. - This object contains meta data used to create the params summary log - - validate_params: - type: boolean - description: Validate the parameters and error if invalid. - - parameters_schema: - type: string - description: | - Path to the parameters JSON schema. - This has to be the same as the schema given to the `validation.parametersSchema` config - option. When this input is empty it will automatically use the configured schema or - "${projectDir}/nextflow_schema.json" as default. The schema should not be given in this way - for meta pipelines. - - help: - type: boolean, string - description: | - Show the help message and exit. When a parameter name is given, show the help message for that parameter instead of the general help message. - - help_full: - type: boolean - description: Show the full help message and exit. - - show_hidden: - type: boolean - description: Show hidden parameters in the help message. - - before_text: - type: string - description: Text to show before the parameters summary and help message. - - after_text: - type: string - description: Text to show after the parameters summary and help message. - - command: - type: string - description: An example command to run the pipeline, to show in the help message and the summary. - - cli_typecast: - type: boolean - description: | - Whether to apply typecasting to the parameters given via the CLI before validation. - Set this to `null` to use the default behavior. -output: - - dummy_emit: - type: boolean - description: Dummy emit to make nf-core subworkflows lint happy -authors: - - "@nvnieuwk" -maintainers: - - "@nvnieuwk" diff --git a/tests/lib/UTILS.groovy b/tests/lib/UTILS.groovy index 3fddabdb..ff29c80d 100644 --- a/tests/lib/UTILS.groovy +++ b/tests/lib/UTILS.groovy @@ -24,13 +24,15 @@ class UTILS { ] // stable_name: All files + folders in ${outdir}/ with a stable name - def stable_name = getAllFilesFromDir(outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + def stable_name = getAllFilesFromPath(outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) // stable_content: All files in ${outdir}/ with stable content - def stable_content = getAllFilesFromDir(outdir, ignoreFile: 'tests/.nftignore', ignore: [scenario.ignoreFiles ]) + def stable_content = getAllFilesFromPath(outdir, ignoreFile: 'tests/.nftignore', ignore: [scenario.ignoreFiles]) // bam_files: All bam files - def bam_files = getAllFilesFromDir(outdir, include: ['**/*.bam'], ignore: [scenario.ignoreFiles ]) + def bam_files = getAllFilesFromPath(outdir, include: ['**/*.bam'], ignore: [scenario.ignoreFiles]) def assertion = [] + // getAllFilesFromPath returns relative paths (strings), so this resolves to an absolute path + def absolutePath = { file -> file.toString().startsWith('/') ? file.toString() : "${outdir}/${file}" } if (!scenario.failure) { assertion.add(workflow.trace.succeeded().size()) @@ -41,8 +43,8 @@ class UTILS { assertion.add(stable_name) if (!scenario.stub) { - assertion.add(stable_content.isEmpty() ? 'No stable content' : stable_content) - assertion.add(bam_files.isEmpty() ? 'No BAM files' : bam_files.collect { file -> file.getName() + ":md5," + bam(file.toString()).readsMD5 }) + assertion.add(stable_content.isEmpty() ? 'No stable content' : stable_content.collect { file -> path(absolutePath(file)) }) + assertion.add(bam_files.isEmpty() ? 'No BAM files' : bam_files.collect { file -> file.tokenize('/').last() + ":md5," + bam(absolutePath(file)).readsMD5 }) } // If we have a snapshot options in scenario then we allow to capture either stderr, stdout or both @@ -115,6 +117,10 @@ class UTILS { tag scenario.tag } + if (scenario.failure) { + tag "failure" + } + if (scenario.rundir_folder && scenario.rundir_samplesheet) { setup { println "" diff --git a/tests/missing_rundir.nf.test.snap b/tests/missing_rundir.nf.test.snap index 7bc9aace..b719eb75 100644 --- a/tests/missing_rundir.nf.test.snap +++ b/tests/missing_rundir.nf.test.snap @@ -76,11 +76,10 @@ ], [ "WARN: More than one rundir, or sample(s) missing rundir, skipping MULTIQC_SAV", - "WARN: No rundir for sample(s): SampleA_02, sampletest_04", - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." + "WARN: No rundir for sample(s): SampleA_02, sampletest_04" ] ], - "timestamp": "2026-06-16T16:36:43.640701391", + "timestamp": "2026-06-17T10:52:03.137264827", "meta": { "nf-test": "0.9.5", "nextflow": "26.04.3" @@ -151,14 +150,13 @@ "WARN: No rundir for sample(s): Sample1_01, Sample23_03, SampleA_02, Undetermined_05, sampletest_04", "WARN: No samples with rundir found, skipping CHECKQC", "WARN: No samples with rundir found, skipping MULTIQC_SAV", - "WARN: No samples with rundir found, skipping RUNDIRPARSER", - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." + "WARN: No samples with rundir found, skipping RUNDIRPARSER" ] ], - "timestamp": "2026-04-09T14:02:31.345913418", + "timestamp": "2026-06-17T10:52:26.499349564", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } }, "NovaSeq6000 data test - checkqc,fastqc,multiqcsav,rundirparser - missing rundir": { diff --git a/tests/multiple_rundir.nf.test.snap b/tests/multiple_rundir.nf.test.snap index a3c8c8f3..b2343389 100644 --- a/tests/multiple_rundir.nf.test.snap +++ b/tests/multiple_rundir.nf.test.snap @@ -43,14 +43,13 @@ "reports/fastqc/SAMPLE_SINGLE_END_03/SAMPLE_SINGLE_END_03.zip" ], [ - "WARN: More than one rundir, or sample(s) missing rundir, skipping MULTIQC_SAV", - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." + "WARN: More than one rundir, or sample(s) missing rundir, skipping MULTIQC_SAV" ] ], - "timestamp": "2026-04-09T14:02:55.413630663", + "timestamp": "2026-06-17T10:52:58.650571032", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } }, "MiSeq data test - fastqc,multiqcsav - multiple rundir": { diff --git a/tests/no_genome.nf.test.snap b/tests/no_genome.nf.test.snap index 366cc76d..d72af2c2 100644 --- a/tests/no_genome.nf.test.snap +++ b/tests/no_genome.nf.test.snap @@ -180,14 +180,13 @@ ], [ "WARN: BWAMEM2, SAMTOOLS and PICARD processes, will be skipped", - "WARN: No fasta was provided, but picard was requested", - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." + "WARN: No fasta was provided, but picard was requested" ] ], - "timestamp": "2026-04-09T14:03:26.270832747", + "timestamp": "2026-06-17T10:53:35.845478476", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } } } \ No newline at end of file diff --git a/tests/tag_collision.nf.test.snap b/tests/tag_collision.nf.test.snap index f451384e..a5d9d3ff 100644 --- a/tests/tag_collision.nf.test.snap +++ b/tests/tag_collision.nf.test.snap @@ -94,14 +94,13 @@ "WARN: On a MacOS system these tags will be considered as one", "WARN: Tag name collision: [group1, Group1]", "WARN: Tag name collision: [lane1, Lane1, LANE1]", - "WARN: Tag name collision: [test, Test, TEST]", - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." + "WARN: Tag name collision: [test, Test, TEST]" ] ], - "timestamp": "2026-04-09T14:05:10.052392737", + "timestamp": "2026-06-17T10:54:07.631331321", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } }, "NovaSeq6000 data test - tag collision": { diff --git a/tests/tools_bbmap_clumpify.nf.test.snap b/tests/tools_bbmap_clumpify.nf.test.snap index 0ae50d91..080c337b 100644 --- a/tests/tools_bbmap_clumpify.nf.test.snap +++ b/tests/tools_bbmap_clumpify.nf.test.snap @@ -105,9 +105,7 @@ "reports/bbmap/SAMPLE_SINGLE_END_03", "reports/bbmap/SAMPLE_SINGLE_END_03/SAMPLE_SINGLE_END_03.clumpify.log" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], "timestamp": "2026-06-12T13:32:08.528487804", "meta": { diff --git a/tests/tools_checkqc.nf.test.snap b/tests/tools_checkqc.nf.test.snap index f5694bd7..d383b2d3 100644 --- a/tests/tools_checkqc.nf.test.snap +++ b/tests/tools_checkqc.nf.test.snap @@ -47,14 +47,12 @@ "reports/checkqc/200624_A00834_0183_BHMTFYDRXX", "reports/checkqc/200624_A00834_0183_BHMTFYDRXX/checkqc_report.json" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], - "timestamp": "2026-04-09T14:05:47.720193914", + "timestamp": "2026-06-17T10:54:36.750439353", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } }, "NovaSeq6000 data test - checkqc with config - stub": { @@ -105,14 +103,12 @@ "reports/checkqc/200624_A00834_0183_BHMTFYDRXX", "reports/checkqc/200624_A00834_0183_BHMTFYDRXX/checkqc_report.json" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], - "timestamp": "2026-04-09T14:06:25.988266748", + "timestamp": "2026-06-17T10:59:07.997427285", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } }, "NovaSeq6000 data test - checkqc": { diff --git a/tests/tools_fastp.nf.test.snap b/tests/tools_fastp.nf.test.snap index cd98c71d..f38be7b2 100644 --- a/tests/tools_fastp.nf.test.snap +++ b/tests/tools_fastp.nf.test.snap @@ -322,14 +322,12 @@ "reports/fastp/SAMPLE_SINGLE_END_03/SAMPLE_SINGLE_END_03.fastp.json", "reports/fastp/SAMPLE_SINGLE_END_03/SAMPLE_SINGLE_END_03.fastp.log" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], - "timestamp": "2026-04-09T14:06:51.867481976", + "timestamp": "2026-06-17T10:59:37.283095869", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } } } \ No newline at end of file diff --git a/tests/tools_fastqe.nf.test.snap b/tests/tools_fastqe.nf.test.snap index 21acf689..6dcb8a93 100644 --- a/tests/tools_fastqe.nf.test.snap +++ b/tests/tools_fastqe.nf.test.snap @@ -108,14 +108,12 @@ "reports/fastqe/SAMPLE_SINGLE_END_03", "reports/fastqe/SAMPLE_SINGLE_END_03/SAMPLE_SINGLE_END_03.tsv" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], - "timestamp": "2026-04-09T14:07:15.56753043", + "timestamp": "2026-06-17T11:00:03.532332332", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } } } \ No newline at end of file diff --git a/tests/tools_fq_lint.nf.test.snap b/tests/tools_fq_lint.nf.test.snap index 907f57ad..ffcccd91 100644 --- a/tests/tools_fq_lint.nf.test.snap +++ b/tests/tools_fq_lint.nf.test.snap @@ -55,14 +55,12 @@ "reports/fq/sampletest_04", "reports/fq/sampletest_04/sampletest_04.fq_lint.txt" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], - "timestamp": "2026-04-09T14:08:19.966257144", + "timestamp": "2026-06-17T11:00:55.334756735", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } }, "NovaSeq6000 data test - args for fq/lint": { @@ -208,14 +206,12 @@ "reports/fq/Sample1_01", "reports/fq/Sample1_01/Sample1_01.fq_lint.txt" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], - "timestamp": "2026-04-09T14:07:33.929613017", + "timestamp": "2026-06-17T11:00:24.556712525", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } }, "NovaSeq6000 data test - fq_lint force success": { diff --git a/tests/tools_kraken2.nf.test.snap b/tests/tools_kraken2.nf.test.snap index 2429301f..1b48f386 100644 --- a/tests/tools_kraken2.nf.test.snap +++ b/tests/tools_kraken2.nf.test.snap @@ -645,14 +645,12 @@ "subsampled/sampletest_04", "subsampled/sampletest_04/sampletest_04.fastq.gz" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], - "timestamp": "2026-04-09T14:09:00.853191657", + "timestamp": "2026-06-17T11:01:25.548385547", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } }, "NovaSeq6000 data test - kraken2 - no_db - stub": { @@ -660,17 +658,15 @@ [ "pipeline_info" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ], + "No warnings", [ "No kraken2_db was provided, but Kraken2 was requested" ] ], - "timestamp": "2026-04-09T14:09:27.312230993", + "timestamp": "2026-06-17T11:01:45.01126395", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } } } \ No newline at end of file diff --git a/tests/tools_multiqcsav.nf.test.snap b/tests/tools_multiqcsav.nf.test.snap index 9494a6d1..65223edf 100644 --- a/tests/tools_multiqcsav.nf.test.snap +++ b/tests/tools_multiqcsav.nf.test.snap @@ -168,14 +168,12 @@ "pipeline_info", "pipeline_info/nf_core_seqinspector_software_mqc_versions.yml" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], - "timestamp": "2026-04-09T14:09:54.657255279", + "timestamp": "2026-06-17T11:02:08.136373674", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } } } \ No newline at end of file diff --git a/tests/tools_picard.nf.test.snap b/tests/tools_picard.nf.test.snap index 720e8d70..97fc14bd 100644 --- a/tests/tools_picard.nf.test.snap +++ b/tests/tools_picard.nf.test.snap @@ -684,11 +684,9 @@ "reports/picard_collectmultiplemetrics/sampletest_04/sampletest_04.CollectMultipleMetrics.quality_by_cycle_metrics", "reports/picard_collectmultiplemetrics/sampletest_04/sampletest_04.CollectMultipleMetrics.quality_distribution_metrics" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], - "timestamp": "2026-06-08T14:21:24.291339228", + "timestamp": "2026-06-17T11:02:51.951677937", "meta": { "nf-test": "0.9.5", "nextflow": "26.04.3" diff --git a/tests/tools_seqkit.nf.test.snap b/tests/tools_seqkit.nf.test.snap index 079bd179..c1e5c5a7 100644 --- a/tests/tools_seqkit.nf.test.snap +++ b/tests/tools_seqkit.nf.test.snap @@ -39,11 +39,9 @@ "reports/seqkit/SAMPLE_SINGLE_END_03", "reports/seqkit/SAMPLE_SINGLE_END_03/SAMPLE_SINGLE_END_03.tsv" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], - "timestamp": "2026-06-15T12:07:18.701682984", + "timestamp": "2026-06-17T11:03:21.022749912", "meta": { "nf-test": "0.9.5", "nextflow": "26.04.3" diff --git a/tests/tools_sequali.nf.test.snap b/tests/tools_sequali.nf.test.snap index 24559804..e4bc9a9b 100644 --- a/tests/tools_sequali.nf.test.snap +++ b/tests/tools_sequali.nf.test.snap @@ -60,14 +60,12 @@ "reports/sequali/sampletest_04/sampletest_04.html", "reports/sequali/sampletest_04/sampletest_04.json" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ] + "No warnings" ], - "timestamp": "2026-04-15T18:18:01.020240586", + "timestamp": "2026-06-17T11:03:49.6512543", "meta": { "nf-test": "0.9.5", - "nextflow": "26.03.2" + "nextflow": "26.04.3" } }, "NovaSeq6000 data test - sequali": { diff --git a/tests/tools_toulligqc.nf.test.snap b/tests/tools_toulligqc.nf.test.snap index 5e082ae4..64f58727 100644 --- a/tests/tools_toulligqc.nf.test.snap +++ b/tests/tools_toulligqc.nf.test.snap @@ -4,17 +4,15 @@ [ "pipeline_info" ], - [ - "WARN: nf-core pipelines do not accept positional arguments. The positional argument `true` has been detected." - ], + "No warnings", [ "ToulligQC is not compatible with the 'emulate_amd64' profile. Please remove ToulligQC from the list of tools if you wish to run seqinspector on this architecture." ] ], - "timestamp": "2026-04-09T14:10:13.561661222", + "timestamp": "2026-06-17T11:04:04.734103456", "meta": { "nf-test": "0.9.5", - "nextflow": "25.10.4" + "nextflow": "26.04.3" } }, "PromethION data test - toulligqc fail": { diff --git a/workflows/seqinspector.nf b/workflows/seqinspector.nf index f2528f3f..b90f2327 100644 --- a/workflows/seqinspector.nf +++ b/workflows/seqinspector.nf @@ -28,13 +28,16 @@ include { BAM_QC } from '../subworkflows/local/bam_qc' include { FASTQ_QC_PHYLOGENETIC } from '../subworkflows/local/fastq_qc_phylogenetic' // functions -include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_seqinspector_pipeline' +include { citationsOnTheFly } from 'plugin/nf-core-utils' +include { methodsDescriptionText } from 'plugin/nf-core-utils' include { paramsSummaryMap } from 'plugin/nf-schema' -include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline' -include { reportIndexMultiqc } from '../subworkflows/local/utils_nfcore_seqinspector_pipeline' +include { paramsSummaryMultiqc } from 'plugin/nf-core-utils' include { samplesheetToList } from 'plugin/nf-schema' include { softwareVersionsToYAML } from 'plugin/nf-core-utils' +// custom functions +include { reportIndexMultiqc } from '../subworkflows/local/utils_nfcore_seqinspector_pipeline' + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -341,12 +344,11 @@ workflow SEQINSPECTOR { ? file(multiqc_methods_description, checkIfExists: true) : file("${projectDir}/assets/methods_description_template.yml", checkIfExists: true) - ch_methods_description = channel.topic("versions") - .map { _process, tool, _version -> tool } - .unique() - .collect() - .map { tool_list -> ('multiqcsav' in tools ? tool_list + ['multiqcsav'] : tool_list).unique() } - .map { tool_list -> methodsDescriptionText(ch_multiqc_custom_methods_description, tool_list) } + // Build citations on the fly from versions topic + meta.yml files + ch_methods_description = channel.topic('versions') + .collect(flat: false) + .map { versions -> citationsOnTheFly(versions, files("${projectDir}/modules/**/meta.yml").collect { path -> path.toString() }, ['multiqcsav']) } + .map { versions -> methodsDescriptionText(ch_multiqc_custom_methods_description.toString(), versions) } ch_multiqc_extra_files = ch_multiqc_extra_files.mix(ch_methods_description.collectFile(name: 'methods_description_mqc.yaml', sort: true))