diff --git a/CHANGELOG.md b/CHANGELOG.md index 603fa77e2..926535077 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # nf-core/tools: Changelog +## [v3.1.1 - Brass Boxfish Patch](https://github.com/nf-core/tools/releases/tag/3.1.1) - [2024-12-20] + +### Template + +- Use outputs instead of the environment to pass around values between steps in the Download Test Action ([#3351](https://github.com/nf-core/tools/pull/3351)) +- Fix pre commit template ([#3358](https://github.com/nf-core/tools/pull/3358)) +- Set LICENSE copyright to nf-core community ([#3366](https://github.com/nf-core/tools/pull/3366)) +- fix including modules.config ([#3356](https://github.com/nf-core/tools/pull/3356)) + +### Linting + +- Linting of pipeline LICENSE file is a warning to allow for author/maintainer names ([#3366](https://github.com/nf-core/tools/pull/3366)) + +### General + +- Add missing p ([#3357](https://github.com/nf-core/tools/pull/3357)) +- Use `manifest.contributors` names if available, otherwise default to `manifest.author` ([#3362](https://github.com/nf-core/tools/pull/3362)) +- Properly parse the names form `manifest.contributors` ([#3364](https://github.com/nf-core/tools/pull/3364)) + ## [v3.1.0 - Brass Boxfish](https://github.com/nf-core/tools/releases/tag/3.1.0) - [2024-12-09] **Highlights** diff --git a/nf_core/pipeline-template/.editorconfig b/nf_core/pipeline-template/.editorconfig index c78ec8e96..eccca026e 100644 --- a/nf_core/pipeline-template/.editorconfig +++ b/nf_core/pipeline-template/.editorconfig @@ -35,3 +35,7 @@ indent_size = unset # ignore python and markdown [*.{py,md}] indent_style = unset + +# ignore ro-crate metadata files +[**/ro-crate-metadata.json] +insert_final_newline = unset diff --git a/nf_core/pipeline-template/.github/ISSUE_TEMPLATE/bug_report.yml b/nf_core/pipeline-template/.github/ISSUE_TEMPLATE/bug_report.yml index 412f5bd3b..f3624afc9 100644 --- a/nf_core/pipeline-template/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/nf_core/pipeline-template/.github/ISSUE_TEMPLATE/bug_report.yml @@ -11,7 +11,6 @@ body: - [nf-core website: troubleshooting](https://nf-co.re/usage/troubleshooting) - [{{ name }} pipeline documentation](https://nf-co.re/{{ short_name }}/usage) {%- endif %} - - type: textarea id: description attributes: diff --git a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml index 05397358c..f270dc541 100644 --- a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml +++ b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml @@ -28,10 +28,14 @@ env: NXF_ANSI_LOG: false jobs: - download: - runs-on: ubuntu-latest + configure: + runs-on: ubuntu-latest{% raw %} + outputs: + REPO_LOWERCASE: ${{ steps.get_repo_properties.outputs.REPO_LOWERCASE }} + REPOTITLE_LOWERCASE: ${{ steps.get_repo_properties.outputs.REPOTITLE_LOWERCASE }} + REPO_BRANCH: ${{ steps.get_repo_properties.outputs.REPO_BRANCH }} steps: - - name: Install Nextflow + - name: Install Nextflow{% endraw %} uses: nf-core/setup-nextflow@v2 - name: Disk space cleanup @@ -53,22 +57,27 @@ jobs: pip install git+https://github.com/nf-core/tools.git@dev - name: Get the repository name and current branch set as environment variable + id: get_repo_properties run: | - echo "REPO_LOWERCASE=${GITHUB_REPOSITORY,,}" >> ${GITHUB_ENV} - echo "REPOTITLE_LOWERCASE=$(basename ${GITHUB_REPOSITORY,,})" >> ${GITHUB_ENV} - echo "{% raw %}REPO_BRANCH=${{ github.event.inputs.testbranch || 'dev' }}" >> ${GITHUB_ENV} + echo "REPO_LOWERCASE=${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" + echo "REPOTITLE_LOWERCASE=$(basename ${GITHUB_REPOSITORY,,})" >> "$GITHUB_OUTPUT" + echo "{% raw %}REPO_BRANCH=${{ github.event.inputs.testbranch || 'dev' }}" >> "$GITHUB_OUTPUT" - name: Make a cache directory for the container images run: | mkdir -p ./singularity_container_images + download: + runs-on: ubuntu-latest + needs: configure + steps: - name: Download the pipeline env: NXF_SINGULARITY_CACHEDIR: ./singularity_container_images run: | - nf-core pipelines download ${{ env.REPO_LOWERCASE }} \ - --revision ${{ env.REPO_BRANCH }} \ - --outdir ./${{ env.REPOTITLE_LOWERCASE }} \ + nf-core pipelines download ${{ needs.configure.outputs.REPO_LOWERCASE }} \ + --revision ${{ needs.configure.outputs.REPO_BRANCH }} \ + --outdir ./${{ needs.configure.outputs.REPOTITLE_LOWERCASE }} \ --compress "none" \ --container-system 'singularity' \ --container-library "quay.io" -l "docker.io" -l "community.wave.seqera.io/library/" \ @@ -76,14 +85,14 @@ jobs: --download-configuration 'yes' - name: Inspect download - run: tree ./${{ env.REPOTITLE_LOWERCASE }}{% endraw %}{% if test_config %}{% raw %} + run: tree ./${{ needs.configure.outputs.REPOTITLE_LOWERCASE }}{% endraw %}{% if test_config %}{% raw %} - name: Count the downloaded number of container images id: count_initial run: | image_count=$(ls -1 ./singularity_container_images | wc -l | xargs) echo "Initial container image count: $image_count" - echo "IMAGE_COUNT_INITIAL=$image_count" >> ${GITHUB_ENV} + echo "IMAGE_COUNT_INITIAL=$image_count" >> "$GITHUB_OUTPUT" - name: Run the downloaded pipeline (stub) id: stub_run_pipeline @@ -91,27 +100,27 @@ jobs: env: NXF_SINGULARITY_CACHEDIR: ./singularity_container_images NXF_SINGULARITY_HOME_MOUNT: true - run: nextflow run ./${{ env.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ env.REPO_BRANCH }}) -stub -profile test,singularity --outdir ./results + run: nextflow run ./${{needs.configure.outputs.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ needs.configure.outputs.REPO_BRANCH }}) -stub -profile test,singularity --outdir ./results - name: Run the downloaded pipeline (stub run not supported) id: run_pipeline - if: ${{ job.steps.stub_run_pipeline.status == failure() }} + if: ${{ steps.stub_run_pipeline.outcome == 'failure' }} env: NXF_SINGULARITY_CACHEDIR: ./singularity_container_images NXF_SINGULARITY_HOME_MOUNT: true - run: nextflow run ./${{ env.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ env.REPO_BRANCH }}) -profile test,singularity --outdir ./results + run: nextflow run ./${{ needs.configure.outputs.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ needs.configure.outputs.REPO_BRANCH }}) -profile test,singularity --outdir ./results - name: Count the downloaded number of container images id: count_afterwards run: | image_count=$(ls -1 ./singularity_container_images | wc -l | xargs) echo "Post-pipeline run container image count: $image_count" - echo "IMAGE_COUNT_AFTER=$image_count" >> ${GITHUB_ENV} + echo "IMAGE_COUNT_AFTER=$image_count" >> "$GITHUB_OUTPUT" - name: Compare container image counts run: | - if [ "${{ env.IMAGE_COUNT_INITIAL }}" -ne "${{ env.IMAGE_COUNT_AFTER }}" ]; then - initial_count=${{ env.IMAGE_COUNT_INITIAL }} - final_count=${{ env.IMAGE_COUNT_AFTER }} + if [ "${{ steps.count_initial.outputs.IMAGE_COUNT_INITIAL }}" -ne "${{ steps.count_afterwards.outputs.IMAGE_COUNT_AFTER }}" ]; then + initial_count=${{ steps.count_initial.outputs.IMAGE_COUNT_INITIAL }} + final_count=${{ steps.count_afterwards.outputs.IMAGE_COUNT_AFTER }} difference=$((final_count - initial_count)) echo "$difference additional container images were \n downloaded at runtime . The pipeline has no support for offline runs!" tree ./singularity_container_images diff --git a/nf_core/pipeline-template/.gitpod.yml b/nf_core/pipeline-template/.gitpod.yml index c02b93834..c6a2e40b8 100644 --- a/nf_core/pipeline-template/.gitpod.yml +++ b/nf_core/pipeline-template/.gitpod.yml @@ -3,7 +3,7 @@ tasks: - name: Update Nextflow and setup pre-commit command: | pre-commit install --install-hooks - nextflow self-update {% if code_linters %} + nextflow self-update {%- if code_linters %} vscode: extensions: diff --git a/nf_core/pipeline-template/.prettierignore b/nf_core/pipeline-template/.prettierignore index 7ecc9b61c..02ba84c00 100644 --- a/nf_core/pipeline-template/.prettierignore +++ b/nf_core/pipeline-template/.prettierignore @@ -16,3 +16,6 @@ testing/ testing* *.pyc bin/ +{%- if rocrate %} +ro-crate-metadata.json +{%- endif %} diff --git a/nf_core/pipeline-template/CITATIONS.md b/nf_core/pipeline-template/CITATIONS.md index 16da9a420..c355fd612 100644 --- a/nf_core/pipeline-template/CITATIONS.md +++ b/nf_core/pipeline-template/CITATIONS.md @@ -18,7 +18,7 @@ {%- endif %} -{% if multiqc %}- [MultiQC](https://pubmed.ncbi.nlm.nih.gov/27312411/) +{%- if multiqc %}- [MultiQC](https://pubmed.ncbi.nlm.nih.gov/27312411/) > Ewels P, Magnusson M, Lundin S, Käller M. MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics. 2016 Oct 1;32(19):3047-8. doi: 10.1093/bioinformatics/btw354. Epub 2016 Jun 16. PubMed PMID: 27312411; PubMed Central PMCID: PMC5039924. diff --git a/nf_core/pipeline-template/LICENSE b/nf_core/pipeline-template/LICENSE index 9fc4e61c3..97fe7b2d3 100644 --- a/nf_core/pipeline-template/LICENSE +++ b/nf_core/pipeline-template/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) {{ author }} +Copyright (c) The {{ name }} team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/nf_core/pipeline-template/README.md b/nf_core/pipeline-template/README.md index a8f2e6054..4cd41de36 100644 --- a/nf_core/pipeline-template/README.md +++ b/nf_core/pipeline-template/README.md @@ -7,7 +7,7 @@ -{% else %} +{%- else -%} # {{ name }} @@ -48,13 +48,13 @@ workflows use the "tube map" design for that. See https://nf-co.re/docs/contributing/design_guidelines#examples for examples. --> -{% if fastqc %}1. Read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/)){% endif %} -{% if multiqc %}2. Present QC for raw reads ([`MultiQC`](http://multiqc.info/)){% endif %} +{%- if fastqc %}1. Read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/)){% endif %} +{%- if multiqc %}2. Present QC for raw reads ([`MultiQC`](http://multiqc.info/)){% endif %} ## Usage > [!NOTE] -> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. {% if test_config %}Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.{% endif %} +> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. {%- if test_config %}Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.{% endif %} -{% if citations %} +{%- if citations %} An extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file. -{% endif %} +{%- endif %} + {% if is_nfcore -%} You can cite the `nf-core` publication as follows: diff --git a/nf_core/pipeline-template/docs/output.md b/nf_core/pipeline-template/docs/output.md index 83d5d23fe..a9be6620e 100644 --- a/nf_core/pipeline-template/docs/output.md +++ b/nf_core/pipeline-template/docs/output.md @@ -2,7 +2,7 @@ ## Introduction -This document describes the output produced by the pipeline. {% if multiqc %}Most of the plots are taken from the MultiQC report, which summarises results at the end of the pipeline.{% endif %} +This document describes the output produced by the pipeline.{% if multiqc %} Most of the plots are taken from the MultiQC report, which summarises results at the end of the pipeline.{% endif %} The directories listed below will be created in the results directory after the pipeline has finished. All paths are relative to the top-level results directory. @@ -14,9 +14,8 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d {% if fastqc -%} -- [FastQC](#fastqc) - Raw read QC - {%- endif %} - {%- if multiqc %} +- [FastQC](#fastqc) - Raw read QC{% endif %} + {%- if multiqc -%} - [MultiQC](#multiqc) - Aggregate report describing results and QC from the whole pipeline {%- endif %} - [Pipeline information](#pipeline-information) - Report metrics generated during the workflow execution @@ -35,7 +34,7 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d [FastQC](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/) gives general quality metrics about your sequenced reads. It provides information about the quality score distribution across your reads, per base sequence content (%A/T/G/C), adapter contamination and overrepresented sequences. For further reading and documentation see the [FastQC help pages](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/). -{%- endif %} +{%- endif -%} {% if multiqc -%} @@ -54,7 +53,7 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d [MultiQC](http://multiqc.info) is a visualization tool that generates a single HTML report summarising all samples in your project. Most of the pipeline QC results are visualised in the report and further statistics are available in the report data directory. Results generated by MultiQC collate pipeline QC from supported tools e.g. FastQC. The pipeline has special steps which also allow the software versions to be reported in the MultiQC output for future traceability. For more information about how to use MultiQC reports, see . -{%- endif %} +{%- endif -%} ### Pipeline information diff --git a/nf_core/pipeline-template/docs/usage.md b/nf_core/pipeline-template/docs/usage.md index 85f119e04..bbc8a828c 100644 --- a/nf_core/pipeline-template/docs/usage.md +++ b/nf_core/pipeline-template/docs/usage.md @@ -115,7 +115,7 @@ It is a good idea to specify the pipeline version when running the pipeline on y First, go to the [{{ name }} releases page](https://github.com/{{ name }}/releases) and find the latest pipeline version - numeric only (eg. `1.3.1`). Then specify this when running the pipeline with `-r` (one hyphen) - eg. `-r 1.3.1`. Of course, you can switch to another version by changing the number after the `-r` flag. -This version number will be logged in reports when you run the pipeline, so that you'll know what you used when you look back in the future. {% if multiqc %}For example, at the bottom of the MultiQC reports.{% endif %} +This version number will be logged in reports when you run the pipeline, so that you'll know what you used when you look back in the future.{% if multiqc %} For example, at the bottom of the MultiQC reports.{% endif %} To further assist in reproducibility, you can use share and reuse [parameter files](#running-the-pipeline) to repeat pipeline runs with the same settings without having to write out a command with every single parameter. @@ -138,7 +138,7 @@ Several generic profiles are bundled with the pipeline which instruct the pipeli {%- if nf_core_configs %} -The pipeline also dynamically loads configurations from [https://github.com/nf-core/configs](https://github.com/nf-core/configs) when it runs, making multiple config profiles for various institutional clusters available at run time. For more information and to check if your system is suported, please see the [nf-core/configs documentation](https://github.com/nf-core/configs#documentation). +The pipeline also dynamically loads configurations from [https://github.com/nf-core/configs](https://github.com/nf-core/configs) when it runs, making multiple config profiles for various institutional clusters available at run time. For more information and to check if your system is supported, please see the [nf-core/configs documentation](https://github.com/nf-core/configs#documentation). {% else %} {% endif %} Note that multiple profiles can be loaded, for example: `-profile test,docker` - the order of arguments is important! diff --git a/nf_core/pipeline-template/nextflow.config b/nf_core/pipeline-template/nextflow.config index 36018b106..3325af4e0 100644 --- a/nf_core/pipeline-template/nextflow.config +++ b/nf_core/pipeline-template/nextflow.config @@ -77,11 +77,6 @@ params { includeConfig 'conf/base.config' {%- else %} -{% if modules -%} -// Load modules.config for DSL2 module specific options -includeConfig 'conf/modules.config' -{%- endif %} - process { // TODO nf-core: Check the defaults for all processes cpus = { 1 * task.attempt } @@ -311,7 +306,7 @@ validation { command = "nextflow run {{ name }} -profile --input samplesheet.csv --outdir " fullParameter = "help_full" showHiddenParameter = "show_hidden" - {% if is_nfcore -%} + {%- if is_nfcore %} beforeText = """ -\033[2m----------------------------------------------------\033[0m- \033[0;32m,--.\033[0;30m/\033[0;32m,-.\033[0m @@ -336,3 +331,8 @@ validation { }{% endif %} } {%- endif %} + +{% if modules -%} +// Load modules.config for DSL2 module specific options +includeConfig 'conf/modules.config' +{%- endif %} diff --git a/nf_core/pipeline-template/nextflow_schema.json b/nf_core/pipeline-template/nextflow_schema.json index 97359a1f9..c28929b47 100644 --- a/nf_core/pipeline-template/nextflow_schema.json +++ b/nf_core/pipeline-template/nextflow_schema.json @@ -243,10 +243,12 @@ { "$ref": "#/$defs/input_output_options" }, - {% if igenomes %}{ + {%- if igenomes %} + { "$ref": "#/$defs/reference_genome_options" },{% endif %} - {% if nf_core_configs %}{ + {%- if nf_core_configs %} + { "$ref": "#/$defs/institutional_config_options" },{% endif %} { diff --git a/nf_core/pipeline-template/subworkflows/local/utils_nfcore_pipeline_pipeline/main.nf b/nf_core/pipeline-template/subworkflows/local/utils_nfcore_pipeline_pipeline/main.nf index 06692f1dc..3d540600b 100644 --- a/nf_core/pipeline-template/subworkflows/local/utils_nfcore_pipeline_pipeline/main.nf +++ b/nf_core/pipeline-template/subworkflows/local/utils_nfcore_pipeline_pipeline/main.nf @@ -143,7 +143,7 @@ workflow PIPELINE_COMPLETION { {%- if multiqc %} def multiqc_reports = multiqc_report.toList() {%- endif %} - + // // Completion email and summary // diff --git a/nf_core/pipelines/bump_version.py b/nf_core/pipelines/bump_version.py index de0342c7f..664d7a22a 100644 --- a/nf_core/pipelines/bump_version.py +++ b/nf_core/pipelines/bump_version.py @@ -128,8 +128,9 @@ def bump_pipeline_version(pipeline_obj: Pipeline, new_version: str) -> None: yaml_key=["template", "version"], ) - # update rocrate - ROCrate(pipeline_obj.wf_path).update_rocrate() + # update rocrate if ro-crate is present + if Path(pipeline_obj.wf_path, "ro-crate-metadata.json").exists(): + ROCrate(pipeline_obj.wf_path).update_rocrate() def bump_nextflow_version(pipeline_obj: Pipeline, new_version: str) -> None: diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index 0e2c683e6..4f90ca17f 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -22,7 +22,7 @@ from nf_core.pipelines.create_logo import create_logo from nf_core.pipelines.lint_utils import run_prettier_on_file from nf_core.pipelines.rocrate import ROCrate -from nf_core.utils import NFCoreTemplateConfig, NFCoreYamlLintConfig +from nf_core.utils import NFCoreTemplateConfig, NFCoreYamlLintConfig, custom_yaml_dumper log = logging.getLogger(__name__) @@ -266,6 +266,14 @@ def init_pipeline(self): # Init the git repository and make the first commit if not self.no_git: self.git_init_pipeline() + # Run prettier on files + if self.config.skip_features is None or not ( + "code_linters" in self.config.skip_features or "github" in self.config.skip_features + ): + current_dir = Path.cwd() + os.chdir(self.outdir) + run_prettier_on_file([str(f) for f in self.outdir.glob("**/*")]) + os.chdir(current_dir) if self.config.is_nfcore and not self.is_interactive: log.info( @@ -362,7 +370,7 @@ def render_template(self) -> None: # Make a logo and save it, if it is a nf-core pipeline self.make_pipeline_logo() - if self.config.skip_features is None or "ro-crate" not in self.config.skip_features: + if self.config.skip_features is None or "rocrate" not in self.config.skip_features: # Create the RO-Crate metadata file rocrate_obj = ROCrate(self.outdir) rocrate_obj.create_rocrate(json_path=self.outdir / "ro-crate-metadata.json") @@ -375,12 +383,9 @@ def render_template(self) -> None: if config_fn is not None and config_yml is not None: with open(str(config_fn), "w") as fh: config_yml.template = NFCoreTemplateConfig(**self.config.model_dump(exclude_none=True)) - yaml.safe_dump(config_yml.model_dump(exclude_none=True), fh) + yaml.dump(config_yml.model_dump(exclude_none=True), fh, Dumper=custom_yaml_dumper()) log.debug(f"Dumping pipeline template yml to pipeline config file '{config_fn.name}'") - # Run prettier on files - run_prettier_on_file([str(f) for f in self.outdir.glob("**/*")]) - def fix_linting(self): """ Updates the .nf-core.yml with linting configurations @@ -408,7 +413,13 @@ def fix_linting(self): if config_fn is not None and nf_core_yml is not None: nf_core_yml.lint = NFCoreYamlLintConfig(**lint_config) with open(self.outdir / config_fn, "w") as fh: - yaml.dump(nf_core_yml.model_dump(exclude_none=True), fh, default_flow_style=False, sort_keys=False) + yaml.dump( + nf_core_yml.model_dump(exclude_none=True), + fh, + sort_keys=False, + default_flow_style=False, + Dumper=custom_yaml_dumper(), + ) def make_pipeline_logo(self): """Fetch a logo for the new pipeline from the nf-core website""" diff --git a/nf_core/pipelines/create/template_features.yml b/nf_core/pipelines/create/template_features.yml index 9841879e8..fa24debff 100644 --- a/nf_core/pipelines/create/template_features.yml +++ b/nf_core/pipelines/create/template_features.yml @@ -148,6 +148,10 @@ is_nfcore: - "docs/images/nf-core-{{short_name}}_logo_light.png" - "docs/images/nf-core-{{short_name}}_logo_dark.png" - ".github/ISSUE_TEMPLATE/bug_report.yml" + - ".github/CONTRIBUTING.md" + - ".github/PULL_REQUEST_TEMPLATE.md" + - "assets/email_template.txt" + - "docs/README.md" nextflow_config: - "manifest.name" - "manifest.homePage" @@ -445,6 +449,8 @@ rocrate: linting: files_warn: - "ro-crate-metadata.json" + files_unchanged: + - ".prettierignore" vscode: skippable_paths: - ".vscode" diff --git a/nf_core/pipelines/lint/files_unchanged.py b/nf_core/pipelines/lint/files_unchanged.py index 300b3674b..c1c3acd31 100644 --- a/nf_core/pipelines/lint/files_unchanged.py +++ b/nf_core/pipelines/lint/files_unchanged.py @@ -62,6 +62,7 @@ def files_unchanged(self) -> Dict[str, Union[List[str], bool]]: passed: List[str] = [] failed: List[str] = [] + warned: List[str] = [] ignored: List[str] = [] fixed: List[str] = [] could_fix: bool = False @@ -173,6 +174,12 @@ def _tf(file_path: Union[str, Path]) -> Path: shutil.copy(_tf(f), _pf(f)) passed.append(f"`{f}` matches the template") fixed.append(f"`{f}` overwritten with template file") + elif f.name in ["LICENSE", "LICENSE.md", "LICENCE", "LICENCE.md"]: + # Report LICENSE as a warning since we are not using the manifest.author names + # TODO: Lint the content of the LICENSE file except the line containing author names + # to allow for people to opt-in listing author/maintainer names instead of using the "nf-core community" + warned.append(f"`{f}` does not match the template") + could_fix = True else: failed.append(f"`{f}` does not match the template") could_fix = True @@ -217,4 +224,11 @@ def _tf(file_path: Union[str, Path]) -> Path: # cleaning up temporary dir shutil.rmtree(tmp_dir) - return {"passed": passed, "failed": failed, "ignored": ignored, "fixed": fixed, "could_fix": could_fix} + return { + "passed": passed, + "failed": failed, + "warned": warned, + "ignored": ignored, + "fixed": fixed, + "could_fix": could_fix, + } diff --git a/nf_core/pipelines/lint_utils.py b/nf_core/pipelines/lint_utils.py index b4c56c600..a6b98b189 100644 --- a/nf_core/pipelines/lint_utils.py +++ b/nf_core/pipelines/lint_utils.py @@ -97,7 +97,7 @@ def run_prettier_on_file(file: Union[Path, str, List[str]]) -> None: all_lines = [line for line in e.stdout.decode().split("\n")] files = "\n".join(all_lines[3:]) log.debug(f"The following files were modified by prettier:\n {files}") - elif e.stderr.decode(): + else: log.warning( "There was an error running the prettier pre-commit hook.\n" f"STDOUT: {e.stdout.decode()}\nSTDERR: {e.stderr.decode()}" diff --git a/nf_core/pipelines/rocrate.py b/nf_core/pipelines/rocrate.py index bc868273c..f87cc7d8d 100644 --- a/nf_core/pipelines/rocrate.py +++ b/nf_core/pipelines/rocrate.py @@ -270,20 +270,16 @@ def add_main_authors(self, wf_file: rocrate.model.entity.Entity) -> None: authors = [] if "manifest.author" in self.pipeline_obj.nf_config: authors.extend([a.strip() for a in self.pipeline_obj.nf_config["manifest.author"].split(",")]) - if "manifest.contributor" in self.pipeline_obj.nf_config: - authors.extend( - [ - c.get("name", "").strip() - for c in self.pipeline_obj.nf_config["manifest.contributor"] - if "name" in c - ] - ) + if "manifest.contributors" in self.pipeline_obj.nf_config: + contributors = self.pipeline_obj.nf_config["manifest.contributors"] + names = re.findall(r"name:'([^']+)'", contributors) + authors.extend(names) if not authors: raise KeyError("No authors found") # add manifest authors as maintainer to crate except KeyError: - log.error("No author or contributor fields found in manifest of nextflow.config") + log.error("No author or contributors fields found in manifest of nextflow.config") return # remove duplicates authors = list(set(authors)) diff --git a/nf_core/utils.py b/nf_core/utils.py index 30b074349..e2b61329c 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -1083,7 +1083,7 @@ def get_repo_releases_branches(pipeline, wfs): raise AssertionError(f"Not able to find pipeline '{pipeline}'") # Get branch information from github api - should be no need to check if the repo exists again - branch_response = gh_api.safe_get(f"https://api.github.com/repos/{pipeline}/branches") + branch_response = gh_api.safe_get(f"https://api.github.com/repos/{pipeline}/branches?per_page=100") for branch in branch_response.json(): if ( branch["name"] != "TEMPLATE" @@ -1327,13 +1327,20 @@ def load_tools_config(directory: Union[str, Path] = ".") -> Tuple[Optional[Path] # Retrieve information if template from config file is empty template = tools_config.get("template") config_template_keys = template.keys() if template is not None else [] + # Get author names from contributors first, then fallback to author + if "manifest.contributors" in wf_config: + contributors = wf_config["manifest.contributors"] + names = re.findall(r"name:'([^']+)'", contributors) + author_names = ", ".join(names) + else: + author_names = wf_config["manifest.author"].strip("'\"") if nf_core_yaml_config.template is None: # The .nf-core.yml file did not contain template information nf_core_yaml_config.template = NFCoreTemplateConfig( org="nf-core", name=wf_config["manifest.name"].strip("'\"").split("/")[-1], description=wf_config["manifest.description"].strip("'\""), - author=wf_config["manifest.author"].strip("'\""), + author=author_names, version=wf_config["manifest.version"].strip("'\""), outdir=str(directory), is_nfcore=True, @@ -1344,7 +1351,7 @@ def load_tools_config(directory: Union[str, Path] = ".") -> Tuple[Optional[Path] org=tools_config["template"].get("prefix", tools_config["template"].get("org", "nf-core")), name=tools_config["template"].get("name", wf_config["manifest.name"].strip("'\"").split("/")[-1]), description=tools_config["template"].get("description", wf_config["manifest.description"].strip("'\"")), - author=tools_config["template"].get("author", wf_config["manifest.author"].strip("'\"")), + author=tools_config["template"].get("author", author_names), version=tools_config["template"].get("version", wf_config["manifest.version"].strip("'\"")), outdir=tools_config["template"].get("outdir", str(directory)), skip_features=tools_config["template"].get("skip", tools_config["template"].get("skip_features")), diff --git a/setup.py b/setup.py index 6b68973a6..5617520e9 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import find_packages, setup -version = "3.1.0" +version = "3.1.1" with open("README.md") as f: readme = f.read() diff --git a/tests/utils.py b/tests/utils.py index 022b91227..4c1c620ad 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -14,7 +14,7 @@ import nf_core.modules import nf_core.pipelines.create.create from nf_core import __version__ -from nf_core.utils import NFCoreTemplateConfig, NFCoreYamlConfig +from nf_core.utils import NFCoreTemplateConfig, NFCoreYamlConfig, custom_yaml_dumper TEST_DATA_DIR = Path(__file__).parent / "data" OLD_TRIMGALORE_SHA = "9b7a3bdefeaad5d42324aa7dd50f87bea1b04386" @@ -136,7 +136,7 @@ def create_tmp_pipeline(no_git: bool = False) -> Tuple[Path, Path, str, Path]: bump_version=None, ) with open(str(Path(pipeline_dir, ".nf-core.yml")), "w") as fh: - yaml.dump(nf_core_yml.model_dump(), fh) + yaml.dump(nf_core_yml.model_dump(), fh, Dumper=custom_yaml_dumper()) nf_core.pipelines.create.create.PipelineCreate( pipeline_name, "it is mine", "me", no_git=no_git, outdir=pipeline_dir, force=True