+
Skip to content

Add nf-core create subworkflow #1835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

### Template

- Add template for subworkflows
- Add `actions/upload-artifact` step to the awstest workflows, to expose the debug log file
- Add `prettier` as a requirement to Gitpod Dockerimage
- Bioconda incompatible conda channel setups now result in more informative error messages ([#1812](https://github.com/nf-core/tools/pull/1812))
Expand All @@ -41,6 +42,7 @@
- Schema: Remove `allOf` if no definition groups are left.
- Use contextlib to temporarily change working directories ([#1819](https://github.com/nf-core/tools/pull/1819))
- More helpful error messages if `nf-core download` can't parse a singularity image download
- Add `nf-core subworkflows create` command

### Modules

Expand Down
71 changes: 70 additions & 1 deletion nf_core/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import nf_core.list
import nf_core.modules
import nf_core.schema
import nf_core.subworkflows
import nf_core.sync
import nf_core.utils

Expand Down Expand Up @@ -54,6 +55,12 @@
"commands": ["create", "create-test-yml", "lint", "bump-versions", "mulled", "test"],
},
],
"nf-core subworkflows": [
{
"name": "Developing new subworkflows",
"commands": ["create"],
},
],
}
click.rich_click.OPTION_GROUPS = {
"nf-core modules list local": [{"options": ["--dir", "--json", "--help"]}],
Expand Down Expand Up @@ -89,7 +96,7 @@ def run_nf_core():
log.debug(f"Could not check latest version: {e}")
stderr.print("\n")

# Lanch the click cli
# Launch the click cli
nf_core_cli(auto_envvar_prefix="NFCORE")


Expand Down Expand Up @@ -383,6 +390,38 @@ def modules(ctx, git_remote, branch, no_pull):
ctx.obj["modules_repo_no_pull"] = no_pull


# nf-core subworkflows click command
@nf_core_cli.group()
@click.option(
"-g",
"--git-remote",
type=str,
default=nf_core.modules.modules_repo.NF_CORE_MODULES_REMOTE,
help="Remote git repo to fetch files from",
)
@click.option("-b", "--branch", type=str, default=None, help="Branch of git repository hosting modules.")
@click.option(
"-N",
"--no-pull",
is_flag=True,
default=False,
help="Do not pull in latest changes to local clone of modules repository.",
)
@click.pass_context
def subworkflows(ctx, git_remote, branch, no_pull):
"""
Commands to manage Nextflow DSL2 subworkflows (tool wrappers).
"""
# ensure that ctx.obj exists and is a dict (in case `cli()` is called
# by means other than the `if` block below)
ctx.ensure_object(dict)

# Place the arguments in a context object
ctx.obj["subworkflows_repo_url"] = git_remote
ctx.obj["subworkflows_repo_branch"] = branch
ctx.obj["subworkflows_repo_no_pull"] = no_pull


# nf-core modules list subcommands
@modules.group()
@click.pass_context
Expand Down Expand Up @@ -855,6 +894,36 @@ def test_module(ctx, tool, no_prompts, pytest_args):
sys.exit(1)


# nf-core subworkflows create
@subworkflows.command("create")
@click.pass_context
@click.argument("subworkflow", type=str, required=False, metavar="subworkflow name")
@click.option("-d", "--dir", type=click.Path(exists=True), default=".", metavar="<directory>")
@click.option("-a", "--author", type=str, metavar="<author>", help="Module author's GitHub username prefixed with '@'")
@click.option("-f", "--force", is_flag=True, default=False, help="Overwrite any files if they already exist")
def create_subworkflow(ctx, subworkflow, dir, author, force):
"""
Create a new subworkflow from the nf-core template.

If the specified directory is a pipeline, this function creates a file called
'subworkflows/local/<subworkflow_name>.nf'

If the specified directory is a clone of nf-core/modules, it creates or modifies files
in 'subworkflows/', 'tests/subworkflows' and 'tests/config/pytest_modules.yml'
"""

# Run function
try:
subworkflow_create = nf_core.subworkflows.SubworkflowCreate(dir, subworkflow, author, force)
subworkflow_create.create()
except UserWarning as e:
log.critical(e)
sys.exit(1)
except LookupError as e:
log.error(e)
sys.exit(1)


# nf-core schema subcommands
@nf_core_cli.group()
def schema():
Expand Down
4 changes: 2 additions & 2 deletions nf_core/modules/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def create(self):

self.tool_name_underscore = self.tool_name.replace("/", "_")

# Check existance of directories early for fast-fail
# Check existence of directories early for fast-fail
self.file_paths = self.get_module_dirs()

# Try to find a bioconda package for 'tool'
Expand Down Expand Up @@ -246,7 +246,7 @@ def create(self):
"[violet]Will the module require a meta map of sample information?", default=True
)

# Create module template with cokiecutter
# Create module template with jinja
self.render_template()

if self.repo_type == "modules":
Expand Down
37 changes: 37 additions & 0 deletions nf_core/subworkflow-template/subworkflows/main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// TODO nf-core: If in doubt look at other nf-core/subworkflows to see how we are doing things! :)
// https://github.com/nf-core/modules/tree/master/subworkflows
// You can also ask for help via your pull request or on the #subworkflows channel on the nf-core Slack workspace:
// https://nf-co.re/join
// TODO nf-core: A subworkflow SHOULD only import modules not other subworkflows
// TODO nf-core: A subworkflow SHOULD import at least two modules

include { SAMTOOLS_SORT } from '../../../modules/nf-core/samtools/sort/main'
include { SAMTOOLS_INDEX } from '../../../modules/nf-core/samtools/index/main'

workflow {{ subworkflow_name|upper }} {

take:
// TODO nf-core: edit input (take) channels
ch_bam // channel: [ val(meta), [ bam ] ]

main:

ch_versions = Channel.empty()

// TODO nf-core: substitute modules here for the modules of your subworkflow

SAMTOOLS_SORT ( ch_bam )
ch_versions = ch_versions.mix(SAMTOOLS_SORT.out.versions.first())

SAMTOOLS_INDEX ( SAMTOOLS_SORT.out.bam )
ch_versions = ch_versions.mix(SAMTOOLS_INDEX.out.versions.first())

emit:
// TODO nf-core: edit emitted channels
bam = SAMTOOLS_SORT.out.bam // channel: [ val(meta), [ bam ] ]
bai = SAMTOOLS_INDEX.out.bai // channel: [ val(meta), [ bai ] ]
csi = SAMTOOLS_INDEX.out.csi // channel: [ val(meta), [ csi ] ]

versions = ch_versions // channel: [ versions.yml ]
}

48 changes: 48 additions & 0 deletions nf_core/subworkflow-template/subworkflows/meta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: "{{ subworkflow_name }}"
## TODO nf-core: Add a description of the subworkflow and list keywords
description: Sort SAM/BAM/CRAM file
keywords:
- sort
- bam
- sam
- cram
## TODO nf-core: Add a list of the modules used in the subworkflow
modules:
- samtools/sort
- samtools/index
## TODO nf-core: List all of the variables used as input, including their types and descriptions
input:
- meta:
type: map
description: |
Groovy Map containing sample information
e.g. [ id:'test' ]
- bam:
type: file
description: BAM/CRAM/SAM file
pattern: "*.{bam,cram,sam}"
## TODO nf-core: List all of the variables used as output, including their types and descriptions
output:
- meta:
type: map
description: |
Groovy Map containing sample information
e.g. [ id:'test' ]
- bam:
type: file
description: Sorted BAM/CRAM/SAM file
pattern: "*.{bam,cram,sam}"
- bai:
type: file
description: BAM/CRAM/SAM samtools index
pattern: "*.{bai,crai,sai}"
- csi:
type: file
description: CSI samtools index
pattern: "*.csi"
- versions:
type: file
description: File containing software versions
pattern: "versions.yml"
authors:
- "{{ author }}"
18 changes: 18 additions & 0 deletions nf_core/subworkflow-template/tests/main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env nextflow

nextflow.enable.dsl = 2

include { {{ subworkflow_name|upper }} } from '../../../../subworkflows/nf-core/{{ subworkflow_dir }}/main.nf'

workflow test_{{ subworkflow_name }} {
{% if has_meta %}
input = [
[ id:'test' ], // meta map
file(params.test_data['sarscov2']['illumina']['test_paired_end_bam'], checkIfExists: true)
]
{%- else %}
input = file(params.test_data['sarscov2']['illumina']['test_single_end_bam'], checkIfExists: true)
{%- endif %}

{{ subworkflow_name|upper }} ( input )
}
5 changes: 5 additions & 0 deletions nf_core/subworkflow-template/tests/nextflow.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
process {

publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }

}
12 changes: 12 additions & 0 deletions nf_core/subworkflow-template/tests/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## TODO nf-core: Please run the following command to build this file:
# nf-core subworkflows create-test-yml {{ subworkflow_name_underscore }}

- name: "{{ subworkflow_name }}"
command: nextflow run ./tests/subworkflows/nf-core/{{ subworkflow_dir }} -entry test_{{ subworkflow_name }} -c ./tests/config/nextflow.config -c ./tests/subworkflows/nf-core/{{ subworkflow_dir }}/nextflow.config
tags:
- "{{ subworkflow_name }}"
files:
- path: "output/{{ subworkflow_name }}/test.bam"
md5sum: e667c7caad0bc4b7ac383fd023c654fc
- path: output/{{ subworkflow_name }}/versions.yml
md5sum: a01fe51bc4c6a3a6226fbf77b2c7cf3b
1 change: 1 addition & 0 deletions nf_core/subworkflows/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .create import SubworkflowCreate
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载