From 513de9528235a5d90ed4c7f09427c9d399c384e5 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Mon, 21 Aug 2023 00:15:13 +0200 Subject: [PATCH 001/175] WIP: First stab at writing some Textual --- nf_core/__main__.py | 43 ++++++ nf_core/pipelines/create.py | 273 ++++++++++++++++++++++++++++++++++ nf_core/pipelines/create.tcss | 32 ++++ requirements-dev.txt | 1 + requirements.txt | 4 +- 5 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 nf_core/pipelines/create.py create mode 100644 nf_core/pipelines/create.tcss diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 72762ff026..f3f2d2bf55 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -488,6 +488,49 @@ def lint(ctx, dir, release, fix, key, show_passed, fail_ignored, fail_warned, ma sys.exit(1) +# nf-core pipelines subcommands +@nf_core_cli.group() +@click.pass_context +def pipelines(ctx): + """ + Commands to manage nf-core pipelines. + """ + # 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) + + +# nf-core pipeline install +@pipelines.command("create") +@click.pass_context +@click.option( + "-n", + "--name", + type=str, + help="The name of your new pipeline", +) +@click.option("-d", "--description", type=str, help="A short description of your pipeline") +@click.option("-a", "--author", type=str, help="Name of the main author(s)") +@click.option("--version", type=str, default="1.0dev", help="The initial version number to use") +@click.option("-f", "--force", is_flag=True, default=False, help="Overwrite output directory if it already exists") +@click.option("-o", "--outdir", help="Output directory for new pipeline (default: pipeline name)") +@click.option("-t", "--template-yaml", help="Pass a YAML file to customize the template") +@click.option("--plain", is_flag=True, help="Use the standard nf-core template") +def create_pipeline(ctx, name, description, author, version, force, outdir, template_yaml, plain): + """ + Create a new pipeline using the nf-core template. + + Uses the nf-core template to make a skeleton Nextflow pipeline with all required + files, boilerplate code and best-practices. + \n\n + Run without any command line arguments to use an interactive interface. + """ + from nf_core.pipelines.create import PipelineCreateApp + + app = PipelineCreateApp() + app.run() + + # nf-core modules subcommands @nf_core_cli.group() @click.option( diff --git a/nf_core/pipelines/create.py b/nf_core/pipelines/create.py new file mode 100644 index 0000000000..970d2dd8c5 --- /dev/null +++ b/nf_core/pipelines/create.py @@ -0,0 +1,273 @@ +"""A Textual app to create a pipeline.""" +from pydantic import BaseModel, field_validator, Field +import re +from typing import Optional +from textual import on +from textual.app import App, ComposeResult +from textual.screen import Screen +from textual.containers import Horizontal, Center +from textual.validation import Function, Validator, ValidationResult +from textual.widgets import Button, Footer, Header, Static, Markdown, Input, Pretty +from textwrap import dedent + + +class CreateConfig(BaseModel): + """Pydantic model for the nf-core create config.""" + + org: Optional[str] = None + name: Optional[str] = None + description: Optional[str] = None + author: Optional[str] = None + version: Optional[str] = None + force: Optional[bool] = None + outdir: Optional[str] = None + template_yaml: Optional[str] = None + is_nfcore: Optional[bool] = None + + @field_validator("name") + @classmethod + def name_nospecialchars(cls, v: str) -> str: + """Check that the pipeline name is simple.""" + if not re.match(r"^[a-z]+$", v): + raise ValueError("Must be lowercase without punctuation.") + return v + + @field_validator("org", "description", "author") + @classmethod + def notempty(cls, v: str) -> str: + """Check that string values are not empty.""" + if v.strip() == "": + raise ValueError("Cannot be left empty.") + return v + + +# Initialise as empty +TEMPLATE_CONFIG = CreateConfig() + + +class TextInput(Static): + """Widget for text inputs. + + Provides standard interface for a text input with help text + and validation messages. + """ + + def __init__(self, field_id, placeholder, description, default=None, **kwargs) -> None: + """Initialise the widget with our values. + + Pass on kwargs upstream for standard usage.""" + super().__init__(**kwargs) + self.field_id: str = field_id + self.placeholder: str = placeholder + self.description: str = description + self.default: str = default + + def compose(self) -> ComposeResult: + yield Static(self.description, classes="field_help") + yield Input( + placeholder=self.placeholder, + validators=[ValidateConfig(self.field_id)], + value=self.default, + ) + yield Static(classes="validation_msg") + + @on(Input.Changed) + def show_invalid_reasons(self, event: Input.Changed) -> None: + """Validate the text input and show errors if invalid.""" + if not event.validation_result.is_valid: + self.query_one(".validation_msg").update("\n".join(event.validation_result.failure_descriptions)) + else: + self.query_one(".validation_msg").update("") + + +class ValidateConfig(Validator): + """Validate any config value, using Pydantic.""" + + def __init__(self, key) -> None: + """Initialise the validator with the model key to validate.""" + super().__init__() + self.key = key + + def validate(self, value: str) -> ValidationResult: + """Try creating a Pydantic object with this key set to this value. + + If it fails, return the error messages.""" + try: + CreateConfig(**{f"{self.key}": value}) + return self.success() + except ValueError as e: + return self.failure(", ".join([err["msg"] for err in e.errors()])) + + +class WelcomeScreen(Screen): + """A welcome screen for the app.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Static( + f"\n[green]{' ' * 40},--.[grey39]/[green],-." + + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + "\n[green] `._,._,'\n", + id="logo", + ) + yield Markdown( + dedent( + """ + # nf-core create + + This app will help you create a new nf-core pipeline. + It uses the nf-core pipeline template, which is kept at + within the [nf-core/tools repository](https://github.com/nf-core/tools). + + Using this tool is mandatory when making a pipeline that may + be part of the nf-core community collection at some point. + However, this tool can also be used to create pipelines that will + never be part of nf-core. You can still benefit from the community + best practices for your own workflow. + """ + ) + ) + yield Center(Button("Let's go!", id="start", variant="success"), classes="cta") + + +class BasicDetails(Screen): + """Name, description, author, etc.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Markdown( + dedent( + """ + # Basic details + """ + ) + ) + with Horizontal(): + yield TextInput( + "org", + "Organisation", + "GitHub organisation", + "nf-core", + classes="column", + ) + yield TextInput( + "name", + "Pipeline Name", + "Workflow name", + classes="column", + ) + + yield TextInput( + "description", + "Description", + "A short description of your pipeline.", + ) + yield TextInput( + "author", + "Author(s)", + "Name of the main author / authors", + ) + yield Center( + Button("Next", variant="success"), + classes="cta", + ) + + @on(Button.Pressed) + def on_button_pressed(self, event: Button.Pressed) -> None: + """Save fields to the config.""" + config = {} + for text_input in self.query("TextInput"): + this_input = text_input.query_one(Input) + this_input.validate(this_input.value) + config[text_input.field_id] = this_input.value + try: + TEMPLATE_CONFIG = CreateConfig(**config) + self.parent.switch_screen("choose_type") + except ValueError as e: + pass + + +class ChoosePipelineType(Screen): + """Choose whether this will be an nf-core pipeline or not.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Markdown( + dedent( + """ + # To nf-core or not to nf-core? + + Next, we need to know what kind of pipeline this will be. + + Choose _"nf-core"_ if: + + * You want your pipeline to be part of the nf-core community + * You think that there's an outside chance that it ever _could_ be part of nf-core + + Choose _"Custom"_ if: + + * Your pipeline will _never_ be part of nf-core + * You want full control over *all* features that are included from the template + (including those that are mandatory for nf-core). + """ + ) + ) + yield Center( + Button("nf-core", id="type_nfcore", variant="success"), + Button("Custom", id="type_custom", variant="primary"), + classes="cta", + ) + yield Markdown( + dedent( + """ + ## Not sure? What's the difference? + + Choosing _"nf-core"_ effectively pre-selects the following template features: + + * GitHub Actions Continuous Integration (CI) configuration for the following: + * Small-scale (GitHub) and large-scale (AWS) tests + * Code format linting with prettier + * Auto-fix functionality using @nf-core-bot + * Marking old issues as stale + * Inclusion of shared nf-core config profiles + """ + ) + ) + + +class PipelineCreateApp(App): + """A Textual app to manage stopwatches.""" + + CSS_PATH = "create.tcss" + TITLE = "nf-core create" + SUB_TITLE = "Create a new pipeline with the nf-core pipeline template" + BINDINGS = [ + ("d", "toggle_dark", "Toggle dark mode"), + ("q", "quit", "Quit"), + ] + SCREENS = { + "welcome": WelcomeScreen(), + "basic_details": BasicDetails(), + "choose_type": ChoosePipelineType(), + } + + def on_mount(self) -> None: + self.push_screen("welcome") + + def on_button_pressed(self, event: Button.Pressed) -> None: + """Handle all button pressed events.""" + if event.button.id == "start": + self.switch_screen("basic_details") + elif event.button.id == "type_nfcore": + self.switch_screen("type_nfcore") + elif event.button.id == "type_custom": + self.switch_screen("type_custom") + + def action_toggle_dark(self) -> None: + """An action to toggle dark mode.""" + self.dark = not self.dark diff --git a/nf_core/pipelines/create.tcss b/nf_core/pipelines/create.tcss new file mode 100644 index 0000000000..079d51659f --- /dev/null +++ b/nf_core/pipelines/create.tcss @@ -0,0 +1,32 @@ +#logo { + text-align:center; +} +.cta { + layout: horizontal; + margin-bottom: 1; +} +.cta Button { + margin-left: 3; + margin-right: 3; +} + +.field_help { + padding: 1 1 0 1; + color: $text-muted; + text-style: italic; +} +.validation_msg { + padding: 0 1; + color: $error; +} +.-valid { + border: tall $success-darken-3; +} + +Horizontal{ + width: 100%; + height: auto; +} +.column { + width: 1fr; +} diff --git a/requirements-dev.txt b/requirements-dev.txt index 360f6ff87f..23d540ca85 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,3 +6,4 @@ pytest-datafiles responses Sphinx sphinx-rtd-theme +textual-dev>=1.1.0 diff --git a/requirements.txt b/requirements.txt index 9cc7fc6be5..b5fc542591 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,8 +7,9 @@ markdown>=3.3 packaging pre-commit prompt_toolkit>=3.0.3 -pytest>=7.0.0 +pydantic>=2.2.1 pytest-workflow>=1.6.0 +pytest>=7.0.0 pyyaml questionary>=1.8.0 refgenie @@ -17,3 +18,4 @@ requests_cache rich-click>=1.6.1 rich>=13.3.1 tabulate +textual>=0.33.0 From 0e8204e45358acf20e15c5e2ce304737ced0066e Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Mon, 21 Aug 2023 14:15:38 +0200 Subject: [PATCH 002/175] Refactor: Break into multiple files --- nf_core/pipelines/create.py | 273 --------------------- nf_core/pipelines/create/__init__.py | 52 ++++ nf_core/pipelines/create/basicdetails.py | 67 +++++ nf_core/pipelines/{ => create}/create.tcss | 0 nf_core/pipelines/create/pipelinetype.py | 49 ++++ nf_core/pipelines/create/utils.py | 91 +++++++ nf_core/pipelines/create/welcome.py | 36 +++ 7 files changed, 295 insertions(+), 273 deletions(-) delete mode 100644 nf_core/pipelines/create.py create mode 100644 nf_core/pipelines/create/__init__.py create mode 100644 nf_core/pipelines/create/basicdetails.py rename nf_core/pipelines/{ => create}/create.tcss (100%) create mode 100644 nf_core/pipelines/create/pipelinetype.py create mode 100644 nf_core/pipelines/create/utils.py create mode 100644 nf_core/pipelines/create/welcome.py diff --git a/nf_core/pipelines/create.py b/nf_core/pipelines/create.py deleted file mode 100644 index 970d2dd8c5..0000000000 --- a/nf_core/pipelines/create.py +++ /dev/null @@ -1,273 +0,0 @@ -"""A Textual app to create a pipeline.""" -from pydantic import BaseModel, field_validator, Field -import re -from typing import Optional -from textual import on -from textual.app import App, ComposeResult -from textual.screen import Screen -from textual.containers import Horizontal, Center -from textual.validation import Function, Validator, ValidationResult -from textual.widgets import Button, Footer, Header, Static, Markdown, Input, Pretty -from textwrap import dedent - - -class CreateConfig(BaseModel): - """Pydantic model for the nf-core create config.""" - - org: Optional[str] = None - name: Optional[str] = None - description: Optional[str] = None - author: Optional[str] = None - version: Optional[str] = None - force: Optional[bool] = None - outdir: Optional[str] = None - template_yaml: Optional[str] = None - is_nfcore: Optional[bool] = None - - @field_validator("name") - @classmethod - def name_nospecialchars(cls, v: str) -> str: - """Check that the pipeline name is simple.""" - if not re.match(r"^[a-z]+$", v): - raise ValueError("Must be lowercase without punctuation.") - return v - - @field_validator("org", "description", "author") - @classmethod - def notempty(cls, v: str) -> str: - """Check that string values are not empty.""" - if v.strip() == "": - raise ValueError("Cannot be left empty.") - return v - - -# Initialise as empty -TEMPLATE_CONFIG = CreateConfig() - - -class TextInput(Static): - """Widget for text inputs. - - Provides standard interface for a text input with help text - and validation messages. - """ - - def __init__(self, field_id, placeholder, description, default=None, **kwargs) -> None: - """Initialise the widget with our values. - - Pass on kwargs upstream for standard usage.""" - super().__init__(**kwargs) - self.field_id: str = field_id - self.placeholder: str = placeholder - self.description: str = description - self.default: str = default - - def compose(self) -> ComposeResult: - yield Static(self.description, classes="field_help") - yield Input( - placeholder=self.placeholder, - validators=[ValidateConfig(self.field_id)], - value=self.default, - ) - yield Static(classes="validation_msg") - - @on(Input.Changed) - def show_invalid_reasons(self, event: Input.Changed) -> None: - """Validate the text input and show errors if invalid.""" - if not event.validation_result.is_valid: - self.query_one(".validation_msg").update("\n".join(event.validation_result.failure_descriptions)) - else: - self.query_one(".validation_msg").update("") - - -class ValidateConfig(Validator): - """Validate any config value, using Pydantic.""" - - def __init__(self, key) -> None: - """Initialise the validator with the model key to validate.""" - super().__init__() - self.key = key - - def validate(self, value: str) -> ValidationResult: - """Try creating a Pydantic object with this key set to this value. - - If it fails, return the error messages.""" - try: - CreateConfig(**{f"{self.key}": value}) - return self.success() - except ValueError as e: - return self.failure(", ".join([err["msg"] for err in e.errors()])) - - -class WelcomeScreen(Screen): - """A welcome screen for the app.""" - - def compose(self) -> ComposeResult: - yield Header() - yield Footer() - yield Static( - f"\n[green]{' ' * 40},--.[grey39]/[green],-." - + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + "\n[green] `._,._,'\n", - id="logo", - ) - yield Markdown( - dedent( - """ - # nf-core create - - This app will help you create a new nf-core pipeline. - It uses the nf-core pipeline template, which is kept at - within the [nf-core/tools repository](https://github.com/nf-core/tools). - - Using this tool is mandatory when making a pipeline that may - be part of the nf-core community collection at some point. - However, this tool can also be used to create pipelines that will - never be part of nf-core. You can still benefit from the community - best practices for your own workflow. - """ - ) - ) - yield Center(Button("Let's go!", id="start", variant="success"), classes="cta") - - -class BasicDetails(Screen): - """Name, description, author, etc.""" - - def compose(self) -> ComposeResult: - yield Header() - yield Footer() - yield Markdown( - dedent( - """ - # Basic details - """ - ) - ) - with Horizontal(): - yield TextInput( - "org", - "Organisation", - "GitHub organisation", - "nf-core", - classes="column", - ) - yield TextInput( - "name", - "Pipeline Name", - "Workflow name", - classes="column", - ) - - yield TextInput( - "description", - "Description", - "A short description of your pipeline.", - ) - yield TextInput( - "author", - "Author(s)", - "Name of the main author / authors", - ) - yield Center( - Button("Next", variant="success"), - classes="cta", - ) - - @on(Button.Pressed) - def on_button_pressed(self, event: Button.Pressed) -> None: - """Save fields to the config.""" - config = {} - for text_input in self.query("TextInput"): - this_input = text_input.query_one(Input) - this_input.validate(this_input.value) - config[text_input.field_id] = this_input.value - try: - TEMPLATE_CONFIG = CreateConfig(**config) - self.parent.switch_screen("choose_type") - except ValueError as e: - pass - - -class ChoosePipelineType(Screen): - """Choose whether this will be an nf-core pipeline or not.""" - - def compose(self) -> ComposeResult: - yield Header() - yield Footer() - yield Markdown( - dedent( - """ - # To nf-core or not to nf-core? - - Next, we need to know what kind of pipeline this will be. - - Choose _"nf-core"_ if: - - * You want your pipeline to be part of the nf-core community - * You think that there's an outside chance that it ever _could_ be part of nf-core - - Choose _"Custom"_ if: - - * Your pipeline will _never_ be part of nf-core - * You want full control over *all* features that are included from the template - (including those that are mandatory for nf-core). - """ - ) - ) - yield Center( - Button("nf-core", id="type_nfcore", variant="success"), - Button("Custom", id="type_custom", variant="primary"), - classes="cta", - ) - yield Markdown( - dedent( - """ - ## Not sure? What's the difference? - - Choosing _"nf-core"_ effectively pre-selects the following template features: - - * GitHub Actions Continuous Integration (CI) configuration for the following: - * Small-scale (GitHub) and large-scale (AWS) tests - * Code format linting with prettier - * Auto-fix functionality using @nf-core-bot - * Marking old issues as stale - * Inclusion of shared nf-core config profiles - """ - ) - ) - - -class PipelineCreateApp(App): - """A Textual app to manage stopwatches.""" - - CSS_PATH = "create.tcss" - TITLE = "nf-core create" - SUB_TITLE = "Create a new pipeline with the nf-core pipeline template" - BINDINGS = [ - ("d", "toggle_dark", "Toggle dark mode"), - ("q", "quit", "Quit"), - ] - SCREENS = { - "welcome": WelcomeScreen(), - "basic_details": BasicDetails(), - "choose_type": ChoosePipelineType(), - } - - def on_mount(self) -> None: - self.push_screen("welcome") - - def on_button_pressed(self, event: Button.Pressed) -> None: - """Handle all button pressed events.""" - if event.button.id == "start": - self.switch_screen("basic_details") - elif event.button.id == "type_nfcore": - self.switch_screen("type_nfcore") - elif event.button.id == "type_custom": - self.switch_screen("type_custom") - - def action_toggle_dark(self) -> None: - """An action to toggle dark mode.""" - self.dark = not self.dark diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py new file mode 100644 index 0000000000..4de661675a --- /dev/null +++ b/nf_core/pipelines/create/__init__.py @@ -0,0 +1,52 @@ +"""A Textual app to create a pipeline.""" +from pydantic import BaseModel, field_validator, Field +import re +from typing import Optional +from textual import on +from textual.app import App, ComposeResult +from textual.screen import Screen +from textual.containers import Horizontal, Center +from textual.validation import Function, Validator, ValidationResult +from textual.widgets import Button, Footer, Header, Static, Markdown, Input, Pretty +from textwrap import dedent + +from nf_core.pipelines.create.utils import CreateConfig +from nf_core.pipelines.create.welcome import WelcomeScreen +from nf_core.pipelines.create.basicdetails import BasicDetails +from nf_core.pipelines.create.pipelinetype import ChoosePipelineType + + +class PipelineCreateApp(App): + """A Textual app to manage stopwatches.""" + + CSS_PATH = "create.tcss" + TITLE = "nf-core create" + SUB_TITLE = "Create a new pipeline with the nf-core pipeline template" + BINDINGS = [ + ("d", "toggle_dark", "Toggle dark mode"), + ("q", "quit", "Quit"), + ] + SCREENS = { + "welcome": WelcomeScreen(), + "basic_details": BasicDetails(), + "choose_type": ChoosePipelineType(), + } + + # Initialise config as empty + TEMPLATE_CONFIG = CreateConfig() + + def on_mount(self) -> None: + self.push_screen("welcome") + + def on_button_pressed(self, event: Button.Pressed) -> None: + """Handle all button pressed events.""" + if event.button.id == "start": + self.switch_screen("basic_details") + elif event.button.id == "type_nfcore": + self.switch_screen("type_nfcore") + elif event.button.id == "type_custom": + self.switch_screen("type_custom") + + def action_toggle_dark(self) -> None: + """An action to toggle dark mode.""" + self.dark = not self.dark diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py new file mode 100644 index 0000000000..63b99ed402 --- /dev/null +++ b/nf_core/pipelines/create/basicdetails.py @@ -0,0 +1,67 @@ +"""A Textual app to create a pipeline.""" +from textual import on +from textual.app import ComposeResult +from textual.screen import Screen +from textual.containers import Horizontal, Center +from textual.widgets import Button, Footer, Header, Markdown, Input +from textwrap import dedent + +from nf_core.pipelines.create.utils import CreateConfig, TextInput + + +class BasicDetails(Screen): + """Name, description, author, etc.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Markdown( + dedent( + """ + # Basic details + """ + ) + ) + with Horizontal(): + yield TextInput( + "org", + "Organisation", + "GitHub organisation", + "nf-core", + classes="column", + ) + yield TextInput( + "name", + "Pipeline Name", + "Workflow name", + classes="column", + ) + + yield TextInput( + "description", + "Description", + "A short description of your pipeline.", + ) + yield TextInput( + "author", + "Author(s)", + "Name of the main author / authors", + ) + yield Center( + Button("Next", variant="success"), + classes="cta", + ) + + @on(Button.Pressed) + def on_button_pressed(self, event: Button.Pressed) -> None: + """Save fields to the config.""" + config = {} + for text_input in self.query("TextInput"): + this_input = text_input.query_one(Input) + this_input.validate(this_input.value) + config[text_input.field_id] = this_input.value + try: + self.parent.TEMPLATE_CONFIG = CreateConfig(**config) + self.parent.switch_screen("choose_type") + except ValueError: + pass diff --git a/nf_core/pipelines/create.tcss b/nf_core/pipelines/create/create.tcss similarity index 100% rename from nf_core/pipelines/create.tcss rename to nf_core/pipelines/create/create.tcss diff --git a/nf_core/pipelines/create/pipelinetype.py b/nf_core/pipelines/create/pipelinetype.py new file mode 100644 index 0000000000..72624c5f80 --- /dev/null +++ b/nf_core/pipelines/create/pipelinetype.py @@ -0,0 +1,49 @@ +from textual.app import ComposeResult +from textual.screen import Screen +from textual.containers import Center +from textual.widgets import Button, Footer, Header, Markdown + +markdown_intro = """ +# To nf-core or not to nf-core? + +Next, we need to know what kind of pipeline this will be. + +Choose _"nf-core"_ if: + +* You want your pipeline to be part of the nf-core community +* You think that there's an outside chance that it ever _could_ be part of nf-core + +Choose _"Custom"_ if: + +* Your pipeline will _never_ be part of nf-core +* You want full control over *all* features that are included from the template + (including those that are mandatory for nf-core). +""" + +markdown_details = """ +## Not sure? What's the difference? + +Choosing _"nf-core"_ effectively pre-selects the following template features: + +* GitHub Actions Continuous Integration (CI) configuration for the following: + * Small-scale (GitHub) and large-scale (AWS) tests + * Code format linting with prettier + * Auto-fix functionality using @nf-core-bot + * Marking old issues as stale +* Inclusion of shared nf-core config profiles +""" + + +class ChoosePipelineType(Screen): + """Choose whether this will be an nf-core pipeline or not.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Markdown(markdown_intro) + yield Center( + Button("nf-core", id="type_nfcore", variant="success"), + Button("Custom", id="type_custom", variant="primary"), + classes="cta", + ) + yield Markdown(markdown_details) diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py new file mode 100644 index 0000000000..017040d7dd --- /dev/null +++ b/nf_core/pipelines/create/utils.py @@ -0,0 +1,91 @@ +from pydantic import BaseModel, field_validator +import re +from typing import Optional +from textual import on +from textual.app import ComposeResult +from textual.validation import Validator, ValidationResult +from textual.widgets import Static, Input + + +class CreateConfig(BaseModel): + """Pydantic model for the nf-core create config.""" + + org: Optional[str] = None + name: Optional[str] = None + description: Optional[str] = None + author: Optional[str] = None + version: Optional[str] = None + force: Optional[bool] = None + outdir: Optional[str] = None + template_yaml: Optional[str] = None + is_nfcore: Optional[bool] = None + + @field_validator("name") + @classmethod + def name_nospecialchars(cls, v: str) -> str: + """Check that the pipeline name is simple.""" + if not re.match(r"^[a-z]+$", v): + raise ValueError("Must be lowercase without punctuation.") + return v + + @field_validator("org", "description", "author") + @classmethod + def notempty(cls, v: str) -> str: + """Check that string values are not empty.""" + if v.strip() == "": + raise ValueError("Cannot be left empty.") + return v + + +class TextInput(Static): + """Widget for text inputs. + + Provides standard interface for a text input with help text + and validation messages. + """ + + def __init__(self, field_id, placeholder, description, default=None, **kwargs) -> None: + """Initialise the widget with our values. + + Pass on kwargs upstream for standard usage.""" + super().__init__(**kwargs) + self.field_id: str = field_id + self.placeholder: str = placeholder + self.description: str = description + self.default: str = default + + def compose(self) -> ComposeResult: + yield Static(self.description, classes="field_help") + yield Input( + placeholder=self.placeholder, + validators=[ValidateConfig(self.field_id)], + value=self.default, + ) + yield Static(classes="validation_msg") + + @on(Input.Changed) + def show_invalid_reasons(self, event: Input.Changed) -> None: + """Validate the text input and show errors if invalid.""" + if not event.validation_result.is_valid: + self.query_one(".validation_msg").update("\n".join(event.validation_result.failure_descriptions)) + else: + self.query_one(".validation_msg").update("") + + +class ValidateConfig(Validator): + """Validate any config value, using Pydantic.""" + + def __init__(self, key) -> None: + """Initialise the validator with the model key to validate.""" + super().__init__() + self.key = key + + def validate(self, value: str) -> ValidationResult: + """Try creating a Pydantic object with this key set to this value. + + If it fails, return the error messages.""" + try: + CreateConfig(**{f"{self.key}": value}) + return self.success() + except ValueError as e: + return self.failure(", ".join([err["msg"] for err in e.errors()])) diff --git a/nf_core/pipelines/create/welcome.py b/nf_core/pipelines/create/welcome.py new file mode 100644 index 0000000000..2e75ec597b --- /dev/null +++ b/nf_core/pipelines/create/welcome.py @@ -0,0 +1,36 @@ +from textual.app import ComposeResult +from textual.screen import Screen +from textual.containers import Center +from textual.widgets import Button, Footer, Header, Static, Markdown + +markdown = """ +# nf-core create + +This app will help you create a new nf-core pipeline. +It uses the nf-core pipeline template, which is kept at +within the [nf-core/tools repository](https://github.com/nf-core/tools). + +Using this tool is mandatory when making a pipeline that may +be part of the nf-core community collection at some point. +However, this tool can also be used to create pipelines that will +never be part of nf-core. You can still benefit from the community +best practices for your own workflow. +""" + + +class WelcomeScreen(Screen): + """A welcome screen for the app.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Static( + f"\n[green]{' ' * 40},--.[grey39]/[green],-." + + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + "\n[green] `._,._,'\n", + id="logo", + ) + yield Markdown(markdown) + yield Center(Button("Let's go!", id="start", variant="success"), classes="cta") From e37d2e522cda72e59fe259eb4a394708cf428bc7 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Mon, 21 Aug 2023 14:16:16 +0200 Subject: [PATCH 003/175] Remove unusued imports --- nf_core/pipelines/create/__init__.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 4de661675a..7d339a1aa1 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -1,14 +1,6 @@ """A Textual app to create a pipeline.""" -from pydantic import BaseModel, field_validator, Field -import re -from typing import Optional -from textual import on -from textual.app import App, ComposeResult -from textual.screen import Screen -from textual.containers import Horizontal, Center -from textual.validation import Function, Validator, ValidationResult -from textual.widgets import Button, Footer, Header, Static, Markdown, Input, Pretty -from textwrap import dedent +from textual.app import App +from textual.widgets import Button from nf_core.pipelines.create.utils import CreateConfig from nf_core.pipelines.create.welcome import WelcomeScreen From ee12eb5df27ae198a0b9f57bb96a8592da52bee6 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 22 Aug 2023 13:43:47 +0200 Subject: [PATCH 004/175] show error message when pressing enter --- nf_core/pipelines/create/utils.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 017040d7dd..c5e85aeffa 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -1,10 +1,11 @@ -from pydantic import BaseModel, field_validator import re from typing import Optional + +from pydantic import BaseModel, field_validator from textual import on from textual.app import ComposeResult -from textual.validation import Validator, ValidationResult -from textual.widgets import Static, Input +from textual.validation import ValidationResult, Validator +from textual.widgets import Input, Static class CreateConfig(BaseModel): @@ -64,7 +65,8 @@ def compose(self) -> ComposeResult: yield Static(classes="validation_msg") @on(Input.Changed) - def show_invalid_reasons(self, event: Input.Changed) -> None: + @on(Input.Submitted) + def show_invalid_reasons(self, event: Input.Changed | Input.Submitted) -> None: """Validate the text input and show errors if invalid.""" if not event.validation_result.is_valid: self.query_one(".validation_msg").update("\n".join(event.validation_result.failure_descriptions)) From dd18bcc90b520cc010a296812c5a93efa9507745 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 22 Aug 2023 15:32:04 +0200 Subject: [PATCH 005/175] show failure messages when button is pressed --- nf_core/pipelines/create/basicdetails.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py index 63b99ed402..5ffae135c9 100644 --- a/nf_core/pipelines/create/basicdetails.py +++ b/nf_core/pipelines/create/basicdetails.py @@ -1,10 +1,11 @@ """A Textual app to create a pipeline.""" +from textwrap import dedent + from textual import on from textual.app import ComposeResult +from textual.containers import Center, Horizontal from textual.screen import Screen -from textual.containers import Horizontal, Center -from textual.widgets import Button, Footer, Header, Markdown, Input -from textwrap import dedent +from textual.widgets import Button, Footer, Header, Input, Markdown from nf_core.pipelines.create.utils import CreateConfig, TextInput @@ -58,8 +59,12 @@ def on_button_pressed(self, event: Button.Pressed) -> None: config = {} for text_input in self.query("TextInput"): this_input = text_input.query_one(Input) - this_input.validate(this_input.value) + validation_result = this_input.validate(this_input.value) config[text_input.field_id] = this_input.value + if not validation_result.is_valid: + text_input.query_one(".validation_msg").update("\n".join(validation_result.failure_descriptions)) + else: + text_input.query_one(".validation_msg").update("") try: self.parent.TEMPLATE_CONFIG = CreateConfig(**config) self.parent.switch_screen("choose_type") From 486f180f876c38a906687daa1b494db0b9239bcb Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 22 Aug 2023 17:20:59 +0200 Subject: [PATCH 006/175] add usegenomicdata screen (TODO on_button_pressed) --- nf_core/pipelines/create/__init__.py | 8 ++-- nf_core/pipelines/create/usegenomicdata.py | 47 ++++++++++++++++++++++ nf_core/pipelines/create/utils.py | 2 +- 3 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 nf_core/pipelines/create/usegenomicdata.py diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 7d339a1aa1..5d8eee2bc1 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -2,10 +2,11 @@ from textual.app import App from textual.widgets import Button -from nf_core.pipelines.create.utils import CreateConfig -from nf_core.pipelines.create.welcome import WelcomeScreen from nf_core.pipelines.create.basicdetails import BasicDetails from nf_core.pipelines.create.pipelinetype import ChoosePipelineType +from nf_core.pipelines.create.usegenomicdata import UseGenomicData +from nf_core.pipelines.create.utils import CreateConfig +from nf_core.pipelines.create.welcome import WelcomeScreen class PipelineCreateApp(App): @@ -22,6 +23,7 @@ class PipelineCreateApp(App): "welcome": WelcomeScreen(), "basic_details": BasicDetails(), "choose_type": ChoosePipelineType(), + "genomic_data": UseGenomicData(), } # Initialise config as empty @@ -37,7 +39,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: elif event.button.id == "type_nfcore": self.switch_screen("type_nfcore") elif event.button.id == "type_custom": - self.switch_screen("type_custom") + self.switch_screen("genomic_data") def action_toggle_dark(self) -> None: """An action to toggle dark mode.""" diff --git a/nf_core/pipelines/create/usegenomicdata.py b/nf_core/pipelines/create/usegenomicdata.py new file mode 100644 index 0000000000..591e7893aa --- /dev/null +++ b/nf_core/pipelines/create/usegenomicdata.py @@ -0,0 +1,47 @@ +from textual import on +from textual.app import ComposeResult +from textual.containers import Center +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Markdown + +markdown_intro = """ +## You are now creating a custom pipeline + +# Will your pipeline use genomic data? + +Nf-core pipelines are configured to use a copy of the most common reference genome files. + +By selecting this option, your pipeline will include a configuration file specifying the paths to these files. + +The required code to use these files will also be included in the template. +When the pipeline user provides an appropriate genome key, +the pipeline will automatically download the required reference files. + +For more information about reference genomes in nf-core pipelines, +see the [nf-core docs](https://nf-co.re/docs/usage/reference_genomes). +""" + + +class UseGenomicData(Screen): + """Select if the pipeline will use genomic data.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Markdown(markdown_intro) + yield Center( + Button("Use genomic data", id="true", variant="success"), + Button("Skip genomic data", id="false", variant="primary"), + classes="cta", + ) + + @on(Button.Pressed) + def on_button_pressed(self, event: Button.Pressed) -> None: + """Save answer to the config.""" + try: + # TODO + # self.parent.TEMPLATE_CONFIG.template_yaml["skip"] = [True if event.button.id == "true" else False] + # self.parent.switch_screen("continuous_integration") + pass + except ValueError: + pass diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index c5e85aeffa..3823011a8e 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -18,7 +18,7 @@ class CreateConfig(BaseModel): version: Optional[str] = None force: Optional[bool] = None outdir: Optional[str] = None - template_yaml: Optional[str] = None + template_yaml: Optional[dict] = None is_nfcore: Optional[bool] = None @field_validator("name") From 5b8cfd5eb9fe7d72b8fd5b1ad11071662f8adb5c Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 23 Aug 2023 17:04:49 +0200 Subject: [PATCH 007/175] add custom pipeline switch table to select pipeline features --- nf_core/pipelines/create/__init__.py | 6 +- nf_core/pipelines/create/create.tcss | 39 +++++++++++ nf_core/pipelines/create/custompipeline.py | 80 ++++++++++++++++++++++ nf_core/pipelines/create/usegenomicdata.py | 47 ------------- 4 files changed, 122 insertions(+), 50 deletions(-) create mode 100644 nf_core/pipelines/create/custompipeline.py delete mode 100644 nf_core/pipelines/create/usegenomicdata.py diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 5d8eee2bc1..f8d5efd288 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -3,8 +3,8 @@ from textual.widgets import Button from nf_core.pipelines.create.basicdetails import BasicDetails +from nf_core.pipelines.create.custompipeline import CustomPipeline from nf_core.pipelines.create.pipelinetype import ChoosePipelineType -from nf_core.pipelines.create.usegenomicdata import UseGenomicData from nf_core.pipelines.create.utils import CreateConfig from nf_core.pipelines.create.welcome import WelcomeScreen @@ -23,7 +23,7 @@ class PipelineCreateApp(App): "welcome": WelcomeScreen(), "basic_details": BasicDetails(), "choose_type": ChoosePipelineType(), - "genomic_data": UseGenomicData(), + "type_custom": CustomPipeline(), } # Initialise config as empty @@ -39,7 +39,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: elif event.button.id == "type_nfcore": self.switch_screen("type_nfcore") elif event.button.id == "type_custom": - self.switch_screen("genomic_data") + self.switch_screen("type_custom") def action_toggle_dark(self) -> None: """An action to toggle dark mode.""" diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index 079d51659f..ee00a1e918 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -10,6 +10,20 @@ margin-right: 3; } +.custom_grid { + height: auto; +} +.custom_grid Switch { + width: auto; +} +.custom_grid Static { + width: 1fr; + margin: 1 8; +} +.custom_grid Button { + width: auto; +} + .field_help { padding: 1 1 0 1; color: $text-muted; @@ -30,3 +44,28 @@ Horizontal{ .column { width: 1fr; } + +/* Display help messages */ + +.help_box { + background: white; + margin-left: 15; + margin-right: 25; + margin-bottom: 1; + display: none; +} +.displayed .help_box { + display: block; +} +#show_help { + display: block; +} +#hide_help { + display: none; +} +.displayed #show_help { + display: none; +} +.displayed #hide_help { + display: block; +} diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py new file mode 100644 index 0000000000..a857eb545f --- /dev/null +++ b/nf_core/pipelines/create/custompipeline.py @@ -0,0 +1,80 @@ +from textual import on +from textual.app import ComposeResult +from textual.containers import Center, Horizontal +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Markdown, Static, Switch + +markdown_genomes = """ +Nf-core pipelines are configured to use a copy of the most common reference genome files. + +By selecting this option, your pipeline will include a configuration file specifying the paths to these files. + +The required code to use these files will also be included in the template. +When the pipeline user provides an appropriate genome key, +the pipeline will automatically download the required reference files. + +For more information about reference genomes in nf-core pipelines, +see the [nf-core docs](https://nf-co.re/docs/usage/reference_genomes). +""" + +markdown_ci = """ +Add Github Continuous Integration tests +""" + + +class HelpText(Markdown): + """A class to show a text box with help text.""" + + def __init__(self, markdown: str, classes: str, id: str) -> None: + super().__init__(markdown=markdown, classes=classes, id=id) + + def show(self) -> None: + """Method to show the help text box.""" + self.add_class("displayed") + + def hide(self) -> None: + """Method to hide the help text box.""" + self.remove_class("displayed") + + +class CustomPipeline(Screen): + """Select if the pipeline will use genomic data.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Horizontal( + Switch(value=True), + Static("Use reference genomes"), + Button("Show help", id="show_help", name="genomes", variant="primary"), + Button("Hide help", id="hide_help", name="genomes"), + classes="custom_grid", + ) + yield HelpText(markdown_genomes, classes="help_box", id="genomes") + + yield Horizontal( + Switch(value=True), + Static("Include GitHub Continuous Integration (CI) tests"), + Button("Show help", id="show_help", name="ci", variant="primary"), + Button("Hide help", id="hide_help", name="ci"), + classes="custom_grid", + ) + yield HelpText(markdown_ci, classes="help_box", id="ci") + + yield Center( + Button("Done", id="done", variant="success"), + classes="cta", + ) + + @on(Button.Pressed) + def on_button_pressed(self, event: Button.Pressed) -> None: + """Save answer to the config.""" + help_text = self.query_one(f"#{event.button.name}", HelpText) + if event.button.id == "show_help": + help_text.show() + self.add_class("displayed") + elif event.button.id == "hide_help": + help_text.hide() + self.remove_class("displayed") + elif event.button.id == "done": + pass diff --git a/nf_core/pipelines/create/usegenomicdata.py b/nf_core/pipelines/create/usegenomicdata.py deleted file mode 100644 index 591e7893aa..0000000000 --- a/nf_core/pipelines/create/usegenomicdata.py +++ /dev/null @@ -1,47 +0,0 @@ -from textual import on -from textual.app import ComposeResult -from textual.containers import Center -from textual.screen import Screen -from textual.widgets import Button, Footer, Header, Markdown - -markdown_intro = """ -## You are now creating a custom pipeline - -# Will your pipeline use genomic data? - -Nf-core pipelines are configured to use a copy of the most common reference genome files. - -By selecting this option, your pipeline will include a configuration file specifying the paths to these files. - -The required code to use these files will also be included in the template. -When the pipeline user provides an appropriate genome key, -the pipeline will automatically download the required reference files. - -For more information about reference genomes in nf-core pipelines, -see the [nf-core docs](https://nf-co.re/docs/usage/reference_genomes). -""" - - -class UseGenomicData(Screen): - """Select if the pipeline will use genomic data.""" - - def compose(self) -> ComposeResult: - yield Header() - yield Footer() - yield Markdown(markdown_intro) - yield Center( - Button("Use genomic data", id="true", variant="success"), - Button("Skip genomic data", id="false", variant="primary"), - classes="cta", - ) - - @on(Button.Pressed) - def on_button_pressed(self, event: Button.Pressed) -> None: - """Save answer to the config.""" - try: - # TODO - # self.parent.TEMPLATE_CONFIG.template_yaml["skip"] = [True if event.button.id == "true" else False] - # self.parent.switch_screen("continuous_integration") - pass - except ValueError: - pass From 0a40dab34c6e11b8cc878460f8eb86930ed8778b Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 24 Aug 2023 13:42:44 +0200 Subject: [PATCH 008/175] create new widget PipelineFeature to display feature buttons and help text --- nf_core/pipelines/create/__init__.py | 2 + nf_core/pipelines/create/create.tcss | 7 ++ nf_core/pipelines/create/custompipeline.py | 76 ++++++++++++---------- 3 files changed, 50 insertions(+), 35 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index f8d5efd288..a207ec7484 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -40,6 +40,8 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.switch_screen("type_nfcore") elif event.button.id == "type_custom": self.switch_screen("type_custom") + elif event.button.id == "custom_done": + pass def action_toggle_dark(self) -> None: """An action to toggle dark mode.""" diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index ee00a1e918..7a86dec6bc 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -45,6 +45,13 @@ Horizontal{ width: 1fr; } +HorizontalScroll { + width: 100%; +} +.feature_subtitle { + color: grey; +} + /* Display help messages */ .help_box { diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index a857eb545f..1a0fc9bbae 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -1,6 +1,5 @@ -from textual import on from textual.app import ComposeResult -from textual.containers import Center, Horizontal +from textual.containers import Center, HorizontalScroll, ScrollableContainer from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown, Static, Switch @@ -25,8 +24,8 @@ class HelpText(Markdown): """A class to show a text box with help text.""" - def __init__(self, markdown: str, classes: str, id: str) -> None: - super().__init__(markdown=markdown, classes=classes, id=id) + def __init__(self, markdown: str, classes: str) -> None: + super().__init__(markdown=markdown, classes=classes) def show(self) -> None: """Method to show the help text box.""" @@ -37,44 +36,51 @@ def hide(self) -> None: self.remove_class("displayed") -class CustomPipeline(Screen): - """Select if the pipeline will use genomic data.""" +class PipelineFeature(Static): + """Widget for the selection of pipeline features.""" + + def __init__(self, markdown: str, title: str, subtitle: str) -> None: + self.markdown = markdown + self.title = title + self.subtitle = subtitle + super().__init__() + + def on_button_pressed(self, event: Button.Pressed) -> None: + """When the button is pressed, change the type of the button.""" + if event.button.id == "show_help": + self.add_class("displayed") + elif event.button.id == "hide_help": + self.remove_class("displayed") def compose(self) -> ComposeResult: - yield Header() - yield Footer() - yield Horizontal( - Switch(value=True), - Static("Use reference genomes"), - Button("Show help", id="show_help", name="genomes", variant="primary"), - Button("Hide help", id="hide_help", name="genomes"), - classes="custom_grid", - ) - yield HelpText(markdown_genomes, classes="help_box", id="genomes") + """ + Create child widgets. - yield Horizontal( + Displayed row with a switch, a short text description and a help button. + Hidden row with a help text box. + """ + yield HorizontalScroll( Switch(value=True), - Static("Include GitHub Continuous Integration (CI) tests"), - Button("Show help", id="show_help", name="ci", variant="primary"), - Button("Hide help", id="hide_help", name="ci"), + Static(self.title, classes="feature_title"), + Static(self.subtitle, classes="feature_subtitle"), + Button("Show help", id="show_help", variant="primary"), + Button("Hide help", id="hide_help"), classes="custom_grid", ) - yield HelpText(markdown_ci, classes="help_box", id="ci") + yield HelpText(self.markdown, classes="help_box") + +class CustomPipeline(Screen): + """Select if the pipeline will use genomic data.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield ScrollableContainer( + PipelineFeature(markdown_genomes, "Use reference genomes", "Include reference genome files"), + PipelineFeature(markdown_ci, "Add Github CI tests", "Include GitHub Continuous Integration (CI) tests"), + ) yield Center( - Button("Done", id="done", variant="success"), + Button("Done", id="custom_done", variant="success"), classes="cta", ) - - @on(Button.Pressed) - def on_button_pressed(self, event: Button.Pressed) -> None: - """Save answer to the config.""" - help_text = self.query_one(f"#{event.button.name}", HelpText) - if event.button.id == "show_help": - help_text.show() - self.add_class("displayed") - elif event.button.id == "hide_help": - help_text.hide() - self.remove_class("displayed") - elif event.button.id == "done": - pass From 39b9e3c206bbf61ace886e909721b3d306473922 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 24 Aug 2023 16:02:51 +0200 Subject: [PATCH 009/175] add more custom features --- nf_core/pipelines/create/custompipeline.py | 53 ++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 1a0fc9bbae..47663f5bb8 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -17,7 +17,36 @@ """ markdown_ci = """ -Add Github Continuous Integration tests +Nf-core provides a set of Continuous Integration (CI) tests for Github. +When you open a pull request (PR) on your pipeline repository, these tests will run automatically. + +There are different types of tests: +* Linting tests check that your code is formatted correctly and that it adheres to nf-core standards + For code linting they will use [prettier](https://prettier.io/). +* Pipeline tests run your pipeline on a small dataset to check that it works + These tests are run with a small test dataset on GitHub and a larger test dataset on AWS +* Marking old issues as stale +""" + +markdown_badges = """ +The pipeline `README.md` will include badges for: +* AWS CI Tests +* Zenodo DOI +* Nextflow +* Conda +* Docker +* Singularity +* Launching on Nextflow Tower +""" + +markdown_configuration = """ +Nf-core has a repository with a collection of configuration profiles. + +Those config files define a set of parameters which are specific to compute environments at different Institutions. +They can be used within all nf-core pipelines. +If you are likely to be running nf-core pipelines regularly it is a good idea to use or create a custom config file for your organisation. + +For more information about nf-core configuration profiles, see the [nf-core/configs repository](https://github.com/nf-core/configs) """ @@ -77,8 +106,26 @@ def compose(self) -> ComposeResult: yield Header() yield Footer() yield ScrollableContainer( - PipelineFeature(markdown_genomes, "Use reference genomes", "Include reference genome files"), - PipelineFeature(markdown_ci, "Add Github CI tests", "Include GitHub Continuous Integration (CI) tests"), + PipelineFeature( + markdown_genomes, + "Use reference genomes", + "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", + ), + PipelineFeature( + markdown_ci, + "Add Github CI tests", + "The pipeline will include several GitHub actions for Continuous Integration (CI) testing", + ), + PipelineFeature( + markdown_badges, + "Add Github badges", + "The README.md file of the pipeline will include GitHub badges", + ), + PipelineFeature( + markdown_configuration, + "Add configuration files", + "The pipeline will include configuration profiles containing custom parameters requried to run nf-core pipelines at different institutions", + ), ) yield Center( Button("Done", id="custom_done", variant="success"), From 25c9fa1c92b593a7970a1366c87d01429204f0c0 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 25 Aug 2023 11:07:04 +0200 Subject: [PATCH 010/175] add template features to skip to TEMPLATE_CONFIG --- nf_core/pipelines/create/custompipeline.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 47663f5bb8..409c260418 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -1,5 +1,7 @@ +from textual import on from textual.app import ComposeResult from textual.containers import Center, HorizontalScroll, ScrollableContainer +from textual.reactive import reactive from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown, Static, Switch @@ -68,10 +70,11 @@ def hide(self) -> None: class PipelineFeature(Static): """Widget for the selection of pipeline features.""" - def __init__(self, markdown: str, title: str, subtitle: str) -> None: + def __init__(self, markdown: str, title: str, subtitle: str, field_id: str) -> None: self.markdown = markdown self.title = title self.subtitle = subtitle + self.field_id = field_id super().__init__() def on_button_pressed(self, event: Button.Pressed) -> None: @@ -89,7 +92,7 @@ def compose(self) -> ComposeResult: Hidden row with a help text box. """ yield HorizontalScroll( - Switch(value=True), + Switch(value=True, id=self.field_id), Static(self.title, classes="feature_title"), Static(self.subtitle, classes="feature_subtitle"), Button("Show help", id="show_help", variant="primary"), @@ -110,24 +113,39 @@ def compose(self) -> ComposeResult: markdown_genomes, "Use reference genomes", "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", + "igenomes", ), PipelineFeature( markdown_ci, "Add Github CI tests", "The pipeline will include several GitHub actions for Continuous Integration (CI) testing", + "ci", ), PipelineFeature( markdown_badges, "Add Github badges", "The README.md file of the pipeline will include GitHub badges", + "github_badges", ), PipelineFeature( markdown_configuration, "Add configuration files", "The pipeline will include configuration profiles containing custom parameters requried to run nf-core pipelines at different institutions", + "nf_core_configs", ), ) yield Center( Button("Done", id="custom_done", variant="success"), classes="cta", ) + + @on(Button.Pressed) + def on_button_pressed(self, event: Button.Pressed) -> None: + """Save fields to the config.""" + skip = [] + for feature_input in self.query("PipelineFeature"): + this_switch = feature_input.query_one(Switch) + if not this_switch.value: + skip.append(this_switch.id) + self.parent.TEMPLATE_CONFIG.template_yaml = {"skip": skip} + self.parent.switch_screen("custom_done") From 610cbd901e1d9fd9ebb76f5ef754c1b3f13b6964 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 28 Aug 2023 10:14:24 +0200 Subject: [PATCH 011/175] animate help box --- nf_core/pipelines/create/__init__.py | 2 -- nf_core/pipelines/create/create.tcss | 6 ++++++ nf_core/pipelines/create/custompipeline.py | 15 ++++++++------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index a207ec7484..f8d5efd288 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -40,8 +40,6 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.switch_screen("type_nfcore") elif event.button.id == "type_custom": self.switch_screen("type_custom") - elif event.button.id == "custom_done": - pass def action_toggle_dark(self) -> None: """An action to toggle dark mode.""" diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index 7a86dec6bc..39bc8d9076 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -59,10 +59,16 @@ HorizontalScroll { margin-left: 15; margin-right: 25; margin-bottom: 1; + overflow-y: scroll; display: none; + + height: 0; } .displayed .help_box { display: block; + + transition: height 50ms; + height: 10; } #show_help { display: block; diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 409c260418..259e5bd29c 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -142,10 +142,11 @@ def compose(self) -> ComposeResult: @on(Button.Pressed) def on_button_pressed(self, event: Button.Pressed) -> None: """Save fields to the config.""" - skip = [] - for feature_input in self.query("PipelineFeature"): - this_switch = feature_input.query_one(Switch) - if not this_switch.value: - skip.append(this_switch.id) - self.parent.TEMPLATE_CONFIG.template_yaml = {"skip": skip} - self.parent.switch_screen("custom_done") + if event.button.id == "custom_done": + skip = [] + for feature_input in self.query("PipelineFeature"): + this_switch = feature_input.query_one(Switch) + if not this_switch.value: + skip.append(this_switch.id) + self.parent.TEMPLATE_CONFIG.template_yaml = {"skip": skip} + self.parent.switch_screen("custom_done") From 6677144045ddd92e73fd1db74b221af8e9d6ef08 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 29 Aug 2023 13:48:51 +0200 Subject: [PATCH 012/175] add type_nfcore screen and use PipelineCreate to create a pipeline --- nf_core/__main__.py | 15 ++++++++++- nf_core/pipelines/create/__init__.py | 6 ++++- nf_core/pipelines/create/custompipeline.py | 19 +++++++------- nf_core/pipelines/create/nfcorepipeline.py | 29 ++++++++++++++++++++++ 4 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 nf_core/pipelines/create/nfcorepipeline.py diff --git a/nf_core/__main__.py b/nf_core/__main__.py index f3f2d2bf55..4b926931a7 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -525,10 +525,23 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp \n\n Run without any command line arguments to use an interactive interface. """ + from nf_core.create import PipelineCreate from nf_core.pipelines.create import PipelineCreateApp app = PipelineCreateApp() - app.run() + config = app.run() + + create_obj = PipelineCreate( + config.name, + config.description, + config.author, + version=config.version, + force=config.force, + outdir=config.outdir, + template_yaml_path=config.template_yaml, + plain=config.is_nfcore, + ) + create_obj.init_pipeline() # nf-core modules subcommands diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index f8d5efd288..10182c6feb 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -4,12 +4,13 @@ from nf_core.pipelines.create.basicdetails import BasicDetails from nf_core.pipelines.create.custompipeline import CustomPipeline +from nf_core.pipelines.create.nfcorepipeline import NfcorePipeline from nf_core.pipelines.create.pipelinetype import ChoosePipelineType from nf_core.pipelines.create.utils import CreateConfig from nf_core.pipelines.create.welcome import WelcomeScreen -class PipelineCreateApp(App): +class PipelineCreateApp(App[CreateConfig]): """A Textual app to manage stopwatches.""" CSS_PATH = "create.tcss" @@ -24,6 +25,7 @@ class PipelineCreateApp(App): "basic_details": BasicDetails(), "choose_type": ChoosePipelineType(), "type_custom": CustomPipeline(), + "type_nfcore": NfcorePipeline(), } # Initialise config as empty @@ -40,6 +42,8 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.switch_screen("type_nfcore") elif event.button.id == "type_custom": self.switch_screen("type_custom") + elif event.button.id == "done": + self.exit(self.TEMPLATE_CONFIG) def action_toggle_dark(self) -> None: """An action to toggle dark mode.""" diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 259e5bd29c..6e62095ac9 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -135,18 +135,17 @@ def compose(self) -> ComposeResult: ), ) yield Center( - Button("Done", id="custom_done", variant="success"), + Button("Done", id="done", variant="success"), classes="cta", ) - @on(Button.Pressed) + @on(Button.Pressed, "#done") def on_button_pressed(self, event: Button.Pressed) -> None: """Save fields to the config.""" - if event.button.id == "custom_done": - skip = [] - for feature_input in self.query("PipelineFeature"): - this_switch = feature_input.query_one(Switch) - if not this_switch.value: - skip.append(this_switch.id) - self.parent.TEMPLATE_CONFIG.template_yaml = {"skip": skip} - self.parent.switch_screen("custom_done") + skip = [] + for feature_input in self.query("PipelineFeature"): + this_switch = feature_input.query_one(Switch) + if not this_switch.value: + skip.append(this_switch.id) + self.parent.TEMPLATE_CONFIG.template_yaml = {"skip": skip} + self.parent.TEMPLATE_CONFIG.is_nfcore = False diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py new file mode 100644 index 0000000000..817e09e780 --- /dev/null +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -0,0 +1,29 @@ +from textual import on +from textual.app import ComposeResult +from textual.containers import Center, HorizontalScroll, ScrollableContainer +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Markdown, Static, Switch + + +class NfcorePipeline(Screen): + """Select if the pipeline will use genomic data.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + # TODO: add features to customise the pipeline template + yield Center( + Button("Done", id="done", variant="success"), + classes="cta", + ) + + @on(Button.Pressed, "#done") + def on_button_pressed(self, event: Button.Pressed) -> None: + """Save fields to the config.""" + skip = [] + for feature_input in self.query("PipelineFeature"): + this_switch = feature_input.query_one(Switch) + if not this_switch.value: + skip.append(this_switch.id) + self.parent.TEMPLATE_CONFIG.template_yaml = {"skip": skip} + self.parent.TEMPLATE_CONFIG.is_nfcore = True From 8bac0bed341e96756ca854dd367e916d12671631 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 29 Aug 2023 14:06:43 +0200 Subject: [PATCH 013/175] modify PipelineCreate to accept a template dictionary --- nf_core/__main__.py | 1 + nf_core/create.py | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 4b926931a7..dafeb77576 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -539,6 +539,7 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp force=config.force, outdir=config.outdir, template_yaml_path=config.template_yaml, + organisation=config.org, plain=config.is_nfcore, ) create_obj.init_pipeline() diff --git a/nf_core/create.py b/nf_core/create.py index 470623f551..6fd4c4d25c 100644 --- a/nf_core/create.py +++ b/nf_core/create.py @@ -40,6 +40,7 @@ class PipelineCreate: outdir (str): Path to the local output directory. template_yaml_path (str): Path to template.yml file for pipeline creation settings. plain (bool): If true the Git repository will be initialized plain. + organisation (str): Name of the GitHub organisation to create the pipeline. Will be the prefix of the pipeline. default_branch (str): Specifies the --initial-branch name. """ @@ -54,10 +55,11 @@ def __init__( outdir=None, template_yaml_path=None, plain=False, + organisation="nf-core", default_branch=None, ): self.template_params, skip_paths_keys, self.template_yaml = self.create_param_dict( - name, description, author, version, template_yaml_path, plain, outdir if outdir else "." + name, description, author, organisation, version, template_yaml_path, plain, outdir if outdir else "." ) skippable_paths = { @@ -90,13 +92,16 @@ def __init__( outdir = os.path.join(os.getcwd(), self.template_params["name_noslash"]) self.outdir = Path(outdir) - def create_param_dict(self, name, description, author, version, template_yaml_path, plain, pipeline_dir): + def create_param_dict( + self, name, description, author, organisation, version, template_yaml_path, plain, pipeline_dir + ): """Creates a dictionary of parameters for the new pipeline. Args: name (str): Name for the pipeline. description (str): Description for the pipeline. author (str): Authors name of the pipeline. + organisation (str): Name of the GitHub organisation to create the pipeline. version (str): Version flag. template_yaml_path (str): Path to YAML file containing template parameters. plain (bool): If true the pipeline template will be initialized plain, without customisation. @@ -108,8 +113,11 @@ def create_param_dict(self, name, description, author, version, template_yaml_pa # Obtain template customization info from template yaml file or `.nf-core.yml` config file try: if template_yaml_path is not None: - with open(template_yaml_path, "r") as f: - template_yaml = yaml.safe_load(f) + if isinstance(template_yaml_path, str): + with open(template_yaml_path, "r") as f: + template_yaml = yaml.safe_load(f) + else: + template_yaml = template_yaml_path elif "template" in config_yml: template_yaml = config_yml["template"] else: @@ -150,7 +158,10 @@ def create_param_dict(self, name, description, author, version, template_yaml_pa template_yaml.update(self.customize_template(template_areas)) # Now look in the template for more options, otherwise default to nf-core defaults - param_dict["prefix"] = template_yaml.get("prefix", "nf-core") + if "prefix" in template_yaml: + log.info(f"Using organisation name found in {template_yaml_path}") + organisation = template_yaml.get("prefix") + param_dict["prefix"] = organisation param_dict["branded"] = param_dict["prefix"] == "nf-core" skip_paths = [] if param_dict["branded"] else ["branded"] From 43db7f62cb588d1c9b9ec05c9c60a45e6c12d6f3 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 30 Aug 2023 18:21:39 +0200 Subject: [PATCH 014/175] start modifying nf-core create command to use TUI and not CLI --- nf_core/__main__.py | 93 +++---- nf_core/create.py | 290 ++++++++++----------- nf_core/pipelines/create/custompipeline.py | 2 +- nf_core/pipelines/create/nfcorepipeline.py | 2 +- nf_core/pipelines/create/utils.py | 6 +- 5 files changed, 174 insertions(+), 219 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index dafeb77576..63d43f8cfc 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -367,47 +367,6 @@ def licences(pipeline, json): sys.exit(1) -# nf-core create -@nf_core_cli.command() -@click.option( - "-n", - "--name", - type=str, - help="The name of your new pipeline", -) -@click.option("-d", "--description", type=str, help="A short description of your pipeline") -@click.option("-a", "--author", type=str, help="Name of the main author(s)") -@click.option("--version", type=str, default="1.0dev", help="The initial version number to use") -@click.option("-f", "--force", is_flag=True, default=False, help="Overwrite output directory if it already exists") -@click.option("-o", "--outdir", help="Output directory for new pipeline (default: pipeline name)") -@click.option("-t", "--template-yaml", help="Pass a YAML file to customize the template") -@click.option("--plain", is_flag=True, help="Use the standard nf-core template") -def create(name, description, author, version, force, outdir, template_yaml, plain): - """ - Create a new pipeline using the nf-core template. - - Uses the nf-core template to make a skeleton Nextflow pipeline with all required - files, boilerplate code and best-practices. - """ - from nf_core.create import PipelineCreate - - try: - create_obj = PipelineCreate( - name, - description, - author, - version=version, - force=force, - outdir=outdir, - template_yaml_path=template_yaml, - plain=plain, - ) - create_obj.init_pipeline() - except UserWarning as e: - log.error(e) - sys.exit(1) - - # nf-core lint @nf_core_cli.command() @click.option( @@ -500,7 +459,7 @@ def pipelines(ctx): ctx.ensure_object(dict) -# nf-core pipeline install +# nf-core pipeline create @pipelines.command("create") @click.pass_context @click.option( @@ -515,8 +474,12 @@ def pipelines(ctx): @click.option("-f", "--force", is_flag=True, default=False, help="Overwrite output directory if it already exists") @click.option("-o", "--outdir", help="Output directory for new pipeline (default: pipeline name)") @click.option("-t", "--template-yaml", help="Pass a YAML file to customize the template") -@click.option("--plain", is_flag=True, help="Use the standard nf-core template") -def create_pipeline(ctx, name, description, author, version, force, outdir, template_yaml, plain): +@click.option( + "--organisation", + type=str, + help="The name of the GitHub organisation where the pipeline will be hosted (default: nf-core", +) +def create_pipeline(ctx, name, description, author, version, force, outdir, template_yaml, organisation): """ Create a new pipeline using the nf-core template. @@ -528,21 +491,33 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp from nf_core.create import PipelineCreate from nf_core.pipelines.create import PipelineCreateApp - app = PipelineCreateApp() - config = app.run() - - create_obj = PipelineCreate( - config.name, - config.description, - config.author, - version=config.version, - force=config.force, - outdir=config.outdir, - template_yaml_path=config.template_yaml, - organisation=config.org, - plain=config.is_nfcore, - ) - create_obj.init_pipeline() + if (name and description and author) or (template_yaml): + # If all command arguments are used, run without the interactive interface + config = organisation if template_yaml else None + else: + log.info( + "Ignoring provided arguments. Launching interactive nf-core pipeline creation tool." + "\nRun with all command line arguments to avoid using an interactive interface." + ) + app = PipelineCreateApp() + config = app.run() + print(config) + + try: + create_obj = PipelineCreate( + name, + description, + author, + version=version, + force=force, + outdir=outdir, + template_config=config, + organisation=organisation, + ) + create_obj.init_pipeline() + except UserWarning as e: + log.error(e) + sys.exit(1) # nf-core modules subcommands diff --git a/nf_core/create.py b/nf_core/create.py index 6fd4c4d25c..a60bfac75d 100644 --- a/nf_core/create.py +++ b/nf_core/create.py @@ -22,6 +22,7 @@ import nf_core.schema import nf_core.utils from nf_core.lint_utils import run_prettier_on_file +from nf_core.pipelines.create.utils import CreateConfig log = logging.getLogger(__name__) @@ -38,9 +39,9 @@ class PipelineCreate: force (bool): Overwrites a given workflow directory with the same name. Defaults to False. May the force be with you. outdir (str): Path to the local output directory. - template_yaml_path (str): Path to template.yml file for pipeline creation settings. - plain (bool): If true the Git repository will be initialized plain. + template_config (str|CreateConfig): Path to template.yml file for pipeline creation settings. or pydantic model with the customisation for pipeline creation settings. organisation (str): Name of the GitHub organisation to create the pipeline. Will be the prefix of the pipeline. + from_config_file (bool): If true the pipeline will be created from the `.nf-core.yml` config file. default_branch (str): Specifies the --initial-branch name. """ @@ -53,13 +54,26 @@ def __init__( no_git=False, force=False, outdir=None, - template_yaml_path=None, - plain=False, + template_config=None, organisation="nf-core", + from_config_file=False, default_branch=None, ): - self.template_params, skip_paths_keys, self.template_yaml = self.create_param_dict( - name, description, author, organisation, version, template_yaml_path, plain, outdir if outdir else "." + if template_config is not None and isinstance(template_config, str): + # Obtain a CreateConfig object from the template yaml file + self.config = self.check_template_yaml_info(template_config, name, description, author) + self.update_config(self, organisation, version, force, outdir if outdir else ".") + elif isinstance(template_config, CreateConfig): + self.config = template_config + elif from_config_file: + # Try reading config file + _, config_yml = nf_core.utils.load_tools_config(outdir if outdir else ".") + # Obtain a CreateConfig object from `.nf-core.yml` config file + if "template" in config_yml: + self.config = CreateConfig(**config_yml["template"]) + + self.skip_areas, skip_paths = self.obtain_skipped_areas_dict( + self.config.skip_features, outdir if outdir else "." ) skippable_paths = { @@ -77,65 +91,96 @@ def __init__( ], } # Get list of files we're skipping with the supplied skip keys - self.skip_paths = set(sp for k in skip_paths_keys for sp in skippable_paths[k]) + self.skip_paths = set(sp for k in skip_paths for sp in skippable_paths[k]) # Set convenience variables - self.name = self.template_params["name"] + self.name = self.config.name # Set fields used by the class methods - self.no_git = ( - no_git if self.template_params["github"] else True - ) # Set to True if template was configured without github hosting + self.no_git = no_git self.default_branch = default_branch self.force = force if outdir is None: - outdir = os.path.join(os.getcwd(), self.template_params["name_noslash"]) + outdir = os.path.join(os.getcwd(), self.config.name_noslash) self.outdir = Path(outdir) - def create_param_dict( - self, name, description, author, organisation, version, template_yaml_path, plain, pipeline_dir - ): - """Creates a dictionary of parameters for the new pipeline. + def check_template_yaml_info(self, template_yaml, name, description, author): + """Ensure that the provided template yaml file contains the necessary information. Args: + template_yaml (str): Template yaml file. name (str): Name for the pipeline. description (str): Description for the pipeline. author (str): Authors name of the pipeline. - organisation (str): Name of the GitHub organisation to create the pipeline. - version (str): Version flag. - template_yaml_path (str): Path to YAML file containing template parameters. - plain (bool): If true the pipeline template will be initialized plain, without customisation. - pipeline_dir (str): Path to the pipeline directory. - """ - # Try reading config file - _, config_yml = nf_core.utils.load_tools_config(pipeline_dir) + Returns: + CreateConfig: Pydantic model for the nf-core create config. + + Raises: + UserWarning: if template yaml file does not contain all the necessary information. + UserWarning: if template yaml file does not exist. + """ # Obtain template customization info from template yaml file or `.nf-core.yml` config file try: - if template_yaml_path is not None: - if isinstance(template_yaml_path, str): - with open(template_yaml_path, "r") as f: - template_yaml = yaml.safe_load(f) - else: - template_yaml = template_yaml_path - elif "template" in config_yml: - template_yaml = config_yml["template"] - else: - template_yaml = {} + with open(template_yaml, "r") as f: + template_yaml = yaml.safe_load(f) + config = CreateConfig(**template_yaml) except FileNotFoundError: - raise UserWarning(f"Template YAML file '{template_yaml_path}' not found.") + raise UserWarning(f"Template YAML file '{template_yaml}' not found.") + + missing_fields = [] + if config.name is None and name is None: + missing_fields.append("name") + elif config.name is None: + config.name = name + if config.description is None and description is None: + missing_fields.append("description") + elif config.description is None: + config.description = description + if config.author is None and author is None: + missing_fields.append("author") + elif config.author is None: + config.author = author + if len(missing_fields) > 0: + raise UserWarning( + f"Template YAML file does not contain the following required fields: {', '.join(missing_fields)}" + ) + + return config - param_dict = {} - # Get the necessary parameters either from the template or command line arguments - param_dict["name"] = self.get_param("name", name, template_yaml, template_yaml_path) - param_dict["description"] = self.get_param("description", description, template_yaml, template_yaml_path) - param_dict["author"] = self.get_param("author", author, template_yaml, template_yaml_path) + def update_config(self, organisation, version, force, pipeline_dir): + """Updates the config file with arguments provided through command line. - if "version" in template_yaml: - if version is not None: - log.info(f"Overriding --version with version found in {template_yaml_path}") - version = template_yaml["version"] - param_dict["version"] = version + Args: + organisation (str): Name of the GitHub organisation to create the pipeline. + version (str): Version of the pipeline. + force (bool): Overwrites a given workflow directory with the same name. + pipeline_dir (str): Path to the local output directory. + """ + if self.config.org is None: + self.config.org = organisation + if self.config.version is None: + self.config.version = version + if self.config.force is None: + self.config.force = force + if self.config.outdir is None: + self.config.outdir = pipeline_dir + if self.config.is_nfcore is None: + self.config.is_nfcore = True if organisation == "nf-core" else False + + def obtain_skipped_areas_dict(self, features_to_skip, pipeline_dir): + """Creates a dictionary of parameters for the new pipeline. + + Args: + features_to_skip (list): List of template features/areas to skip. + pipeline_dir (str): Path to the pipeline directory. + + Returns: + skip_areas (dict): Dictionary of template areas to skip with values true/false. + skip_paths (list): List of template areas which contain paths to skip. + """ + # Try reading config file + _, config_yml = nf_core.utils.load_tools_config(pipeline_dir) # Define the different template areas, and what actions to take for each # if they are skipped @@ -147,115 +192,48 @@ def create_param_dict( "nf_core_configs": {"name": "nf-core/configs", "file": False, "content": True}, } - # Once all necessary parameters are set, check if the user wants to customize the template more - if template_yaml_path is None and not plain: - customize_template = questionary.confirm( - "Do you want to customize which parts of the template are used?", - style=nf_core.utils.nfcore_question_style, - default=False, - ).unsafe_ask() - if customize_template: - template_yaml.update(self.customize_template(template_areas)) - - # Now look in the template for more options, otherwise default to nf-core defaults - if "prefix" in template_yaml: - log.info(f"Using organisation name found in {template_yaml_path}") - organisation = template_yaml.get("prefix") - param_dict["prefix"] = organisation - param_dict["branded"] = param_dict["prefix"] == "nf-core" - - skip_paths = [] if param_dict["branded"] else ["branded"] - + skip_paths = [] + skip_areas = {} for t_area in template_areas: - areas_to_skip = template_yaml.get("skip", []) - if isinstance(areas_to_skip, str): - areas_to_skip = [areas_to_skip] - if t_area in areas_to_skip: + if t_area in features_to_skip: if template_areas[t_area]["file"]: skip_paths.append(t_area) - param_dict[t_area] = False + skip_areas[t_area] = False else: - param_dict[t_area] = True + skip_areas[t_area] = True + # If github is selected, exclude also github_badges - if not param_dict["github"]: - param_dict["github_badges"] = False + # if not param_dict["github"]: + # param_dict["github_badges"] = False # Set the last parameters based on the ones provided - param_dict["short_name"] = ( - param_dict["name"].lower().replace(r"/\s+/", "-").replace(f"{param_dict['prefix']}/", "").replace("/", "-") + self.config.short_name = ( + self.config.name.lower().replace(r"/\s+/", "-").replace(f"{self.config.org}/", "").replace("/", "-") ) - param_dict["name"] = f"{param_dict['prefix']}/{param_dict['short_name']}" - param_dict["name_noslash"] = param_dict["name"].replace("/", "-") - param_dict["prefix_nodash"] = param_dict["prefix"].replace("-", "") - param_dict["name_docker"] = param_dict["name"].replace(param_dict["prefix"], param_dict["prefix_nodash"]) - param_dict["logo_light"] = f"{param_dict['name_noslash']}_logo_light.png" - param_dict["logo_dark"] = f"{param_dict['name_noslash']}_logo_dark.png" - param_dict["version"] = version + self.config.name = f"{self.config.org}/{self.config.short_name}" + self.config.name_noslash = self.config.name.replace("/", "-") + self.config.prefix_nodash = self.config.org.replace("-", "") + self.config.name_docker = self.config.name.replace(self.config.org, self.config.prefix_nodash) + self.config.logo_light = f"{self.config.name_noslash}_logo_light.png" + self.config.logo_dark = f"{self.config.name_noslash}_logo_dark.png" if ( "lint" in config_yml and "nextflow_config" in config_yml["lint"] and "manifest.name" in config_yml["lint"]["nextflow_config"] ): - return param_dict, skip_paths, template_yaml + return skip_areas, skip_paths # Check that the pipeline name matches the requirements - if not re.match(r"^[a-z]+$", param_dict["short_name"]): - if param_dict["prefix"] == "nf-core": + if not re.match(r"^[a-z]+$", self.config.short_name): + if self.config.is_nfcore: raise UserWarning("[red]Invalid workflow name: must be lowercase without punctuation.") else: log.warning( "Your workflow name is not lowercase without punctuation. This may cause Nextflow errors.\nConsider changing the name to avoid special characters." ) - return param_dict, skip_paths, template_yaml - - def customize_template(self, template_areas): - """Customizes the template parameters. - - Args: - template_areas (list): List of available template areas to skip. - """ - template_yaml = {} - prefix = questionary.text("Pipeline prefix", style=nf_core.utils.nfcore_question_style).unsafe_ask() - while not re.match(r"^[a-zA-Z_][a-zA-Z0-9-_]*$", prefix): - log.error("[red]Pipeline prefix cannot start with digit or hyphen and cannot contain punctuation.[/red]") - prefix = questionary.text( - "Please provide a new pipeline prefix", style=nf_core.utils.nfcore_question_style - ).unsafe_ask() - template_yaml["prefix"] = prefix - - choices = [{"name": template_areas[area]["name"], "value": area} for area in template_areas] - template_yaml["skip"] = questionary.checkbox( - "Skip template areas?", choices=choices, style=nf_core.utils.nfcore_question_style - ).unsafe_ask() - return template_yaml - - def get_param(self, param_name, passed_value, template_yaml, template_yaml_path): - if param_name in template_yaml: - if passed_value is not None: - log.info(f"overriding --{param_name} with name found in {template_yaml_path}") - passed_value = template_yaml[param_name] - if passed_value is None: - passed_value = getattr(self, f"prompt_wf_{param_name}")() - return passed_value - - def prompt_wf_name(self): - wf_name = questionary.text("Workflow name", style=nf_core.utils.nfcore_question_style).unsafe_ask() - while not re.match(r"^[a-z]+$", wf_name): - log.error("[red]Invalid workflow name: must be lowercase without punctuation.") - wf_name = questionary.text( - "Please provide a new workflow name", style=nf_core.utils.nfcore_question_style - ).unsafe_ask() - return wf_name - - def prompt_wf_description(self): - wf_description = questionary.text("Description", style=nf_core.utils.nfcore_question_style).unsafe_ask() - return wf_description - - def prompt_wf_author(self): - wf_author = questionary.text("Author", style=nf_core.utils.nfcore_question_style).unsafe_ask() - return wf_author + return skip_areas, skip_paths def init_pipeline(self): """Creates the nf-core pipeline.""" @@ -267,7 +245,7 @@ def init_pipeline(self): if not self.no_git: self.git_init_pipeline() - if self.template_params["branded"]: + if self.config.is_nfcore: log.info( "[green bold]!!!!!! IMPORTANT !!!!!!\n\n" "[green not bold]If you are interested in adding your pipeline to the nf-core community,\n" @@ -283,30 +261,32 @@ def render_template(self): # Check if the output directory exists if self.outdir.exists(): if self.force: - log.warning(f"Output directory '{self.outdir}' exists - continuing as --force specified") + log.warning( + f"Output directory '{self.outdir}' exists - removing the existing directory as --force specified" + ) + shutil.rmtree(self.outdir) else: log.error(f"Output directory '{self.outdir}' exists!") log.info("Use -f / --force to overwrite existing files") sys.exit(1) - else: - os.makedirs(self.outdir) + os.makedirs(self.outdir) # Run jinja2 for each file in the template folder env = jinja2.Environment( loader=jinja2.PackageLoader("nf_core", "pipeline-template"), keep_trailing_newline=True ) template_dir = os.path.join(os.path.dirname(__file__), "pipeline-template") - object_attrs = self.template_params + object_attrs = self.config.model_dump() object_attrs["nf_core_version"] = nf_core.__version__ # Can't use glob.glob() as need recursive hidden dotfiles - https://stackoverflow.com/a/58126417/713980 template_files = list(Path(template_dir).glob("**/*")) template_files += list(Path(template_dir).glob("*")) ignore_strs = [".pyc", "__pycache__", ".pyo", ".pyd", ".DS_Store", ".egg"] - short_name = self.template_params["short_name"] + short_name = self.config.short_name rename_files = { "workflows/pipeline.nf": f"workflows/{short_name}.nf", - "lib/WorkflowPipeline.groovy": f"lib/Workflow{short_name[0].upper()}{short_name[1:]}.groovy", + "lib/WorkflowPipeline.groovy": f"lib/Workflow{short_name.title()}.groovy", } # Set the paths to skip according to customization @@ -361,14 +341,14 @@ def render_template(self): os.chmod(output_path, template_stat.st_mode) # Remove all unused parameters in the nextflow schema - if not self.template_params["igenomes"] or not self.template_params["nf_core_configs"]: + if not self.skip_areas["igenomes"] or not self.skip_areas["nf_core_configs"]: self.update_nextflow_schema() - if self.template_params["branded"]: + if self.config.is_nfcore: # Make a logo and save it, if it is a nf-core pipeline self.make_pipeline_logo() else: - if self.template_params["github"]: + if self.skip_areas["github"]: # Remove field mentioning nf-core docs # in the github bug report template self.remove_nf_core_in_bug_report_template() @@ -376,10 +356,10 @@ def render_template(self): # Update the .nf-core.yml with linting configurations self.fix_linting() - if self.template_yaml: + if self.config: config_fn, config_yml = nf_core.utils.load_tools_config(self.outdir) with open(self.outdir / config_fn, "w") as fh: - config_yml.update(template=self.template_yaml) + config_yml.update(template=self.config.model_dump()) yaml.safe_dump(config_yml, fh) log.debug(f"Dumping pipeline template yml to pipeline config file '{config_fn.name}'") run_prettier_on_file(self.outdir / config_fn) @@ -423,7 +403,7 @@ def fix_linting(self): for a customized pipeline. """ # Create a lint config - short_name = self.template_params["short_name"] + short_name = self.skip_areas["short_name"] lint_config = { "files_exist": [ "CODE_OF_CONDUCT.md", @@ -448,7 +428,7 @@ def fix_linting(self): } # Add GitHub hosting specific configurations - if not self.template_params["github"]: + if not self.skip_areas["github"]: lint_config["files_exist"].extend( [ ".github/ISSUE_TEMPLATE/bug_report.yml", @@ -474,7 +454,7 @@ def fix_linting(self): ) # Add CI specific configurations - if not self.template_params["ci"]: + if not self.skip_areas["ci"]: lint_config["files_exist"].extend( [ ".github/workflows/branch.yml", @@ -485,7 +465,7 @@ def fix_linting(self): ) # Add custom config specific configurations - if not self.template_params["nf_core_configs"]: + if not self.skip_areas["nf_core_configs"]: lint_config["files_exist"].extend(["conf/igenomes.config"]) lint_config["nextflow_config"].extend( [ @@ -497,15 +477,15 @@ def fix_linting(self): ) # Add igenomes specific configurations - if not self.template_params["igenomes"]: + if not self.skip_areas["igenomes"]: lint_config["files_exist"].extend(["conf/igenomes.config"]) # Add github badges specific configurations - if not self.template_params["github_badges"] or not self.template_params["github"]: + if not self.skip_areas["github_badges"] or not self.skip_areas["github"]: lint_config["readme"] = ["nextflow_badge"] # If the pipeline is unbranded - if not self.template_params["branded"]: + if not self.skip_areas["branded"]: lint_config["files_unchanged"].extend([".github/ISSUE_TEMPLATE/bug_report.yml"]) # Add the lint content to the preexisting nf-core config @@ -519,16 +499,14 @@ def fix_linting(self): def make_pipeline_logo(self): """Fetch a logo for the new pipeline from the nf-core website""" - logo_url = f"https://nf-co.re/logo/{self.template_params['short_name']}?theme=light" + logo_url = f"https://nf-co.re/logo/{self.config.short_name}?theme=light" log.debug(f"Fetching logo from {logo_url}") - email_logo_path = self.outdir / "assets" / f"{self.template_params['name_noslash']}_logo_light.png" + email_logo_path = self.outdir / "assets" / f"{self.config.name_noslash}_logo_light.png" self.download_pipeline_logo(f"{logo_url}?w=600&theme=light", email_logo_path) for theme in ["dark", "light"]: readme_logo_url = f"{logo_url}?w=600&theme={theme}" - readme_logo_path = ( - self.outdir / "docs" / "images" / f"{self.template_params['name_noslash']}_logo_{theme}.png" - ) + readme_logo_path = self.outdir / "docs" / "images" / f"{self.config.name_noslash}_logo_{theme}.png" self.download_pipeline_logo(readme_logo_url, readme_logo_path) def download_pipeline_logo(self, url, img_fn): diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 6e62095ac9..ad5d4fbe0e 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -147,5 +147,5 @@ def on_button_pressed(self, event: Button.Pressed) -> None: this_switch = feature_input.query_one(Switch) if not this_switch.value: skip.append(this_switch.id) - self.parent.TEMPLATE_CONFIG.template_yaml = {"skip": skip} + self.parent.TEMPLATE_CONFIG.skip_features = skip self.parent.TEMPLATE_CONFIG.is_nfcore = False diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py index 817e09e780..b1b5af8163 100644 --- a/nf_core/pipelines/create/nfcorepipeline.py +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -25,5 +25,5 @@ def on_button_pressed(self, event: Button.Pressed) -> None: this_switch = feature_input.query_one(Switch) if not this_switch.value: skip.append(this_switch.id) - self.parent.TEMPLATE_CONFIG.template_yaml = {"skip": skip} + self.parent.TEMPLATE_CONFIG.skip_features = skip self.parent.TEMPLATE_CONFIG.is_nfcore = True diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 3823011a8e..0fb743299e 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -1,7 +1,7 @@ import re from typing import Optional -from pydantic import BaseModel, field_validator +from pydantic import BaseModel, ConfigDict, field_validator from textual import on from textual.app import ComposeResult from textual.validation import ValidationResult, Validator @@ -18,9 +18,11 @@ class CreateConfig(BaseModel): version: Optional[str] = None force: Optional[bool] = None outdir: Optional[str] = None - template_yaml: Optional[dict] = None + skip_features: Optional[dict] = None is_nfcore: Optional[bool] = None + model_config = ConfigDict(extra="allow") + @field_validator("name") @classmethod def name_nospecialchars(cls, v: str) -> str: From 99f426af80a483107b8a5f41cdf950a7c38332f6 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 31 Aug 2023 09:31:40 +0200 Subject: [PATCH 015/175] small bug fixes and add a deprecation message for nf-core create command --- nf_core/__main__.py | 59 ++++++++++++++++++++++++++-- nf_core/create.py | 11 ++++-- nf_core/pipelines/create/create.tcss | 2 +- nf_core/pipelines/create/utils.py | 2 +- nf_core/pipelines/create/welcome.py | 6 +-- 5 files changed, 67 insertions(+), 13 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 63d43f8cfc..beeb687374 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -459,7 +459,7 @@ def pipelines(ctx): ctx.ensure_object(dict) -# nf-core pipeline create +# nf-core pipelines create @pipelines.command("create") @click.pass_context @click.option( @@ -493,15 +493,14 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp if (name and description and author) or (template_yaml): # If all command arguments are used, run without the interactive interface - config = organisation if template_yaml else None + config = None else: log.info( - "Ignoring provided arguments. Launching interactive nf-core pipeline creation tool." + "Launching interactive nf-core pipeline creation tool." "\nRun with all command line arguments to avoid using an interactive interface." ) app = PipelineCreateApp() config = app.run() - print(config) try: create_obj = PipelineCreate( @@ -520,6 +519,58 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp sys.exit(1) +# nf-core create (deprecated) +@nf_core_cli.command(hidden=True, deprecated=True) +@click.option( + "-n", + "--name", + type=str, + help="The name of your new pipeline", +) +@click.option("-d", "--description", type=str, help="A short description of your pipeline") +@click.option("-a", "--author", type=str, help="Name of the main author(s)") +@click.option("--version", type=str, default="1.0dev", help="The initial version number to use") +@click.option("-f", "--force", is_flag=True, default=False, help="Overwrite output directory if it already exists") +@click.option("-o", "--outdir", help="Output directory for new pipeline (default: pipeline name)") +@click.option("-t", "--template-yaml", help="Pass a YAML file to customize the template") +@click.option("--plain", is_flag=True, help="Use the standard nf-core template") +def create(name, description, author, version, force, outdir, template_yaml, plain): + """ + Create a new pipeline using the nf-core template. + + Uses the nf-core template to make a skeleton Nextflow pipeline with all required + files, boilerplate code and best-practices. + """ + from nf_core.create import PipelineCreate + from nf_core.pipelines.create import PipelineCreateApp + + if (name and description and author) or (template_yaml): + # If all command arguments are used, run without the interactive interface + config = None + else: + log.info( + "Launching interactive nf-core pipeline creation tool." + "\nRun with all command line arguments to avoid using an interactive interface." + ) + app = PipelineCreateApp() + config = app.run() + + try: + create_obj = PipelineCreate( + name, + description, + author, + version=version, + force=force, + outdir=outdir, + template_config=config, + ) + create_obj.init_pipeline() + except UserWarning as e: + log.error(e) + sys.exit(1) + + # nf-core modules subcommands @nf_core_cli.group() @click.option( diff --git a/nf_core/create.py b/nf_core/create.py index a60bfac75d..3e639962b8 100644 --- a/nf_core/create.py +++ b/nf_core/create.py @@ -41,7 +41,7 @@ class PipelineCreate: outdir (str): Path to the local output directory. template_config (str|CreateConfig): Path to template.yml file for pipeline creation settings. or pydantic model with the customisation for pipeline creation settings. organisation (str): Name of the GitHub organisation to create the pipeline. Will be the prefix of the pipeline. - from_config_file (bool): If true the pipeline will be created from the `.nf-core.yml` config file. + from_config_file (bool): If true the pipeline will be created from the `.nf-core.yml` config file. Used for tests and sync command. default_branch (str): Specifies the --initial-branch name. """ @@ -62,15 +62,18 @@ def __init__( if template_config is not None and isinstance(template_config, str): # Obtain a CreateConfig object from the template yaml file self.config = self.check_template_yaml_info(template_config, name, description, author) - self.update_config(self, organisation, version, force, outdir if outdir else ".") + self.update_config(organisation, version, force, outdir if outdir else ".") elif isinstance(template_config, CreateConfig): self.config = template_config + self.update_config(organisation, version, force, outdir if outdir else ".") elif from_config_file: # Try reading config file _, config_yml = nf_core.utils.load_tools_config(outdir if outdir else ".") # Obtain a CreateConfig object from `.nf-core.yml` config file if "template" in config_yml: self.config = CreateConfig(**config_yml["template"]) + else: + raise UserWarning("The template configuration was not provided.") self.skip_areas, skip_paths = self.obtain_skipped_areas_dict( self.config.skip_features, outdir if outdir else "." @@ -160,9 +163,9 @@ def update_config(self, organisation, version, force, pipeline_dir): if self.config.org is None: self.config.org = organisation if self.config.version is None: - self.config.version = version + self.config.version = version if version else "1.0dev" if self.config.force is None: - self.config.force = force + self.config.force = force if force else False if self.config.outdir is None: self.config.outdir = pipeline_dir if self.config.is_nfcore is None: diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index 39bc8d9076..4ebc1936ff 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -59,13 +59,13 @@ HorizontalScroll { margin-left: 15; margin-right: 25; margin-bottom: 1; - overflow-y: scroll; display: none; height: 0; } .displayed .help_box { display: block; + overflow-y: scroll; transition: height 50ms; height: 10; diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 0fb743299e..ae8b09a262 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -18,7 +18,7 @@ class CreateConfig(BaseModel): version: Optional[str] = None force: Optional[bool] = None outdir: Optional[str] = None - skip_features: Optional[dict] = None + skip_features: Optional[list] = None is_nfcore: Optional[bool] = None model_config = ConfigDict(extra="allow") diff --git a/nf_core/pipelines/create/welcome.py b/nf_core/pipelines/create/welcome.py index 2e75ec597b..0be70cc4c0 100644 --- a/nf_core/pipelines/create/welcome.py +++ b/nf_core/pipelines/create/welcome.py @@ -1,13 +1,13 @@ from textual.app import ComposeResult -from textual.screen import Screen from textual.containers import Center -from textual.widgets import Button, Footer, Header, Static, Markdown +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Markdown, Static markdown = """ # nf-core create This app will help you create a new nf-core pipeline. -It uses the nf-core pipeline template, which is kept at +It uses the nf-core pipeline template, which is kept within the [nf-core/tools repository](https://github.com/nf-core/tools). Using this tool is mandatory when making a pipeline that may From 09bd5dbdf8ca3aa353c33d54eaea128225de536d Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 31 Aug 2023 11:18:42 +0200 Subject: [PATCH 016/175] create command fails if one but not all arguments are provided --- nf_core/__main__.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index beeb687374..d08b489c8b 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -494,6 +494,13 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp if (name and description and author) or (template_yaml): # If all command arguments are used, run without the interactive interface config = None + elif name or description or author or version or force or outdir or organisation: + log.error( + "Command arguments are not accepted in interactive mode.\n" + "Run with all command line arguments to avoid using an interactive interface" + "or run without any command line arguments to use an interactive interface." + ) + sys.exit(1) else: log.info( "Launching interactive nf-core pipeline creation tool." @@ -547,6 +554,13 @@ def create(name, description, author, version, force, outdir, template_yaml, pla if (name and description and author) or (template_yaml): # If all command arguments are used, run without the interactive interface config = None + elif name or description or author or version or force or outdir or plain: + log.error( + "Command arguments are not accepted in interactive mode.\n" + "Run with all command line arguments to avoid using an interactive interface" + "or run without any command line arguments to use an interactive interface." + ) + sys.exit(1) else: log.info( "Launching interactive nf-core pipeline creation tool." From 9f121f70874d5dded896c517c4d3a6b15537b2dd Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 31 Aug 2023 12:05:06 +0200 Subject: [PATCH 017/175] ask if launching TUI when using deprecated nf-core create command --- nf_core/__main__.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index d08b489c8b..84ddc3e6bf 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -536,7 +536,7 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp ) @click.option("-d", "--description", type=str, help="A short description of your pipeline") @click.option("-a", "--author", type=str, help="Name of the main author(s)") -@click.option("--version", type=str, default="1.0dev", help="The initial version number to use") +@click.option("--version", type=str, help="The initial version number to use") @click.option("-f", "--force", is_flag=True, default=False, help="Overwrite output directory if it already exists") @click.option("-o", "--outdir", help="Output directory for new pipeline (default: pipeline name)") @click.option("-t", "--template-yaml", help="Pass a YAML file to customize the template") @@ -562,12 +562,18 @@ def create(name, description, author, version, force, outdir, template_yaml, pla ) sys.exit(1) else: - log.info( - "Launching interactive nf-core pipeline creation tool." - "\nRun with all command line arguments to avoid using an interactive interface." - ) - app = PipelineCreateApp() - config = app.run() + if rich.prompt.Confirm.ask( + "[blue bold]?[/] [bold] [green]nf-core create[/] command is deprecated in favor of [green]nf-core pipelines create[/].[/]\n" + "[bold]Will launch an interactive interface. Do you want to continue?[/]" + ): + log.info( + "Launching interactive nf-core pipeline creation tool." + "\nRun with all command line arguments to avoid using an interactive interface." + ) + app = PipelineCreateApp() + config = app.run() + else: + sys.exit(0) try: create_obj = PipelineCreate( From 0c77029c7ca037c51a3d5985faf66d9410e8c54a Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 31 Aug 2023 13:48:13 +0200 Subject: [PATCH 018/175] add final_details screen for version and force --- nf_core/__main__.py | 2 +- nf_core/create.py | 7 +-- nf_core/pipelines/create/__init__.py | 6 +- nf_core/pipelines/create/custompipeline.py | 4 +- nf_core/pipelines/create/finaldetails.py | 64 ++++++++++++++++++++++ nf_core/pipelines/create/nfcorepipeline.py | 4 +- nf_core/pipelines/create/utils.py | 12 +++- 7 files changed, 87 insertions(+), 12 deletions(-) create mode 100644 nf_core/pipelines/create/finaldetails.py diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 84ddc3e6bf..09ecf1de63 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -470,7 +470,7 @@ def pipelines(ctx): ) @click.option("-d", "--description", type=str, help="A short description of your pipeline") @click.option("-a", "--author", type=str, help="Name of the main author(s)") -@click.option("--version", type=str, default="1.0dev", help="The initial version number to use") +@click.option("--version", type=str, help="The initial version number to use") @click.option("-f", "--force", is_flag=True, default=False, help="Overwrite output directory if it already exists") @click.option("-o", "--outdir", help="Output directory for new pipeline (default: pipeline name)") @click.option("-t", "--template-yaml", help="Pass a YAML file to customize the template") diff --git a/nf_core/create.py b/nf_core/create.py index 3e639962b8..42f635d006 100644 --- a/nf_core/create.py +++ b/nf_core/create.py @@ -65,7 +65,6 @@ def __init__( self.update_config(organisation, version, force, outdir if outdir else ".") elif isinstance(template_config, CreateConfig): self.config = template_config - self.update_config(organisation, version, force, outdir if outdir else ".") elif from_config_file: # Try reading config file _, config_yml = nf_core.utils.load_tools_config(outdir if outdir else ".") @@ -102,7 +101,7 @@ def __init__( # Set fields used by the class methods self.no_git = no_git self.default_branch = default_branch - self.force = force + self.force = self.config.force if outdir is None: outdir = os.path.join(os.getcwd(), self.config.name_noslash) self.outdir = Path(outdir) @@ -406,7 +405,7 @@ def fix_linting(self): for a customized pipeline. """ # Create a lint config - short_name = self.skip_areas["short_name"] + short_name = self.config.short_name lint_config = { "files_exist": [ "CODE_OF_CONDUCT.md", @@ -488,7 +487,7 @@ def fix_linting(self): lint_config["readme"] = ["nextflow_badge"] # If the pipeline is unbranded - if not self.skip_areas["branded"]: + if not self.config.is_nfcore: lint_config["files_unchanged"].extend([".github/ISSUE_TEMPLATE/bug_report.yml"]) # Add the lint content to the preexisting nf-core config diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 10182c6feb..5cae6b9b5c 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -4,6 +4,7 @@ from nf_core.pipelines.create.basicdetails import BasicDetails from nf_core.pipelines.create.custompipeline import CustomPipeline +from nf_core.pipelines.create.finaldetails import FinalDetails from nf_core.pipelines.create.nfcorepipeline import NfcorePipeline from nf_core.pipelines.create.pipelinetype import ChoosePipelineType from nf_core.pipelines.create.utils import CreateConfig @@ -26,6 +27,7 @@ class PipelineCreateApp(App[CreateConfig]): "choose_type": ChoosePipelineType(), "type_custom": CustomPipeline(), "type_nfcore": NfcorePipeline(), + "final_details": FinalDetails(), } # Initialise config as empty @@ -42,8 +44,8 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.switch_screen("type_nfcore") elif event.button.id == "type_custom": self.switch_screen("type_custom") - elif event.button.id == "done": - self.exit(self.TEMPLATE_CONFIG) + elif event.button.id == "continue": + self.switch_screen("final_details") def action_toggle_dark(self) -> None: """An action to toggle dark mode.""" diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index ad5d4fbe0e..0100943c1e 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -135,11 +135,11 @@ def compose(self) -> ComposeResult: ), ) yield Center( - Button("Done", id="done", variant="success"), + Button("Continue", id="continue", variant="success"), classes="cta", ) - @on(Button.Pressed, "#done") + @on(Button.Pressed, "#continue") def on_button_pressed(self, event: Button.Pressed) -> None: """Save fields to the config.""" skip = [] diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py new file mode 100644 index 0000000000..c7a979d9f4 --- /dev/null +++ b/nf_core/pipelines/create/finaldetails.py @@ -0,0 +1,64 @@ +"""A Textual app to create a pipeline.""" +from textwrap import dedent + +from textual import on +from textual.app import ComposeResult +from textual.containers import Center, Horizontal +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch + +from nf_core.pipelines.create.utils import CreateConfig, TextInput + + +class FinalDetails(Screen): + """Name, description, author, etc.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Markdown( + dedent( + """ + # Final details + """ + ) + ) + + yield TextInput( + "version", + "Version", + "First version of the pipeline", + "1.0dev", + ) + with Horizontal(): + yield Switch(value=False, id="force") + yield Static("If the pipeline output directory exists, remove it and continue.", classes="custom_grid") + + yield Center( + Button("Finish", id="finish", variant="success"), + classes="cta", + ) + + @on(Button.Pressed, "#finish") + def on_button_pressed(self, event: Button.Pressed) -> None: + """Save fields to the config.""" + for text_input in self.query("TextInput"): + this_input = self.query_one(Input) + validation_result = this_input.validate(this_input.value) + version = this_input.value + if not validation_result.is_valid: + text_input.query_one(".validation_msg").update("\n".join(validation_result.failure_descriptions)) + else: + text_input.query_one(".validation_msg").update("") + try: + self.parent.TEMPLATE_CONFIG.version = version + except ValueError: + pass + + this_switch = self.query_one(Switch) + try: + self.parent.TEMPLATE_CONFIG.force = this_switch.value + except ValueError: + pass + + self.parent.exit(self.parent.TEMPLATE_CONFIG) diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py index b1b5af8163..7e2078429d 100644 --- a/nf_core/pipelines/create/nfcorepipeline.py +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -13,11 +13,11 @@ def compose(self) -> ComposeResult: yield Footer() # TODO: add features to customise the pipeline template yield Center( - Button("Done", id="done", variant="success"), + Button("Continue", id="continue", variant="success"), classes="cta", ) - @on(Button.Pressed, "#done") + @on(Button.Pressed, "#continue") def on_button_pressed(self, event: Button.Pressed) -> None: """Save fields to the config.""" skip = [] diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index ae8b09a262..19f2df6d6d 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -31,7 +31,7 @@ def name_nospecialchars(cls, v: str) -> str: raise ValueError("Must be lowercase without punctuation.") return v - @field_validator("org", "description", "author") + @field_validator("org", "description", "author", "version") @classmethod def notempty(cls, v: str) -> str: """Check that string values are not empty.""" @@ -39,6 +39,16 @@ def notempty(cls, v: str) -> str: raise ValueError("Cannot be left empty.") return v + @field_validator("version") + @classmethod + def version_nospecialchars(cls, v: str) -> str: + """Check that the pipeline version is simple.""" + if not re.match(r"^([0-9]+)(\.?([0-9]+))*(dev)?$", v): + raise ValueError( + "Must contain at least one number, and can be prefixed by 'dev'. Do not use a 'v' prefix or spaces." + ) + return v + class TextInput(Static): """Widget for text inputs. From bf9a541c43011ea325ba563697421a3df342f132 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 31 Aug 2023 15:06:37 +0200 Subject: [PATCH 019/175] add nfcorepipeline grid with features to select --- nf_core/create.py | 2 +- nf_core/pipelines/create/custompipeline.py | 68 +--------------------- nf_core/pipelines/create/nfcorepipeline.py | 13 ++++- nf_core/pipelines/create/utils.py | 68 +++++++++++++++++++++- 4 files changed, 82 insertions(+), 69 deletions(-) diff --git a/nf_core/create.py b/nf_core/create.py index 42f635d006..844f697542 100644 --- a/nf_core/create.py +++ b/nf_core/create.py @@ -36,7 +36,7 @@ class PipelineCreate: author (str): Authors name of the pipeline. version (str): Version flag. Semantic versioning only. Defaults to `1.0dev`. no_git (bool): Prevents the creation of a local Git repository for the pipeline. Defaults to False. - force (bool): Overwrites a given workflow directory with the same name. Defaults to False. + force (bool): Overwrites a given workflow directory with the same name. Defaults to False. Used for tests and sync command. May the force be with you. outdir (str): Path to the local output directory. template_config (str|CreateConfig): Path to template.yml file for pipeline creation settings. or pydantic model with the customisation for pipeline creation settings. diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 0100943c1e..3693dc9897 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -1,22 +1,10 @@ from textual import on from textual.app import ComposeResult -from textual.containers import Center, HorizontalScroll, ScrollableContainer -from textual.reactive import reactive +from textual.containers import Center, ScrollableContainer from textual.screen import Screen -from textual.widgets import Button, Footer, Header, Markdown, Static, Switch +from textual.widgets import Button, Footer, Header, Switch -markdown_genomes = """ -Nf-core pipelines are configured to use a copy of the most common reference genome files. - -By selecting this option, your pipeline will include a configuration file specifying the paths to these files. - -The required code to use these files will also be included in the template. -When the pipeline user provides an appropriate genome key, -the pipeline will automatically download the required reference files. - -For more information about reference genomes in nf-core pipelines, -see the [nf-core docs](https://nf-co.re/docs/usage/reference_genomes). -""" +from nf_core.pipelines.create.utils import PipelineFeature, markdown_genomes markdown_ci = """ Nf-core provides a set of Continuous Integration (CI) tests for Github. @@ -52,56 +40,6 @@ """ -class HelpText(Markdown): - """A class to show a text box with help text.""" - - def __init__(self, markdown: str, classes: str) -> None: - super().__init__(markdown=markdown, classes=classes) - - def show(self) -> None: - """Method to show the help text box.""" - self.add_class("displayed") - - def hide(self) -> None: - """Method to hide the help text box.""" - self.remove_class("displayed") - - -class PipelineFeature(Static): - """Widget for the selection of pipeline features.""" - - def __init__(self, markdown: str, title: str, subtitle: str, field_id: str) -> None: - self.markdown = markdown - self.title = title - self.subtitle = subtitle - self.field_id = field_id - super().__init__() - - def on_button_pressed(self, event: Button.Pressed) -> None: - """When the button is pressed, change the type of the button.""" - if event.button.id == "show_help": - self.add_class("displayed") - elif event.button.id == "hide_help": - self.remove_class("displayed") - - def compose(self) -> ComposeResult: - """ - Create child widgets. - - Displayed row with a switch, a short text description and a help button. - Hidden row with a help text box. - """ - yield HorizontalScroll( - Switch(value=True, id=self.field_id), - Static(self.title, classes="feature_title"), - Static(self.subtitle, classes="feature_subtitle"), - Button("Show help", id="show_help", variant="primary"), - Button("Hide help", id="hide_help"), - classes="custom_grid", - ) - yield HelpText(self.markdown, classes="help_box") - - class CustomPipeline(Screen): """Select if the pipeline will use genomic data.""" diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py index 7e2078429d..2af99af5fd 100644 --- a/nf_core/pipelines/create/nfcorepipeline.py +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -2,7 +2,9 @@ from textual.app import ComposeResult from textual.containers import Center, HorizontalScroll, ScrollableContainer from textual.screen import Screen -from textual.widgets import Button, Footer, Header, Markdown, Static, Switch +from textual.widgets import Button, Footer, Header, Switch + +from nf_core.pipelines.create.utils import PipelineFeature, markdown_genomes class NfcorePipeline(Screen): @@ -11,7 +13,14 @@ class NfcorePipeline(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - # TODO: add features to customise the pipeline template + yield ScrollableContainer( + PipelineFeature( + markdown_genomes, + "Use reference genomes", + "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", + "igenomes", + ), + ) yield Center( Button("Continue", id="continue", variant="success"), classes="cta", diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 19f2df6d6d..1fbd646d3a 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -4,8 +4,9 @@ from pydantic import BaseModel, ConfigDict, field_validator from textual import on from textual.app import ComposeResult +from textual.containers import HorizontalScroll from textual.validation import ValidationResult, Validator -from textual.widgets import Input, Static +from textual.widgets import Button, Input, Markdown, Static, Switch class CreateConfig(BaseModel): @@ -103,3 +104,68 @@ def validate(self, value: str) -> ValidationResult: return self.success() except ValueError as e: return self.failure(", ".join([err["msg"] for err in e.errors()])) + + +class HelpText(Markdown): + """A class to show a text box with help text.""" + + def __init__(self, markdown: str, classes: str) -> None: + super().__init__(markdown=markdown, classes=classes) + + def show(self) -> None: + """Method to show the help text box.""" + self.add_class("displayed") + + def hide(self) -> None: + """Method to hide the help text box.""" + self.remove_class("displayed") + + +class PipelineFeature(Static): + """Widget for the selection of pipeline features.""" + + def __init__(self, markdown: str, title: str, subtitle: str, field_id: str) -> None: + self.markdown = markdown + self.title = title + self.subtitle = subtitle + self.field_id = field_id + super().__init__() + + def on_button_pressed(self, event: Button.Pressed) -> None: + """When the button is pressed, change the type of the button.""" + if event.button.id == "show_help": + self.add_class("displayed") + elif event.button.id == "hide_help": + self.remove_class("displayed") + + def compose(self) -> ComposeResult: + """ + Create child widgets. + + Displayed row with a switch, a short text description and a help button. + Hidden row with a help text box. + """ + yield HorizontalScroll( + Switch(value=True, id=self.field_id), + Static(self.title, classes="feature_title"), + Static(self.subtitle, classes="feature_subtitle"), + Button("Show help", id="show_help", variant="primary"), + Button("Hide help", id="hide_help"), + classes="custom_grid", + ) + yield HelpText(self.markdown, classes="help_box") + + +## Markdown text to reuse in different screens +markdown_genomes = """ +Nf-core pipelines are configured to use a copy of the most common reference genome files. + +By selecting this option, your pipeline will include a configuration file specifying the paths to these files. + +The required code to use these files will also be included in the template. +When the pipeline user provides an appropriate genome key, +the pipeline will automatically download the required reference files. + +For more information about reference genomes in nf-core pipelines, +see the [nf-core docs](https://nf-co.re/docs/usage/reference_genomes). +""" From fec5e3eb6481109ee49850d2582e8bb95e11ae97 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 31 Aug 2023 15:21:48 +0200 Subject: [PATCH 020/175] first ask if the pipeline will be nf-core or custom before basicdetails --- nf_core/pipelines/create/__init__.py | 11 ++++++++--- nf_core/pipelines/create/basicdetails.py | 6 +++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 5cae6b9b5c..0fe143b3bc 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -33,17 +33,22 @@ class PipelineCreateApp(App[CreateConfig]): # Initialise config as empty TEMPLATE_CONFIG = CreateConfig() + # Initialise pipeline type + PIPELINE_TYPE = None + def on_mount(self) -> None: self.push_screen("welcome") def on_button_pressed(self, event: Button.Pressed) -> None: """Handle all button pressed events.""" if event.button.id == "start": - self.switch_screen("basic_details") + self.switch_screen("choose_type") elif event.button.id == "type_nfcore": - self.switch_screen("type_nfcore") + self.PIPELINE_TYPE = "nfcore" + self.switch_screen("basic_details") elif event.button.id == "type_custom": - self.switch_screen("type_custom") + self.PIPELINE_TYPE = "custom" + self.switch_screen("basic_details") elif event.button.id == "continue": self.switch_screen("final_details") diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py index 5ffae135c9..dc7248d977 100644 --- a/nf_core/pipelines/create/basicdetails.py +++ b/nf_core/pipelines/create/basicdetails.py @@ -30,6 +30,7 @@ def compose(self) -> ComposeResult: "GitHub organisation", "nf-core", classes="column", + disabled=self.parent.PIPELINE_TYPE == "nfcore", ) yield TextInput( "name", @@ -67,6 +68,9 @@ def on_button_pressed(self, event: Button.Pressed) -> None: text_input.query_one(".validation_msg").update("") try: self.parent.TEMPLATE_CONFIG = CreateConfig(**config) - self.parent.switch_screen("choose_type") + if self.parent.PIPELINE_TYPE == "nfcore": + self.parent.switch_screen("type_nfcore") + elif self.parent.PIPELINE_TYPE == "custom": + self.parent.switch_screen("type_custom") except ValueError: pass From 0ef16b57d664acf4b46fedbd7ddf238c32455d4f Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 31 Aug 2023 15:27:33 +0200 Subject: [PATCH 021/175] use kwargs --- nf_core/pipelines/create/utils.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 1fbd646d3a..cd81e41ab0 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -109,8 +109,8 @@ def validate(self, value: str) -> ValidationResult: class HelpText(Markdown): """A class to show a text box with help text.""" - def __init__(self, markdown: str, classes: str) -> None: - super().__init__(markdown=markdown, classes=classes) + def __init__(self, **kwargs) -> None: + super().__init__(**kwargs) def show(self) -> None: """Method to show the help text box.""" @@ -124,12 +124,12 @@ def hide(self) -> None: class PipelineFeature(Static): """Widget for the selection of pipeline features.""" - def __init__(self, markdown: str, title: str, subtitle: str, field_id: str) -> None: + def __init__(self, markdown: str, title: str, subtitle: str, field_id: str, **kwargs) -> None: + super().__init__(**kwargs) self.markdown = markdown self.title = title self.subtitle = subtitle self.field_id = field_id - super().__init__() def on_button_pressed(self, event: Button.Pressed) -> None: """When the button is pressed, change the type of the button.""" @@ -153,7 +153,7 @@ def compose(self) -> ComposeResult: Button("Hide help", id="hide_help"), classes="custom_grid", ) - yield HelpText(self.markdown, classes="help_box") + yield HelpText(markdown=self.markdown, classes="help_box") ## Markdown text to reuse in different screens From 238767f73785e5bb4f6a5c28e4c57906e09e906e Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 21 Aug 2023 10:12:16 +0200 Subject: [PATCH 022/175] remove inexisten variable version from send-tweet github workflow --- .../.github/workflows/release-announcments.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nf_core/pipeline-template/.github/workflows/release-announcments.yml b/nf_core/pipeline-template/.github/workflows/release-announcments.yml index f2a45d7147..a6e976855c 100644 --- a/nf_core/pipeline-template/.github/workflows/release-announcments.yml +++ b/nf_core/pipeline-template/.github/workflows/release-announcments.yml @@ -41,8 +41,7 @@ jobs: consumer_key=os.getenv("TWITTER_CONSUMER_KEY"), consumer_secret=os.getenv("TWITTER_CONSUMER_SECRET"), ) - version = os.getenv("VERSION").strip('"') - tweet = os.getenv("TWEET").format(version=version) + tweet = os.getenv("TWEET") client.create_tweet(text=tweet) env: TWEET: | From 7b4a342d577466ad50171f3a975534e8ad7c34f3 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 24 Aug 2023 16:14:01 +0200 Subject: [PATCH 023/175] fix typo in gh_badges jinja variable to github_badges --- nf_core/pipeline-template/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/pipeline-template/README.md b/nf_core/pipeline-template/README.md index 27e96de7f6..cddf8d13c6 100644 --- a/nf_core/pipeline-template/README.md +++ b/nf_core/pipeline-template/README.md @@ -3,7 +3,7 @@ # ![{{ name }}](docs/images/{{ logo_light }}#gh-light-mode-only) ![{{ name }}](docs/images/{{ logo_dark }}#gh-dark-mode-only) {% endif -%} -{% if gh_badges -%} +{% if github_badges -%} [![GitHub Actions CI Status](https://github.com/{{ name }}/workflows/nf-core%20CI/badge.svg)](https://github.com/{{ name }}/actions?query=workflow%3A%22nf-core+CI%22) [![GitHub Actions Linting Status](https://github.com/{{ name }}/workflows/nf-core%20linting/badge.svg)](https://github.com/{{ name }}/actions?query=workflow%3A%22nf-core+linting%22){% endif -%} {% if branded -%}[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/{{ short_name }}/results){% endif -%} From b3fa25e60c87b7d82dedd1c58c78e6e5aade3fe9 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 30 Aug 2023 08:44:02 +0200 Subject: [PATCH 024/175] bump version of nf-test snap files --- nf_core/bump_version.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nf_core/bump_version.py b/nf_core/bump_version.py index 5f4616edfb..ada7f0b994 100644 --- a/nf_core/bump_version.py +++ b/nf_core/bump_version.py @@ -60,6 +60,20 @@ def bump_pipeline_version(pipeline_obj, new_version): ), ], ) + # nf-test snap files + pipeline_name = pipeline_obj.nf_config.get("manifest.name", "").strip(" '\"") + snap_files = [f for f in Path().glob("tests/pipeline/*.snap")] + for snap_file in snap_files: + update_file_version( + snap_file, + pipeline_obj, + [ + ( + f"{pipeline_name}={current_version}", + f"{pipeline_name}={new_version}", + ) + ], + ) def bump_nextflow_version(pipeline_obj, new_version): From 6ff69b2bc94ddc650f791241382c7ca0b6f35167 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 30 Aug 2023 08:56:48 +0200 Subject: [PATCH 025/175] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7222da104..4c6cfc1fa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ - Update the Code of Conduct ([#2381](https://github.com/nf-core/tools/pull/2381)) - Remove `--no-git` option from `nf-core create` ([#2394](https://github.com/nf-core/tools/pull/2394)) - Throw warning when custom workflow name contains special characters ([#2401](https://github.com/nf-core/tools/pull/2401)) +- Bump version of nf-test snapshot files with `nf-core bump-version` ([#2410](https://github.com/nf-core/tools/pull/2410)) # [v2.9 - Chromium Falcon](https://github.com/nf-core/tools/releases/tag/2.9) + [2023-06-29] From 17ba9711bcab71402a714287dd85c55759c41682 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 1 Sep 2023 08:49:22 +0200 Subject: [PATCH 026/175] add outdir textinput and update config --- nf_core/pipelines/create/custompipeline.py | 3 +-- nf_core/pipelines/create/finaldetails.py | 30 ++++++++++++++-------- nf_core/pipelines/create/nfcorepipeline.py | 3 +-- nf_core/pipelines/create/utils.py | 11 +++++++- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 3693dc9897..5cc2f87d95 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -85,5 +85,4 @@ def on_button_pressed(self, event: Button.Pressed) -> None: this_switch = feature_input.query_one(Switch) if not this_switch.value: skip.append(this_switch.id) - self.parent.TEMPLATE_CONFIG.skip_features = skip - self.parent.TEMPLATE_CONFIG.is_nfcore = False + self.parent.TEMPLATE_CONFIG.__dict__.update({"skip_features": skip, "is_nfcore": False}) diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index c7a979d9f4..4f65f97629 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -24,12 +24,21 @@ def compose(self) -> ComposeResult: ) ) - yield TextInput( - "version", - "Version", - "First version of the pipeline", - "1.0dev", - ) + with Horizontal(): + yield TextInput( + "version", + "Version", + "First version of the pipeline", + "1.0dev", + classes="column", + ) + yield TextInput( + "outdir", + "Output directory", + "Path to the output directory where the pipeline will be created", + ".", + classes="column", + ) with Horizontal(): yield Switch(value=False, id="force") yield Static("If the pipeline output directory exists, remove it and continue.", classes="custom_grid") @@ -42,22 +51,23 @@ def compose(self) -> ComposeResult: @on(Button.Pressed, "#finish") def on_button_pressed(self, event: Button.Pressed) -> None: """Save fields to the config.""" + new_config = {} for text_input in self.query("TextInput"): - this_input = self.query_one(Input) + this_input = text_input.query_one(Input) validation_result = this_input.validate(this_input.value) - version = this_input.value + new_config[text_input.field_id] = this_input.value if not validation_result.is_valid: text_input.query_one(".validation_msg").update("\n".join(validation_result.failure_descriptions)) else: text_input.query_one(".validation_msg").update("") try: - self.parent.TEMPLATE_CONFIG.version = version + self.parent.TEMPLATE_CONFIG.__dict__.update(new_config) except ValueError: pass this_switch = self.query_one(Switch) try: - self.parent.TEMPLATE_CONFIG.force = this_switch.value + self.parent.TEMPLATE_CONFIG.__dict__.update({"force": this_switch.value}) except ValueError: pass diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py index 2af99af5fd..a8902daf37 100644 --- a/nf_core/pipelines/create/nfcorepipeline.py +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -34,5 +34,4 @@ def on_button_pressed(self, event: Button.Pressed) -> None: this_switch = feature_input.query_one(Switch) if not this_switch.value: skip.append(this_switch.id) - self.parent.TEMPLATE_CONFIG.skip_features = skip - self.parent.TEMPLATE_CONFIG.is_nfcore = True + self.parent.TEMPLATE_CONFIG.__dict__.update({"skip_features": skip, "is_nfcore": True}) diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index cd81e41ab0..5566c17c8e 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -1,4 +1,5 @@ import re +from pathlib import Path from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator @@ -32,7 +33,7 @@ def name_nospecialchars(cls, v: str) -> str: raise ValueError("Must be lowercase without punctuation.") return v - @field_validator("org", "description", "author", "version") + @field_validator("org", "description", "author", "version", "outdir") @classmethod def notempty(cls, v: str) -> str: """Check that string values are not empty.""" @@ -50,6 +51,14 @@ def version_nospecialchars(cls, v: str) -> str: ) return v + @field_validator("outdir") + @classmethod + def path_valid(cls, v: str) -> str: + """Check that a path is valid.""" + if not Path(v).is_dir(): + raise ValueError("Must be a valid path.") + return v + class TextInput(Static): """Widget for text inputs. From 0c64de879e97cfa7bcd88e6c7fd2dce472c276f6 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 1 Sep 2023 09:13:11 +0200 Subject: [PATCH 027/175] refactor jinja template 'branded' to 'is_nfcore' --- nf_core/create.py | 14 +++++++------- .../pipeline-template/.github/CONTRIBUTING.md | 4 ++-- .../.github/PULL_REQUEST_TEMPLATE.md | 2 +- nf_core/pipeline-template/README.md | 18 +++++++++--------- .../assets/email_template.txt | 2 +- .../assets/multiqc_config.yml | 4 ++-- nf_core/pipeline-template/docs/README.md | 2 +- nf_core/pipeline-template/docs/usage.md | 2 +- .../lib/NfcoreTemplate.groovy | 2 +- nf_core/pipeline-template/main.nf | 2 +- nf_core/pipeline-template/nextflow_schema.json | 2 +- 11 files changed, 27 insertions(+), 27 deletions(-) diff --git a/nf_core/create.py b/nf_core/create.py index 844f697542..cf0d450a11 100644 --- a/nf_core/create.py +++ b/nf_core/create.py @@ -85,7 +85,7 @@ def __init__( ], "ci": [".github/workflows/"], "igenomes": ["conf/igenomes.config"], - "branded": [ + "is_nfcore": [ ".github/ISSUE_TEMPLATE/config", "CODE_OF_CONDUCT.md", ".github/workflows/awsfulltest.yml", @@ -187,11 +187,11 @@ def obtain_skipped_areas_dict(self, features_to_skip, pipeline_dir): # Define the different template areas, and what actions to take for each # if they are skipped template_areas = { - "github": {"name": "GitHub hosting", "file": True, "content": False}, - "ci": {"name": "GitHub CI", "file": True, "content": False}, - "github_badges": {"name": "GitHub badges", "file": False, "content": True}, - "igenomes": {"name": "iGenomes config", "file": True, "content": True}, - "nf_core_configs": {"name": "nf-core/configs", "file": False, "content": True}, + "github": {"file": True, "content": False}, + "ci": {"file": True, "content": False}, + "github_badges": {"file": False, "content": True}, + "igenomes": {"file": True, "content": True}, + "nf_core_configs": {"file": False, "content": True}, } skip_paths = [] @@ -486,7 +486,7 @@ def fix_linting(self): if not self.skip_areas["github_badges"] or not self.skip_areas["github"]: lint_config["readme"] = ["nextflow_badge"] - # If the pipeline is unbranded + # If the pipeline is not nf-core if not self.config.is_nfcore: lint_config["files_unchanged"].extend([".github/ISSUE_TEMPLATE/bug_report.yml"]) diff --git a/nf_core/pipeline-template/.github/CONTRIBUTING.md b/nf_core/pipeline-template/.github/CONTRIBUTING.md index 6a1b9a9176..3a9c0fbff9 100644 --- a/nf_core/pipeline-template/.github/CONTRIBUTING.md +++ b/nf_core/pipeline-template/.github/CONTRIBUTING.md @@ -9,7 +9,7 @@ Please use the pre-filled template to save time. However, don't be put off by this template - other more general issues and suggestions are welcome! Contributions to the code are even more welcome ;) -{% if branded -%} +{% if is_nfcore -%} :::info If you need help using or modifying {{ name }} then the best place to ask is on the nf-core Slack [#{{ short_name }}](https://nfcore.slack.com/channels/{{ short_name }}) channel ([join our Slack here](https://nf-co.re/join/slack)). @@ -58,7 +58,7 @@ These tests are run both with the latest available version of `Nextflow` and als - Fix the bug, and bump version (X.Y.Z+1). - A PR should be made on `master` from patch to directly this particular bug. -{% if branded -%} +{% if is_nfcore -%} ## Getting help diff --git a/nf_core/pipeline-template/.github/PULL_REQUEST_TEMPLATE.md b/nf_core/pipeline-template/.github/PULL_REQUEST_TEMPLATE.md index 0f81ebaa4c..03c700bacb 100644 --- a/nf_core/pipeline-template/.github/PULL_REQUEST_TEMPLATE.md +++ b/nf_core/pipeline-template/.github/PULL_REQUEST_TEMPLATE.md @@ -16,7 +16,7 @@ Learn more about contributing: [CONTRIBUTING.md](https://github.com/{{ name }}/t - [ ] This comment contains a description of changes (with reason). - [ ] If you've fixed a bug or added code that should be tested, add tests! - [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/{{ name }}/tree/master/.github/CONTRIBUTING.md) - {%- if branded %} + {%- if is_nfcore %} - [ ] If necessary, also make a PR on the {{ name }} _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository. {%- endif %} - [ ] Make sure your code lints (`nf-core lint`). diff --git a/nf_core/pipeline-template/README.md b/nf_core/pipeline-template/README.md index cddf8d13c6..9064611455 100644 --- a/nf_core/pipeline-template/README.md +++ b/nf_core/pipeline-template/README.md @@ -1,4 +1,4 @@ -{% if branded -%} +{% if is_nfcore -%} # ![{{ name }}](docs/images/{{ logo_light }}#gh-light-mode-only) ![{{ name }}](docs/images/{{ logo_dark }}#gh-dark-mode-only) @@ -6,7 +6,7 @@ {% if github_badges -%} [![GitHub Actions CI Status](https://github.com/{{ name }}/workflows/nf-core%20CI/badge.svg)](https://github.com/{{ name }}/actions?query=workflow%3A%22nf-core+CI%22) [![GitHub Actions Linting Status](https://github.com/{{ name }}/workflows/nf-core%20linting/badge.svg)](https://github.com/{{ name }}/actions?query=workflow%3A%22nf-core+linting%22){% endif -%} -{% if branded -%}[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/{{ short_name }}/results){% endif -%} +{% if is_nfcore -%}[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/{{ short_name }}/results){% endif -%} {%- if github_badges -%} [![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX) @@ -17,10 +17,10 @@ [![Launch on Nextflow Tower](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Nextflow%20Tower-%234256e7)](https://tower.nf/launch?pipeline=https://github.com/{{ name }}) {% endif -%} -{%- if branded -%}[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23{{ short_name }}-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/{{ short_name }}){% endif -%} -{%- if branded -%}[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core){% endif -%} -{%- if branded -%}[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core){% endif -%} -{%- if branded -%}[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core) +{%- if is_nfcore -%}[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23{{ short_name }}-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/{{ short_name }}){% endif -%} +{%- if is_nfcore -%}[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core){% endif -%} +{%- if is_nfcore -%}[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core){% endif -%} +{%- if is_nfcore -%}[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core) {% endif -%} @@ -82,7 +82,7 @@ provided by the `-c` Nextflow option can be used to provide any configuration _* see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). ::: -{% if branded -%} +{% if is_nfcore -%} For more details and further functionality, please refer to the [usage documentation](https://nf-co.re/{{ short_name }}/usage) and the [parameter documentation](https://nf-co.re/{{ short_name }}/parameters). @@ -106,7 +106,7 @@ We thank the following people for their extensive assistance in the development If you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md). -{% if branded -%} +{% if is_nfcore -%} For further information or help, don't hesitate to get in touch on the [Slack `#{{ short_name }}` channel](https://nfcore.slack.com/channels/{{ short_name }}) (you can join with [this invite](https://nf-co.re/join/slack)). {% endif -%} @@ -120,7 +120,7 @@ For further information or help, don't hesitate to get in touch on the [Slack `# An extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file. -{% if branded -%} +{% if is_nfcore -%} You can cite the `nf-core` publication as follows: {% else -%} diff --git a/nf_core/pipeline-template/assets/email_template.txt b/nf_core/pipeline-template/assets/email_template.txt index edc8f71016..8c40733fdf 100644 --- a/nf_core/pipeline-template/assets/email_template.txt +++ b/nf_core/pipeline-template/assets/email_template.txt @@ -1,4 +1,4 @@ -{% if branded -%} +{% if is_nfcore -%} ---------------------------------------------------- ,--./,-. ___ __ __ __ ___ /,-._.--~\\ diff --git a/nf_core/pipeline-template/assets/multiqc_config.yml b/nf_core/pipeline-template/assets/multiqc_config.yml index 9423ee53f7..4d97621063 100644 --- a/nf_core/pipeline-template/assets/multiqc_config.yml +++ b/nf_core/pipeline-template/assets/multiqc_config.yml @@ -1,11 +1,11 @@ report_comment: > {% if 'dev' in version -%} This report has been generated by the {{ name }} - analysis pipeline.{% if branded %} For information about how to interpret these results, please see the + analysis pipeline.{% if is_nfcore %} For information about how to interpret these results, please see the documentation.{% endif %} {%- else %} This report has been generated by the {{ name }} - analysis pipeline.{% if branded %} For information about how to interpret these results, please see the + analysis pipeline.{% if is_nfcore %} For information about how to interpret these results, please see the documentation.{% endif %} {% endif %} report_section_order: diff --git a/nf_core/pipeline-template/docs/README.md b/nf_core/pipeline-template/docs/README.md index e94889c53d..9a237c1ad4 100644 --- a/nf_core/pipeline-template/docs/README.md +++ b/nf_core/pipeline-template/docs/README.md @@ -6,7 +6,7 @@ The {{ name }} documentation is split into the following pages: - An overview of how the pipeline works, how to run it and a description of all of the different command-line flags. - [Output](output.md) - An overview of the different results produced by the pipeline and how to interpret them. - {%- if branded %} + {%- if is_nfcore %} You can find a lot more documentation about installing, configuring and running nf-core pipelines on the website: [https://nf-co.re](https://nf-co.re) {% else %} diff --git a/nf_core/pipeline-template/docs/usage.md b/nf_core/pipeline-template/docs/usage.md index 6dba3032a4..ca06bff9c8 100644 --- a/nf_core/pipeline-template/docs/usage.md +++ b/nf_core/pipeline-template/docs/usage.md @@ -1,6 +1,6 @@ # {{ name }}: Usage -{% if branded -%} +{% if is_nfcore -%} ## :warning: Please read this documentation on the nf-core website: [https://nf-co.re/{{ short_name }}/usage](https://nf-co.re/{{ short_name }}/usage) diff --git a/nf_core/pipeline-template/lib/NfcoreTemplate.groovy b/nf_core/pipeline-template/lib/NfcoreTemplate.groovy index a1a726d69f..e69de4f6b9 100755 --- a/nf_core/pipeline-template/lib/NfcoreTemplate.groovy +++ b/nf_core/pipeline-template/lib/NfcoreTemplate.groovy @@ -322,7 +322,7 @@ class NfcoreTemplate { String workflow_version = NfcoreTemplate.version(workflow) String.format( """\n - ${dashedLine(monochrome_logs)}{% if branded %} + ${dashedLine(monochrome_logs)}{% if is_nfcore %} ${colors.green},--.${colors.black}/${colors.green},-.${colors.reset} ${colors.blue} ___ __ __ __ ___ ${colors.green}/,-._.--~\'${colors.reset} ${colors.blue} |\\ | |__ __ / ` / \\ |__) |__ ${colors.yellow}} {${colors.reset} diff --git a/nf_core/pipeline-template/main.nf b/nf_core/pipeline-template/main.nf index 3d632eb8c5..210cff6165 100644 --- a/nf_core/pipeline-template/main.nf +++ b/nf_core/pipeline-template/main.nf @@ -4,7 +4,7 @@ {{ name }} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Github : https://github.com/{{ name }} -{%- if branded %} +{%- if is_nfcore %} Website: https://nf-co.re/{{ short_name }} Slack : https://nfcore.slack.com/channels/{{ short_name }} {%- endif %} diff --git a/nf_core/pipeline-template/nextflow_schema.json b/nf_core/pipeline-template/nextflow_schema.json index 49549d0464..7bef33d1bc 100644 --- a/nf_core/pipeline-template/nextflow_schema.json +++ b/nf_core/pipeline-template/nextflow_schema.json @@ -19,7 +19,7 @@ "mimetype": "text/csv", "pattern": "^\\S+\\.csv$", "description": "Path to comma-separated file containing information about the samples in the experiment.", - "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.{% if branded %} See [usage docs](https://nf-co.re/{{ short_name }}/usage#samplesheet-input).{% endif %}", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.{% if is_nfcore %} See [usage docs](https://nf-co.re/{{ short_name }}/usage#samplesheet-input).{% endif %}", "fa_icon": "fas fa-file-csv" }, "outdir": { From 772011718798047c5ec394da91beb888b5c9770f Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 1 Sep 2023 09:56:20 +0200 Subject: [PATCH 028/175] refactor params_dict to jinja_params and use that instead of the config --- nf_core/create.py | 65 +++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/nf_core/create.py b/nf_core/create.py index cf0d450a11..b607c78b8b 100644 --- a/nf_core/create.py +++ b/nf_core/create.py @@ -74,7 +74,7 @@ def __init__( else: raise UserWarning("The template configuration was not provided.") - self.skip_areas, skip_paths = self.obtain_skipped_areas_dict( + self.jinja_params, skip_paths = self.obtain_skipped_areas_dict( self.config.skip_features, outdir if outdir else "." ) @@ -103,7 +103,7 @@ def __init__( self.default_branch = default_branch self.force = self.config.force if outdir is None: - outdir = os.path.join(os.getcwd(), self.config.name_noslash) + outdir = os.path.join(os.getcwd(), self.jinja_params["name_noslash"]) self.outdir = Path(outdir) def check_template_yaml_info(self, template_yaml, name, description, author): @@ -178,7 +178,7 @@ def obtain_skipped_areas_dict(self, features_to_skip, pipeline_dir): pipeline_dir (str): Path to the pipeline directory. Returns: - skip_areas (dict): Dictionary of template areas to skip with values true/false. + jinja_params (dict): Dictionary of template areas to skip with values true/false. skip_paths (list): List of template areas which contain paths to skip. """ # Try reading config file @@ -194,48 +194,51 @@ def obtain_skipped_areas_dict(self, features_to_skip, pipeline_dir): "nf_core_configs": {"file": False, "content": True}, } + # Set the parameters for the jinja template + jinja_params = self.config.model_dump() + + # Add template areas to jinja params and create list of areas with paths to skip skip_paths = [] - skip_areas = {} for t_area in template_areas: if t_area in features_to_skip: if template_areas[t_area]["file"]: skip_paths.append(t_area) - skip_areas[t_area] = False + jinja_params[t_area] = False else: - skip_areas[t_area] = True + jinja_params[t_area] = True # If github is selected, exclude also github_badges # if not param_dict["github"]: # param_dict["github_badges"] = False # Set the last parameters based on the ones provided - self.config.short_name = ( - self.config.name.lower().replace(r"/\s+/", "-").replace(f"{self.config.org}/", "").replace("/", "-") + jinja_params["short_name"] = ( + jinja_params["name"].lower().replace(r"/\s+/", "-").replace(f"{jinja_params['org']}/", "").replace("/", "-") ) - self.config.name = f"{self.config.org}/{self.config.short_name}" - self.config.name_noslash = self.config.name.replace("/", "-") - self.config.prefix_nodash = self.config.org.replace("-", "") - self.config.name_docker = self.config.name.replace(self.config.org, self.config.prefix_nodash) - self.config.logo_light = f"{self.config.name_noslash}_logo_light.png" - self.config.logo_dark = f"{self.config.name_noslash}_logo_dark.png" + jinja_params["name"] = f"{jinja_params['org']}/{jinja_params['short_name']}" + jinja_params["name_noslash"] = jinja_params["name"].replace("/", "-") + jinja_params["prefix_nodash"] = jinja_params["org"].replace("-", "") + jinja_params["name_docker"] = jinja_params["name"].replace(jinja_params["org"], jinja_params["prefix_nodash"]) + jinja_params["logo_light"] = f"{jinja_params['name_noslash']}_logo_light.png" + jinja_params["logo_dark"] = f"{jinja_params['name_noslash']}_logo_dark.png" if ( "lint" in config_yml and "nextflow_config" in config_yml["lint"] and "manifest.name" in config_yml["lint"]["nextflow_config"] ): - return skip_areas, skip_paths + return jinja_params, skip_paths # Check that the pipeline name matches the requirements - if not re.match(r"^[a-z]+$", self.config.short_name): - if self.config.is_nfcore: + if not re.match(r"^[a-z]+$", jinja_params["short_name"]): + if jinja_params["is_nfcore"]: raise UserWarning("[red]Invalid workflow name: must be lowercase without punctuation.") else: log.warning( "Your workflow name is not lowercase without punctuation. This may cause Nextflow errors.\nConsider changing the name to avoid special characters." ) - return skip_areas, skip_paths + return jinja_params, skip_paths def init_pipeline(self): """Creates the nf-core pipeline.""" @@ -278,14 +281,14 @@ def render_template(self): loader=jinja2.PackageLoader("nf_core", "pipeline-template"), keep_trailing_newline=True ) template_dir = os.path.join(os.path.dirname(__file__), "pipeline-template") - object_attrs = self.config.model_dump() + object_attrs = self.jinja_params object_attrs["nf_core_version"] = nf_core.__version__ # Can't use glob.glob() as need recursive hidden dotfiles - https://stackoverflow.com/a/58126417/713980 template_files = list(Path(template_dir).glob("**/*")) template_files += list(Path(template_dir).glob("*")) ignore_strs = [".pyc", "__pycache__", ".pyo", ".pyd", ".DS_Store", ".egg"] - short_name = self.config.short_name + short_name = self.jinja_params["short_name"] rename_files = { "workflows/pipeline.nf": f"workflows/{short_name}.nf", "lib/WorkflowPipeline.groovy": f"lib/Workflow{short_name.title()}.groovy", @@ -343,14 +346,14 @@ def render_template(self): os.chmod(output_path, template_stat.st_mode) # Remove all unused parameters in the nextflow schema - if not self.skip_areas["igenomes"] or not self.skip_areas["nf_core_configs"]: + if not self.jinja_params["igenomes"] or not self.jinja_params["nf_core_configs"]: self.update_nextflow_schema() if self.config.is_nfcore: # Make a logo and save it, if it is a nf-core pipeline self.make_pipeline_logo() else: - if self.skip_areas["github"]: + if self.jinja_params["github"]: # Remove field mentioning nf-core docs # in the github bug report template self.remove_nf_core_in_bug_report_template() @@ -405,7 +408,7 @@ def fix_linting(self): for a customized pipeline. """ # Create a lint config - short_name = self.config.short_name + short_name = self.jinja_params["short_name"] lint_config = { "files_exist": [ "CODE_OF_CONDUCT.md", @@ -430,7 +433,7 @@ def fix_linting(self): } # Add GitHub hosting specific configurations - if not self.skip_areas["github"]: + if not self.jinja_params["github"]: lint_config["files_exist"].extend( [ ".github/ISSUE_TEMPLATE/bug_report.yml", @@ -456,7 +459,7 @@ def fix_linting(self): ) # Add CI specific configurations - if not self.skip_areas["ci"]: + if not self.jinja_params["ci"]: lint_config["files_exist"].extend( [ ".github/workflows/branch.yml", @@ -467,7 +470,7 @@ def fix_linting(self): ) # Add custom config specific configurations - if not self.skip_areas["nf_core_configs"]: + if not self.jinja_params["nf_core_configs"]: lint_config["files_exist"].extend(["conf/igenomes.config"]) lint_config["nextflow_config"].extend( [ @@ -479,11 +482,11 @@ def fix_linting(self): ) # Add igenomes specific configurations - if not self.skip_areas["igenomes"]: + if not self.jinja_params["igenomes"]: lint_config["files_exist"].extend(["conf/igenomes.config"]) # Add github badges specific configurations - if not self.skip_areas["github_badges"] or not self.skip_areas["github"]: + if not self.jinja_params["github_badges"] or not self.jinja_params["github"]: lint_config["readme"] = ["nextflow_badge"] # If the pipeline is not nf-core @@ -501,14 +504,14 @@ def fix_linting(self): def make_pipeline_logo(self): """Fetch a logo for the new pipeline from the nf-core website""" - logo_url = f"https://nf-co.re/logo/{self.config.short_name}?theme=light" + logo_url = f"https://nf-co.re/logo/{self.jinja_params['short_name']}?theme=light" log.debug(f"Fetching logo from {logo_url}") - email_logo_path = self.outdir / "assets" / f"{self.config.name_noslash}_logo_light.png" + email_logo_path = self.outdir / "assets" / f"{self.jinja_params['name_noslash']}_logo_light.png" self.download_pipeline_logo(f"{logo_url}?w=600&theme=light", email_logo_path) for theme in ["dark", "light"]: readme_logo_url = f"{logo_url}?w=600&theme={theme}" - readme_logo_path = self.outdir / "docs" / "images" / f"{self.config.name_noslash}_logo_{theme}.png" + readme_logo_path = self.outdir / "docs" / "images" / f"{self.jinja_params['name_noslash']}_logo_{theme}.png" self.download_pipeline_logo(readme_logo_url, readme_logo_path) def download_pipeline_logo(self, url, img_fn): From cb62be330d26c2a4a38fd64a072884b144b66b19 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 1 Sep 2023 11:14:47 +0200 Subject: [PATCH 029/175] refactor function obtain_jinja_params_dict --- nf_core/create.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nf_core/create.py b/nf_core/create.py index b607c78b8b..fe8f0fee95 100644 --- a/nf_core/create.py +++ b/nf_core/create.py @@ -74,7 +74,7 @@ def __init__( else: raise UserWarning("The template configuration was not provided.") - self.jinja_params, skip_paths = self.obtain_skipped_areas_dict( + self.jinja_params, skip_paths = self.obtain_jinja_params_dict( self.config.skip_features, outdir if outdir else "." ) @@ -170,7 +170,7 @@ def update_config(self, organisation, version, force, pipeline_dir): if self.config.is_nfcore is None: self.config.is_nfcore = True if organisation == "nf-core" else False - def obtain_skipped_areas_dict(self, features_to_skip, pipeline_dir): + def obtain_jinja_params_dict(self, features_to_skip, pipeline_dir): """Creates a dictionary of parameters for the new pipeline. Args: From da1c68f4307f2a8b6eeb2248a642d950a43bcd24 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 1 Sep 2023 12:40:06 +0200 Subject: [PATCH 030/175] run create command from the App, mv nf_core/create.py to nf_core/pipelines/create/create.py --- nf_core/__main__.py | 68 +++++++++++------------- nf_core/lint/files_unchanged.py | 6 +-- nf_core/{ => pipelines/create}/create.py | 46 ++++++++-------- nf_core/pipelines/create/finaldetails.py | 10 +++- nf_core/sync.py | 6 +-- tests/lint/nextflow_config.py | 2 +- tests/lint/version_consistency.py | 2 +- tests/modules/patch.py | 2 +- tests/test_bump_version.py | 8 +-- tests/test_cli.py | 2 +- tests/test_create.py | 16 +++--- tests/test_download.py | 4 +- tests/test_launch.py | 4 +- tests/test_lint.py | 6 +-- tests/test_modules.py | 4 +- tests/test_params_file.py | 4 +- tests/test_schema.py | 4 +- tests/test_subworkflows.py | 4 +- tests/test_sync.py | 4 +- tests/test_utils.py | 6 +-- 20 files changed, 105 insertions(+), 103 deletions(-) rename nf_core/{ => pipelines/create}/create.py (95%) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 09ecf1de63..97f166f289 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -488,12 +488,25 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp \n\n Run without any command line arguments to use an interactive interface. """ - from nf_core.create import PipelineCreate from nf_core.pipelines.create import PipelineCreateApp + from nf_core.pipelines.create.create import PipelineCreate if (name and description and author) or (template_yaml): # If all command arguments are used, run without the interactive interface - config = None + try: + create_obj = PipelineCreate( + name, + description, + author, + version=version, + force=force, + outdir=outdir, + organisation=organisation, + ) + create_obj.init_pipeline() + except UserWarning as e: + log.error(e) + sys.exit(1) elif name or description or author or version or force or outdir or organisation: log.error( "Command arguments are not accepted in interactive mode.\n" @@ -507,23 +520,7 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp "\nRun with all command line arguments to avoid using an interactive interface." ) app = PipelineCreateApp() - config = app.run() - - try: - create_obj = PipelineCreate( - name, - description, - author, - version=version, - force=force, - outdir=outdir, - template_config=config, - organisation=organisation, - ) - create_obj.init_pipeline() - except UserWarning as e: - log.error(e) - sys.exit(1) + app.run() # nf-core create (deprecated) @@ -548,12 +545,24 @@ def create(name, description, author, version, force, outdir, template_yaml, pla Uses the nf-core template to make a skeleton Nextflow pipeline with all required files, boilerplate code and best-practices. """ - from nf_core.create import PipelineCreate from nf_core.pipelines.create import PipelineCreateApp + from nf_core.pipelines.create.create import PipelineCreate if (name and description and author) or (template_yaml): # If all command arguments are used, run without the interactive interface - config = None + try: + create_obj = PipelineCreate( + name, + description, + author, + version=version, + force=force, + outdir=outdir, + ) + create_obj.init_pipeline() + except UserWarning as e: + log.error(e) + sys.exit(1) elif name or description or author or version or force or outdir or plain: log.error( "Command arguments are not accepted in interactive mode.\n" @@ -571,25 +580,10 @@ def create(name, description, author, version, force, outdir, template_yaml, pla "\nRun with all command line arguments to avoid using an interactive interface." ) app = PipelineCreateApp() - config = app.run() + app.run() else: sys.exit(0) - try: - create_obj = PipelineCreate( - name, - description, - author, - version=version, - force=force, - outdir=outdir, - template_config=config, - ) - create_obj.init_pipeline() - except UserWarning as e: - log.error(e) - sys.exit(1) - # nf-core modules subcommands @nf_core_cli.group() diff --git a/nf_core/lint/files_unchanged.py b/nf_core/lint/files_unchanged.py index 2b64d62638..9a0175571f 100644 --- a/nf_core/lint/files_unchanged.py +++ b/nf_core/lint/files_unchanged.py @@ -6,7 +6,7 @@ import yaml -import nf_core.create +import nf_core.pipelines.create.create log = logging.getLogger(__name__) @@ -111,7 +111,7 @@ def files_unchanged(self): ] # Only show error messages from pipeline creation - logging.getLogger("nf_core.create").setLevel(logging.ERROR) + logging.getLogger("nf_core.pipelines.create").setLevel(logging.ERROR) # Generate a new pipeline with nf-core create that we can compare to tmp_dir = tempfile.mkdtemp() @@ -129,7 +129,7 @@ def files_unchanged(self): yaml.dump(template_yaml, fh, default_flow_style=False) test_pipeline_dir = os.path.join(tmp_dir, f"{prefix}-{short_name}") - create_obj = nf_core.create.PipelineCreate( + create_obj = nf_core.pipelines.create.create.PipelineCreate( None, None, None, no_git=True, outdir=test_pipeline_dir, template_yaml_path=template_yaml_path ) create_obj.init_pipeline() diff --git a/nf_core/create.py b/nf_core/pipelines/create/create.py similarity index 95% rename from nf_core/create.py rename to nf_core/pipelines/create/create.py index fe8f0fee95..4bdf64a629 100644 --- a/nf_core/create.py +++ b/nf_core/pipelines/create/create.py @@ -47,9 +47,9 @@ class PipelineCreate: def __init__( self, - name, - description, - author, + name=None, + description=None, + author=None, version="1.0dev", no_git=False, force=False, @@ -59,11 +59,7 @@ def __init__( from_config_file=False, default_branch=None, ): - if template_config is not None and isinstance(template_config, str): - # Obtain a CreateConfig object from the template yaml file - self.config = self.check_template_yaml_info(template_config, name, description, author) - self.update_config(organisation, version, force, outdir if outdir else ".") - elif isinstance(template_config, CreateConfig): + if isinstance(template_config, CreateConfig): self.config = template_config elif from_config_file: # Try reading config file @@ -71,12 +67,16 @@ def __init__( # Obtain a CreateConfig object from `.nf-core.yml` config file if "template" in config_yml: self.config = CreateConfig(**config_yml["template"]) + else: + raise UserWarning("The template configuration was not provided in '.nf-core.yml'.") + elif (name and description and author) or (template_config and isinstance(template_config, str)): + # Obtain a CreateConfig object from the template yaml file + self.config = self.check_template_yaml_info(template_config, name, description, author) + self.update_config(organisation, version, force, outdir) else: raise UserWarning("The template configuration was not provided.") - self.jinja_params, skip_paths = self.obtain_jinja_params_dict( - self.config.skip_features, outdir if outdir else "." - ) + self.jinja_params, skip_paths = self.obtain_jinja_params_dict(self.config.skip_features, self.config.outdir) skippable_paths = { "github": [ @@ -123,12 +123,14 @@ def check_template_yaml_info(self, template_yaml, name, description, author): UserWarning: if template yaml file does not exist. """ # Obtain template customization info from template yaml file or `.nf-core.yml` config file - try: - with open(template_yaml, "r") as f: - template_yaml = yaml.safe_load(f) - config = CreateConfig(**template_yaml) - except FileNotFoundError: - raise UserWarning(f"Template YAML file '{template_yaml}' not found.") + config = CreateConfig() + if template_yaml: + try: + with open(template_yaml, "r") as f: + template_yaml = yaml.safe_load(f) + config = CreateConfig(**template_yaml) + except FileNotFoundError: + raise UserWarning(f"Template YAML file '{template_yaml}' not found.") missing_fields = [] if config.name is None and name is None: @@ -150,14 +152,14 @@ def check_template_yaml_info(self, template_yaml, name, description, author): return config - def update_config(self, organisation, version, force, pipeline_dir): + def update_config(self, organisation, version, force, outdir): """Updates the config file with arguments provided through command line. Args: organisation (str): Name of the GitHub organisation to create the pipeline. version (str): Version of the pipeline. force (bool): Overwrites a given workflow directory with the same name. - pipeline_dir (str): Path to the local output directory. + outdir (str): Path to the local output directory. """ if self.config.org is None: self.config.org = organisation @@ -166,9 +168,9 @@ def update_config(self, organisation, version, force, pipeline_dir): if self.config.force is None: self.config.force = force if force else False if self.config.outdir is None: - self.config.outdir = pipeline_dir + self.config.outdir = outdir if outdir else "." if self.config.is_nfcore is None: - self.config.is_nfcore = True if organisation == "nf-core" else False + self.config.is_nfcore = organisation == "nf-core" def obtain_jinja_params_dict(self, features_to_skip, pipeline_dir): """Creates a dictionary of parameters for the new pipeline. @@ -280,7 +282,7 @@ def render_template(self): env = jinja2.Environment( loader=jinja2.PackageLoader("nf_core", "pipeline-template"), keep_trailing_newline=True ) - template_dir = os.path.join(os.path.dirname(__file__), "pipeline-template") + template_dir = os.path.join(os.path.dirname(nf_core.__file__), "pipeline-template") object_attrs = self.jinja_params object_attrs["nf_core_version"] = nf_core.__version__ diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 4f65f97629..c73038ee95 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -7,7 +7,8 @@ from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch -from nf_core.pipelines.create.utils import CreateConfig, TextInput +from nf_core.pipelines.create.create import PipelineCreate +from nf_core.pipelines.create.utils import TextInput class FinalDetails(Screen): @@ -71,4 +72,9 @@ def on_button_pressed(self, event: Button.Pressed) -> None: except ValueError: pass - self.parent.exit(self.parent.TEMPLATE_CONFIG) + # self.parent.exit(self.parent.TEMPLATE_CONFIG) + # Create the new pipeline + create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) + create_obj.init_pipeline() + self.parent.exit() + # self.parent.switch_screen("github_repo") diff --git a/nf_core/sync.py b/nf_core/sync.py index 5402a6121d..6175ebff08 100644 --- a/nf_core/sync.py +++ b/nf_core/sync.py @@ -16,8 +16,8 @@ from git import GitCommandError, InvalidGitRepositoryError import nf_core -import nf_core.create import nf_core.list +import nf_core.pipelines.create.create import nf_core.utils log = logging.getLogger(__name__) @@ -251,7 +251,7 @@ def make_template_pipeline(self): log.info("Making a new template pipeline using pipeline variables") # Only show error messages from pipeline creation - logging.getLogger("nf_core.create").setLevel(logging.ERROR) + logging.getLogger("nf_core.pipelines.create").setLevel(logging.ERROR) # Re-write the template yaml info from .nf-core.yml config if "template" in self.config_yml: @@ -259,7 +259,7 @@ def make_template_pipeline(self): yaml.safe_dump(self.config_yml, config_path) try: - nf_core.create.PipelineCreate( + nf_core.pipelines.create.create.PipelineCreate( name=self.wf_config["manifest.name"].strip('"').strip("'"), description=self.wf_config["manifest.description"].strip('"').strip("'"), version=self.wf_config["manifest.version"].strip('"').strip("'"), diff --git a/tests/lint/nextflow_config.py b/tests/lint/nextflow_config.py index f53765dce9..1d7ca36abf 100644 --- a/tests/lint/nextflow_config.py +++ b/tests/lint/nextflow_config.py @@ -1,5 +1,5 @@ -import nf_core.create import nf_core.lint +import nf_core.pipelines.create.create def test_nextflow_config_example_pass(self): diff --git a/tests/lint/version_consistency.py b/tests/lint/version_consistency.py index c682800646..6f70d67c40 100644 --- a/tests/lint/version_consistency.py +++ b/tests/lint/version_consistency.py @@ -1,5 +1,5 @@ -import nf_core.create import nf_core.lint +import nf_core.pipelines.create.create def test_version_consistency(self): diff --git a/tests/modules/patch.py b/tests/modules/patch.py index 338d890f2f..7263d30263 100644 --- a/tests/modules/patch.py +++ b/tests/modules/patch.py @@ -349,7 +349,7 @@ def test_remove_patch(self): "modules", REPO_NAME, BISMARK_ALIGN, patch_fn ) - with mock.patch.object(nf_core.create.questionary, "confirm") as mock_questionary: + with mock.patch.object(nf_core.pipelines.create.questionary, "confirm") as mock_questionary: mock_questionary.unsafe_ask.return_value = True patch_obj.remove(BISMARK_ALIGN) # Check that the diff file has been removed diff --git a/tests/test_bump_version.py b/tests/test_bump_version.py index 658a2339d4..07de9687fa 100644 --- a/tests/test_bump_version.py +++ b/tests/test_bump_version.py @@ -5,7 +5,7 @@ import yaml import nf_core.bump_version -import nf_core.create +import nf_core.pipelines.create.create import nf_core.utils @@ -16,7 +16,7 @@ def test_bump_pipeline_version(datafiles, tmp_path): # Get a workflow and configs test_pipeline_dir = os.path.join(tmp_path, "nf-core-testpipeline") - create_obj = nf_core.create.PipelineCreate( + create_obj = nf_core.pipelines.create.create.PipelineCreate( "testpipeline", "This is a test pipeline", "Test McTestFace", no_git=True, outdir=test_pipeline_dir, plain=True ) create_obj.init_pipeline() @@ -36,7 +36,7 @@ def test_dev_bump_pipeline_version(datafiles, tmp_path): """Test that making a release works with a dev name and a leading v""" # Get a workflow and configs test_pipeline_dir = os.path.join(tmp_path, "nf-core-testpipeline") - create_obj = nf_core.create.PipelineCreate( + create_obj = nf_core.pipelines.create.create.PipelineCreate( "testpipeline", "This is a test pipeline", "Test McTestFace", no_git=True, outdir=test_pipeline_dir, plain=True ) create_obj.init_pipeline() @@ -55,7 +55,7 @@ def test_dev_bump_pipeline_version(datafiles, tmp_path): def test_bump_nextflow_version(datafiles, tmp_path): # Get a workflow and configs test_pipeline_dir = os.path.join(tmp_path, "nf-core-testpipeline") - create_obj = nf_core.create.PipelineCreate( + create_obj = nf_core.pipelines.create.create.PipelineCreate( "testpipeline", "This is a test pipeline", "Test McTestFace", no_git=True, outdir=test_pipeline_dir, plain=True ) create_obj.init_pipeline() diff --git a/tests/test_cli.py b/tests/test_cli.py index fc172deba9..d488e6493f 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -228,7 +228,7 @@ def test_licences_log_error(self, mock_lic): assert error_txt in captured_logs.output[-1] assert captured_logs.records[-1].levelname == "ERROR" - @mock.patch("nf_core.create.PipelineCreate") + @mock.patch("nf_core.pipelines.create.PipelineCreate") def test_create(self, mock_create): """Test nf-core pipeline is created and cli parameters are passed on.""" params = { diff --git a/tests/test_create.py b/tests/test_create.py index 1cc073cb54..3154539bb6 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -8,7 +8,7 @@ import git import yaml -import nf_core.create +import nf_core.pipelines.create.create from .utils import with_temporary_folder @@ -26,7 +26,7 @@ def setUp(self): self.default_branch = "default" def test_pipeline_creation(self): - pipeline = nf_core.create.PipelineCreate( + pipeline = nf_core.pipelines.create.create.PipelineCreate( name=self.pipeline_name, description=self.pipeline_description, author=self.pipeline_author, @@ -44,7 +44,7 @@ def test_pipeline_creation(self): @with_temporary_folder def test_pipeline_creation_initiation(self, tmp_path): - pipeline = nf_core.create.PipelineCreate( + pipeline = nf_core.pipelines.create.create.PipelineCreate( name=self.pipeline_name, description=self.pipeline_description, author=self.pipeline_author, @@ -64,7 +64,7 @@ def test_pipeline_creation_initiation(self, tmp_path): @with_temporary_folder def test_pipeline_creation_initiation_with_yml(self, tmp_path): - pipeline = nf_core.create.PipelineCreate( + pipeline = nf_core.pipelines.create.create.PipelineCreate( name=self.pipeline_name, description=self.pipeline_description, author=self.pipeline_author, @@ -88,13 +88,13 @@ def test_pipeline_creation_initiation_with_yml(self, tmp_path): assert "template" in nfcore_yml assert nfcore_yml["template"] == yaml.safe_load(PIPELINE_TEMPLATE_YML.read_text()) - @mock.patch.object(nf_core.create.PipelineCreate, "customize_template") - @mock.patch.object(nf_core.create.questionary, "confirm") + @mock.patch.object(nf_core.pipelines.create.create.PipelineCreate, "customize_template") + @mock.patch.object(nf_core.pipelines.create.create.questionary, "confirm") @with_temporary_folder def test_pipeline_creation_initiation_customize_template(self, mock_questionary, mock_customize, tmp_path): mock_questionary.unsafe_ask.return_value = True mock_customize.return_value = {"prefix": "testprefix"} - pipeline = nf_core.create.PipelineCreate( + pipeline = nf_core.pipelines.create.create.PipelineCreate( name=self.pipeline_name, description=self.pipeline_description, author=self.pipeline_author, @@ -118,7 +118,7 @@ def test_pipeline_creation_initiation_customize_template(self, mock_questionary, @with_temporary_folder def test_pipeline_creation_with_yml_skip(self, tmp_path): - pipeline = nf_core.create.PipelineCreate( + pipeline = nf_core.pipelines.create.create.PipelineCreate( name=self.pipeline_name, description=self.pipeline_description, author=self.pipeline_author, diff --git a/tests/test_download.py b/tests/test_download.py index dfd78adcfb..ea59c7bd62 100644 --- a/tests/test_download.py +++ b/tests/test_download.py @@ -12,7 +12,7 @@ import pytest -import nf_core.create +import nf_core.pipelines.create.create import nf_core.utils from nf_core.download import ContainerError, DownloadWorkflow, WorkflowRepo from nf_core.synced_repo import SyncedRepo @@ -110,7 +110,7 @@ def test_download_configs(self, outdir): def test_wf_use_local_configs(self, tmp_path): # Get a workflow and configs test_pipeline_dir = os.path.join(tmp_path, "nf-core-testpipeline") - create_obj = nf_core.create.PipelineCreate( + create_obj = nf_core.pipelines.create.create.PipelineCreate( "testpipeline", "This is a test pipeline", "Test McTestFace", diff --git a/tests/test_launch.py b/tests/test_launch.py index d830311ba3..d3ddde6c8c 100644 --- a/tests/test_launch.py +++ b/tests/test_launch.py @@ -9,8 +9,8 @@ import pytest -import nf_core.create import nf_core.launch +import nf_core.pipelines.create.create from .utils import with_temporary_file, with_temporary_folder @@ -71,7 +71,7 @@ def test_get_pipeline_schema(self): def test_make_pipeline_schema(self, tmp_path): """Create a workflow, but delete the schema file, then try to load it""" test_pipeline_dir = os.path.join(tmp_path, "wf") - create_obj = nf_core.create.PipelineCreate( + create_obj = nf_core.pipelines.create.create.PipelineCreate( "testpipeline", "", "", outdir=test_pipeline_dir, no_git=True, plain=True ) create_obj.init_pipeline() diff --git a/tests/test_lint.py b/tests/test_lint.py index e4e93bd1f4..99e0506cf8 100644 --- a/tests/test_lint.py +++ b/tests/test_lint.py @@ -9,8 +9,8 @@ import yaml -import nf_core.create import nf_core.lint +import nf_core.pipelines.create.create from .utils import with_temporary_folder @@ -21,12 +21,12 @@ class TestLint(unittest.TestCase): def setUp(self): """Function that runs at start of tests for common resources - Use nf_core.create() to make a pipeline that we can use for testing + Use nf_core.pipelines.create() to make a pipeline that we can use for testing """ self.tmp_dir = tempfile.mkdtemp() self.test_pipeline_dir = os.path.join(self.tmp_dir, "nf-core-testpipeline") - self.create_obj = nf_core.create.PipelineCreate( + self.create_obj = nf_core.pipelines.create.create.PipelineCreate( "testpipeline", "This is a test pipeline", "Test McTestFace", outdir=self.test_pipeline_dir, plain=True ) self.create_obj.init_pipeline() diff --git a/tests/test_modules.py b/tests/test_modules.py index 047369b7c3..0d784c74ed 100644 --- a/tests/test_modules.py +++ b/tests/test_modules.py @@ -9,8 +9,8 @@ import requests_cache import responses -import nf_core.create import nf_core.modules +import nf_core.pipelines.create.create from .utils import ( GITLAB_BRANCH_TEST_BRANCH, @@ -72,7 +72,7 @@ def setUp(self): self.template_dir = os.path.join(root_repo_dir, "nf_core", "pipeline-template") self.pipeline_name = "mypipeline" self.pipeline_dir = os.path.join(self.tmp_dir, self.pipeline_name) - nf_core.create.PipelineCreate( + nf_core.pipelines.create.create.PipelineCreate( self.pipeline_name, "it is mine", "me", no_git=True, outdir=self.pipeline_dir, plain=True ).init_pipeline() # Set up install objects diff --git a/tests/test_params_file.py b/tests/test_params_file.py index 824e8fe345..882b575125 100644 --- a/tests/test_params_file.py +++ b/tests/test_params_file.py @@ -4,7 +4,7 @@ import tempfile from pathlib import Path -import nf_core.create +import nf_core.pipelines.create.create import nf_core.schema from nf_core.params_file import ParamsFileBuilder @@ -21,7 +21,7 @@ def setup_class(cls): # Create a test pipeline in temp directory cls.tmp_dir = tempfile.mkdtemp() cls.template_dir = os.path.join(cls.tmp_dir, "wf") - create_obj = nf_core.create.PipelineCreate( + create_obj = nf_core.pipelines.create.create.PipelineCreate( "testpipeline", "", "", outdir=cls.template_dir, no_git=True, plain=True ) create_obj.init_pipeline() diff --git a/tests/test_schema.py b/tests/test_schema.py index d3b4fda817..4d8f2e0ef6 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -12,7 +12,7 @@ import requests import yaml -import nf_core.create +import nf_core.pipelines.create.create import nf_core.schema from .utils import with_temporary_file, with_temporary_folder @@ -29,7 +29,7 @@ def setUp(self): # Create a test pipeline in temp directory self.tmp_dir = tempfile.mkdtemp() self.template_dir = os.path.join(self.tmp_dir, "wf") - create_obj = nf_core.create.PipelineCreate( + create_obj = nf_core.pipelines.create.create.PipelineCreate( "testpipeline", "", "", outdir=self.template_dir, no_git=True, plain=True ) create_obj.init_pipeline() diff --git a/tests/test_subworkflows.py b/tests/test_subworkflows.py index 1c290cb882..fb15211319 100644 --- a/tests/test_subworkflows.py +++ b/tests/test_subworkflows.py @@ -8,8 +8,8 @@ import responses -import nf_core.create import nf_core.modules +import nf_core.pipelines.create.create import nf_core.subworkflows from .utils import ( @@ -55,7 +55,7 @@ def setUp(self): self.template_dir = os.path.join(root_repo_dir, "nf_core", "pipeline-template") self.pipeline_name = "mypipeline" self.pipeline_dir = os.path.join(self.tmp_dir, self.pipeline_name) - nf_core.create.PipelineCreate( + nf_core.pipelines.create.create.PipelineCreate( self.pipeline_name, "it is mine", "me", no_git=True, outdir=self.pipeline_dir, plain=True ).init_pipeline() diff --git a/tests/test_sync.py b/tests/test_sync.py index 597e4375d3..228a6682ed 100644 --- a/tests/test_sync.py +++ b/tests/test_sync.py @@ -12,7 +12,7 @@ import git import pytest -import nf_core.create +import nf_core.pipelines.create.create import nf_core.sync from .utils import with_temporary_folder @@ -26,7 +26,7 @@ def setUp(self): self.tmp_dir = tempfile.mkdtemp() self.pipeline_dir = os.path.join(self.tmp_dir, "testpipeline") default_branch = "master" - self.create_obj = nf_core.create.PipelineCreate( + self.create_obj = nf_core.pipelines.create.create.PipelineCreate( "testing", "test pipeline", "tester", outdir=self.pipeline_dir, plain=True, default_branch=default_branch ) self.create_obj.init_pipeline() diff --git a/tests/test_utils.py b/tests/test_utils.py index 2ab5b64bfc..22b5a23321 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -11,8 +11,8 @@ import pytest import requests -import nf_core.create import nf_core.list +import nf_core.pipelines.create.create import nf_core.utils from .utils import with_temporary_folder @@ -35,11 +35,11 @@ class TestUtils(unittest.TestCase): def setUp(self): """Function that runs at start of tests for common resources - Use nf_core.create() to make a pipeline that we can use for testing + Use nf_core.pipelines.create() to make a pipeline that we can use for testing """ self.tmp_dir = tempfile.mkdtemp() self.test_pipeline_dir = os.path.join(self.tmp_dir, "nf-core-testpipeline") - self.create_obj = nf_core.create.PipelineCreate( + self.create_obj = nf_core.pipelines.create.create.PipelineCreate( "testpipeline", "This is a test pipeline", "Test McTestFace", From 3c14dd7f0ab2953e81bf23c6a1cfbd4454095224 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 3 Oct 2023 11:26:44 +0200 Subject: [PATCH 031/175] add new screen to create a github repo and push the new pipeline (not working from the app) --- nf_core/pipelines/create/__init__.py | 2 + nf_core/pipelines/create/finaldetails.py | 4 +- nf_core/pipelines/create/githubrepo.py | 176 +++++++++++++++++++++++ requirements.txt | 1 + 4 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 nf_core/pipelines/create/githubrepo.py diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 0fe143b3bc..4832a73468 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -5,6 +5,7 @@ from nf_core.pipelines.create.basicdetails import BasicDetails from nf_core.pipelines.create.custompipeline import CustomPipeline from nf_core.pipelines.create.finaldetails import FinalDetails +from nf_core.pipelines.create.githubrepo import GithubRepo from nf_core.pipelines.create.nfcorepipeline import NfcorePipeline from nf_core.pipelines.create.pipelinetype import ChoosePipelineType from nf_core.pipelines.create.utils import CreateConfig @@ -28,6 +29,7 @@ class PipelineCreateApp(App[CreateConfig]): "type_custom": CustomPipeline(), "type_nfcore": NfcorePipeline(), "final_details": FinalDetails(), + "github_repo": GithubRepo(), } # Initialise config as empty diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index c73038ee95..203f2f6bb4 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -72,9 +72,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: except ValueError: pass - # self.parent.exit(self.parent.TEMPLATE_CONFIG) # Create the new pipeline create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) create_obj.init_pipeline() - self.parent.exit() - # self.parent.switch_screen("github_repo") + self.parent.switch_screen("github_repo") diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py new file mode 100644 index 0000000000..6660be622c --- /dev/null +++ b/nf_core/pipelines/create/githubrepo.py @@ -0,0 +1,176 @@ +import logging +import os +from textwrap import dedent + +import git +from github import Github, GithubException +from textual import on +from textual.app import ComposeResult +from textual.containers import Center, Horizontal +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch + +from nf_core.pipelines.create.utils import TextInput + +log = logging.getLogger(__name__) + +github_text_markdown = """ +# Create a GitHub repo + +After creating the pipeline template locally, we can create a GitHub repository and push the code to it. +""" +repo_config_markdown = """ +Please select the the GitHub repository settings: +""" +exit_help_text_markdown = f""" +If you would like to create the GitHub repository later, you can do it manually by following these steps: +1. Create a new GitHub repository +2. Add the remote to your local repository +```bash +cd +git remote add origin git@github.com:/.git +``` +3. Push the code to the remote +```bash +git push --all origin +``` +""" + + +class GithubRepo(Screen): + """Create a GitHub repository and push all branches.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Markdown(dedent(github_text_markdown)) + with Horizontal(): + yield TextInput( + "gh_username", + "GitHub username", + "Your GitHub username", + classes="column", + ) + token = "GITHUB_AUTH_TOKEN" in os.environ + yield TextInput( + "token", + "GitHub token", + "Your GitHub personal access token for login. Will use the environment variable GITHUB_AUTH_TOKEN if set.", + classes="column", + disabled=token, + ) + yield Markdown(dedent(repo_config_markdown)) + with Horizontal(): + yield Switch(value=False, id="private") + yield Static("Select if the new GitHub repo must be private.", classes="custom_grid") + with Horizontal(): + yield Switch(value=True, id="push") + yield Static( + "Select if you would like to push all the pipeline template files to your GitHub repo\nand all the branches required to keep the pipeline up to date with new releases of nf-core.", + classes="custom_grid", + ) + yield Center( + Button("Create GitHub repo", id="create", variant="success"), + Button("Finish without creating a repo", id="finish", variant="primary"), + classes="cta", + ) + + @on(Button.Pressed, "#create") + def on_button_pressed(self, event: Button.Pressed) -> None: + """Create a GitHub repo""" + # Save GitHub username and token + print("button pressed") + github_variables = {} + for text_input in self.query("TextInput"): + this_input = text_input.query_one(Input) + github_variables[text_input.field_id] = this_input.value + # Save GitHub repo config + for switch_input in self.query("Switch"): + this_switch = switch_input.query_one(Switch) + github_variables[switch_input.field_id] = this_switch.value + + # Pipeline git repo + pipeline_repo = git.Repo.init(self.parent.TEMPLATE_CONFIG.outdir) + + # GitHub authentication + if "GITHUB_AUTH_TOKEN" in os.environ: + github_auth = self._github_authentication(github_variables["gh_username"], os.environ["GITHUB_AUTH_TOKEN"]) + elif github_variables["token"]: + github_auth = self._github_authentication(github_variables["gh_username"], github_variables["token"]) + else: + raise UserWarning( + f"Could not authenticate to GitHub with user name '{github_variables['gh_username']}'." + "Please provide an authentication token or set the environment variable 'GITHUB_AUTH_TOKEN'." + f"\n{exit_help_text_markdown}" + ) + + user = github_auth.get_user() + org = None + # Make sure that the authentication was successful + try: + user.login + except GithubException.GithubException as e: + raise UserWarning( + f"Could not authenticate to GitHub with user name '{github_variables['gh_username']}'." + "Please make sure that the provided user name and token are correct." + f"\n{exit_help_text_markdown}" + ) + + # Check if organisation exists + # If the organisation is nf-core or it doesn¡t exist, the repo will be created in the user account + if self.parent.TEMPLATE_CONFIG.org != "nf-core": + try: + org = github_auth.get_organization(self.parent.TEMPLATE_CONFIG.org) + except GithubException.UnknownObjectException: + pass + + # Create the repo + try: + if org: + self._create_repo_and_push(org, pipeline_repo, github_variables["private"], github_variables["push"]) + else: + # Create the repo in the user's account + self._create_repo_and_push(user, pipeline_repo, github_variables["private"], github_variables["push"]) + except UserWarning as e: + log.info(f"There was an error with message: {e}" f"\n{exit_help_text_markdown}") + + self.parent.exit() + + @on(Button.Pressed, "#finish") + def on_button_pressed(self, event: Button.Pressed) -> None: + """Show help message and exit""" + log.info(exit_help_text_markdown) + self.parent.exit() + + def _create_repo_and_push(self, org, pipeline_repo, private, push): + """Create a GitHub repository and push all branches.""" + # Check if repo already exists + try: + repo = org.get_repo(self.parent.TEMPLATE_CONFIG.name) + # Check if it has a commit history + try: + repo.get_commits().totalCount + raise UserWarning(f"GitHub repository '{self.parent.TEMPLATE_CONFIG.name}' already exists") + except GithubException.GithubException: + # Repo is empty + repo_exists = True + except GithubException.UnknownObjectException: + # Repo doesn't exist + repo_exists = False + + # Create the repo + if not repo_exists: + repo = org.create_repo( + self.parent.TEMPLATE_CONFIG.name, description=self.parent.TEMPLATE_CONFIG.description, private=private + ) + + # Add the remote and push + pipeline_repo.create_remote("origin", repo.clone_url) + if push: + pipeline_repo.remotes.origin.push(all=True).raise_if_error() + + def _github_authentication(self, gh_username, gh_token): + """Authenticate to GitHub""" + log.debug(f"Authenticating GitHub as {gh_username}") + github_auth = Github(gh_username, gh_token) + return github_auth diff --git a/requirements.txt b/requirements.txt index b5fc542591..15c4f9e186 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ click filetype GitPython +PyGithub jinja2 jsonschema>=3.0 markdown>=3.3 From e401a6a692cb785c2afb258bb91051753123b3b6 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Thu, 2 Nov 2023 11:26:28 +0100 Subject: [PATCH 032/175] Some minor CSS tweaks --- nf_core/pipelines/create/create.tcss | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index 4ebc1936ff..42f144c7dd 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -55,20 +55,17 @@ HorizontalScroll { /* Display help messages */ .help_box { - background: white; - margin-left: 15; - margin-right: 25; - margin-bottom: 1; + background: #333333; + padding: 1 5; + margin: 1 10; + overflow-y: auto; + transition: height 50ms; display: none; - height: 0; } .displayed .help_box { display: block; - overflow-y: scroll; - - transition: height 50ms; - height: 10; + height: 12; } #show_help { display: block; From 8b9ad3517d0b44efb809c48b4a0e1c3284ee0275 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 3 Nov 2023 13:13:25 +0100 Subject: [PATCH 033/175] Add logging handler and final screen to visualise logs --- nf_core/pipelines/create/__init__.py | 21 +++++- nf_core/pipelines/create/basicdetails.py | 75 +++++++++++----------- nf_core/pipelines/create/bye.py | 35 ++++++++++ nf_core/pipelines/create/create.tcss | 3 + nf_core/pipelines/create/custompipeline.py | 65 ++++++++++--------- nf_core/pipelines/create/finaldetails.py | 65 ++++++++++--------- nf_core/pipelines/create/githubrepo.py | 72 +++++++++++---------- nf_core/pipelines/create/nfcorepipeline.py | 29 +++++---- nf_core/pipelines/create/pipelinetype.py | 19 +++--- nf_core/pipelines/create/utils.py | 27 +++++++- nf_core/pipelines/create/welcome.py | 25 ++++---- 11 files changed, 270 insertions(+), 166 deletions(-) create mode 100644 nf_core/pipelines/create/bye.py diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 4832a73468..900a0b778b 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -1,16 +1,31 @@ """A Textual app to create a pipeline.""" +import logging + from textual.app import App from textual.widgets import Button from nf_core.pipelines.create.basicdetails import BasicDetails +from nf_core.pipelines.create.bye import ByeScreen from nf_core.pipelines.create.custompipeline import CustomPipeline from nf_core.pipelines.create.finaldetails import FinalDetails from nf_core.pipelines.create.githubrepo import GithubRepo from nf_core.pipelines.create.nfcorepipeline import NfcorePipeline from nf_core.pipelines.create.pipelinetype import ChoosePipelineType -from nf_core.pipelines.create.utils import CreateConfig +from nf_core.pipelines.create.utils import ( + CreateConfig, + CustomLogHandler, + LoggingConsole, +) from nf_core.pipelines.create.welcome import WelcomeScreen +log_handler = CustomLogHandler(console=LoggingConsole(), rich_tracebacks=True) +logging.basicConfig( + level="INFO", + handlers=[log_handler], + format="%(message)s", +) +log_handler.setLevel("INFO") + class PipelineCreateApp(App[CreateConfig]): """A Textual app to manage stopwatches.""" @@ -30,6 +45,7 @@ class PipelineCreateApp(App[CreateConfig]): "type_nfcore": NfcorePipeline(), "final_details": FinalDetails(), "github_repo": GithubRepo(), + "bye": ByeScreen(), } # Initialise config as empty @@ -38,6 +54,9 @@ class PipelineCreateApp(App[CreateConfig]): # Initialise pipeline type PIPELINE_TYPE = None + # Log handler + LOG_HANDLER = log_handler + def on_mount(self) -> None: self.push_screen("welcome") diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py index dc7248d977..072892f392 100644 --- a/nf_core/pipelines/create/basicdetails.py +++ b/nf_core/pipelines/create/basicdetails.py @@ -3,7 +3,7 @@ from textual import on from textual.app import ComposeResult -from textual.containers import Center, Horizontal +from textual.containers import Center, Horizontal, VerticalScroll from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown @@ -16,43 +16,46 @@ class BasicDetails(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - yield Markdown( - dedent( - """ - # Basic details - """ - ) - ) with Horizontal(): - yield TextInput( - "org", - "Organisation", - "GitHub organisation", - "nf-core", - classes="column", - disabled=self.parent.PIPELINE_TYPE == "nfcore", - ) - yield TextInput( - "name", - "Pipeline Name", - "Workflow name", - classes="column", - ) + with VerticalScroll(): + yield Markdown( + dedent( + """ + # Basic details + """ + ) + ) + with Horizontal(): + yield TextInput( + "org", + "Organisation", + "GitHub organisation", + "nf-core", + classes="column", + disabled=self.parent.PIPELINE_TYPE == "nfcore", + ) + yield TextInput( + "name", + "Pipeline Name", + "Workflow name", + classes="column", + ) - yield TextInput( - "description", - "Description", - "A short description of your pipeline.", - ) - yield TextInput( - "author", - "Author(s)", - "Name of the main author / authors", - ) - yield Center( - Button("Next", variant="success"), - classes="cta", - ) + yield TextInput( + "description", + "Description", + "A short description of your pipeline.", + ) + yield TextInput( + "author", + "Author(s)", + "Name of the main author / authors", + ) + yield Center( + Button("Next", variant="success"), + classes="cta", + ) + yield Center(self.parent.LOG_HANDLER.console, classes="cta log") @on(Button.Pressed) def on_button_pressed(self, event: Button.Pressed) -> None: diff --git a/nf_core/pipelines/create/bye.py b/nf_core/pipelines/create/bye.py new file mode 100644 index 0000000000..89d9737785 --- /dev/null +++ b/nf_core/pipelines/create/bye.py @@ -0,0 +1,35 @@ +from textual import on +from textual.app import ComposeResult +from textual.containers import Center +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Markdown, Static + +markdown = """ +# nf-core create + +Bye! +""" + + +class ByeScreen(Screen): + """A screen to show the final logs.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Static( + f"\n[green]{' ' * 40},--.[grey39]/[green],-." + + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + "\n[green] `._,._,'\n", + id="logo", + ) + yield Markdown(markdown) + yield Center(self.parent.LOG_HANDLER.console, classes="cta") + yield Center(Button("Close", id="close", variant="success"), classes="cta") + + @on(Button.Pressed, "#close") + def on_button_pressed(self, event: Button.Pressed) -> None: + """Close app""" + self.parent.exit() diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index 42f144c7dd..a718b940dc 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -9,6 +9,9 @@ margin-left: 3; margin-right: 3; } +.log { + width: 30%; +} .custom_grid { height: auto; diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 5cc2f87d95..9ac76d80d9 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -1,6 +1,6 @@ from textual import on from textual.app import ComposeResult -from textual.containers import Center, ScrollableContainer +from textual.containers import Center, Horizontal, ScrollableContainer, VerticalScroll from textual.screen import Screen from textual.widgets import Button, Footer, Header, Switch @@ -46,36 +46,39 @@ class CustomPipeline(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - yield ScrollableContainer( - PipelineFeature( - markdown_genomes, - "Use reference genomes", - "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", - "igenomes", - ), - PipelineFeature( - markdown_ci, - "Add Github CI tests", - "The pipeline will include several GitHub actions for Continuous Integration (CI) testing", - "ci", - ), - PipelineFeature( - markdown_badges, - "Add Github badges", - "The README.md file of the pipeline will include GitHub badges", - "github_badges", - ), - PipelineFeature( - markdown_configuration, - "Add configuration files", - "The pipeline will include configuration profiles containing custom parameters requried to run nf-core pipelines at different institutions", - "nf_core_configs", - ), - ) - yield Center( - Button("Continue", id="continue", variant="success"), - classes="cta", - ) + with Horizontal(): + with VerticalScroll(): + yield ScrollableContainer( + PipelineFeature( + markdown_genomes, + "Use reference genomes", + "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", + "igenomes", + ), + PipelineFeature( + markdown_ci, + "Add Github CI tests", + "The pipeline will include several GitHub actions for Continuous Integration (CI) testing", + "ci", + ), + PipelineFeature( + markdown_badges, + "Add Github badges", + "The README.md file of the pipeline will include GitHub badges", + "github_badges", + ), + PipelineFeature( + markdown_configuration, + "Add configuration files", + "The pipeline will include configuration profiles containing custom parameters requried to run nf-core pipelines at different institutions", + "nf_core_configs", + ), + ) + yield Center( + Button("Continue", id="continue", variant="success"), + classes="cta", + ) + yield Center(self.parent.LOG_HANDLER.console, classes="cta log") @on(Button.Pressed, "#continue") def on_button_pressed(self, event: Button.Pressed) -> None: diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 203f2f6bb4..904d0e3622 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -3,7 +3,7 @@ from textual import on from textual.app import ComposeResult -from textual.containers import Center, Horizontal +from textual.containers import Center, Horizontal, VerticalScroll from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch @@ -17,37 +17,42 @@ class FinalDetails(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - yield Markdown( - dedent( - """ - # Final details - """ - ) - ) - - with Horizontal(): - yield TextInput( - "version", - "Version", - "First version of the pipeline", - "1.0dev", - classes="column", - ) - yield TextInput( - "outdir", - "Output directory", - "Path to the output directory where the pipeline will be created", - ".", - classes="column", - ) with Horizontal(): - yield Switch(value=False, id="force") - yield Static("If the pipeline output directory exists, remove it and continue.", classes="custom_grid") + with VerticalScroll(): + yield Markdown( + dedent( + """ + # Final details + """ + ) + ) + + with Horizontal(): + yield TextInput( + "version", + "Version", + "First version of the pipeline", + "1.0dev", + classes="column", + ) + yield TextInput( + "outdir", + "Output directory", + "Path to the output directory where the pipeline will be created", + ".", + classes="column", + ) + with Horizontal(): + yield Switch(value=False, id="force") + yield Static( + "If the pipeline output directory exists, remove it and continue.", classes="custom_grid" + ) - yield Center( - Button("Finish", id="finish", variant="success"), - classes="cta", - ) + yield Center( + Button("Finish", id="finish", variant="success"), + classes="cta", + ) + yield Center(self.parent.LOG_HANDLER.console, classes="cta log") @on(Button.Pressed, "#finish") def on_button_pressed(self, event: Button.Pressed) -> None: diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 6660be622c..79db4a4220 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -6,7 +6,7 @@ from github import Github, GithubException from textual import on from textual.app import ComposeResult -from textual.containers import Center, Horizontal +from textual.containers import Center, Horizontal, VerticalScroll from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch @@ -43,43 +43,45 @@ class GithubRepo(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - yield Markdown(dedent(github_text_markdown)) with Horizontal(): - yield TextInput( - "gh_username", - "GitHub username", - "Your GitHub username", - classes="column", - ) - token = "GITHUB_AUTH_TOKEN" in os.environ - yield TextInput( - "token", - "GitHub token", - "Your GitHub personal access token for login. Will use the environment variable GITHUB_AUTH_TOKEN if set.", - classes="column", - disabled=token, - ) - yield Markdown(dedent(repo_config_markdown)) - with Horizontal(): - yield Switch(value=False, id="private") - yield Static("Select if the new GitHub repo must be private.", classes="custom_grid") - with Horizontal(): - yield Switch(value=True, id="push") - yield Static( - "Select if you would like to push all the pipeline template files to your GitHub repo\nand all the branches required to keep the pipeline up to date with new releases of nf-core.", - classes="custom_grid", - ) - yield Center( - Button("Create GitHub repo", id="create", variant="success"), - Button("Finish without creating a repo", id="finish", variant="primary"), - classes="cta", - ) + with VerticalScroll(): + yield Markdown(dedent(github_text_markdown)) + with Horizontal(): + yield TextInput( + "gh_username", + "GitHub username", + "Your GitHub username", + classes="column", + ) + token = "GITHUB_AUTH_TOKEN" in os.environ + yield TextInput( + "token", + "GitHub token", + "Your GitHub personal access token for login. Will use the environment variable GITHUB_AUTH_TOKEN if set.", + classes="column", + disabled=token, + ) + yield Markdown(dedent(repo_config_markdown)) + with Horizontal(): + yield Switch(value=False, id="private") + yield Static("Select if the new GitHub repo must be private.", classes="custom_grid") + with Horizontal(): + yield Switch(value=True, id="push") + yield Static( + "Select if you would like to push all the pipeline template files to your GitHub repo\nand all the branches required to keep the pipeline up to date with new releases of nf-core.", + classes="custom_grid", + ) + yield Center( + Button("Create GitHub repo", id="create", variant="success"), + Button("Finish without creating a repo", id="exit", variant="primary"), + classes="cta", + ) + yield Center(self.parent.LOG_HANDLER.console, classes="cta log") @on(Button.Pressed, "#create") def on_button_pressed(self, event: Button.Pressed) -> None: """Create a GitHub repo""" # Save GitHub username and token - print("button pressed") github_variables = {} for text_input in self.query("TextInput"): this_input = text_input.query_one(Input) @@ -134,13 +136,13 @@ def on_button_pressed(self, event: Button.Pressed) -> None: except UserWarning as e: log.info(f"There was an error with message: {e}" f"\n{exit_help_text_markdown}") - self.parent.exit() + self.parent.switch_screen("bye") - @on(Button.Pressed, "#finish") + @on(Button.Pressed, "#exit") def on_button_pressed(self, event: Button.Pressed) -> None: """Show help message and exit""" log.info(exit_help_text_markdown) - self.parent.exit() + self.parent.switch_screen("bye") def _create_repo_and_push(self, org, pipeline_repo, private, push): """Create a GitHub repository and push all branches.""" diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py index a8902daf37..746fbf40bf 100644 --- a/nf_core/pipelines/create/nfcorepipeline.py +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -1,6 +1,6 @@ from textual import on from textual.app import ComposeResult -from textual.containers import Center, HorizontalScroll, ScrollableContainer +from textual.containers import Center, Horizontal, ScrollableContainer, VerticalScroll from textual.screen import Screen from textual.widgets import Button, Footer, Header, Switch @@ -13,18 +13,21 @@ class NfcorePipeline(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - yield ScrollableContainer( - PipelineFeature( - markdown_genomes, - "Use reference genomes", - "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", - "igenomes", - ), - ) - yield Center( - Button("Continue", id="continue", variant="success"), - classes="cta", - ) + with Horizontal(): + with VerticalScroll(): + yield ScrollableContainer( + PipelineFeature( + markdown_genomes, + "Use reference genomes", + "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", + "igenomes", + ), + ) + yield Center( + Button("Continue", id="continue", variant="success"), + classes="cta", + ) + yield Center(self.parent.LOG_HANDLER.console, classes="cta log") @on(Button.Pressed, "#continue") def on_button_pressed(self, event: Button.Pressed) -> None: diff --git a/nf_core/pipelines/create/pipelinetype.py b/nf_core/pipelines/create/pipelinetype.py index 72624c5f80..979e4408c9 100644 --- a/nf_core/pipelines/create/pipelinetype.py +++ b/nf_core/pipelines/create/pipelinetype.py @@ -1,6 +1,6 @@ from textual.app import ComposeResult +from textual.containers import Center, Horizontal, VerticalScroll from textual.screen import Screen -from textual.containers import Center from textual.widgets import Button, Footer, Header, Markdown markdown_intro = """ @@ -40,10 +40,13 @@ class ChoosePipelineType(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - yield Markdown(markdown_intro) - yield Center( - Button("nf-core", id="type_nfcore", variant="success"), - Button("Custom", id="type_custom", variant="primary"), - classes="cta", - ) - yield Markdown(markdown_details) + with Horizontal(): + with VerticalScroll(): + yield Markdown(markdown_intro) + yield Center( + Button("nf-core", id="type_nfcore", variant="success"), + Button("Custom", id="type_custom", variant="primary"), + classes="cta", + ) + yield Markdown(markdown_details) + yield Center(self.parent.LOG_HANDLER.console, classes="cta log") diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 5566c17c8e..ae7ac097db 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -1,13 +1,17 @@ import re +from logging import LogRecord from pathlib import Path from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator +from rich.logging import RichHandler from textual import on +from textual._context import active_app from textual.app import ComposeResult from textual.containers import HorizontalScroll from textual.validation import ValidationResult, Validator -from textual.widgets import Button, Input, Markdown, Static, Switch +from textual.widget import Widget +from textual.widgets import Button, Input, Markdown, RichLog, Static, Switch class CreateConfig(BaseModel): @@ -165,6 +169,27 @@ def compose(self) -> ComposeResult: yield HelpText(markdown=self.markdown, classes="help_box") +class LoggingConsole(RichLog): + file = False + console: Widget + + def print(self, content): + self.write(content) + + +class CustomLogHandler(RichHandler): + """A Logging handler which extends RichHandler to write to a Widget and handle a Textual App.""" + + def emit(self, record: LogRecord) -> None: + """Invoked by logging.""" + try: + app = active_app.get() + except LookupError: + pass + else: + super().emit(record) + + ## Markdown text to reuse in different screens markdown_genomes = """ Nf-core pipelines are configured to use a copy of the most common reference genome files. diff --git a/nf_core/pipelines/create/welcome.py b/nf_core/pipelines/create/welcome.py index 0be70cc4c0..d572f3149c 100644 --- a/nf_core/pipelines/create/welcome.py +++ b/nf_core/pipelines/create/welcome.py @@ -1,5 +1,5 @@ from textual.app import ComposeResult -from textual.containers import Center +from textual.containers import Center, Horizontal, VerticalScroll from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown, Static @@ -24,13 +24,16 @@ class WelcomeScreen(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - yield Static( - f"\n[green]{' ' * 40},--.[grey39]/[green],-." - + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + "\n[green] `._,._,'\n", - id="logo", - ) - yield Markdown(markdown) - yield Center(Button("Let's go!", id="start", variant="success"), classes="cta") + with Horizontal(): + with VerticalScroll(): + yield Static( + f"\n[green]{' ' * 40},--.[grey39]/[green],-." + + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + "\n[green] `._,._,'\n", + id="logo", + ) + yield Markdown(markdown) + yield Center(Button("Let's go!", id="start", variant="success"), classes="cta") + yield Center(self.parent.LOG_HANDLER.console, classes="cta log") From 4c237e29ba61e6b36571601bdc24f2c7f3dbbc4c Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 3 Nov 2023 14:16:54 +0100 Subject: [PATCH 034/175] fix githubrepo buttons handled by the same function --- nf_core/__main__.py | 6 +- nf_core/pipelines/create/githubrepo.py | 147 ++++++++++++++----------- 2 files changed, 87 insertions(+), 66 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 97f166f289..13e2e97a54 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -580,7 +580,11 @@ def create(name, description, author, version, force, outdir, template_yaml, pla "\nRun with all command line arguments to avoid using an interactive interface." ) app = PipelineCreateApp() - app.run() + try: + app.run() + except UserWarning as e: + log.error(e) + sys.exit(1) else: sys.exit(0) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 79db4a4220..a99f28feb1 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -3,7 +3,7 @@ from textwrap import dedent import git -from github import Github, GithubException +from github import Github, GithubException, UnknownObjectException from textual import on from textual.app import ComposeResult from textual.containers import Center, Horizontal, VerticalScroll @@ -56,8 +56,8 @@ def compose(self) -> ComposeResult: token = "GITHUB_AUTH_TOKEN" in os.environ yield TextInput( "token", - "GitHub token", - "Your GitHub personal access token for login. Will use the environment variable GITHUB_AUTH_TOKEN if set.", + "Using the environment variable GITHUB_AUTH_TOKEN" if token else "GitHub token", + "Your GitHub personal access token for login.", classes="column", disabled=token, ) @@ -72,76 +72,89 @@ def compose(self) -> ComposeResult: classes="custom_grid", ) yield Center( - Button("Create GitHub repo", id="create", variant="success"), + Button("Create GitHub repo", id="create_github", variant="success"), Button("Finish without creating a repo", id="exit", variant="primary"), classes="cta", ) yield Center(self.parent.LOG_HANDLER.console, classes="cta log") - @on(Button.Pressed, "#create") def on_button_pressed(self, event: Button.Pressed) -> None: - """Create a GitHub repo""" - # Save GitHub username and token - github_variables = {} - for text_input in self.query("TextInput"): - this_input = text_input.query_one(Input) - github_variables[text_input.field_id] = this_input.value - # Save GitHub repo config - for switch_input in self.query("Switch"): - this_switch = switch_input.query_one(Switch) - github_variables[switch_input.field_id] = this_switch.value - - # Pipeline git repo - pipeline_repo = git.Repo.init(self.parent.TEMPLATE_CONFIG.outdir) - - # GitHub authentication - if "GITHUB_AUTH_TOKEN" in os.environ: - github_auth = self._github_authentication(github_variables["gh_username"], os.environ["GITHUB_AUTH_TOKEN"]) - elif github_variables["token"]: - github_auth = self._github_authentication(github_variables["gh_username"], github_variables["token"]) - else: - raise UserWarning( - f"Could not authenticate to GitHub with user name '{github_variables['gh_username']}'." - "Please provide an authentication token or set the environment variable 'GITHUB_AUTH_TOKEN'." - f"\n{exit_help_text_markdown}" - ) - - user = github_auth.get_user() - org = None - # Make sure that the authentication was successful - try: - user.login - except GithubException.GithubException as e: - raise UserWarning( - f"Could not authenticate to GitHub with user name '{github_variables['gh_username']}'." - "Please make sure that the provided user name and token are correct." - f"\n{exit_help_text_markdown}" - ) + """Create a GitHub repo or show help message and exit""" + if event.button.id == "create_github": + # Create a GitHub repo + + # Save GitHub username and token + github_variables = {} + for text_input in self.query("TextInput"): + this_input = text_input.query_one(Input) + github_variables[text_input.field_id] = this_input.value + # Save GitHub repo config + for switch_input in self.query("Switch"): + github_variables[switch_input.id] = switch_input.value + + # Pipeline git repo + pipeline_repo = git.Repo.init(self.parent.TEMPLATE_CONFIG.outdir) + + # GitHub authentication + if "GITHUB_AUTH_TOKEN" in os.environ: + github_auth = self._github_authentication( + github_variables["gh_username"], os.environ["GITHUB_AUTH_TOKEN"] + ) + log.debug("Using GITHUB_AUTH_TOKEN environment variable") + elif github_variables["token"]: + github_auth = self._github_authentication(github_variables["gh_username"], github_variables["token"]) + else: + raise UserWarning( + f"Could not authenticate to GitHub with user name '{github_variables['gh_username']}'." + "Please provide an authentication token or set the environment variable 'GITHUB_AUTH_TOKEN'." + f"\n{exit_help_text_markdown}" + ) - # Check if organisation exists - # If the organisation is nf-core or it doesn¡t exist, the repo will be created in the user account - if self.parent.TEMPLATE_CONFIG.org != "nf-core": + user = github_auth.get_user() + org = None + # Make sure that the authentication was successful try: - org = github_auth.get_organization(self.parent.TEMPLATE_CONFIG.org) - except GithubException.UnknownObjectException: - pass + user.login + log.debug("GitHub authentication successful") + except GithubException as e: + raise UserWarning( + f"Could not authenticate to GitHub with user name '{github_variables['gh_username']}'." + "Please make sure that the provided user name and token are correct." + f"\n{exit_help_text_markdown}" + ) - # Create the repo - try: - if org: - self._create_repo_and_push(org, pipeline_repo, github_variables["private"], github_variables["push"]) - else: - # Create the repo in the user's account - self._create_repo_and_push(user, pipeline_repo, github_variables["private"], github_variables["push"]) - except UserWarning as e: - log.info(f"There was an error with message: {e}" f"\n{exit_help_text_markdown}") + # Check if organisation exists + # If the organisation is nf-core or it doesn't exist, the repo will be created in the user account + if self.parent.TEMPLATE_CONFIG.org != "nf-core": + try: + org = github_auth.get_organization(self.parent.TEMPLATE_CONFIG.org) + log.info( + f"Repo will be created in the GitHub organisation account '{self.parent.TEMPLATE_CONFIG.org}'" + ) + except UnknownObjectException: + pass - self.parent.switch_screen("bye") + # Create the repo + try: + if org: + self._create_repo_and_push( + org, pipeline_repo, github_variables["private"], github_variables["push"] + ) + else: + # Create the repo in the user's account + log.info( + f"Repo will be created in the GitHub organisation account '{github_variables['gh_username']}'" + ) + self._create_repo_and_push( + user, pipeline_repo, github_variables["private"], github_variables["push"] + ) + log.info(f"GitHub repository '{self.parent.TEMPLATE_CONFIG.name}' created successfully") + except UserWarning as e: + log.info(f"There was an error with message: {e}" f"\n{exit_help_text_markdown}") + elif event.button.id == "exit": + # Show help message and exit + log.info(exit_help_text_markdown) - @on(Button.Pressed, "#exit") - def on_button_pressed(self, event: Button.Pressed) -> None: - """Show help message and exit""" - log.info(exit_help_text_markdown) self.parent.switch_screen("bye") def _create_repo_and_push(self, org, pipeline_repo, private, push): @@ -153,10 +166,10 @@ def _create_repo_and_push(self, org, pipeline_repo, private, push): try: repo.get_commits().totalCount raise UserWarning(f"GitHub repository '{self.parent.TEMPLATE_CONFIG.name}' already exists") - except GithubException.GithubException: + except GithubException: # Repo is empty repo_exists = True - except GithubException.UnknownObjectException: + except UnknownObjectException: # Repo doesn't exist repo_exists = False @@ -167,7 +180,11 @@ def _create_repo_and_push(self, org, pipeline_repo, private, push): ) # Add the remote and push - pipeline_repo.create_remote("origin", repo.clone_url) + try: + pipeline_repo.create_remote("origin", repo.clone_url) + except git.exc.GitCommandError: + # Remote already exists + pass if push: pipeline_repo.remotes.origin.push(all=True).raise_if_error() From 8318e0c9f8fb7ff163dd2b33654caa3681a029ae Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 6 Nov 2023 13:29:26 +0100 Subject: [PATCH 035/175] fix pytests --- nf_core/lint/files_unchanged.py | 2 +- nf_core/pipelines/create/create.py | 38 ++++++++------- nf_core/sync.py | 1 - tests/data/pipeline_create_template.yml | 7 ++- tests/data/pipeline_create_template_skip.yml | 10 +++- tests/modules/patch.py | 2 +- tests/test_bump_version.py | 6 +-- tests/test_cli.py | 40 +++++++++++---- tests/test_create.py | 51 +++++--------------- tests/test_download.py | 1 - tests/test_launch.py | 2 +- tests/test_lint.py | 2 +- tests/test_modules.py | 2 +- tests/test_params_file.py | 2 +- tests/test_schema.py | 2 +- tests/test_subworkflows.py | 2 +- tests/test_sync.py | 2 +- tests/test_utils.py | 1 - 18 files changed, 89 insertions(+), 84 deletions(-) diff --git a/nf_core/lint/files_unchanged.py b/nf_core/lint/files_unchanged.py index 9a0175571f..8fc5160b49 100644 --- a/nf_core/lint/files_unchanged.py +++ b/nf_core/lint/files_unchanged.py @@ -130,7 +130,7 @@ def files_unchanged(self): test_pipeline_dir = os.path.join(tmp_dir, f"{prefix}-{short_name}") create_obj = nf_core.pipelines.create.create.PipelineCreate( - None, None, None, no_git=True, outdir=test_pipeline_dir, template_yaml_path=template_yaml_path + None, None, None, no_git=True, outdir=test_pipeline_dir, template_config=template_yaml_path ) create_obj.init_pipeline() diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index 4bdf64a629..7660b3850c 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -10,11 +10,11 @@ import sys import time from pathlib import Path +from typing import Optional, Union import filetype import git import jinja2 -import questionary import requests import yaml @@ -47,17 +47,17 @@ class PipelineCreate: def __init__( self, - name=None, - description=None, - author=None, - version="1.0dev", - no_git=False, - force=False, - outdir=None, - template_config=None, - organisation="nf-core", - from_config_file=False, - default_branch=None, + name: Optional[str] = None, + description: Optional[str] = None, + author: Optional[str] = None, + version: str = "1.0dev", + no_git: bool = False, + force: bool = False, + outdir: Optional[str] = None, + template_config: Optional[Union[str, CreateConfig, Path]] = None, + organisation: str = "nf-core", + from_config_file: bool = False, + default_branch: Optional[str] = None, ): if isinstance(template_config, CreateConfig): self.config = template_config @@ -69,14 +69,18 @@ def __init__( self.config = CreateConfig(**config_yml["template"]) else: raise UserWarning("The template configuration was not provided in '.nf-core.yml'.") - elif (name and description and author) or (template_config and isinstance(template_config, str)): + elif (name and description and author) or ( + template_config and (isinstance(template_config, str) or isinstance(template_config, Path)) + ): # Obtain a CreateConfig object from the template yaml file self.config = self.check_template_yaml_info(template_config, name, description, author) self.update_config(organisation, version, force, outdir) else: raise UserWarning("The template configuration was not provided.") - self.jinja_params, skip_paths = self.obtain_jinja_params_dict(self.config.skip_features, self.config.outdir) + self.jinja_params, skip_paths = self.obtain_jinja_params_dict( + self.config.skip_features or [], self.config.outdir + ) skippable_paths = { "github": [ @@ -209,9 +213,9 @@ def obtain_jinja_params_dict(self, features_to_skip, pipeline_dir): else: jinja_params[t_area] = True - # If github is selected, exclude also github_badges - # if not param_dict["github"]: - # param_dict["github_badges"] = False + # Add is_nfcore as an area to skip for non-nf-core pipelines, to skip all nf-core files + if not jinja_params["is_nfcore"]: + skip_paths.append("is_nfcore") # Set the last parameters based on the ones provided jinja_params["short_name"] = ( diff --git a/nf_core/sync.py b/nf_core/sync.py index 6175ebff08..45abe2b799 100644 --- a/nf_core/sync.py +++ b/nf_core/sync.py @@ -267,7 +267,6 @@ def make_template_pipeline(self): force=True, outdir=self.pipeline_dir, author=self.wf_config["manifest.author"].strip('"').strip("'"), - plain=True, ).init_pipeline() except Exception as err: # Reset to where you were to prevent git getting messed up. diff --git a/tests/data/pipeline_create_template.yml b/tests/data/pipeline_create_template.yml index 12e48e9c27..0ed534aa10 100644 --- a/tests/data/pipeline_create_template.yml +++ b/tests/data/pipeline_create_template.yml @@ -1 +1,6 @@ -prefix: testprefix +name: test +description: just for 4w3s0m3 tests +author: Chuck Norris +version: 1.0.0 +force: True +org: testprefix diff --git a/tests/data/pipeline_create_template_skip.yml b/tests/data/pipeline_create_template_skip.yml index b69175e0bb..ed498cb732 100644 --- a/tests/data/pipeline_create_template_skip.yml +++ b/tests/data/pipeline_create_template_skip.yml @@ -1,5 +1,11 @@ -prefix: testprefix -skip: +name: test +description: just for 4w3s0m3 tests +author: Chuck Norris +version: 1.0.0 +force: True +org: testprefix +is_nfcore: False +skip_features: - github - ci - github_badges diff --git a/tests/modules/patch.py b/tests/modules/patch.py index 7263d30263..c34e1f740a 100644 --- a/tests/modules/patch.py +++ b/tests/modules/patch.py @@ -349,7 +349,7 @@ def test_remove_patch(self): "modules", REPO_NAME, BISMARK_ALIGN, patch_fn ) - with mock.patch.object(nf_core.pipelines.create.questionary, "confirm") as mock_questionary: + with mock.patch.object(nf_core.modules.patch.questionary, "confirm") as mock_questionary: mock_questionary.unsafe_ask.return_value = True patch_obj.remove(BISMARK_ALIGN) # Check that the diff file has been removed diff --git a/tests/test_bump_version.py b/tests/test_bump_version.py index 07de9687fa..77edd4bfd0 100644 --- a/tests/test_bump_version.py +++ b/tests/test_bump_version.py @@ -17,7 +17,7 @@ def test_bump_pipeline_version(datafiles, tmp_path): # Get a workflow and configs test_pipeline_dir = os.path.join(tmp_path, "nf-core-testpipeline") create_obj = nf_core.pipelines.create.create.PipelineCreate( - "testpipeline", "This is a test pipeline", "Test McTestFace", no_git=True, outdir=test_pipeline_dir, plain=True + "testpipeline", "This is a test pipeline", "Test McTestFace", no_git=True, outdir=test_pipeline_dir ) create_obj.init_pipeline() pipeline_obj = nf_core.utils.Pipeline(test_pipeline_dir) @@ -37,7 +37,7 @@ def test_dev_bump_pipeline_version(datafiles, tmp_path): # Get a workflow and configs test_pipeline_dir = os.path.join(tmp_path, "nf-core-testpipeline") create_obj = nf_core.pipelines.create.create.PipelineCreate( - "testpipeline", "This is a test pipeline", "Test McTestFace", no_git=True, outdir=test_pipeline_dir, plain=True + "testpipeline", "This is a test pipeline", "Test McTestFace", no_git=True, outdir=test_pipeline_dir ) create_obj.init_pipeline() pipeline_obj = nf_core.utils.Pipeline(test_pipeline_dir) @@ -56,7 +56,7 @@ def test_bump_nextflow_version(datafiles, tmp_path): # Get a workflow and configs test_pipeline_dir = os.path.join(tmp_path, "nf-core-testpipeline") create_obj = nf_core.pipelines.create.create.PipelineCreate( - "testpipeline", "This is a test pipeline", "Test McTestFace", no_git=True, outdir=test_pipeline_dir, plain=True + "testpipeline", "This is a test pipeline", "Test McTestFace", no_git=True, outdir=test_pipeline_dir ) create_obj.init_pipeline() pipeline_obj = nf_core.utils.Pipeline(test_pipeline_dir) diff --git a/tests/test_cli.py b/tests/test_cli.py index d488e6493f..1c110cd6e8 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -228,21 +228,17 @@ def test_licences_log_error(self, mock_lic): assert error_txt in captured_logs.output[-1] assert captured_logs.records[-1].levelname == "ERROR" - @mock.patch("nf_core.pipelines.create.PipelineCreate") + @mock.patch("nf_core.pipelines.create.create.PipelineCreate") def test_create(self, mock_create): """Test nf-core pipeline is created and cli parameters are passed on.""" params = { - "name": "pipeline name", + "name": "pipelinename", "description": "pipeline description", "author": "Kalle Anka", - "version": "1.2.3", - "force": None, "outdir": "/path/outdir", - "template-yaml": "file.yaml", - "plain": None, } - cmd = ["create"] + self.assemble_params(params) + cmd = ["pipelines", "create"] + self.assemble_params(params) result = self.invoke_cli(cmd) assert result.exit_code == 0 @@ -250,14 +246,38 @@ def test_create(self, mock_create): params["name"], params["description"], params["author"], - version=params["version"], force="force" in params, + version=None, outdir=params["outdir"], - template_yaml_path=params["template-yaml"], - plain="plain" in params, + organisation=None, ) mock_create.return_value.init_pipeline.assert_called_once() + @mock.patch("nf_core.pipelines.create.create.PipelineCreate") + def test_create_error(self, mock_create): + """Test `nf-core pipelines create` run without providing all the arguments thorws an error.""" + params = { + "name": "pipelinename", + } + + cmd = ["pipelines", "create"] + self.assemble_params(params) + result = self.invoke_cli(cmd) + + assert result.exit_code == 1 + assert "Command arguments are not accepted in interactive mode." in result.output + + @mock.patch("nf_core.pipelines.create.PipelineCreateApp") + def test_create_app(self, mock_create): + """Test `nf-core pipelines create` runs an App.""" + cmd = ["pipelines", "create"] + result = self.invoke_cli(cmd) + + assert result.exit_code == 0 + assert "Launching interactive nf-core pipeline creation tool." in result.output + + mock_create.assert_called_once_with() + mock_create.return_value.run.assert_called_once() + @mock.patch("nf_core.utils.is_pipeline_directory") @mock.patch("nf_core.lint.run_linting") def test_lint(self, mock_lint, mock_is_pipeline): diff --git a/tests/test_create.py b/tests/test_create.py index 3154539bb6..c3b7f931f0 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -33,14 +33,13 @@ def test_pipeline_creation(self): version=self.pipeline_version, no_git=False, force=True, - plain=True, default_branch=self.default_branch, ) - assert pipeline.template_params["name"] == self.pipeline_name - assert pipeline.template_params["description"] == self.pipeline_description - assert pipeline.template_params["author"] == self.pipeline_author - assert pipeline.template_params["version"] == self.pipeline_version + assert pipeline.config.name == self.pipeline_name + assert pipeline.config.description == self.pipeline_description + assert pipeline.config.author == self.pipeline_author + assert pipeline.config.version == self.pipeline_version @with_temporary_folder def test_pipeline_creation_initiation(self, tmp_path): @@ -52,7 +51,6 @@ def test_pipeline_creation_initiation(self, tmp_path): no_git=False, force=True, outdir=tmp_path, - plain=True, default_branch=self.default_branch, ) pipeline.init_pipeline() @@ -60,20 +58,14 @@ def test_pipeline_creation_initiation(self, tmp_path): assert f" {self.default_branch}\n" in git.Repo.init(pipeline.outdir).git.branch() assert not os.path.exists(os.path.join(pipeline.outdir, "pipeline_template.yml")) with open(os.path.join(pipeline.outdir, ".nf-core.yml")) as fh: - assert "template" not in fh.read() + assert "template" in fh.read() @with_temporary_folder def test_pipeline_creation_initiation_with_yml(self, tmp_path): pipeline = nf_core.pipelines.create.create.PipelineCreate( - name=self.pipeline_name, - description=self.pipeline_description, - author=self.pipeline_author, - version=self.pipeline_version, no_git=False, - force=True, outdir=tmp_path, - template_yaml_path=PIPELINE_TEMPLATE_YML, - plain=True, + template_config=PIPELINE_TEMPLATE_YML, default_branch=self.default_branch, ) pipeline.init_pipeline() @@ -86,23 +78,12 @@ def test_pipeline_creation_initiation_with_yml(self, tmp_path): with open(os.path.join(pipeline.outdir, ".nf-core.yml")) as fh: nfcore_yml = yaml.safe_load(fh) assert "template" in nfcore_yml - assert nfcore_yml["template"] == yaml.safe_load(PIPELINE_TEMPLATE_YML.read_text()) + assert yaml.safe_load(PIPELINE_TEMPLATE_YML.read_text()).items() <= nfcore_yml["template"].items() - @mock.patch.object(nf_core.pipelines.create.create.PipelineCreate, "customize_template") - @mock.patch.object(nf_core.pipelines.create.create.questionary, "confirm") @with_temporary_folder - def test_pipeline_creation_initiation_customize_template(self, mock_questionary, mock_customize, tmp_path): - mock_questionary.unsafe_ask.return_value = True - mock_customize.return_value = {"prefix": "testprefix"} + def test_pipeline_creation_initiation_customize_template(self, tmp_path): pipeline = nf_core.pipelines.create.create.PipelineCreate( - name=self.pipeline_name, - description=self.pipeline_description, - author=self.pipeline_author, - version=self.pipeline_version, - no_git=False, - force=True, - outdir=tmp_path, - default_branch=self.default_branch, + outdir=tmp_path, template_config=PIPELINE_TEMPLATE_YML, default_branch=self.default_branch ) pipeline.init_pipeline() assert os.path.isdir(os.path.join(pipeline.outdir, ".git")) @@ -114,24 +95,16 @@ def test_pipeline_creation_initiation_customize_template(self, mock_questionary, with open(os.path.join(pipeline.outdir, ".nf-core.yml")) as fh: nfcore_yml = yaml.safe_load(fh) assert "template" in nfcore_yml - assert nfcore_yml["template"] == yaml.safe_load(PIPELINE_TEMPLATE_YML.read_text()) + assert yaml.safe_load(PIPELINE_TEMPLATE_YML.read_text()).items() <= nfcore_yml["template"].items() @with_temporary_folder def test_pipeline_creation_with_yml_skip(self, tmp_path): pipeline = nf_core.pipelines.create.create.PipelineCreate( - name=self.pipeline_name, - description=self.pipeline_description, - author=self.pipeline_author, - version=self.pipeline_version, - no_git=False, - force=True, outdir=tmp_path, - template_yaml_path=PIPELINE_TEMPLATE_YML_SKIP, - plain=True, + template_config=PIPELINE_TEMPLATE_YML_SKIP, default_branch=self.default_branch, ) pipeline.init_pipeline() - assert not os.path.isdir(os.path.join(pipeline.outdir, ".git")) # Check pipeline template yml has been dumped to `.nf-core.yml` and matches input assert not os.path.exists(os.path.join(pipeline.outdir, "pipeline_template.yml")) @@ -139,7 +112,7 @@ def test_pipeline_creation_with_yml_skip(self, tmp_path): with open(os.path.join(pipeline.outdir, ".nf-core.yml")) as fh: nfcore_yml = yaml.safe_load(fh) assert "template" in nfcore_yml - assert nfcore_yml["template"] == yaml.safe_load(PIPELINE_TEMPLATE_YML_SKIP.read_text()) + assert yaml.safe_load(PIPELINE_TEMPLATE_YML.read_text()).items() <= nfcore_yml["template"].items() # Check that some of the skipped files are not present assert not os.path.exists(os.path.join(pipeline.outdir, "CODE_OF_CONDUCT.md")) diff --git a/tests/test_download.py b/tests/test_download.py index ea59c7bd62..c9240e2cec 100644 --- a/tests/test_download.py +++ b/tests/test_download.py @@ -116,7 +116,6 @@ def test_wf_use_local_configs(self, tmp_path): "Test McTestFace", no_git=True, outdir=test_pipeline_dir, - plain=True, ) create_obj.init_pipeline() diff --git a/tests/test_launch.py b/tests/test_launch.py index d3ddde6c8c..5de841e9e1 100644 --- a/tests/test_launch.py +++ b/tests/test_launch.py @@ -72,7 +72,7 @@ def test_make_pipeline_schema(self, tmp_path): """Create a workflow, but delete the schema file, then try to load it""" test_pipeline_dir = os.path.join(tmp_path, "wf") create_obj = nf_core.pipelines.create.create.PipelineCreate( - "testpipeline", "", "", outdir=test_pipeline_dir, no_git=True, plain=True + "testpipeline", "a description", "Me", outdir=test_pipeline_dir, no_git=True ) create_obj.init_pipeline() os.remove(os.path.join(test_pipeline_dir, "nextflow_schema.json")) diff --git a/tests/test_lint.py b/tests/test_lint.py index 99e0506cf8..a967618a97 100644 --- a/tests/test_lint.py +++ b/tests/test_lint.py @@ -27,7 +27,7 @@ def setUp(self): self.tmp_dir = tempfile.mkdtemp() self.test_pipeline_dir = os.path.join(self.tmp_dir, "nf-core-testpipeline") self.create_obj = nf_core.pipelines.create.create.PipelineCreate( - "testpipeline", "This is a test pipeline", "Test McTestFace", outdir=self.test_pipeline_dir, plain=True + "testpipeline", "This is a test pipeline", "Test McTestFace", outdir=self.test_pipeline_dir ) self.create_obj.init_pipeline() # Base lint object on this directory diff --git a/tests/test_modules.py b/tests/test_modules.py index 0d784c74ed..76dff9da3e 100644 --- a/tests/test_modules.py +++ b/tests/test_modules.py @@ -73,7 +73,7 @@ def setUp(self): self.pipeline_name = "mypipeline" self.pipeline_dir = os.path.join(self.tmp_dir, self.pipeline_name) nf_core.pipelines.create.create.PipelineCreate( - self.pipeline_name, "it is mine", "me", no_git=True, outdir=self.pipeline_dir, plain=True + self.pipeline_name, "it is mine", "me", no_git=True, outdir=self.pipeline_dir ).init_pipeline() # Set up install objects self.mods_install = nf_core.modules.ModuleInstall(self.pipeline_dir, prompt=False, force=True) diff --git a/tests/test_params_file.py b/tests/test_params_file.py index 882b575125..e692ad687c 100644 --- a/tests/test_params_file.py +++ b/tests/test_params_file.py @@ -22,7 +22,7 @@ def setup_class(cls): cls.tmp_dir = tempfile.mkdtemp() cls.template_dir = os.path.join(cls.tmp_dir, "wf") create_obj = nf_core.pipelines.create.create.PipelineCreate( - "testpipeline", "", "", outdir=cls.template_dir, no_git=True, plain=True + "testpipeline", "a description", "Me", outdir=cls.template_dir, no_git=True ) create_obj.init_pipeline() diff --git a/tests/test_schema.py b/tests/test_schema.py index 4d8f2e0ef6..1f30c9e0fc 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -30,7 +30,7 @@ def setUp(self): self.tmp_dir = tempfile.mkdtemp() self.template_dir = os.path.join(self.tmp_dir, "wf") create_obj = nf_core.pipelines.create.create.PipelineCreate( - "testpipeline", "", "", outdir=self.template_dir, no_git=True, plain=True + "testpipeline", "a description", "Me", outdir=self.template_dir, no_git=True ) create_obj.init_pipeline() diff --git a/tests/test_subworkflows.py b/tests/test_subworkflows.py index fb15211319..c5af1ff426 100644 --- a/tests/test_subworkflows.py +++ b/tests/test_subworkflows.py @@ -56,7 +56,7 @@ def setUp(self): self.pipeline_name = "mypipeline" self.pipeline_dir = os.path.join(self.tmp_dir, self.pipeline_name) nf_core.pipelines.create.create.PipelineCreate( - self.pipeline_name, "it is mine", "me", no_git=True, outdir=self.pipeline_dir, plain=True + self.pipeline_name, "it is mine", "me", no_git=True, outdir=self.pipeline_dir ).init_pipeline() # Set up the nf-core/modules repo dummy diff --git a/tests/test_sync.py b/tests/test_sync.py index 228a6682ed..fabdf122e3 100644 --- a/tests/test_sync.py +++ b/tests/test_sync.py @@ -27,7 +27,7 @@ def setUp(self): self.pipeline_dir = os.path.join(self.tmp_dir, "testpipeline") default_branch = "master" self.create_obj = nf_core.pipelines.create.create.PipelineCreate( - "testing", "test pipeline", "tester", outdir=self.pipeline_dir, plain=True, default_branch=default_branch + "testing", "test pipeline", "tester", outdir=self.pipeline_dir, default_branch=default_branch ) self.create_obj.init_pipeline() self.remote_path = os.path.join(self.tmp_dir, "remote_repo") diff --git a/tests/test_utils.py b/tests/test_utils.py index 22b5a23321..035b0d97db 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -45,7 +45,6 @@ def setUp(self): "Test McTestFace", no_git=True, outdir=self.test_pipeline_dir, - plain=True, ) self.create_obj.init_pipeline() # Base Pipeline object on this directory From c2c0561de95410cc3a8a62f9eb99906411e74da8 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 6 Nov 2023 14:06:23 +0100 Subject: [PATCH 036/175] fix test_remove_patch --- tests/modules/patch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/patch.py b/tests/modules/patch.py index c34e1f740a..bd6b5accd3 100644 --- a/tests/modules/patch.py +++ b/tests/modules/patch.py @@ -349,7 +349,7 @@ def test_remove_patch(self): "modules", REPO_NAME, BISMARK_ALIGN, patch_fn ) - with mock.patch.object(nf_core.modules.patch.questionary, "confirm") as mock_questionary: + with mock.patch.object(nf_core.components.patch.questionary, "confirm") as mock_questionary: mock_questionary.unsafe_ask.return_value = True patch_obj.remove(BISMARK_ALIGN) # Check that the diff file has been removed From ef9ea81467c05fb9f0c9bd396b0071b62d9e2106 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 6 Nov 2023 15:17:16 +0100 Subject: [PATCH 037/175] add types-requests to requirements-dev --- requirements-dev.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-dev.txt b/requirements-dev.txt index 4cc78d25fd..1b92a49c65 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -9,3 +9,4 @@ sphinx-rtd-theme textual-dev>=1.1.0 mypy types-PyYAML +types-requests From 798dad9796ec6d5ecf3735d0d6b306f6bdea79f0 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 10 Nov 2023 17:21:20 +0100 Subject: [PATCH 038/175] add full logging screen to show logging messages --- nf_core/pipelines/create/__init__.py | 4 +- nf_core/pipelines/create/basicdetails.py | 75 +++++++++---------- nf_core/pipelines/create/create.tcss | 3 - nf_core/pipelines/create/custompipeline.py | 65 ++++++++-------- nf_core/pipelines/create/finaldetails.py | 69 ++++++++--------- nf_core/pipelines/create/githubrepo.py | 69 +++++++++-------- .../create/{bye.py => loggingscreen.py} | 23 ++++-- nf_core/pipelines/create/nfcorepipeline.py | 29 ++++--- nf_core/pipelines/create/pipelinetype.py | 19 ++--- nf_core/pipelines/create/welcome.py | 25 +++---- 10 files changed, 185 insertions(+), 196 deletions(-) rename nf_core/pipelines/create/{bye.py => loggingscreen.py} (59%) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 900a0b778b..a1f83df2b5 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -5,7 +5,6 @@ from textual.widgets import Button from nf_core.pipelines.create.basicdetails import BasicDetails -from nf_core.pipelines.create.bye import ByeScreen from nf_core.pipelines.create.custompipeline import CustomPipeline from nf_core.pipelines.create.finaldetails import FinalDetails from nf_core.pipelines.create.githubrepo import GithubRepo @@ -45,7 +44,6 @@ class PipelineCreateApp(App[CreateConfig]): "type_nfcore": NfcorePipeline(), "final_details": FinalDetails(), "github_repo": GithubRepo(), - "bye": ByeScreen(), } # Initialise config as empty @@ -56,6 +54,8 @@ class PipelineCreateApp(App[CreateConfig]): # Log handler LOG_HANDLER = log_handler + # Logging state + LOGGING_STATE = None def on_mount(self) -> None: self.push_screen("welcome") diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py index 072892f392..dc7248d977 100644 --- a/nf_core/pipelines/create/basicdetails.py +++ b/nf_core/pipelines/create/basicdetails.py @@ -3,7 +3,7 @@ from textual import on from textual.app import ComposeResult -from textual.containers import Center, Horizontal, VerticalScroll +from textual.containers import Center, Horizontal from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown @@ -16,46 +16,43 @@ class BasicDetails(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() + yield Markdown( + dedent( + """ + # Basic details + """ + ) + ) with Horizontal(): - with VerticalScroll(): - yield Markdown( - dedent( - """ - # Basic details - """ - ) - ) - with Horizontal(): - yield TextInput( - "org", - "Organisation", - "GitHub organisation", - "nf-core", - classes="column", - disabled=self.parent.PIPELINE_TYPE == "nfcore", - ) - yield TextInput( - "name", - "Pipeline Name", - "Workflow name", - classes="column", - ) + yield TextInput( + "org", + "Organisation", + "GitHub organisation", + "nf-core", + classes="column", + disabled=self.parent.PIPELINE_TYPE == "nfcore", + ) + yield TextInput( + "name", + "Pipeline Name", + "Workflow name", + classes="column", + ) - yield TextInput( - "description", - "Description", - "A short description of your pipeline.", - ) - yield TextInput( - "author", - "Author(s)", - "Name of the main author / authors", - ) - yield Center( - Button("Next", variant="success"), - classes="cta", - ) - yield Center(self.parent.LOG_HANDLER.console, classes="cta log") + yield TextInput( + "description", + "Description", + "A short description of your pipeline.", + ) + yield TextInput( + "author", + "Author(s)", + "Name of the main author / authors", + ) + yield Center( + Button("Next", variant="success"), + classes="cta", + ) @on(Button.Pressed) def on_button_pressed(self, event: Button.Pressed) -> None: diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index a718b940dc..42f144c7dd 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -9,9 +9,6 @@ margin-left: 3; margin-right: 3; } -.log { - width: 30%; -} .custom_grid { height: auto; diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 9ac76d80d9..5cc2f87d95 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -1,6 +1,6 @@ from textual import on from textual.app import ComposeResult -from textual.containers import Center, Horizontal, ScrollableContainer, VerticalScroll +from textual.containers import Center, ScrollableContainer from textual.screen import Screen from textual.widgets import Button, Footer, Header, Switch @@ -46,39 +46,36 @@ class CustomPipeline(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - with Horizontal(): - with VerticalScroll(): - yield ScrollableContainer( - PipelineFeature( - markdown_genomes, - "Use reference genomes", - "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", - "igenomes", - ), - PipelineFeature( - markdown_ci, - "Add Github CI tests", - "The pipeline will include several GitHub actions for Continuous Integration (CI) testing", - "ci", - ), - PipelineFeature( - markdown_badges, - "Add Github badges", - "The README.md file of the pipeline will include GitHub badges", - "github_badges", - ), - PipelineFeature( - markdown_configuration, - "Add configuration files", - "The pipeline will include configuration profiles containing custom parameters requried to run nf-core pipelines at different institutions", - "nf_core_configs", - ), - ) - yield Center( - Button("Continue", id="continue", variant="success"), - classes="cta", - ) - yield Center(self.parent.LOG_HANDLER.console, classes="cta log") + yield ScrollableContainer( + PipelineFeature( + markdown_genomes, + "Use reference genomes", + "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", + "igenomes", + ), + PipelineFeature( + markdown_ci, + "Add Github CI tests", + "The pipeline will include several GitHub actions for Continuous Integration (CI) testing", + "ci", + ), + PipelineFeature( + markdown_badges, + "Add Github badges", + "The README.md file of the pipeline will include GitHub badges", + "github_badges", + ), + PipelineFeature( + markdown_configuration, + "Add configuration files", + "The pipeline will include configuration profiles containing custom parameters requried to run nf-core pipelines at different institutions", + "nf_core_configs", + ), + ) + yield Center( + Button("Continue", id="continue", variant="success"), + classes="cta", + ) @on(Button.Pressed, "#continue") def on_button_pressed(self, event: Button.Pressed) -> None: diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 904d0e3622..23be7db895 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -3,11 +3,12 @@ from textual import on from textual.app import ComposeResult -from textual.containers import Center, Horizontal, VerticalScroll +from textual.containers import Center, Horizontal from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch from nf_core.pipelines.create.create import PipelineCreate +from nf_core.pipelines.create.loggingscreen import LoggingScreen from nf_core.pipelines.create.utils import TextInput @@ -17,42 +18,37 @@ class FinalDetails(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - with Horizontal(): - with VerticalScroll(): - yield Markdown( - dedent( - """ - # Final details - """ - ) - ) + yield Markdown( + dedent( + """ + # Final details + """ + ) + ) - with Horizontal(): - yield TextInput( - "version", - "Version", - "First version of the pipeline", - "1.0dev", - classes="column", - ) - yield TextInput( - "outdir", - "Output directory", - "Path to the output directory where the pipeline will be created", - ".", - classes="column", - ) - with Horizontal(): - yield Switch(value=False, id="force") - yield Static( - "If the pipeline output directory exists, remove it and continue.", classes="custom_grid" - ) + with Horizontal(): + yield TextInput( + "version", + "Version", + "First version of the pipeline", + "1.0dev", + classes="column", + ) + yield TextInput( + "outdir", + "Output directory", + "Path to the output directory where the pipeline will be created", + ".", + classes="column", + ) + with Horizontal(): + yield Switch(value=False, id="force") + yield Static("If the pipeline output directory exists, remove it and continue.", classes="custom_grid") - yield Center( - Button("Finish", id="finish", variant="success"), - classes="cta", - ) - yield Center(self.parent.LOG_HANDLER.console, classes="cta log") + yield Center( + Button("Finish", id="finish", variant="success"), + classes="cta", + ) @on(Button.Pressed, "#finish") def on_button_pressed(self, event: Button.Pressed) -> None: @@ -80,4 +76,5 @@ def on_button_pressed(self, event: Button.Pressed) -> None: # Create the new pipeline create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) create_obj.init_pipeline() - self.parent.switch_screen("github_repo") + self.parent.LOGGING_STATE = "pipeline created" + self.parent.switch_screen(LoggingScreen()) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index a99f28feb1..56d5953199 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -6,10 +6,11 @@ from github import Github, GithubException, UnknownObjectException from textual import on from textual.app import ComposeResult -from textual.containers import Center, Horizontal, VerticalScroll +from textual.containers import Center, Horizontal from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch +from nf_core.pipelines.create.loggingscreen import LoggingScreen from nf_core.pipelines.create.utils import TextInput log = logging.getLogger(__name__) @@ -43,40 +44,37 @@ class GithubRepo(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() + yield Markdown(dedent(github_text_markdown)) with Horizontal(): - with VerticalScroll(): - yield Markdown(dedent(github_text_markdown)) - with Horizontal(): - yield TextInput( - "gh_username", - "GitHub username", - "Your GitHub username", - classes="column", - ) - token = "GITHUB_AUTH_TOKEN" in os.environ - yield TextInput( - "token", - "Using the environment variable GITHUB_AUTH_TOKEN" if token else "GitHub token", - "Your GitHub personal access token for login.", - classes="column", - disabled=token, - ) - yield Markdown(dedent(repo_config_markdown)) - with Horizontal(): - yield Switch(value=False, id="private") - yield Static("Select if the new GitHub repo must be private.", classes="custom_grid") - with Horizontal(): - yield Switch(value=True, id="push") - yield Static( - "Select if you would like to push all the pipeline template files to your GitHub repo\nand all the branches required to keep the pipeline up to date with new releases of nf-core.", - classes="custom_grid", - ) - yield Center( - Button("Create GitHub repo", id="create_github", variant="success"), - Button("Finish without creating a repo", id="exit", variant="primary"), - classes="cta", - ) - yield Center(self.parent.LOG_HANDLER.console, classes="cta log") + yield TextInput( + "gh_username", + "GitHub username", + "Your GitHub username", + classes="column", + ) + token = "GITHUB_AUTH_TOKEN" in os.environ + yield TextInput( + "token", + "Using the environment variable GITHUB_AUTH_TOKEN" if token else "GitHub token", + "Your GitHub personal access token for login.", + classes="column", + disabled=token, + ) + yield Markdown(dedent(repo_config_markdown)) + with Horizontal(): + yield Switch(value=False, id="private") + yield Static("Select if the new GitHub repo must be private.", classes="custom_grid") + with Horizontal(): + yield Switch(value=True, id="push") + yield Static( + "Select if you would like to push all the pipeline template files to your GitHub repo\nand all the branches required to keep the pipeline up to date with new releases of nf-core.", + classes="custom_grid", + ) + yield Center( + Button("Create GitHub repo", id="create_github", variant="success"), + Button("Finish without creating a repo", id="exit", variant="primary"), + classes="cta", + ) def on_button_pressed(self, event: Button.Pressed) -> None: """Create a GitHub repo or show help message and exit""" @@ -155,7 +153,8 @@ def on_button_pressed(self, event: Button.Pressed) -> None: # Show help message and exit log.info(exit_help_text_markdown) - self.parent.switch_screen("bye") + self.parent.LOGGING_STATE = "repo created" + self.parent.switch_screen(LoggingScreen()) def _create_repo_and_push(self, org, pipeline_repo, private, push): """Create a GitHub repository and push all branches.""" diff --git a/nf_core/pipelines/create/bye.py b/nf_core/pipelines/create/loggingscreen.py similarity index 59% rename from nf_core/pipelines/create/bye.py rename to nf_core/pipelines/create/loggingscreen.py index 89d9737785..4ef332bbcb 100644 --- a/nf_core/pipelines/create/bye.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -7,11 +7,11 @@ markdown = """ # nf-core create -Bye! +Visualising logging output. """ -class ByeScreen(Screen): +class LoggingScreen(Screen): """A screen to show the final logs.""" def compose(self) -> ComposeResult: @@ -26,10 +26,21 @@ def compose(self) -> ComposeResult: id="logo", ) yield Markdown(markdown) + if self.parent.LOGGING_STATE == "repo created": + yield Center( + Button("Close App", id="close_app", variant="success"), + classes="cta", + ) + else: + yield Center( + Button("Close logging screen", id="close_screen", variant="success"), + classes="cta", + ) yield Center(self.parent.LOG_HANDLER.console, classes="cta") - yield Center(Button("Close", id="close", variant="success"), classes="cta") - @on(Button.Pressed, "#close") def on_button_pressed(self, event: Button.Pressed) -> None: - """Close app""" - self.parent.exit() + """Close the logging screen or the whole app.""" + if event.button.id == "close_app": + self.parent.exit() + if event.button.id == "close_screen": + self.parent.switch_screen("github_repo") diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py index 746fbf40bf..95c173a406 100644 --- a/nf_core/pipelines/create/nfcorepipeline.py +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -1,6 +1,6 @@ from textual import on from textual.app import ComposeResult -from textual.containers import Center, Horizontal, ScrollableContainer, VerticalScroll +from textual.containers import Center, Horizontal, ScrollableContainer from textual.screen import Screen from textual.widgets import Button, Footer, Header, Switch @@ -13,21 +13,18 @@ class NfcorePipeline(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - with Horizontal(): - with VerticalScroll(): - yield ScrollableContainer( - PipelineFeature( - markdown_genomes, - "Use reference genomes", - "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", - "igenomes", - ), - ) - yield Center( - Button("Continue", id="continue", variant="success"), - classes="cta", - ) - yield Center(self.parent.LOG_HANDLER.console, classes="cta log") + yield ScrollableContainer( + PipelineFeature( + markdown_genomes, + "Use reference genomes", + "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", + "igenomes", + ), + ) + yield Center( + Button("Continue", id="continue", variant="success"), + classes="cta", + ) @on(Button.Pressed, "#continue") def on_button_pressed(self, event: Button.Pressed) -> None: diff --git a/nf_core/pipelines/create/pipelinetype.py b/nf_core/pipelines/create/pipelinetype.py index 979e4408c9..98d5acc97a 100644 --- a/nf_core/pipelines/create/pipelinetype.py +++ b/nf_core/pipelines/create/pipelinetype.py @@ -1,5 +1,5 @@ from textual.app import ComposeResult -from textual.containers import Center, Horizontal, VerticalScroll +from textual.containers import Center from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown @@ -40,13 +40,10 @@ class ChoosePipelineType(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - with Horizontal(): - with VerticalScroll(): - yield Markdown(markdown_intro) - yield Center( - Button("nf-core", id="type_nfcore", variant="success"), - Button("Custom", id="type_custom", variant="primary"), - classes="cta", - ) - yield Markdown(markdown_details) - yield Center(self.parent.LOG_HANDLER.console, classes="cta log") + yield Markdown(markdown_intro) + yield Center( + Button("nf-core", id="type_nfcore", variant="success"), + Button("Custom", id="type_custom", variant="primary"), + classes="cta", + ) + yield Markdown(markdown_details) diff --git a/nf_core/pipelines/create/welcome.py b/nf_core/pipelines/create/welcome.py index d572f3149c..0be70cc4c0 100644 --- a/nf_core/pipelines/create/welcome.py +++ b/nf_core/pipelines/create/welcome.py @@ -1,5 +1,5 @@ from textual.app import ComposeResult -from textual.containers import Center, Horizontal, VerticalScroll +from textual.containers import Center from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown, Static @@ -24,16 +24,13 @@ class WelcomeScreen(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - with Horizontal(): - with VerticalScroll(): - yield Static( - f"\n[green]{' ' * 40},--.[grey39]/[green],-." - + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + "\n[green] `._,._,'\n", - id="logo", - ) - yield Markdown(markdown) - yield Center(Button("Let's go!", id="start", variant="success"), classes="cta") - yield Center(self.parent.LOG_HANDLER.console, classes="cta log") + yield Static( + f"\n[green]{' ' * 40},--.[grey39]/[green],-." + + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + "\n[green] `._,._,'\n", + id="logo", + ) + yield Markdown(markdown) + yield Center(Button("Let's go!", id="start", variant="success"), classes="cta") From 4758c7d64a786c84d8ca22f61f80a0f11593ea64 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 13 Nov 2023 10:47:58 +0100 Subject: [PATCH 039/175] autopopulate github credentials and hide password --- nf_core/pipelines/create/__init__.py | 4 +++ nf_core/pipelines/create/githubrepo.py | 33 ++++++++++++++++------- nf_core/pipelines/create/loggingscreen.py | 7 ----- nf_core/pipelines/create/utils.py | 4 ++- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index a1f83df2b5..68833877ca 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -72,6 +72,10 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.switch_screen("basic_details") elif event.button.id == "continue": self.switch_screen("final_details") + elif event.button.id == "close_screen": + self.switch_screen("github_repo") + if event.button.id == "close_app": + self.exit() def action_toggle_dark(self) -> None: """An action to toggle dark mode.""" diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 56d5953199..539958aaa9 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -3,8 +3,8 @@ from textwrap import dedent import git +import yaml from github import Github, GithubException, UnknownObjectException -from textual import on from textual.app import ComposeResult from textual.containers import Center, Horizontal from textual.screen import Screen @@ -46,19 +46,21 @@ def compose(self) -> ComposeResult: yield Footer() yield Markdown(dedent(github_text_markdown)) with Horizontal(): + gh_user, gh_token = self._get_github_credentials() yield TextInput( "gh_username", "GitHub username", "Your GitHub username", + default=gh_user[0] if gh_user is not None else "GitHub username", classes="column", ) - token = "GITHUB_AUTH_TOKEN" in os.environ yield TextInput( "token", - "Using the environment variable GITHUB_AUTH_TOKEN" if token else "GitHub token", + "GitHub token", "Your GitHub personal access token for login.", + default=gh_token if gh_token is not None else "GitHub token", + password=True, classes="column", - disabled=token, ) yield Markdown(dedent(repo_config_markdown)) with Horizontal(): @@ -94,12 +96,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: pipeline_repo = git.Repo.init(self.parent.TEMPLATE_CONFIG.outdir) # GitHub authentication - if "GITHUB_AUTH_TOKEN" in os.environ: - github_auth = self._github_authentication( - github_variables["gh_username"], os.environ["GITHUB_AUTH_TOKEN"] - ) - log.debug("Using GITHUB_AUTH_TOKEN environment variable") - elif github_variables["token"]: + if github_variables["token"]: github_auth = self._github_authentication(github_variables["gh_username"], github_variables["token"]) else: raise UserWarning( @@ -192,3 +189,19 @@ def _github_authentication(self, gh_username, gh_token): log.debug(f"Authenticating GitHub as {gh_username}") github_auth = Github(gh_username, gh_token) return github_auth + + def _get_github_credentials(self): + """Get GitHub credentials""" + gh_user = None + gh_token = None + # Use gh CLI config if installed + gh_cli_config_fn = os.path.expanduser("~/.config/gh/hosts.yml") + if os.path.exists(gh_cli_config_fn): + with open(gh_cli_config_fn, "r") as fh: + gh_cli_config = yaml.safe_load(fh) + gh_user = (gh_cli_config["github.com"]["user"],) + gh_token = gh_cli_config["github.com"]["oauth_token"] + # If gh CLI not installed, try to get credentials from environment variables + elif os.environ.get("GITHUB_TOKEN") is not None: + gh_token = self.auth = os.environ["GITHUB_TOKEN"] + return (gh_user, gh_token) diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index 4ef332bbcb..5f40047987 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -37,10 +37,3 @@ def compose(self) -> ComposeResult: classes="cta", ) yield Center(self.parent.LOG_HANDLER.console, classes="cta") - - def on_button_pressed(self, event: Button.Pressed) -> None: - """Close the logging screen or the whole app.""" - if event.button.id == "close_app": - self.parent.exit() - if event.button.id == "close_screen": - self.parent.switch_screen("github_repo") diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index ae7ac097db..7b5cb8f956 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -71,7 +71,7 @@ class TextInput(Static): and validation messages. """ - def __init__(self, field_id, placeholder, description, default=None, **kwargs) -> None: + def __init__(self, field_id, placeholder, description, default=None, password=None, **kwargs) -> None: """Initialise the widget with our values. Pass on kwargs upstream for standard usage.""" @@ -80,6 +80,7 @@ def __init__(self, field_id, placeholder, description, default=None, **kwargs) - self.placeholder: str = placeholder self.description: str = description self.default: str = default + self.password: bool = password def compose(self) -> ComposeResult: yield Static(self.description, classes="field_help") @@ -87,6 +88,7 @@ def compose(self) -> ComposeResult: placeholder=self.placeholder, validators=[ValidateConfig(self.field_id)], value=self.default, + password=self.password, ) yield Static(classes="validation_msg") From 665d37825304b78c8a2fee580206eec1ade7fa28 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 13 Nov 2023 15:13:24 +0100 Subject: [PATCH 040/175] add button to show or hide password --- nf_core/pipelines/create/create.tcss | 15 +++++++++++++++ nf_core/pipelines/create/githubrepo.py | 19 ++++++++++++++++--- nf_core/pipelines/create/utils.py | 1 + 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index 42f144c7dd..df37e50ed8 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -79,3 +79,18 @@ HorizontalScroll { .displayed #hide_help { display: block; } + +/* Show password */ + +#show_password { + display: block; +} +#hide_password { + display: none; +} +.displayed #show_password { + display: none; +} +.displayed #hide_password { + display: block; +} diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 539958aaa9..270107c688 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -62,6 +62,8 @@ def compose(self) -> ComposeResult: password=True, classes="column", ) + yield Button("Show", id="show_password") + yield Button("Hide", id="hide_password") yield Markdown(dedent(repo_config_markdown)) with Horizontal(): yield Switch(value=False, id="private") @@ -80,7 +82,15 @@ def compose(self) -> ComposeResult: def on_button_pressed(self, event: Button.Pressed) -> None: """Create a GitHub repo or show help message and exit""" - if event.button.id == "create_github": + if event.button.id == "show_password": + self.add_class("displayed") + text_input = self.query_one("#token", TextInput) + text_input.query_one(Input).password = False + elif event.button.id == "hide_password": + self.remove_class("displayed") + text_input = self.query_one("#token", TextInput) + text_input.query_one(Input).password = True + elif event.button.id == "create_github": # Create a GitHub repo # Save GitHub username and token @@ -146,12 +156,15 @@ def on_button_pressed(self, event: Button.Pressed) -> None: log.info(f"GitHub repository '{self.parent.TEMPLATE_CONFIG.name}' created successfully") except UserWarning as e: log.info(f"There was an error with message: {e}" f"\n{exit_help_text_markdown}") + + self.parent.LOGGING_STATE = "repo created" + self.parent.switch_screen(LoggingScreen()) elif event.button.id == "exit": # Show help message and exit log.info(exit_help_text_markdown) - self.parent.LOGGING_STATE = "repo created" - self.parent.switch_screen(LoggingScreen()) + self.parent.LOGGING_STATE = "repo created" + self.parent.switch_screen(LoggingScreen()) def _create_repo_and_push(self, org, pipeline_repo, private, push): """Create a GitHub repository and push all branches.""" diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 7b5cb8f956..c01c947b42 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -77,6 +77,7 @@ def __init__(self, field_id, placeholder, description, default=None, password=No Pass on kwargs upstream for standard usage.""" super().__init__(**kwargs) self.field_id: str = field_id + self.id: str = field_id self.placeholder: str = placeholder self.description: str = description self.default: str = default From 19f60bcf04e8e8e7a381995653439162adbd7764 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 14 Nov 2023 10:13:38 +0100 Subject: [PATCH 041/175] update textual and textual-dev versions --- requirements-dev.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 1b92a49c65..07da7914a6 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,7 +6,7 @@ pytest-datafiles responses Sphinx sphinx-rtd-theme -textual-dev>=1.1.0 +textual-dev>=1.2.1 mypy types-PyYAML types-requests diff --git a/requirements.txt b/requirements.txt index 15c4f9e186..7c7cde7a8a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,4 +19,4 @@ requests_cache rich-click>=1.6.1 rich>=13.3.1 tabulate -textual>=0.33.0 +textual>=0.41.0 From 887f372433954481f3afe2c5ec0e79d203b1e15c Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 14 Nov 2023 16:30:32 +0100 Subject: [PATCH 042/175] add first snapshot tests --- nf_core/__main__.py | 2 + nf_core/pipelines/create/__init__.py | 2 +- requirements-dev.txt | 1 + tests/__snapshots__/test_create_app.ambr | 442 +++++++++++++++++++++++ tests/test_create_app.py | 37 ++ 5 files changed, 483 insertions(+), 1 deletion(-) create mode 100644 tests/__snapshots__/test_create_app.ambr create mode 100644 tests/test_create_app.py diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 13e2e97a54..1f200112fb 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -521,6 +521,7 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp ) app = PipelineCreateApp() app.run() + sys.exit(app.return_code or 0) # nf-core create (deprecated) @@ -582,6 +583,7 @@ def create(name, description, author, version, force, outdir, template_yaml, pla app = PipelineCreateApp() try: app.run() + sys.exit(app.return_code or 0) except UserWarning as e: log.error(e) sys.exit(1) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 68833877ca..52a6b39614 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -75,7 +75,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: elif event.button.id == "close_screen": self.switch_screen("github_repo") if event.button.id == "close_app": - self.exit() + self.exit(return_code=0) def action_toggle_dark(self) -> None: """An action to toggle dark mode.""" diff --git a/requirements-dev.txt b/requirements-dev.txt index 07da7914a6..96b6ab77b4 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -10,3 +10,4 @@ textual-dev>=1.2.1 mypy types-PyYAML types-requests +pytest-textual-snapshot diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr new file mode 100644 index 0000000000..ae80f7d847 --- /dev/null +++ b/tests/__snapshots__/test_create_app.ambr @@ -0,0 +1,442 @@ +# serializer version: 1 +# name: test_choose_type + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + To nf-core or not to nf-core? + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Next, we need to know what kind of pipeline this will be. + + Choose "nf-core" if: + + ● You want your pipeline to be part of the nf-core community + ● You think that there's an outside chance that it ever could be part of nf-core + + Choose "Custom" if: + + ● Your pipeline will never be part of nf-core + ● You want full control over all features that are included from the template(including  + those that are mandatory for nf-core). + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-coreCustom + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Not sure? What's the difference? + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Choosing "nf-core" effectively pre-selects the following template features: + + ● GitHub Actions Continuous Integration (CI) configuration for the following: + ▪ Small-scale (GitHub) and large-scale (AWS) tests + ▪ Code format linting with prettier + ▪ Auto-fix functionality using @nf-core-bot + ▪ Marking old issues as stale + ● Inclusion of shared nf-core config profiles + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_welcome + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pip… + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + nf-core create + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This app will help you create a new nf-core pipeline.It uses the  + nf-core pipeline template, which is keptwithin the nf-core/tools  + repository. + + Using this tool is mandatory when making a pipeline that maybe part  + of the nf-core community collection at some point.However, this tool  + can also be used to create pipelines that willnever be part of ▁▁ + nf-core. You can still benefit from the communitybest practices for  + your own workflow. + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- diff --git a/tests/test_create_app.py b/tests/test_create_app.py new file mode 100644 index 0000000000..eb0f96a0cd --- /dev/null +++ b/tests/test_create_app.py @@ -0,0 +1,37 @@ +""" Test Pipeline Create App """ +import pytest + +from nf_core.pipelines.create import PipelineCreateApp + + +@pytest.mark.asyncio +async def test_app_bindings(): + """Test that the app bindings work.""" + app = PipelineCreateApp() + async with app.run_test() as pilot: + # Test pressing the D key + assert app.dark == True + await pilot.press("d") + assert app.dark == False + await pilot.press("d") + assert app.dark == True + + # Test pressing the Q key + await pilot.press("q") + assert app.return_code == 0 + + +def test_welcome(snap_compare): + """Test snapshot for the first screen in the app. The welcome screen.""" + assert snap_compare("../nf_core/pipelines/create/__init__.py") + + +def test_choose_type(snap_compare): + """Test snapshot for the choose_type screen. + screen welcome > press start > screen choose_type + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) From 77586984ce452359ea1abbd22d0e76ad1b66b5a4 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 5 Dec 2023 11:15:00 +0100 Subject: [PATCH 043/175] add snapshots for all screens --- .gitignore | 3 + nf_core/pipelines/create/basicdetails.py | 2 +- tests/__snapshots__/test_create_app.ambr | 2989 +++++++++++++++++++++- tests/test_create_app.py | 243 +- 4 files changed, 3112 insertions(+), 125 deletions(-) diff --git a/.gitignore b/.gitignore index 271fdb14e3..a3721da86e 100644 --- a/.gitignore +++ b/.gitignore @@ -115,3 +115,6 @@ ENV/ pip-wheel-metadata .vscode .*.sw? + +# Textual +snapshot_report.html diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py index dc7248d977..da1b2bf45a 100644 --- a/nf_core/pipelines/create/basicdetails.py +++ b/nf_core/pipelines/create/basicdetails.py @@ -50,7 +50,7 @@ def compose(self) -> ComposeResult: "Name of the main author / authors", ) yield Center( - Button("Next", variant="success"), + Button("Next", id="next", variant="success"), classes="cta", ) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index ae80f7d847..9a2c11d858 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1,4 +1,553 @@ # serializer version: 1 +# name: test_basic_details_custom + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Next + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_basic_details_nfcore + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Next + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- # name: test_choose_type ''' @@ -22,251 +571,2445 @@ font-weight: 700; } - .terminal-2103023275-matrix { + .terminal-2103023275-matrix { + font-family: Fira Code, monospace; + font-size: 20px; + line-height: 24.4px; + font-variant-east-asian: full-width; + } + + .terminal-2103023275-title { + font-size: 18px; + font-weight: bold; + font-family: arial; + } + + .terminal-2103023275-r1 { fill: #c5c8c6 } + .terminal-2103023275-r2 { fill: #e3e3e3 } + .terminal-2103023275-r3 { fill: #989898 } + .terminal-2103023275-r4 { fill: #e1e1e1 } + .terminal-2103023275-r5 { fill: #121212 } + .terminal-2103023275-r6 { fill: #0053aa } + .terminal-2103023275-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2103023275-r8 { fill: #e1e1e1;font-style: italic; } + .terminal-2103023275-r9 { fill: #4ebf71;font-weight: bold } + .terminal-2103023275-r10 { fill: #7ae998 } + .terminal-2103023275-r11 { fill: #507bb3 } + .terminal-2103023275-r12 { fill: #dde6ed;font-weight: bold } + .terminal-2103023275-r13 { fill: #008139 } + .terminal-2103023275-r14 { fill: #001541 } + .terminal-2103023275-r15 { fill: #24292f } + .terminal-2103023275-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-2103023275-r17 { fill: #ddedf9 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + To nf-core or not to nf-core? + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Next, we need to know what kind of pipeline this will be. + + Choose "nf-core" if: + + ● You want your pipeline to be part of the nf-core community + ● You think that there's an outside chance that it ever could be part of nf-core + + Choose "Custom" if: + + ● Your pipeline will never be part of nf-core + ● You want full control over all features that are included from the template(including  + those that are mandatory for nf-core). + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-coreCustom + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Not sure? What's the difference? + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Choosing "nf-core" effectively pre-selects the following template features: + + ● GitHub Actions Continuous Integration (CI) configuration for the following: + ▪ Small-scale (GitHub) and large-scale (AWS) tests + ▪ Code format linting with prettier + ▪ Auto-fix functionality using @nf-core-bot + ▪ Marking old issues as stale + ● Inclusion of shared nf-core config profiles + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_customisation_help + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▔▔▔▔▔▔▔▔ + Use reference The pipeline will be▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁genomesconfigured to use a Hide help + copy of the most ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + common reference  + genome files from  + iGenomes + + + + Nf-core pipelines are configured to use a copy of the most common  + reference genome files. + + By selecting this option, your pipeline will include a  + configuration file specifying the paths to these files. + + The required code to use these files will also be included in the  + template.When the pipeline user provides an appropriate genome ▆▆ + key,the pipeline will automatically download the required  + reference files. + + + ▔▔▔▔▔▔▔▔ + Add Github CI testsThe pipeline will ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁include several Show help + GitHub actions for ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Continuous  + Integration (CI)  + testing + + ▔▔▔▔▔▔▔▔ + Add Github badgesThe README.md file ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁of the pipeline willShow help + include GitHub ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + badges + + ▔▔▔▔▔▔▔▔ + Add configuration The pipeline will ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁filesinclude Show help + configuration ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + profiles containing  + custom parameters ▆▆ + requried to run  + nf-core pipelines at + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Continue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_final_details + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Final details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + First version of the pipelinePath to the output directory where the pipeline  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created + 1.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔If the pipeline output directory exists, remove it and continue. + + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Finish + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_github_details + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create a GitHub repo + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + After creating the pipeline template locally, we can create a GitHub repository and push the + code to it. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Your GitHub usernameYour GitHub personal access token for Show + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔login.▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + mirpedrol▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁•••••••••••••••••••••••••••••••••••• + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Please select the the GitHub repository settings: + + + ▔▔▔▔▔▔▔▔Select if the new GitHub repo must be private. + + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔Select if you would like to push all the pipeline template files to your GitHub repo + and all the branches required to keep the pipeline up to date with new releases of nf-core + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Create GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_logging_after_github + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + nf-core create + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Visualising logging output. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close App + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + ▂▂ + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_logging_pipeline_created + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + nf-core create + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Visualising logging output. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close logging screen + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + ▂▂ + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_type_custom + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▔▔▔▔▔▔▔▔ + Use reference genomesThe pipeline will be ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁configured to use a Show help + copy of the most ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + common reference  + genome files from  + iGenomes + + ▔▔▔▔▔▔▔▔ + Add Github CI testsThe pipeline will ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁include several Show help + GitHub actions for ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Continuous  + Integration (CI)  + testing + + ▔▔▔▔▔▔▔▔ + Add Github badgesThe README.md file of▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁the pipeline will Show help + include GitHub badges▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔ + Add configuration The pipeline will ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁filesinclude configurationShow help + profiles containing ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + custom parameters  + requried to run  + nf-core pipelines at  + different  + institutions + + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Continue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_type_nfcore + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▔▔▔▔▔▔▔▔ + Use reference genomesThe pipeline will be ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁configured to use a Show help + copy of the most ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + common reference  + genome files from  + iGenomes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Continue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_type_nfcore_validation + ''' + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - To nf-core or not to nf-core? - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Next, we need to know what kind of pipeline this will be. - - Choose "nf-core" if: - - ● You want your pipeline to be part of the nf-core community - ● You think that there's an outside chance that it ever could be part of nf-core - - Choose "Custom" if: - - ● Your pipeline will never be part of nf-core - ● You want full control over all features that are included from the template(including  - those that are mandatory for nf-core). - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-coreCustom - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Not sure? What's the difference? - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Choosing "nf-core" effectively pre-selects the following template features: - - ● GitHub Actions Continuous Integration (CI) configuration for the following: - ▪ Small-scale (GitHub) and large-scale (AWS) tests - ▪ Code format linting with prettier - ▪ Auto-fix functionality using @nf-core-bot - ▪ Marking old issues as stale - ● Inclusion of shared nf-core config profiles - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Must be lowercase without  + punctuation. + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Next + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  diff --git a/tests/test_create_app.py b/tests/test_create_app.py index eb0f96a0cd..e91d0a0fae 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -1,4 +1,6 @@ """ Test Pipeline Create App """ +from unittest import mock + import pytest from nf_core.pipelines.create import PipelineCreateApp @@ -28,10 +30,249 @@ def test_welcome(snap_compare): def test_choose_type(snap_compare): """Test snapshot for the choose_type screen. - screen welcome > press start > screen choose_type + Steps to get to this screen: + screen welcome > press start > + screen choose_type + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) + + +def test_basic_details_nfcore(snap_compare): + """Test snapshot for the basic_details screen of an nf-core pipeline. + Steps to get to this screen: + screen welcome > press start > + screen choose_type > press nf-core > + screen basic_details + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + await pilot.click("#type_nfcore") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) + + +def test_basic_details_custom(snap_compare): + """Test snapshot for the basic_details screen of a custom pipeline. + Steps to get to this screen: + screen welcome > press start > + screen choose_type > press custom > + screen basic_details + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + await pilot.click("#type_custom") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) + + +def test_type_nfcore(snap_compare): + """Test snapshot for the type_nfcore screen. + Steps to get to this screen: + screen welcome > press start > + screen choose_type > press nf-core > + screen basic_details > enter pipeline details > press next > + screen type_nfcore + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + await pilot.click("#type_nfcore") + await pilot.click("#name") + await pilot.press("m", "y", "p", "i", "p", "e", "l", "i", "n", "e") + await pilot.press("tab") + await pilot.press("A", " ", "c", "o", "o", "l", " ", "d", "e", "s", "c", "r", "i", "p", "t", "i", "o", "n") + await pilot.press("tab") + await pilot.press("M", "e") + await pilot.click("#next") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) + + +def test_type_nfcore_validation(snap_compare): + """Test snapshot for the type_nfcore screen. + Validation errors should appear when input fields are empty. + Steps to get to this screen: + screen welcome > press start > + screen choose_type > press nf-core > + screen basic_details > press next > + ERRORS + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + await pilot.click("#type_nfcore") + await pilot.click("#next") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) + + +def test_type_custom(snap_compare): + """Test snapshot for the type_custom screen. + Steps to get to this screen: + screen welcome > press start > + screen choose_type > press custom > + screen basic_details > enter pipeline details > press next > + screen type_custom + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + await pilot.click("#type_custom") + await pilot.click("#name") + await pilot.press("tab") + await pilot.press("m", "y", "p", "i", "p", "e", "l", "i", "n", "e") + await pilot.press("tab") + await pilot.press("A", " ", "c", "o", "o", "l", " ", "d", "e", "s", "c", "r", "i", "p", "t", "i", "o", "n") + await pilot.press("tab") + await pilot.press("M", "e") + await pilot.click("#next") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) + + +def test_final_details(snap_compare): + """Test snapshot for the final_details screen. + Steps to get to this screen: + screen welcome > press start > + screen choose_type > press nf-core > + screen basic_details > enter pipeline details > press next > + screen type_nfcore > press continue > + screen final_details + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + await pilot.click("#type_nfcore") + await pilot.click("#name") + await pilot.press("m", "y", "p", "i", "p", "e", "l", "i", "n", "e") + await pilot.press("tab") + await pilot.press("A", " ", "c", "o", "o", "l", " ", "d", "e", "s", "c", "r", "i", "p", "t", "i", "o", "n") + await pilot.press("tab") + await pilot.press("M", "e") + await pilot.click("#next") + await pilot.click("#continue") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) + + +def test_customisation_help(snap_compare): + """Test snapshot for the type_custom screen - showing help messages. + Steps to get to this screen: + screen welcome > press start > + screen choose_type > press nf-core > + screen basic_details > enter pipeline details > press next > + screen type_custom > press Show more + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + await pilot.click("#type_custom") + await pilot.click("#name") + await pilot.press("tab") + await pilot.press("m", "y", "p", "i", "p", "e", "l", "i", "n", "e") + await pilot.press("tab") + await pilot.press("A", " ", "c", "o", "o", "l", " ", "d", "e", "s", "c", "r", "i", "p", "t", "i", "o", "n") + await pilot.press("tab") + await pilot.press("M", "e") + await pilot.click("#next") + await pilot.click("#igenomes") + await pilot.press("tab") + await pilot.press("enter") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) + + +@mock.patch("nf_core.pipelines.create.create.PipelineCreate.init_pipeline", return_value=None) +def test_logging_pipeline_created(mock_init_pipeline, snap_compare): + """Test snapshot for the final_details screen. + Steps to get to this screen: + screen welcome > press start > + screen choose_type > press nf-core > + screen basic_details > enter pipeline details > press next > + screen type_nfcore > press continue > + screen final_details > press finish > + screen logging_screen + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + await pilot.click("#type_nfcore") + await pilot.click("#name") + await pilot.press("m", "y", "p", "i", "p", "e", "l", "i", "n", "e") + await pilot.press("tab") + await pilot.press("A", " ", "c", "o", "o", "l", " ", "d", "e", "s", "c", "r", "i", "p", "t", "i", "o", "n") + await pilot.press("tab") + await pilot.press("M", "e") + await pilot.click("#next") + await pilot.click("#continue") + await pilot.click("#finish") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) + + +@mock.patch("nf_core.pipelines.create.create.PipelineCreate.init_pipeline", return_value=None) +def test_github_details(mock_init_pipeline, snap_compare): + """Test snapshot for the final_details screen. + Steps to get to this screen: + screen welcome > press start > + screen choose_type > press nf-core > + screen basic_details > enter pipeline details > press next > + screen type_nfcore > press continue > + screen final_details > press finish > + screen logging_screen > press close_screen > + screen github_repo + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + await pilot.click("#type_nfcore") + await pilot.click("#name") + await pilot.press("m", "y", "p", "i", "p", "e", "l", "i", "n", "e") + await pilot.press("tab") + await pilot.press("A", " ", "c", "o", "o", "l", " ", "d", "e", "s", "c", "r", "i", "p", "t", "i", "o", "n") + await pilot.press("tab") + await pilot.press("M", "e") + await pilot.click("#next") + await pilot.click("#continue") + await pilot.click("#finish") + await pilot.click("#close_screen") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) + + +@mock.patch("nf_core.pipelines.create.create.PipelineCreate.init_pipeline", return_value=None) +def test_logging_after_github(mock_init_pipeline, snap_compare): + """Test snapshot for the final_details screen. + Steps to get to this screen: + screen welcome > press start > + screen choose_type > press nf-core > + screen basic_details > enter pipeline details > press next > + screen type_nfcore > press continue > + screen final_details > press finish > + screen logging_screen > press close_screen > + screen github_repo > press exit (close without creating a repo) > + screen logging_screen """ async def run_before(pilot) -> None: await pilot.click("#start") + await pilot.click("#type_nfcore") + await pilot.click("#name") + await pilot.press("m", "y", "p", "i", "p", "e", "l", "i", "n", "e") + await pilot.press("tab") + await pilot.press("A", " ", "c", "o", "o", "l", " ", "d", "e", "s", "c", "r", "i", "p", "t", "i", "o", "n") + await pilot.press("tab") + await pilot.press("M", "e") + await pilot.click("#next") + await pilot.click("#continue") + await pilot.click("#finish") + await pilot.click("#close_screen") + await pilot.click("#exit") assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) From 390816310783dc0c067e0d8be0f3324459ac417a Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 5 Jan 2024 09:59:41 +0100 Subject: [PATCH 044/175] ruff code modifications --- nf_core/pipelines/create/create.py | 4 ++-- nf_core/pipelines/create/githubrepo.py | 6 +++--- nf_core/pipelines/create/loggingscreen.py | 1 - nf_core/pipelines/create/nfcorepipeline.py | 2 +- nf_core/pipelines/create/utils.py | 2 +- tests/test_create.py | 1 - tests/test_create_app.py | 6 +++--- tests/test_modules.py | 1 - tests/test_subworkflows.py | 1 - 9 files changed, 10 insertions(+), 14 deletions(-) diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index 7838e39a40..51c115e2c6 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -130,7 +130,7 @@ def check_template_yaml_info(self, template_yaml, name, description, author): config = CreateConfig() if template_yaml: try: - with open(template_yaml, "r") as f: + with open(template_yaml) as f: template_yaml = yaml.safe_load(f) config = CreateConfig(**template_yaml) except FileNotFoundError: @@ -397,7 +397,7 @@ def remove_nf_core_in_bug_report_template(self): """ bug_report_path = self.outdir / ".github" / "ISSUE_TEMPLATE" / "bug_report.yml" - with open(bug_report_path, "r") as fh: + with open(bug_report_path) as fh: contents = yaml.load(fh, Loader=yaml.FullLoader) # Remove the first item in the body, which is the information about the docs diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 270107c688..2a98d84985 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -23,7 +23,7 @@ repo_config_markdown = """ Please select the the GitHub repository settings: """ -exit_help_text_markdown = f""" +exit_help_text_markdown = """ If you would like to create the GitHub repository later, you can do it manually by following these steps: 1. Create a new GitHub repository 2. Add the remote to your local repository @@ -121,7 +121,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: try: user.login log.debug("GitHub authentication successful") - except GithubException as e: + except GithubException: raise UserWarning( f"Could not authenticate to GitHub with user name '{github_variables['gh_username']}'." "Please make sure that the provided user name and token are correct." @@ -210,7 +210,7 @@ def _get_github_credentials(self): # Use gh CLI config if installed gh_cli_config_fn = os.path.expanduser("~/.config/gh/hosts.yml") if os.path.exists(gh_cli_config_fn): - with open(gh_cli_config_fn, "r") as fh: + with open(gh_cli_config_fn) as fh: gh_cli_config = yaml.safe_load(fh) gh_user = (gh_cli_config["github.com"]["user"],) gh_token = gh_cli_config["github.com"]["oauth_token"] diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index 5f40047987..2a59e2bcc6 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -1,4 +1,3 @@ -from textual import on from textual.app import ComposeResult from textual.containers import Center from textual.screen import Screen diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py index 95c173a406..10541ced04 100644 --- a/nf_core/pipelines/create/nfcorepipeline.py +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -1,6 +1,6 @@ from textual import on from textual.app import ComposeResult -from textual.containers import Center, Horizontal, ScrollableContainer +from textual.containers import Center, ScrollableContainer from textual.screen import Screen from textual.widgets import Button, Footer, Header, Switch diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index f11ee17531..7842888f05 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -186,7 +186,7 @@ class CustomLogHandler(RichHandler): def emit(self, record: LogRecord) -> None: """Invoked by logging.""" try: - app = active_app.get() + _app = active_app.get() except LookupError: pass else: diff --git a/tests/test_create.py b/tests/test_create.py index c3b7f931f0..5dfd9244c8 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -3,7 +3,6 @@ import os import unittest from pathlib import Path -from unittest import mock import git import yaml diff --git a/tests/test_create_app.py b/tests/test_create_app.py index e91d0a0fae..8b22eabad6 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -12,11 +12,11 @@ async def test_app_bindings(): app = PipelineCreateApp() async with app.run_test() as pilot: # Test pressing the D key - assert app.dark == True + assert app.dark await pilot.press("d") - assert app.dark == False + assert not app.dark await pilot.press("d") - assert app.dark == True + assert app.dark # Test pressing the Q key await pilot.press("q") diff --git a/tests/test_modules.py b/tests/test_modules.py index 05b0c41112..9c045f9d18 100644 --- a/tests/test_modules.py +++ b/tests/test_modules.py @@ -20,7 +20,6 @@ GITLAB_URL, OLD_TRIMGALORE_BRANCH, OLD_TRIMGALORE_SHA, - create_tmp_pipeline, mock_anaconda_api_calls, mock_biocontainers_api_calls, ) diff --git a/tests/test_subworkflows.py b/tests/test_subworkflows.py index 930b929428..a7f3876616 100644 --- a/tests/test_subworkflows.py +++ b/tests/test_subworkflows.py @@ -15,7 +15,6 @@ GITLAB_SUBWORKFLOWS_ORG_PATH_BRANCH, GITLAB_URL, OLD_SUBWORKFLOWS_SHA, - create_tmp_pipeline, ) From 208d832994a34f1cfce22e6612c1471ca375c55e Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 5 Jan 2024 10:18:27 +0100 Subject: [PATCH 045/175] update snapshots --- tests/__snapshots__/test_create_app.ambr | 2849 +++++++++++----------- 1 file changed, 1425 insertions(+), 1424 deletions(-) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index 9a2c11d858..3c5a1b91c1 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -22,250 +22,250 @@ font-weight: 700; } - .terminal-3398870890-matrix { + .terminal-2900179749-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3398870890-title { + .terminal-2900179749-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3398870890-r1 { fill: #c5c8c6 } - .terminal-3398870890-r2 { fill: #e3e3e3 } - .terminal-3398870890-r3 { fill: #989898 } - .terminal-3398870890-r4 { fill: #e1e1e1 } - .terminal-3398870890-r5 { fill: #121212 } - .terminal-3398870890-r6 { fill: #0053aa } - .terminal-3398870890-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3398870890-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-3398870890-r9 { fill: #1e1e1e } - .terminal-3398870890-r10 { fill: #008139 } - .terminal-3398870890-r11 { fill: #e2e2e2 } - .terminal-3398870890-r12 { fill: #787878 } - .terminal-3398870890-r13 { fill: #b93c5b } - .terminal-3398870890-r14 { fill: #7ae998 } - .terminal-3398870890-r15 { fill: #0a180e;font-weight: bold } - .terminal-3398870890-r16 { fill: #ddedf9 } + .terminal-2900179749-r1 { fill: #c5c8c6 } + .terminal-2900179749-r2 { fill: #e3e3e3 } + .terminal-2900179749-r3 { fill: #989898 } + .terminal-2900179749-r4 { fill: #e1e1e1 } + .terminal-2900179749-r5 { fill: #121212 } + .terminal-2900179749-r6 { fill: #0053aa } + .terminal-2900179749-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2900179749-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-2900179749-r9 { fill: #1e1e1e } + .terminal-2900179749-r10 { fill: #008139 } + .terminal-2900179749-r11 { fill: #e2e2e2 } + .terminal-2900179749-r12 { fill: #787878 } + .terminal-2900179749-r13 { fill: #b93c5b } + .terminal-2900179749-r14 { fill: #7ae998 } + .terminal-2900179749-r15 { fill: #0a180e;font-weight: bold } + .terminal-2900179749-r16 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Next - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Next + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -295,253 +295,253 @@ font-weight: 700; } - .terminal-3340021344-matrix { + .terminal-1441415707-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3340021344-title { + .terminal-1441415707-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3340021344-r1 { fill: #c5c8c6 } - .terminal-3340021344-r2 { fill: #e3e3e3 } - .terminal-3340021344-r3 { fill: #989898 } - .terminal-3340021344-r4 { fill: #e1e1e1 } - .terminal-3340021344-r5 { fill: #121212 } - .terminal-3340021344-r6 { fill: #0053aa } - .terminal-3340021344-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3340021344-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-3340021344-r9 { fill: #1e1e1e } - .terminal-3340021344-r10 { fill: #0f4e2a } - .terminal-3340021344-r11 { fill: #0178d4 } - .terminal-3340021344-r12 { fill: #a7a7a7 } - .terminal-3340021344-r13 { fill: #787878 } - .terminal-3340021344-r14 { fill: #e2e2e2 } - .terminal-3340021344-r15 { fill: #b93c5b } - .terminal-3340021344-r16 { fill: #7ae998 } - .terminal-3340021344-r17 { fill: #0a180e;font-weight: bold } - .terminal-3340021344-r18 { fill: #008139 } - .terminal-3340021344-r19 { fill: #ddedf9 } + .terminal-1441415707-r1 { fill: #c5c8c6 } + .terminal-1441415707-r2 { fill: #e3e3e3 } + .terminal-1441415707-r3 { fill: #989898 } + .terminal-1441415707-r4 { fill: #e1e1e1 } + .terminal-1441415707-r5 { fill: #121212 } + .terminal-1441415707-r6 { fill: #0053aa } + .terminal-1441415707-r7 { fill: #dde8f3;font-weight: bold } + .terminal-1441415707-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-1441415707-r9 { fill: #1e1e1e } + .terminal-1441415707-r10 { fill: #0f4e2a } + .terminal-1441415707-r11 { fill: #0178d4 } + .terminal-1441415707-r12 { fill: #a7a7a7 } + .terminal-1441415707-r13 { fill: #787878 } + .terminal-1441415707-r14 { fill: #e2e2e2 } + .terminal-1441415707-r15 { fill: #b93c5b } + .terminal-1441415707-r16 { fill: #7ae998 } + .terminal-1441415707-r17 { fill: #0a180e;font-weight: bold } + .terminal-1441415707-r18 { fill: #008139 } + .terminal-1441415707-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Next - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Next + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -571,251 +571,251 @@ font-weight: 700; } - .terminal-2103023275-matrix { + .terminal-828318910-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2103023275-title { + .terminal-828318910-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2103023275-r1 { fill: #c5c8c6 } - .terminal-2103023275-r2 { fill: #e3e3e3 } - .terminal-2103023275-r3 { fill: #989898 } - .terminal-2103023275-r4 { fill: #e1e1e1 } - .terminal-2103023275-r5 { fill: #121212 } - .terminal-2103023275-r6 { fill: #0053aa } - .terminal-2103023275-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2103023275-r8 { fill: #e1e1e1;font-style: italic; } - .terminal-2103023275-r9 { fill: #4ebf71;font-weight: bold } - .terminal-2103023275-r10 { fill: #7ae998 } - .terminal-2103023275-r11 { fill: #507bb3 } - .terminal-2103023275-r12 { fill: #dde6ed;font-weight: bold } - .terminal-2103023275-r13 { fill: #008139 } - .terminal-2103023275-r14 { fill: #001541 } - .terminal-2103023275-r15 { fill: #24292f } - .terminal-2103023275-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-2103023275-r17 { fill: #ddedf9 } + .terminal-828318910-r1 { fill: #c5c8c6 } + .terminal-828318910-r2 { fill: #e3e3e3 } + .terminal-828318910-r3 { fill: #989898 } + .terminal-828318910-r4 { fill: #e1e1e1 } + .terminal-828318910-r5 { fill: #121212 } + .terminal-828318910-r6 { fill: #0053aa } + .terminal-828318910-r7 { fill: #dde8f3;font-weight: bold } + .terminal-828318910-r8 { fill: #e1e1e1;font-style: italic; } + .terminal-828318910-r9 { fill: #4ebf71;font-weight: bold } + .terminal-828318910-r10 { fill: #7ae998 } + .terminal-828318910-r11 { fill: #507bb3 } + .terminal-828318910-r12 { fill: #dde6ed;font-weight: bold } + .terminal-828318910-r13 { fill: #008139 } + .terminal-828318910-r14 { fill: #001541 } + .terminal-828318910-r15 { fill: #24292f } + .terminal-828318910-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-828318910-r17 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - To nf-core or not to nf-core? - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Next, we need to know what kind of pipeline this will be. - - Choose "nf-core" if: - - ● You want your pipeline to be part of the nf-core community - ● You think that there's an outside chance that it ever could be part of nf-core - - Choose "Custom" if: - - ● Your pipeline will never be part of nf-core - ● You want full control over all features that are included from the template(including  - those that are mandatory for nf-core). - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-coreCustom - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Not sure? What's the difference? - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Choosing "nf-core" effectively pre-selects the following template features: - - ● GitHub Actions Continuous Integration (CI) configuration for the following: - ▪ Small-scale (GitHub) and large-scale (AWS) tests - ▪ Code format linting with prettier - ▪ Auto-fix functionality using @nf-core-bot - ▪ Marking old issues as stale - ● Inclusion of shared nf-core config profiles - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + To nf-core or not to nf-core? + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Next, we need to know what kind of pipeline this will be. + + Choose "nf-core" if: + + ● You want your pipeline to be part of the nf-core community + ● You think that there's an outside chance that it ever could be part of nf-core + + Choose "Custom" if: + + ● Your pipeline will never be part of nf-core + ● You want full control over all features that are included from the template (including  + those that are mandatory for nf-core). + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-coreCustom + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +                             Not sure? What's the difference?                             + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Choosing "nf-core" effectively pre-selects the following template features: + + ● GitHub Actions Continuous Integration (CI) configuration for the following: + ▪ Small-scale (GitHub) and large-scale (AWS) tests + ▪ Code format linting with prettier + ▪ Auto-fix functionality using @nf-core-bot + ▪ Marking old issues as stale + ● Inclusion of shared nf-core config profiles + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -845,255 +845,255 @@ font-weight: 700; } - .terminal-3470600551-matrix { + .terminal-3545740190-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3470600551-title { + .terminal-3545740190-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3470600551-r1 { fill: #c5c8c6 } - .terminal-3470600551-r2 { fill: #e3e3e3 } - .terminal-3470600551-r3 { fill: #989898 } - .terminal-3470600551-r4 { fill: #1e1e1e } - .terminal-3470600551-r5 { fill: #0178d4 } - .terminal-3470600551-r6 { fill: #e1e1e1 } - .terminal-3470600551-r7 { fill: #e2e2e2 } - .terminal-3470600551-r8 { fill: #808080 } - .terminal-3470600551-r9 { fill: #454a50 } - .terminal-3470600551-r10 { fill: #e2e3e3;font-weight: bold } - .terminal-3470600551-r11 { fill: #000000 } - .terminal-3470600551-r12 { fill: #e4e4e4 } - .terminal-3470600551-r13 { fill: #14191f } - .terminal-3470600551-r14 { fill: #507bb3 } - .terminal-3470600551-r15 { fill: #dde6ed;font-weight: bold } - .terminal-3470600551-r16 { fill: #001541 } - .terminal-3470600551-r17 { fill: #7ae998 } - .terminal-3470600551-r18 { fill: #0a180e;font-weight: bold } - .terminal-3470600551-r19 { fill: #008139 } - .terminal-3470600551-r20 { fill: #dde8f3;font-weight: bold } - .terminal-3470600551-r21 { fill: #ddedf9 } + .terminal-3545740190-r1 { fill: #c5c8c6 } + .terminal-3545740190-r2 { fill: #e3e3e3 } + .terminal-3545740190-r3 { fill: #989898 } + .terminal-3545740190-r4 { fill: #1e1e1e } + .terminal-3545740190-r5 { fill: #0178d4 } + .terminal-3545740190-r6 { fill: #e1e1e1 } + .terminal-3545740190-r7 { fill: #454a50 } + .terminal-3545740190-r8 { fill: #e2e2e2 } + .terminal-3545740190-r9 { fill: #808080 } + .terminal-3545740190-r10 { fill: #e2e3e3;font-weight: bold } + .terminal-3545740190-r11 { fill: #000000 } + .terminal-3545740190-r12 { fill: #e4e4e4 } + .terminal-3545740190-r13 { fill: #14191f } + .terminal-3545740190-r14 { fill: #507bb3 } + .terminal-3545740190-r15 { fill: #dde6ed;font-weight: bold } + .terminal-3545740190-r16 { fill: #001541 } + .terminal-3545740190-r17 { fill: #7ae998 } + .terminal-3545740190-r18 { fill: #0a180e;font-weight: bold } + .terminal-3545740190-r19 { fill: #008139 } + .terminal-3545740190-r20 { fill: #dde8f3;font-weight: bold } + .terminal-3545740190-r21 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▔▔▔▔▔▔▔▔ - Use reference The pipeline will be▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁genomesconfigured to use a Hide help - copy of the most ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - common reference  - genome files from  - iGenomes - - - - Nf-core pipelines are configured to use a copy of the most common  - reference genome files. - - By selecting this option, your pipeline will include a  - configuration file specifying the paths to these files. - - The required code to use these files will also be included in the  - template.When the pipeline user provides an appropriate genome ▆▆ - key,the pipeline will automatically download the required  - reference files. - - - ▔▔▔▔▔▔▔▔ - Add Github CI testsThe pipeline will ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁include several Show help - GitHub actions for ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Continuous  - Integration (CI)  - testing - - ▔▔▔▔▔▔▔▔ - Add Github badgesThe README.md file ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁of the pipeline willShow help - include GitHub ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - badges - - ▔▔▔▔▔▔▔▔ - Add configuration The pipeline will ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁filesinclude Show help - configuration ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - profiles containing  - custom parameters ▆▆ - requried to run  - nf-core pipelines at - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Continue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference genomesThe pipeline will be Hide help + ▁▁▁▁▁▁▁▁configured to use a copy ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + of the most common  + reference genome files  + from iGenomes + + + + Nf-core pipelines are configured to use a copy of the most common  + reference genome files. + + By selecting this option, your pipeline will include a configuration + file specifying the paths to these files. + + The required code to use these files will also be included in the  + template. When the pipeline user provides an appropriate genome key,▆▆ + the pipeline will automatically download the required reference  + files. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github CI testsThe pipeline will includeShow help + ▁▁▁▁▁▁▁▁several GitHub actions ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + for Continuous  + Integration (CI) testing + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github badgesThe README.md file of theShow help + ▁▁▁▁▁▁▁▁pipeline will include ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + GitHub badges + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add configuration filesThe pipeline will includeShow help + ▁▁▁▁▁▁▁▁configuration profiles ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + containing custom  + parameters requried to  + run nf-core pipelines at  + different institutions + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Continue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  @@ -1123,249 +1123,249 @@ font-weight: 700; } - .terminal-680074798-matrix { + .terminal-1778650725-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-680074798-title { + .terminal-1778650725-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-680074798-r1 { fill: #c5c8c6 } - .terminal-680074798-r2 { fill: #e3e3e3 } - .terminal-680074798-r3 { fill: #989898 } - .terminal-680074798-r4 { fill: #e1e1e1 } - .terminal-680074798-r5 { fill: #121212 } - .terminal-680074798-r6 { fill: #0053aa } - .terminal-680074798-r7 { fill: #dde8f3;font-weight: bold } - .terminal-680074798-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-680074798-r9 { fill: #1e1e1e } - .terminal-680074798-r10 { fill: #008139 } - .terminal-680074798-r11 { fill: #e2e2e2 } - .terminal-680074798-r12 { fill: #b93c5b } - .terminal-680074798-r13 { fill: #7ae998 } - .terminal-680074798-r14 { fill: #0a180e;font-weight: bold } - .terminal-680074798-r15 { fill: #ddedf9 } + .terminal-1778650725-r1 { fill: #c5c8c6 } + .terminal-1778650725-r2 { fill: #e3e3e3 } + .terminal-1778650725-r3 { fill: #989898 } + .terminal-1778650725-r4 { fill: #e1e1e1 } + .terminal-1778650725-r5 { fill: #121212 } + .terminal-1778650725-r6 { fill: #0053aa } + .terminal-1778650725-r7 { fill: #dde8f3;font-weight: bold } + .terminal-1778650725-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-1778650725-r9 { fill: #1e1e1e } + .terminal-1778650725-r10 { fill: #008139 } + .terminal-1778650725-r11 { fill: #e2e2e2 } + .terminal-1778650725-r12 { fill: #b93c5b } + .terminal-1778650725-r13 { fill: #7ae998 } + .terminal-1778650725-r14 { fill: #0a180e;font-weight: bold } + .terminal-1778650725-r15 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Final details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - First version of the pipelinePath to the output directory where the pipeline  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created - 1.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔If the pipeline output directory exists, remove it and continue. - - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Finish - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Final details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + First version of the pipelinePath to the output directory where the pipeline  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created + 1.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔If the pipeline output directory exists, remove it and continue. + + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Finish + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -1395,255 +1395,255 @@ font-weight: 700; } - .terminal-2034340412-matrix { + .terminal-4207832566-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2034340412-title { + .terminal-4207832566-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2034340412-r1 { fill: #c5c8c6 } - .terminal-2034340412-r2 { fill: #e3e3e3 } - .terminal-2034340412-r3 { fill: #989898 } - .terminal-2034340412-r4 { fill: #e1e1e1 } - .terminal-2034340412-r5 { fill: #121212 } - .terminal-2034340412-r6 { fill: #0053aa } - .terminal-2034340412-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2034340412-r8 { fill: #454a50 } - .terminal-2034340412-r9 { fill: #a5a5a5;font-style: italic; } - .terminal-2034340412-r10 { fill: #e2e3e3;font-weight: bold } - .terminal-2034340412-r11 { fill: #1e1e1e } - .terminal-2034340412-r12 { fill: #008139 } - .terminal-2034340412-r13 { fill: #000000 } - .terminal-2034340412-r14 { fill: #e2e2e2 } - .terminal-2034340412-r15 { fill: #b93c5b } - .terminal-2034340412-r16 { fill: #7ae998 } - .terminal-2034340412-r17 { fill: #507bb3 } - .terminal-2034340412-r18 { fill: #0a180e;font-weight: bold } - .terminal-2034340412-r19 { fill: #dde6ed;font-weight: bold } - .terminal-2034340412-r20 { fill: #001541 } - .terminal-2034340412-r21 { fill: #ddedf9 } + .terminal-4207832566-r1 { fill: #c5c8c6 } + .terminal-4207832566-r2 { fill: #e3e3e3 } + .terminal-4207832566-r3 { fill: #989898 } + .terminal-4207832566-r4 { fill: #e1e1e1 } + .terminal-4207832566-r5 { fill: #121212 } + .terminal-4207832566-r6 { fill: #0053aa } + .terminal-4207832566-r7 { fill: #dde8f3;font-weight: bold } + .terminal-4207832566-r8 { fill: #454a50 } + .terminal-4207832566-r9 { fill: #a5a5a5;font-style: italic; } + .terminal-4207832566-r10 { fill: #e2e3e3;font-weight: bold } + .terminal-4207832566-r11 { fill: #1e1e1e } + .terminal-4207832566-r12 { fill: #008139 } + .terminal-4207832566-r13 { fill: #000000 } + .terminal-4207832566-r14 { fill: #e2e2e2 } + .terminal-4207832566-r15 { fill: #b93c5b } + .terminal-4207832566-r16 { fill: #7ae998 } + .terminal-4207832566-r17 { fill: #507bb3 } + .terminal-4207832566-r18 { fill: #0a180e;font-weight: bold } + .terminal-4207832566-r19 { fill: #dde6ed;font-weight: bold } + .terminal-4207832566-r20 { fill: #001541 } + .terminal-4207832566-r21 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create a GitHub repo - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - After creating the pipeline template locally, we can create a GitHub repository and push the - code to it. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Your GitHub usernameYour GitHub personal access token for Show - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔login.▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - mirpedrol▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁•••••••••••••••••••••••••••••••••••• - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Please select the the GitHub repository settings: - - - ▔▔▔▔▔▔▔▔Select if the new GitHub repo must be private. - - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔Select if you would like to push all the pipeline template files to your GitHub repo - and all the branches required to keep the pipeline up to date with new releases of nf-core - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Create GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create a GitHub repo + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + After creating the pipeline template locally, we can create a GitHub repository and push the + code to it. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Your GitHub usernameYour GitHub personal access token for Show + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔login.▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + mirpedrol▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁•••••••••••••••••••••••••••••••••••• + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Please select the the GitHub repository settings: + + + ▔▔▔▔▔▔▔▔Select if the new GitHub repo must be private. + + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔Select if you would like to push all the pipeline template files to your GitHub repo + and all the branches required to keep the pipeline up to date with new releases of nf-core + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Create GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -1673,250 +1673,250 @@ font-weight: 700; } - .terminal-1522437605-matrix { + .terminal-3944300660-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1522437605-title { + .terminal-3944300660-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1522437605-r1 { fill: #c5c8c6 } - .terminal-1522437605-r2 { fill: #e3e3e3 } - .terminal-1522437605-r3 { fill: #989898 } - .terminal-1522437605-r4 { fill: #e1e1e1 } - .terminal-1522437605-r5 { fill: #98a84b } - .terminal-1522437605-r6 { fill: #626262 } - .terminal-1522437605-r7 { fill: #608ab1 } - .terminal-1522437605-r8 { fill: #d0b344 } - .terminal-1522437605-r9 { fill: #121212 } - .terminal-1522437605-r10 { fill: #0053aa } - .terminal-1522437605-r11 { fill: #dde8f3;font-weight: bold } - .terminal-1522437605-r12 { fill: #7ae998 } - .terminal-1522437605-r13 { fill: #4ebf71;font-weight: bold } - .terminal-1522437605-r14 { fill: #008139 } - .terminal-1522437605-r15 { fill: #14191f } - .terminal-1522437605-r16 { fill: #ddedf9 } + .terminal-3944300660-r1 { fill: #c5c8c6 } + .terminal-3944300660-r2 { fill: #e3e3e3 } + .terminal-3944300660-r3 { fill: #989898 } + .terminal-3944300660-r4 { fill: #e1e1e1 } + .terminal-3944300660-r5 { fill: #98a84b } + .terminal-3944300660-r6 { fill: #626262 } + .terminal-3944300660-r7 { fill: #608ab1 } + .terminal-3944300660-r8 { fill: #d0b344 } + .terminal-3944300660-r9 { fill: #121212 } + .terminal-3944300660-r10 { fill: #0053aa } + .terminal-3944300660-r11 { fill: #dde8f3;font-weight: bold } + .terminal-3944300660-r12 { fill: #7ae998 } + .terminal-3944300660-r13 { fill: #4ebf71;font-weight: bold } + .terminal-3944300660-r14 { fill: #008139 } + .terminal-3944300660-r15 { fill: #14191f } + .terminal-3944300660-r16 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - nf-core create - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Visualising logging output. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close App - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - ▂▂ - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + nf-core create + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Visualising logging output. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close App + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + ▂▂ + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -1946,250 +1946,250 @@ font-weight: 700; } - .terminal-3351663353-matrix { + .terminal-139986312-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3351663353-title { + .terminal-139986312-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3351663353-r1 { fill: #c5c8c6 } - .terminal-3351663353-r2 { fill: #e3e3e3 } - .terminal-3351663353-r3 { fill: #989898 } - .terminal-3351663353-r4 { fill: #e1e1e1 } - .terminal-3351663353-r5 { fill: #98a84b } - .terminal-3351663353-r6 { fill: #626262 } - .terminal-3351663353-r7 { fill: #608ab1 } - .terminal-3351663353-r8 { fill: #d0b344 } - .terminal-3351663353-r9 { fill: #121212 } - .terminal-3351663353-r10 { fill: #0053aa } - .terminal-3351663353-r11 { fill: #dde8f3;font-weight: bold } - .terminal-3351663353-r12 { fill: #7ae998 } - .terminal-3351663353-r13 { fill: #4ebf71;font-weight: bold } - .terminal-3351663353-r14 { fill: #008139 } - .terminal-3351663353-r15 { fill: #14191f } - .terminal-3351663353-r16 { fill: #ddedf9 } + .terminal-139986312-r1 { fill: #c5c8c6 } + .terminal-139986312-r2 { fill: #e3e3e3 } + .terminal-139986312-r3 { fill: #989898 } + .terminal-139986312-r4 { fill: #e1e1e1 } + .terminal-139986312-r5 { fill: #98a84b } + .terminal-139986312-r6 { fill: #626262 } + .terminal-139986312-r7 { fill: #608ab1 } + .terminal-139986312-r8 { fill: #d0b344 } + .terminal-139986312-r9 { fill: #121212 } + .terminal-139986312-r10 { fill: #0053aa } + .terminal-139986312-r11 { fill: #dde8f3;font-weight: bold } + .terminal-139986312-r12 { fill: #7ae998 } + .terminal-139986312-r13 { fill: #4ebf71;font-weight: bold } + .terminal-139986312-r14 { fill: #008139 } + .terminal-139986312-r15 { fill: #14191f } + .terminal-139986312-r16 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - nf-core create - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Visualising logging output. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close logging screen - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - ▂▂ - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + nf-core create + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Visualising logging output. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close logging screen + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + ▂▂ + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -2219,249 +2219,249 @@ font-weight: 700; } - .terminal-3882061156-matrix { + .terminal-2624233686-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3882061156-title { + .terminal-2624233686-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3882061156-r1 { fill: #c5c8c6 } - .terminal-3882061156-r2 { fill: #e3e3e3 } - .terminal-3882061156-r3 { fill: #989898 } - .terminal-3882061156-r4 { fill: #1e1e1e } - .terminal-3882061156-r5 { fill: #e2e2e2 } - .terminal-3882061156-r6 { fill: #e1e1e1 } - .terminal-3882061156-r7 { fill: #808080 } - .terminal-3882061156-r8 { fill: #507bb3 } - .terminal-3882061156-r9 { fill: #dde6ed;font-weight: bold } - .terminal-3882061156-r10 { fill: #001541 } - .terminal-3882061156-r11 { fill: #7ae998 } - .terminal-3882061156-r12 { fill: #0a180e;font-weight: bold } - .terminal-3882061156-r13 { fill: #008139 } - .terminal-3882061156-r14 { fill: #dde8f3;font-weight: bold } - .terminal-3882061156-r15 { fill: #ddedf9 } + .terminal-2624233686-r1 { fill: #c5c8c6 } + .terminal-2624233686-r2 { fill: #e3e3e3 } + .terminal-2624233686-r3 { fill: #989898 } + .terminal-2624233686-r4 { fill: #1e1e1e } + .terminal-2624233686-r5 { fill: #e1e1e1 } + .terminal-2624233686-r6 { fill: #507bb3 } + .terminal-2624233686-r7 { fill: #e2e2e2 } + .terminal-2624233686-r8 { fill: #808080 } + .terminal-2624233686-r9 { fill: #dde6ed;font-weight: bold } + .terminal-2624233686-r10 { fill: #001541 } + .terminal-2624233686-r11 { fill: #7ae998 } + .terminal-2624233686-r12 { fill: #0a180e;font-weight: bold } + .terminal-2624233686-r13 { fill: #008139 } + .terminal-2624233686-r14 { fill: #dde8f3;font-weight: bold } + .terminal-2624233686-r15 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▔▔▔▔▔▔▔▔ - Use reference genomesThe pipeline will be ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁configured to use a Show help - copy of the most ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - common reference  - genome files from  - iGenomes - - ▔▔▔▔▔▔▔▔ - Add Github CI testsThe pipeline will ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁include several Show help - GitHub actions for ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Continuous  - Integration (CI)  - testing - - ▔▔▔▔▔▔▔▔ - Add Github badgesThe README.md file of▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁the pipeline will Show help - include GitHub badges▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔ - Add configuration The pipeline will ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁filesinclude configurationShow help - profiles containing ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - custom parameters  - requried to run  - nf-core pipelines at  - different  - institutions - - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Continue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference genomesThe pipeline will be Show help + ▁▁▁▁▁▁▁▁configured to use a copy ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + of the most common  + reference genome files  + from iGenomes + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github CI testsThe pipeline will includeShow help + ▁▁▁▁▁▁▁▁several GitHub actions ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + for Continuous  + Integration (CI) testing + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github badgesThe README.md file of theShow help + ▁▁▁▁▁▁▁▁pipeline will include ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + GitHub badges + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add configuration filesThe pipeline will includeShow help + ▁▁▁▁▁▁▁▁configuration profiles ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + containing custom  + parameters requried to  + run nf-core pipelines at  + different institutions + + + + + + + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Continue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  @@ -2491,249 +2491,249 @@ font-weight: 700; } - .terminal-339122229-matrix { + .terminal-1728001786-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-339122229-title { + .terminal-1728001786-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-339122229-r1 { fill: #c5c8c6 } - .terminal-339122229-r2 { fill: #e3e3e3 } - .terminal-339122229-r3 { fill: #989898 } - .terminal-339122229-r4 { fill: #1e1e1e } - .terminal-339122229-r5 { fill: #e2e2e2 } - .terminal-339122229-r6 { fill: #e1e1e1 } - .terminal-339122229-r7 { fill: #808080 } - .terminal-339122229-r8 { fill: #507bb3 } - .terminal-339122229-r9 { fill: #dde6ed;font-weight: bold } - .terminal-339122229-r10 { fill: #001541 } - .terminal-339122229-r11 { fill: #7ae998 } - .terminal-339122229-r12 { fill: #0a180e;font-weight: bold } - .terminal-339122229-r13 { fill: #008139 } - .terminal-339122229-r14 { fill: #dde8f3;font-weight: bold } - .terminal-339122229-r15 { fill: #ddedf9 } + .terminal-1728001786-r1 { fill: #c5c8c6 } + .terminal-1728001786-r2 { fill: #e3e3e3 } + .terminal-1728001786-r3 { fill: #989898 } + .terminal-1728001786-r4 { fill: #1e1e1e } + .terminal-1728001786-r5 { fill: #e1e1e1 } + .terminal-1728001786-r6 { fill: #507bb3 } + .terminal-1728001786-r7 { fill: #e2e2e2 } + .terminal-1728001786-r8 { fill: #808080 } + .terminal-1728001786-r9 { fill: #dde6ed;font-weight: bold } + .terminal-1728001786-r10 { fill: #001541 } + .terminal-1728001786-r11 { fill: #7ae998 } + .terminal-1728001786-r12 { fill: #0a180e;font-weight: bold } + .terminal-1728001786-r13 { fill: #008139 } + .terminal-1728001786-r14 { fill: #dde8f3;font-weight: bold } + .terminal-1728001786-r15 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▔▔▔▔▔▔▔▔ - Use reference genomesThe pipeline will be ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁configured to use a Show help - copy of the most ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - common reference  - genome files from  - iGenomes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Continue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference genomesThe pipeline will be Show help + ▁▁▁▁▁▁▁▁configured to use a copy ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + of the most common  + reference genome files  + from iGenomes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Continue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  @@ -2763,253 +2763,253 @@ font-weight: 700; } - .terminal-3185846603-matrix { + .terminal-2559761451-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3185846603-title { + .terminal-2559761451-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3185846603-r1 { fill: #c5c8c6 } - .terminal-3185846603-r2 { fill: #e3e3e3 } - .terminal-3185846603-r3 { fill: #989898 } - .terminal-3185846603-r4 { fill: #e1e1e1 } - .terminal-3185846603-r5 { fill: #121212 } - .terminal-3185846603-r6 { fill: #0053aa } - .terminal-3185846603-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3185846603-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-3185846603-r9 { fill: #1e1e1e } - .terminal-3185846603-r10 { fill: #0f4e2a } - .terminal-3185846603-r11 { fill: #7b3042 } - .terminal-3185846603-r12 { fill: #a7a7a7 } - .terminal-3185846603-r13 { fill: #787878 } - .terminal-3185846603-r14 { fill: #e2e2e2 } - .terminal-3185846603-r15 { fill: #b93c5b } - .terminal-3185846603-r16 { fill: #166d39 } - .terminal-3185846603-r17 { fill: #3c8b54;font-weight: bold } - .terminal-3185846603-r18 { fill: #5aa86f } - .terminal-3185846603-r19 { fill: #ddedf9 } + .terminal-2559761451-r1 { fill: #c5c8c6 } + .terminal-2559761451-r2 { fill: #e3e3e3 } + .terminal-2559761451-r3 { fill: #989898 } + .terminal-2559761451-r4 { fill: #e1e1e1 } + .terminal-2559761451-r5 { fill: #121212 } + .terminal-2559761451-r6 { fill: #0053aa } + .terminal-2559761451-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2559761451-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-2559761451-r9 { fill: #1e1e1e } + .terminal-2559761451-r10 { fill: #0f4e2a } + .terminal-2559761451-r11 { fill: #7b3042 } + .terminal-2559761451-r12 { fill: #a7a7a7 } + .terminal-2559761451-r13 { fill: #787878 } + .terminal-2559761451-r14 { fill: #e2e2e2 } + .terminal-2559761451-r15 { fill: #b93c5b } + .terminal-2559761451-r16 { fill: #166d39 } + .terminal-2559761451-r17 { fill: #3c8b54;font-weight: bold } + .terminal-2559761451-r18 { fill: #5aa86f } + .terminal-2559761451-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Must be lowercase without  - punctuation. - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Cannot be left empty. - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Cannot be left empty. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Next - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Must be lowercase without  + punctuation. + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Next + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -3039,144 +3039,145 @@ font-weight: 700; } - .terminal-1736361706-matrix { + .terminal-2319623653-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1736361706-title { + .terminal-2319623653-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1736361706-r1 { fill: #c5c8c6 } - .terminal-1736361706-r2 { fill: #e3e3e3 } - .terminal-1736361706-r3 { fill: #989898 } - .terminal-1736361706-r4 { fill: #e1e1e1 } - .terminal-1736361706-r5 { fill: #98a84b } - .terminal-1736361706-r6 { fill: #626262 } - .terminal-1736361706-r7 { fill: #608ab1 } - .terminal-1736361706-r8 { fill: #d0b344 } - .terminal-1736361706-r9 { fill: #121212 } - .terminal-1736361706-r10 { fill: #0053aa } - .terminal-1736361706-r11 { fill: #dde8f3;font-weight: bold } - .terminal-1736361706-r12 { fill: #e1e1e1;text-decoration: underline; } - .terminal-1736361706-r13 { fill: #14191f } - .terminal-1736361706-r14 { fill: #ddedf9 } + .terminal-2319623653-r1 { fill: #c5c8c6 } + .terminal-2319623653-r2 { fill: #e3e3e3 } + .terminal-2319623653-r3 { fill: #989898 } + .terminal-2319623653-r4 { fill: #1e1e1e } + .terminal-2319623653-r5 { fill: #e1e1e1 } + .terminal-2319623653-r6 { fill: #98a84b } + .terminal-2319623653-r7 { fill: #626262 } + .terminal-2319623653-r8 { fill: #608ab1 } + .terminal-2319623653-r9 { fill: #d0b344 } + .terminal-2319623653-r10 { fill: #121212 } + .terminal-2319623653-r11 { fill: #0053aa } + .terminal-2319623653-r12 { fill: #dde8f3;font-weight: bold } + .terminal-2319623653-r13 { fill: #e1e1e1;text-decoration: underline; } + .terminal-2319623653-r14 { fill: #14191f } + .terminal-2319623653-r15 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pip… - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - nf-core create - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - This app will help you create a new nf-core pipeline.It uses the  - nf-core pipeline template, which is keptwithin the nf-core/tools  - repository. - - Using this tool is mandatory when making a pipeline that maybe part  - of the nf-core community collection at some point.However, this tool  - can also be used to create pipelines that willnever be part of ▁▁ - nf-core. You can still benefit from the communitybest practices for  - your own workflow. - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pip… + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + nf-core create + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This app will help you create a new nf-core pipeline. It uses the  + nf-core pipeline template, which is kept within the nf-core/tools  + repository. + + Using this tool is mandatory when making a pipeline that may be part  + of the nf-core community collection at some point. However, this tool  + can also be used to create pipelines that will never be part of ▁▁ + nf-core. You can still benefit from the community best practices for  + your own workflow. + +  D  Toggle dark mode  Q  Quit  From bebf067648cdf2df743e031467a85228184939f7 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 5 Jan 2024 11:14:35 +0100 Subject: [PATCH 046/175] ask if we have to create a github repo in a different screen --- nf_core/pipelines/create/__init__.py | 8 ++++ nf_core/pipelines/create/githubexit.py | 40 +++++++++++++++++++ nf_core/pipelines/create/githubrepo.py | 24 +---------- .../pipelines/create/githubrepoquestion.py | 31 ++++++++++++++ 4 files changed, 81 insertions(+), 22 deletions(-) create mode 100644 nf_core/pipelines/create/githubexit.py create mode 100644 nf_core/pipelines/create/githubrepoquestion.py diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index af615a1f03..062b3ba85f 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -7,7 +7,9 @@ from nf_core.pipelines.create.basicdetails import BasicDetails from nf_core.pipelines.create.custompipeline import CustomPipeline from nf_core.pipelines.create.finaldetails import FinalDetails +from nf_core.pipelines.create.githubexit import GithubExit from nf_core.pipelines.create.githubrepo import GithubRepo +from nf_core.pipelines.create.githubrepoquestion import GithubRepoQuestion from nf_core.pipelines.create.nfcorepipeline import NfcorePipeline from nf_core.pipelines.create.pipelinetype import ChoosePipelineType from nf_core.pipelines.create.utils import ( @@ -43,7 +45,9 @@ class PipelineCreateApp(App[CreateConfig]): "type_custom": CustomPipeline(), "type_nfcore": NfcorePipeline(), "final_details": FinalDetails(), + "github_repo_question": GithubRepoQuestion(), "github_repo": GithubRepo(), + "github_exit": GithubExit(), } # Initialise config as empty @@ -73,7 +77,11 @@ def on_button_pressed(self, event: Button.Pressed) -> None: elif event.button.id == "continue": self.switch_screen("final_details") elif event.button.id == "close_screen": + self.switch_screen("github_repo_question") + elif event.button.id == "github_repo": self.switch_screen("github_repo") + elif event.button.id == "exit": + self.switch_screen("github_exit") if event.button.id == "close_app": self.exit(return_code=0) diff --git a/nf_core/pipelines/create/githubexit.py b/nf_core/pipelines/create/githubexit.py new file mode 100644 index 0000000000..04fc7cb0b4 --- /dev/null +++ b/nf_core/pipelines/create/githubexit.py @@ -0,0 +1,40 @@ +from textual.app import ComposeResult +from textual.containers import Center +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Markdown, Static + +exit_help_text_markdown = """ +If you would like to create the GitHub repository later, you can do it manually by following these steps: + +1. Create a new GitHub repository +2. Add the remote to your local repository +```bash +cd +git remote add origin git@github.com:/.git +``` +3. Push the code to the remote +```bash +git push --all origin +``` +""" + + +class GithubExit(Screen): + """A screen to show a help text when a GitHub repo is NOT created.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Static( + f"\n[green]{' ' * 40},--.[grey39]/[green],-." + + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + "\n[green] `._,._,'\n", + id="logo", + ) + yield Markdown(exit_help_text_markdown) + yield Center( + Button("Close App", id="close_app", variant="success"), + classes="cta", + ) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 2a98d84985..28f6521cfd 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -23,19 +23,6 @@ repo_config_markdown = """ Please select the the GitHub repository settings: """ -exit_help_text_markdown = """ -If you would like to create the GitHub repository later, you can do it manually by following these steps: -1. Create a new GitHub repository -2. Add the remote to your local repository -```bash -cd -git remote add origin git@github.com:/.git -``` -3. Push the code to the remote -```bash -git push --all origin -``` -""" class GithubRepo(Screen): @@ -112,7 +99,6 @@ def on_button_pressed(self, event: Button.Pressed) -> None: raise UserWarning( f"Could not authenticate to GitHub with user name '{github_variables['gh_username']}'." "Please provide an authentication token or set the environment variable 'GITHUB_AUTH_TOKEN'." - f"\n{exit_help_text_markdown}" ) user = github_auth.get_user() @@ -125,7 +111,6 @@ def on_button_pressed(self, event: Button.Pressed) -> None: raise UserWarning( f"Could not authenticate to GitHub with user name '{github_variables['gh_username']}'." "Please make sure that the provided user name and token are correct." - f"\n{exit_help_text_markdown}" ) # Check if organisation exists @@ -155,13 +140,8 @@ def on_button_pressed(self, event: Button.Pressed) -> None: ) log.info(f"GitHub repository '{self.parent.TEMPLATE_CONFIG.name}' created successfully") except UserWarning as e: - log.info(f"There was an error with message: {e}" f"\n{exit_help_text_markdown}") - - self.parent.LOGGING_STATE = "repo created" - self.parent.switch_screen(LoggingScreen()) - elif event.button.id == "exit": - # Show help message and exit - log.info(exit_help_text_markdown) + log.info(f"There was an error with message: {e}") + self.parent.switch_screen("github_exit") self.parent.LOGGING_STATE = "repo created" self.parent.switch_screen(LoggingScreen()) diff --git a/nf_core/pipelines/create/githubrepoquestion.py b/nf_core/pipelines/create/githubrepoquestion.py new file mode 100644 index 0000000000..ea32597101 --- /dev/null +++ b/nf_core/pipelines/create/githubrepoquestion.py @@ -0,0 +1,31 @@ +import logging +from textwrap import dedent + +from textual.app import ComposeResult +from textual.containers import Center +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Markdown + +log = logging.getLogger(__name__) + +github_text_markdown = """ +# Create a GitHub repo + +After creating the pipeline template locally, we can create a GitHub repository and push the code to it. + +Do you want to create a GitHub repository? +""" + + +class GithubRepoQuestion(Screen): + """Ask if the user wants to create a GitHub repository.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Markdown(dedent(github_text_markdown)) + yield Center( + Button("Create GitHub repo", id="github_repo", variant="success"), + Button("Finish without creating a repo", id="exit", variant="primary"), + classes="cta", + ) From 7ade926c426a1eb85eb53dba992dab2150640f9a Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 5 Jan 2024 11:22:14 +0100 Subject: [PATCH 047/175] add snapshot for github repo question and exit message --- tests/__snapshots__/test_create_app.ambr | 517 +++++++++++++++++------ tests/test_create_app.py | 42 +- 2 files changed, 432 insertions(+), 127 deletions(-) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index 3c5a1b91c1..b9673d488e 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1650,7 +1650,7 @@ ''' # --- -# name: test_logging_after_github +# name: test_github_exit_message ''' @@ -1673,250 +1673,521 @@ font-weight: 700; } - .terminal-3944300660-matrix { + .terminal-2007955284-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3944300660-title { + .terminal-2007955284-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3944300660-r1 { fill: #c5c8c6 } - .terminal-3944300660-r2 { fill: #e3e3e3 } - .terminal-3944300660-r3 { fill: #989898 } - .terminal-3944300660-r4 { fill: #e1e1e1 } - .terminal-3944300660-r5 { fill: #98a84b } - .terminal-3944300660-r6 { fill: #626262 } - .terminal-3944300660-r7 { fill: #608ab1 } - .terminal-3944300660-r8 { fill: #d0b344 } - .terminal-3944300660-r9 { fill: #121212 } - .terminal-3944300660-r10 { fill: #0053aa } - .terminal-3944300660-r11 { fill: #dde8f3;font-weight: bold } - .terminal-3944300660-r12 { fill: #7ae998 } - .terminal-3944300660-r13 { fill: #4ebf71;font-weight: bold } - .terminal-3944300660-r14 { fill: #008139 } - .terminal-3944300660-r15 { fill: #14191f } - .terminal-3944300660-r16 { fill: #ddedf9 } + .terminal-2007955284-r1 { fill: #c5c8c6 } + .terminal-2007955284-r2 { fill: #e3e3e3 } + .terminal-2007955284-r3 { fill: #989898 } + .terminal-2007955284-r4 { fill: #e1e1e1 } + .terminal-2007955284-r5 { fill: #98a84b } + .terminal-2007955284-r6 { fill: #626262 } + .terminal-2007955284-r7 { fill: #608ab1 } + .terminal-2007955284-r8 { fill: #d0b344 } + .terminal-2007955284-r9 { fill: #4ebf71;font-weight: bold } + .terminal-2007955284-r10 { fill: #d2d2d2 } + .terminal-2007955284-r11 { fill: #82aaff } + .terminal-2007955284-r12 { fill: #eeffff } + .terminal-2007955284-r13 { fill: #7ae998 } + .terminal-2007955284-r14 { fill: #008139 } + .terminal-2007955284-r15 { fill: #dde8f3;font-weight: bold } + .terminal-2007955284-r16 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - nf-core create - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Visualising logging output. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close App - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - ▂▂ - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + + If you would like to create the GitHub repository later, you can do it manually by following + these steps: + +  1. Create a new GitHub repository +  2. Add the remote to your local repository + + + cd<pipeline_directory> + gitremoteaddorigingit@github.com:<username>/<repo_name>.git + + +  3. Push the code to the remote + + + gitpush--allorigin + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close App + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_github_question + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create a GitHub repo + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + After creating the pipeline template locally, we can create a GitHub repository and push the + code to it. + + Do you want to create a GitHub repository? + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Create GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  diff --git a/tests/test_create_app.py b/tests/test_create_app.py index 8b22eabad6..a244c89839 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -216,9 +216,39 @@ async def run_before(pilot) -> None: assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) +@mock.patch("nf_core.pipelines.create.create.PipelineCreate.init_pipeline", return_value=None) +def test_github_question(mock_init_pipeline, snap_compare): + """Test snapshot for the github_repo_question screen. + Steps to get to this screen: + screen welcome > press start > + screen choose_type > press nf-core > + screen basic_details > enter pipeline details > press next > + screen type_nfcore > press continue > + screen final_details > press finish > + screen logging_screen > press close_screen > + screen github_repo_question + """ + + async def run_before(pilot) -> None: + await pilot.click("#start") + await pilot.click("#type_nfcore") + await pilot.click("#name") + await pilot.press("m", "y", "p", "i", "p", "e", "l", "i", "n", "e") + await pilot.press("tab") + await pilot.press("A", " ", "c", "o", "o", "l", " ", "d", "e", "s", "c", "r", "i", "p", "t", "i", "o", "n") + await pilot.press("tab") + await pilot.press("M", "e") + await pilot.click("#next") + await pilot.click("#continue") + await pilot.click("#finish") + await pilot.click("#close_screen") + + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) + + @mock.patch("nf_core.pipelines.create.create.PipelineCreate.init_pipeline", return_value=None) def test_github_details(mock_init_pipeline, snap_compare): - """Test snapshot for the final_details screen. + """Test snapshot for the github_repo screen. Steps to get to this screen: screen welcome > press start > screen choose_type > press nf-core > @@ -226,6 +256,7 @@ def test_github_details(mock_init_pipeline, snap_compare): screen type_nfcore > press continue > screen final_details > press finish > screen logging_screen > press close_screen > + screen github_repo_question > press create repo > screen github_repo """ @@ -242,13 +273,14 @@ async def run_before(pilot) -> None: await pilot.click("#continue") await pilot.click("#finish") await pilot.click("#close_screen") + await pilot.click("#github_repo") assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) @mock.patch("nf_core.pipelines.create.create.PipelineCreate.init_pipeline", return_value=None) -def test_logging_after_github(mock_init_pipeline, snap_compare): - """Test snapshot for the final_details screen. +def test_github_exit_message(mock_init_pipeline, snap_compare): + """Test snapshot for the github_exit screen. Steps to get to this screen: screen welcome > press start > screen choose_type > press nf-core > @@ -256,8 +288,9 @@ def test_logging_after_github(mock_init_pipeline, snap_compare): screen type_nfcore > press continue > screen final_details > press finish > screen logging_screen > press close_screen > + screen github_repo_question > press create repo > screen github_repo > press exit (close without creating a repo) > - screen logging_screen + screen github_exit """ async def run_before(pilot) -> None: @@ -273,6 +306,7 @@ async def run_before(pilot) -> None: await pilot.click("#continue") await pilot.click("#finish") await pilot.click("#close_screen") + await pilot.click("#github_repo") await pilot.click("#exit") assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) From 70492774383466fca6d3ac8592d58a7af310befb Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 5 Jan 2024 14:25:16 +0100 Subject: [PATCH 048/175] add work threads for creating a pipeline and a github repo --- nf_core/pipelines/create/finaldetails.py | 11 ++++++++--- nf_core/pipelines/create/githubrepo.py | 8 +++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 23be7db895..70b5fa8bbd 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -1,7 +1,7 @@ """A Textual app to create a pipeline.""" from textwrap import dedent -from textual import on +from textual import on, work from textual.app import ComposeResult from textual.containers import Center, Horizontal from textual.screen import Screen @@ -74,7 +74,12 @@ def on_button_pressed(self, event: Button.Pressed) -> None: pass # Create the new pipeline - create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) - create_obj.init_pipeline() + self.create_pipeline() self.parent.LOGGING_STATE = "pipeline created" self.parent.switch_screen(LoggingScreen()) + + @work(thread=True) + def create_pipeline(self) -> None: + """Create the pipeline.""" + create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) + create_obj.init_pipeline() diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 28f6521cfd..16465ab9b2 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -1,10 +1,12 @@ import logging import os +from pathlib import Path from textwrap import dedent import git import yaml from github import Github, GithubException, UnknownObjectException +from textual import work from textual.app import ComposeResult from textual.containers import Center, Horizontal from textual.screen import Screen @@ -90,7 +92,10 @@ def on_button_pressed(self, event: Button.Pressed) -> None: github_variables[switch_input.id] = switch_input.value # Pipeline git repo - pipeline_repo = git.Repo.init(self.parent.TEMPLATE_CONFIG.outdir) + pipeline_repo = git.Repo.init( + Path(self.parent.TEMPLATE_CONFIG.outdir) + / Path(self.parent.TEMPLATE_CONFIG.org + "-" + self.parent.TEMPLATE_CONFIG.name) + ) # GitHub authentication if github_variables["token"]: @@ -146,6 +151,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.parent.LOGGING_STATE = "repo created" self.parent.switch_screen(LoggingScreen()) + @work(thread=True) def _create_repo_and_push(self, org, pipeline_repo, private, push): """Create a GitHub repository and push all branches.""" # Check if repo already exists From 41fcc27878517cd65085d2b8adf99e0c9a9b83bf Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 5 Jan 2024 15:31:24 +0100 Subject: [PATCH 049/175] add loading screen when creating a pipeline --- nf_core/pipelines/create/finaldetails.py | 12 ++++++++++++ requirements.txt | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 70b5fa8bbd..9def58aed7 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -4,6 +4,7 @@ from textual import on, work from textual.app import ComposeResult from textual.containers import Center, Horizontal +from textual.message import Message from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch @@ -75,6 +76,16 @@ def on_button_pressed(self, event: Button.Pressed) -> None: # Create the new pipeline self.create_pipeline() + self.screen.loading = True + + class PipelineCreated(Message): + """Custom message to indicate that the pipeline has been created.""" + + pass + + @on(PipelineCreated) + def stop_loading(self) -> None: + self.screen.loading = False self.parent.LOGGING_STATE = "pipeline created" self.parent.switch_screen(LoggingScreen()) @@ -83,3 +94,4 @@ def create_pipeline(self) -> None: """Create the pipeline.""" create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) create_obj.init_pipeline() + self.post_message(self.PipelineCreated()) diff --git a/requirements.txt b/requirements.txt index e953aa84aa..d2fe535003 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,5 +19,5 @@ requests_cache rich-click>=1.6.1 rich>=13.3.1 tabulate -textual>=0.41.0 +textual>=0.47.1 pdiff From cfa0804e1010a924bc8ae71edbd7952194f64773 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 5 Jan 2024 15:49:46 +0100 Subject: [PATCH 050/175] show logging only at the end --- nf_core/pipelines/create/__init__.py | 7 +++---- nf_core/pipelines/create/finaldetails.py | 4 +--- nf_core/pipelines/create/githubexit.py | 1 + nf_core/pipelines/create/githubrepo.py | 4 +++- nf_core/pipelines/create/loggingscreen.py | 14 ++++---------- 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 062b3ba85f..9261b78f52 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -10,6 +10,7 @@ from nf_core.pipelines.create.githubexit import GithubExit from nf_core.pipelines.create.githubrepo import GithubRepo from nf_core.pipelines.create.githubrepoquestion import GithubRepoQuestion +from nf_core.pipelines.create.loggingscreen import LoggingScreen from nf_core.pipelines.create.nfcorepipeline import NfcorePipeline from nf_core.pipelines.create.pipelinetype import ChoosePipelineType from nf_core.pipelines.create.utils import ( @@ -58,8 +59,6 @@ class PipelineCreateApp(App[CreateConfig]): # Log handler LOG_HANDLER = log_handler - # Logging state - LOGGING_STATE = None def on_mount(self) -> None: self.push_screen("welcome") @@ -76,12 +75,12 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.switch_screen("basic_details") elif event.button.id == "continue": self.switch_screen("final_details") - elif event.button.id == "close_screen": - self.switch_screen("github_repo_question") elif event.button.id == "github_repo": self.switch_screen("github_repo") elif event.button.id == "exit": self.switch_screen("github_exit") + elif event.button.id == "show_logging": + self.switch_screen(LoggingScreen()) if event.button.id == "close_app": self.exit(return_code=0) diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 9def58aed7..98df05ef0e 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -9,7 +9,6 @@ from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch from nf_core.pipelines.create.create import PipelineCreate -from nf_core.pipelines.create.loggingscreen import LoggingScreen from nf_core.pipelines.create.utils import TextInput @@ -86,8 +85,7 @@ class PipelineCreated(Message): @on(PipelineCreated) def stop_loading(self) -> None: self.screen.loading = False - self.parent.LOGGING_STATE = "pipeline created" - self.parent.switch_screen(LoggingScreen()) + self.parent.switch_screen("github_repo_question") @work(thread=True) def create_pipeline(self) -> None: diff --git a/nf_core/pipelines/create/githubexit.py b/nf_core/pipelines/create/githubexit.py index 04fc7cb0b4..96178fbcdf 100644 --- a/nf_core/pipelines/create/githubexit.py +++ b/nf_core/pipelines/create/githubexit.py @@ -36,5 +36,6 @@ def compose(self) -> ComposeResult: yield Markdown(exit_help_text_markdown) yield Center( Button("Close App", id="close_app", variant="success"), + Button("Show Logging", id="show_logging", variant="primary"), classes="cta", ) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 16465ab9b2..0ef1b493b1 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -148,7 +148,6 @@ def on_button_pressed(self, event: Button.Pressed) -> None: log.info(f"There was an error with message: {e}") self.parent.switch_screen("github_exit") - self.parent.LOGGING_STATE = "repo created" self.parent.switch_screen(LoggingScreen()) @work(thread=True) @@ -164,6 +163,9 @@ def _create_repo_and_push(self, org, pipeline_repo, private, push): except GithubException: # Repo is empty repo_exists = True + except UserWarning: + # Repo already exists + self.parent.switch_screen(LoggingScreen()) except UnknownObjectException: # Repo doesn't exist repo_exists = False diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index 2a59e2bcc6..bed955e1bc 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -25,14 +25,8 @@ def compose(self) -> ComposeResult: id="logo", ) yield Markdown(markdown) - if self.parent.LOGGING_STATE == "repo created": - yield Center( - Button("Close App", id="close_app", variant="success"), - classes="cta", - ) - else: - yield Center( - Button("Close logging screen", id="close_screen", variant="success"), - classes="cta", - ) + yield Center( + Button("Close App", id="close_app", variant="success"), + classes="cta", + ) yield Center(self.parent.LOG_HANDLER.console, classes="cta") From a85f1dd0f561c53895ac4fe0011276ae6b880da3 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 5 Jan 2024 16:05:05 +0100 Subject: [PATCH 051/175] add loading screen for repo creation --- nf_core/pipelines/create/githubrepo.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 0ef1b493b1..005637abd0 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -6,9 +6,10 @@ import git import yaml from github import Github, GithubException, UnknownObjectException -from textual import work +from textual import on, work from textual.app import ComposeResult from textual.containers import Center, Horizontal +from textual.message import Message from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch @@ -135,6 +136,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self._create_repo_and_push( org, pipeline_repo, github_variables["private"], github_variables["push"] ) + self.screen.loading = True else: # Create the repo in the user's account log.info( @@ -143,12 +145,21 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self._create_repo_and_push( user, pipeline_repo, github_variables["private"], github_variables["push"] ) + self.screen.loading = True log.info(f"GitHub repository '{self.parent.TEMPLATE_CONFIG.name}' created successfully") except UserWarning as e: log.info(f"There was an error with message: {e}") self.parent.switch_screen("github_exit") - self.parent.switch_screen(LoggingScreen()) + class RepoCreated(Message): + """Custom message to indicate that the GitHub repo has been created.""" + + pass + + @on(RepoCreated) + def stop_loading(self) -> None: + self.screen.loading = False + self.parent.switch_screen(LoggingScreen()) @work(thread=True) def _create_repo_and_push(self, org, pipeline_repo, private, push): @@ -163,9 +174,11 @@ def _create_repo_and_push(self, org, pipeline_repo, private, push): except GithubException: # Repo is empty repo_exists = True - except UserWarning: + except UserWarning as e: # Repo already exists - self.parent.switch_screen(LoggingScreen()) + self.post_message(self.RepoCreated()) + log.info(e) + return except UnknownObjectException: # Repo doesn't exist repo_exists = False @@ -185,6 +198,8 @@ def _create_repo_and_push(self, org, pipeline_repo, private, push): if push: pipeline_repo.remotes.origin.push(all=True).raise_if_error() + self.post_message(self.RepoCreated()) + def _github_authentication(self, gh_username, gh_token): """Authenticate to GitHub""" log.debug(f"Authenticating GitHub as {gh_username}") From 456a4be22b7ad0a733725db3da7c78059ee6dca7 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 5 Jan 2024 16:12:19 +0100 Subject: [PATCH 052/175] update app snapshots --- tests/__snapshots__/test_create_app.ambr | 520 ++++++----------------- tests/test_create_app.py | 34 -- 2 files changed, 125 insertions(+), 429 deletions(-) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index b9673d488e..ceb7d82046 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1673,250 +1673,253 @@ font-weight: 700; } - .terminal-2007955284-matrix { + .terminal-1481614550-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2007955284-title { + .terminal-1481614550-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2007955284-r1 { fill: #c5c8c6 } - .terminal-2007955284-r2 { fill: #e3e3e3 } - .terminal-2007955284-r3 { fill: #989898 } - .terminal-2007955284-r4 { fill: #e1e1e1 } - .terminal-2007955284-r5 { fill: #98a84b } - .terminal-2007955284-r6 { fill: #626262 } - .terminal-2007955284-r7 { fill: #608ab1 } - .terminal-2007955284-r8 { fill: #d0b344 } - .terminal-2007955284-r9 { fill: #4ebf71;font-weight: bold } - .terminal-2007955284-r10 { fill: #d2d2d2 } - .terminal-2007955284-r11 { fill: #82aaff } - .terminal-2007955284-r12 { fill: #eeffff } - .terminal-2007955284-r13 { fill: #7ae998 } - .terminal-2007955284-r14 { fill: #008139 } - .terminal-2007955284-r15 { fill: #dde8f3;font-weight: bold } - .terminal-2007955284-r16 { fill: #ddedf9 } + .terminal-1481614550-r1 { fill: #c5c8c6 } + .terminal-1481614550-r2 { fill: #e3e3e3 } + .terminal-1481614550-r3 { fill: #989898 } + .terminal-1481614550-r4 { fill: #e1e1e1 } + .terminal-1481614550-r5 { fill: #98a84b } + .terminal-1481614550-r6 { fill: #626262 } + .terminal-1481614550-r7 { fill: #608ab1 } + .terminal-1481614550-r8 { fill: #d0b344 } + .terminal-1481614550-r9 { fill: #4ebf71;font-weight: bold } + .terminal-1481614550-r10 { fill: #d2d2d2 } + .terminal-1481614550-r11 { fill: #82aaff } + .terminal-1481614550-r12 { fill: #eeffff } + .terminal-1481614550-r13 { fill: #7ae998 } + .terminal-1481614550-r14 { fill: #507bb3 } + .terminal-1481614550-r15 { fill: #dde6ed;font-weight: bold } + .terminal-1481614550-r16 { fill: #008139 } + .terminal-1481614550-r17 { fill: #001541 } + .terminal-1481614550-r18 { fill: #dde8f3;font-weight: bold } + .terminal-1481614550-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - - If you would like to create the GitHub repository later, you can do it manually by following - these steps: - -  1. Create a new GitHub repository -  2. Add the remote to your local repository - - - cd<pipeline_directory> - gitremoteaddorigingit@github.com:<username>/<repo_name>.git - - -  3. Push the code to the remote - - - gitpush--allorigin - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close App - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + + If you would like to create the GitHub repository later, you can do it manually by following + these steps: + +  1. Create a new GitHub repository +  2. Add the remote to your local repository + + + cd<pipeline_directory> + gitremoteaddorigingit@github.com:<username>/<repo_name>.git + + +  3. Push the code to the remote + + + gitpush--allorigin + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close AppShow Logging + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -2194,279 +2197,6 @@ ''' # --- -# name: test_logging_pipeline_created - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - nf-core create - - - - - - - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - nf-core create - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Visualising logging output. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close logging screen - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - ▂▂ - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  - - - - - ''' -# --- # name: test_type_custom ''' diff --git a/tests/test_create_app.py b/tests/test_create_app.py index a244c89839..d226ea2da8 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -188,34 +188,6 @@ async def run_before(pilot) -> None: assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) -@mock.patch("nf_core.pipelines.create.create.PipelineCreate.init_pipeline", return_value=None) -def test_logging_pipeline_created(mock_init_pipeline, snap_compare): - """Test snapshot for the final_details screen. - Steps to get to this screen: - screen welcome > press start > - screen choose_type > press nf-core > - screen basic_details > enter pipeline details > press next > - screen type_nfcore > press continue > - screen final_details > press finish > - screen logging_screen - """ - - async def run_before(pilot) -> None: - await pilot.click("#start") - await pilot.click("#type_nfcore") - await pilot.click("#name") - await pilot.press("m", "y", "p", "i", "p", "e", "l", "i", "n", "e") - await pilot.press("tab") - await pilot.press("A", " ", "c", "o", "o", "l", " ", "d", "e", "s", "c", "r", "i", "p", "t", "i", "o", "n") - await pilot.press("tab") - await pilot.press("M", "e") - await pilot.click("#next") - await pilot.click("#continue") - await pilot.click("#finish") - - assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) - - @mock.patch("nf_core.pipelines.create.create.PipelineCreate.init_pipeline", return_value=None) def test_github_question(mock_init_pipeline, snap_compare): """Test snapshot for the github_repo_question screen. @@ -225,7 +197,6 @@ def test_github_question(mock_init_pipeline, snap_compare): screen basic_details > enter pipeline details > press next > screen type_nfcore > press continue > screen final_details > press finish > - screen logging_screen > press close_screen > screen github_repo_question """ @@ -241,7 +212,6 @@ async def run_before(pilot) -> None: await pilot.click("#next") await pilot.click("#continue") await pilot.click("#finish") - await pilot.click("#close_screen") assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) @@ -255,7 +225,6 @@ def test_github_details(mock_init_pipeline, snap_compare): screen basic_details > enter pipeline details > press next > screen type_nfcore > press continue > screen final_details > press finish > - screen logging_screen > press close_screen > screen github_repo_question > press create repo > screen github_repo """ @@ -272,7 +241,6 @@ async def run_before(pilot) -> None: await pilot.click("#next") await pilot.click("#continue") await pilot.click("#finish") - await pilot.click("#close_screen") await pilot.click("#github_repo") assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) @@ -287,7 +255,6 @@ def test_github_exit_message(mock_init_pipeline, snap_compare): screen basic_details > enter pipeline details > press next > screen type_nfcore > press continue > screen final_details > press finish > - screen logging_screen > press close_screen > screen github_repo_question > press create repo > screen github_repo > press exit (close without creating a repo) > screen github_exit @@ -305,7 +272,6 @@ async def run_before(pilot) -> None: await pilot.click("#next") await pilot.click("#continue") await pilot.click("#finish") - await pilot.click("#close_screen") await pilot.click("#github_repo") await pilot.click("#exit") From bb6cc970c43a83d0551c0d3bedfe3daef2c29353 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 8 Jan 2024 09:48:06 +0100 Subject: [PATCH 053/175] fix typing error --- nf_core/pipelines/create/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 7842888f05..afb5617418 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -1,7 +1,7 @@ import re from logging import LogRecord from pathlib import Path -from typing import Optional +from typing import Optional, Union from pydantic import BaseModel, ConfigDict, ValidationError, field_validator from rich.logging import RichHandler @@ -95,7 +95,7 @@ def compose(self) -> ComposeResult: @on(Input.Changed) @on(Input.Submitted) - def show_invalid_reasons(self, event: Input.Changed | Input.Submitted) -> None: + def show_invalid_reasons(self, event: Union[Input.Changed, Input.Submitted]) -> None: """Validate the text input and show errors if invalid.""" if not event.validation_result.is_valid: self.query_one(".validation_msg").update("\n".join(event.validation_result.failure_descriptions)) From abdffef1ceb21eb6492a7ec6bae2da8921092b80 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 8 Jan 2024 09:58:02 +0100 Subject: [PATCH 054/175] ignroe snapshot files with editorconfig --- .editorconfig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.editorconfig b/.editorconfig index 014c2383bd..c608112063 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,3 +10,11 @@ indent_style = space [*.{md,yml,yaml,html,css,scss,js,cff}] indent_size = 2 + +[tests/__snapshots__/*] +charset = unset +end_of_line = unset +insert_final_newline = unset +trim_trailing_whitespace = unset +indent_style = unset +indent_size = unset From 2e396d9569553fb349a6d5ee9106a802481345d3 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 8 Jan 2024 13:12:29 +0100 Subject: [PATCH 055/175] add exclusive=True to work threads --- nf_core/pipelines/create/create.tcss | 2 ++ nf_core/pipelines/create/finaldetails.py | 6 +++--- nf_core/pipelines/create/githubrepo.py | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index df37e50ed8..bb3690d815 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -94,3 +94,5 @@ HorizontalScroll { .displayed #hide_password { display: block; } + + diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 98df05ef0e..2fa25bec0b 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -74,7 +74,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: pass # Create the new pipeline - self.create_pipeline() + self._create_pipeline() self.screen.loading = True class PipelineCreated(Message): @@ -87,8 +87,8 @@ def stop_loading(self) -> None: self.screen.loading = False self.parent.switch_screen("github_repo_question") - @work(thread=True) - def create_pipeline(self) -> None: + @work(thread=True, exclusive=True) + def _create_pipeline(self) -> None: """Create the pipeline.""" create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) create_obj.init_pipeline() diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 005637abd0..f614d7d274 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -161,7 +161,7 @@ def stop_loading(self) -> None: self.screen.loading = False self.parent.switch_screen(LoggingScreen()) - @work(thread=True) + @work(thread=True, exclusive=True) def _create_repo_and_push(self, org, pipeline_repo, private, push): """Create a GitHub repository and push all branches.""" # Check if repo already exists From 33294113722c1d7c245030e89ca5046e1a370235 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 8 Jan 2024 14:05:21 +0100 Subject: [PATCH 056/175] remove logging and add completed screen instead --- nf_core/pipelines/create/__init__.py | 24 +- nf_core/pipelines/create/completed.py | 40 +++ nf_core/pipelines/create/githubexit.py | 1 - nf_core/pipelines/create/githubrepo.py | 3 +- .../pipelines/create/githubrepoquestion.py | 3 - nf_core/pipelines/create/loggingscreen.py | 32 --- nf_core/pipelines/create/utils.py | 27 +- tests/__snapshots__/test_create_app.ambr | 247 +++++++++--------- 8 files changed, 167 insertions(+), 210 deletions(-) create mode 100644 nf_core/pipelines/create/completed.py delete mode 100644 nf_core/pipelines/create/loggingscreen.py diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 9261b78f52..f7b76ebae5 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -1,33 +1,19 @@ """A Textual app to create a pipeline.""" -import logging - from textual.app import App from textual.widgets import Button from nf_core.pipelines.create.basicdetails import BasicDetails +from nf_core.pipelines.create.completed import Completed from nf_core.pipelines.create.custompipeline import CustomPipeline from nf_core.pipelines.create.finaldetails import FinalDetails from nf_core.pipelines.create.githubexit import GithubExit from nf_core.pipelines.create.githubrepo import GithubRepo from nf_core.pipelines.create.githubrepoquestion import GithubRepoQuestion -from nf_core.pipelines.create.loggingscreen import LoggingScreen from nf_core.pipelines.create.nfcorepipeline import NfcorePipeline from nf_core.pipelines.create.pipelinetype import ChoosePipelineType -from nf_core.pipelines.create.utils import ( - CreateConfig, - CustomLogHandler, - LoggingConsole, -) +from nf_core.pipelines.create.utils import CreateConfig from nf_core.pipelines.create.welcome import WelcomeScreen -log_handler = CustomLogHandler(console=LoggingConsole(), rich_tracebacks=True) -logging.basicConfig( - level="INFO", - handlers=[log_handler], - format="%(message)s", -) -log_handler.setLevel("INFO") - class PipelineCreateApp(App[CreateConfig]): """A Textual app to manage stopwatches.""" @@ -49,6 +35,7 @@ class PipelineCreateApp(App[CreateConfig]): "github_repo_question": GithubRepoQuestion(), "github_repo": GithubRepo(), "github_exit": GithubExit(), + "completed_screen": Completed(), } # Initialise config as empty @@ -57,9 +44,6 @@ class PipelineCreateApp(App[CreateConfig]): # Initialise pipeline type PIPELINE_TYPE = None - # Log handler - LOG_HANDLER = log_handler - def on_mount(self) -> None: self.push_screen("welcome") @@ -79,8 +63,6 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.switch_screen("github_repo") elif event.button.id == "exit": self.switch_screen("github_exit") - elif event.button.id == "show_logging": - self.switch_screen(LoggingScreen()) if event.button.id == "close_app": self.exit(return_code=0) diff --git a/nf_core/pipelines/create/completed.py b/nf_core/pipelines/create/completed.py new file mode 100644 index 0000000000..282dd76882 --- /dev/null +++ b/nf_core/pipelines/create/completed.py @@ -0,0 +1,40 @@ +from textwrap import dedent + +from textual.app import ComposeResult +from textual.containers import Center +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Markdown, Static + + +class Completed(Screen): + """A screen to show the final text and exit the app.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Static( + f"\n[green]{' ' * 40},--.[grey39]/[green],-." + + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + "\n[green] `._,._,'\n", + id="logo", + ) + + completed_text_markdown = f""" + - A pipeline has been created at '`{self.parent.TEMPLATE_CONFIG.outdir + "/" + self.parent.TEMPLATE_CONFIG.org + "-" + self.parent.TEMPLATE_CONFIG.name}`'. + - A GitHub repository '`{self.parent.TEMPLATE_CONFIG.name}`' has been created in the {"user's" if self.parent.TEMPLATE_CONFIG.org == "nf-core" else ""} GitHub organisation account{ " `" + self.parent.TEMPLATE_CONFIG.org + "`" if self.parent.TEMPLATE_CONFIG.org != "nf-core" else ""}. + + !!!!!! IMPORTANT !!!!!! + + If you are interested in adding your pipeline to the nf-core community, + PLEASE COME AND TALK TO US IN THE NF-CORE SLACK BEFORE WRITING ANY CODE! + + - Please read: [https://nf-co.re/developers/adding_pipelines#join-the-community](https://nf-co.re/developers/adding_pipelines#join-the-community) + """ + + yield Markdown(dedent(completed_text_markdown)) + yield Center( + Button("Close App", id="close_app", variant="success"), + classes="cta", + ) diff --git a/nf_core/pipelines/create/githubexit.py b/nf_core/pipelines/create/githubexit.py index 96178fbcdf..04fc7cb0b4 100644 --- a/nf_core/pipelines/create/githubexit.py +++ b/nf_core/pipelines/create/githubexit.py @@ -36,6 +36,5 @@ def compose(self) -> ComposeResult: yield Markdown(exit_help_text_markdown) yield Center( Button("Close App", id="close_app", variant="success"), - Button("Show Logging", id="show_logging", variant="primary"), classes="cta", ) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index f614d7d274..74e96a7425 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -13,7 +13,6 @@ from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch -from nf_core.pipelines.create.loggingscreen import LoggingScreen from nf_core.pipelines.create.utils import TextInput log = logging.getLogger(__name__) @@ -159,7 +158,7 @@ class RepoCreated(Message): @on(RepoCreated) def stop_loading(self) -> None: self.screen.loading = False - self.parent.switch_screen(LoggingScreen()) + self.parent.switch_screen("completed_screen") @work(thread=True, exclusive=True) def _create_repo_and_push(self, org, pipeline_repo, private, push): diff --git a/nf_core/pipelines/create/githubrepoquestion.py b/nf_core/pipelines/create/githubrepoquestion.py index ea32597101..72c5c4a81a 100644 --- a/nf_core/pipelines/create/githubrepoquestion.py +++ b/nf_core/pipelines/create/githubrepoquestion.py @@ -1,4 +1,3 @@ -import logging from textwrap import dedent from textual.app import ComposeResult @@ -6,8 +5,6 @@ from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown -log = logging.getLogger(__name__) - github_text_markdown = """ # Create a GitHub repo diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py deleted file mode 100644 index bed955e1bc..0000000000 --- a/nf_core/pipelines/create/loggingscreen.py +++ /dev/null @@ -1,32 +0,0 @@ -from textual.app import ComposeResult -from textual.containers import Center -from textual.screen import Screen -from textual.widgets import Button, Footer, Header, Markdown, Static - -markdown = """ -# nf-core create - -Visualising logging output. -""" - - -class LoggingScreen(Screen): - """A screen to show the final logs.""" - - def compose(self) -> ComposeResult: - yield Header() - yield Footer() - yield Static( - f"\n[green]{' ' * 40},--.[grey39]/[green],-." - + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + "\n[green] `._,._,'\n", - id="logo", - ) - yield Markdown(markdown) - yield Center( - Button("Close App", id="close_app", variant="success"), - classes="cta", - ) - yield Center(self.parent.LOG_HANDLER.console, classes="cta") diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index afb5617418..5c3b995b12 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -1,17 +1,13 @@ import re -from logging import LogRecord from pathlib import Path from typing import Optional, Union from pydantic import BaseModel, ConfigDict, ValidationError, field_validator -from rich.logging import RichHandler from textual import on -from textual._context import active_app from textual.app import ComposeResult from textual.containers import HorizontalScroll from textual.validation import ValidationResult, Validator -from textual.widget import Widget -from textual.widgets import Button, Input, Markdown, RichLog, Static, Switch +from textual.widgets import Button, Input, Markdown, Static, Switch class CreateConfig(BaseModel): @@ -172,27 +168,6 @@ def compose(self) -> ComposeResult: yield HelpText(markdown=self.markdown, classes="help_box") -class LoggingConsole(RichLog): - file = False - console: Widget - - def print(self, content): - self.write(content) - - -class CustomLogHandler(RichHandler): - """A Logging handler which extends RichHandler to write to a Widget and handle a Textual App.""" - - def emit(self, record: LogRecord) -> None: - """Invoked by logging.""" - try: - _app = active_app.get() - except LookupError: - pass - else: - super().emit(record) - - ## Markdown text to reuse in different screens markdown_genomes = """ Nf-core pipelines are configured to use a copy of the most common reference genome files. diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index ceb7d82046..98bed6fc77 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1673,253 +1673,250 @@ font-weight: 700; } - .terminal-1481614550-matrix { + .terminal-2007955284-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1481614550-title { + .terminal-2007955284-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1481614550-r1 { fill: #c5c8c6 } - .terminal-1481614550-r2 { fill: #e3e3e3 } - .terminal-1481614550-r3 { fill: #989898 } - .terminal-1481614550-r4 { fill: #e1e1e1 } - .terminal-1481614550-r5 { fill: #98a84b } - .terminal-1481614550-r6 { fill: #626262 } - .terminal-1481614550-r7 { fill: #608ab1 } - .terminal-1481614550-r8 { fill: #d0b344 } - .terminal-1481614550-r9 { fill: #4ebf71;font-weight: bold } - .terminal-1481614550-r10 { fill: #d2d2d2 } - .terminal-1481614550-r11 { fill: #82aaff } - .terminal-1481614550-r12 { fill: #eeffff } - .terminal-1481614550-r13 { fill: #7ae998 } - .terminal-1481614550-r14 { fill: #507bb3 } - .terminal-1481614550-r15 { fill: #dde6ed;font-weight: bold } - .terminal-1481614550-r16 { fill: #008139 } - .terminal-1481614550-r17 { fill: #001541 } - .terminal-1481614550-r18 { fill: #dde8f3;font-weight: bold } - .terminal-1481614550-r19 { fill: #ddedf9 } + .terminal-2007955284-r1 { fill: #c5c8c6 } + .terminal-2007955284-r2 { fill: #e3e3e3 } + .terminal-2007955284-r3 { fill: #989898 } + .terminal-2007955284-r4 { fill: #e1e1e1 } + .terminal-2007955284-r5 { fill: #98a84b } + .terminal-2007955284-r6 { fill: #626262 } + .terminal-2007955284-r7 { fill: #608ab1 } + .terminal-2007955284-r8 { fill: #d0b344 } + .terminal-2007955284-r9 { fill: #4ebf71;font-weight: bold } + .terminal-2007955284-r10 { fill: #d2d2d2 } + .terminal-2007955284-r11 { fill: #82aaff } + .terminal-2007955284-r12 { fill: #eeffff } + .terminal-2007955284-r13 { fill: #7ae998 } + .terminal-2007955284-r14 { fill: #008139 } + .terminal-2007955284-r15 { fill: #dde8f3;font-weight: bold } + .terminal-2007955284-r16 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - - If you would like to create the GitHub repository later, you can do it manually by following - these steps: - -  1. Create a new GitHub repository -  2. Add the remote to your local repository - - - cd<pipeline_directory> - gitremoteaddorigingit@github.com:<username>/<repo_name>.git - - -  3. Push the code to the remote - - - gitpush--allorigin - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close AppShow Logging - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + + If you would like to create the GitHub repository later, you can do it manually by following + these steps: + +  1. Create a new GitHub repository +  2. Add the remote to your local repository + + + cd<pipeline_directory> + gitremoteaddorigingit@github.com:<username>/<repo_name>.git + + +  3. Push the code to the remote + + + gitpush--allorigin + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close App + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  From cbce046a32f6a4c69de508f0ad42e2372672c386 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 8 Jan 2024 15:24:06 +0100 Subject: [PATCH 057/175] show an error message if the pipeline already exists --- nf_core/pipelines/create/__init__.py | 2 ++ nf_core/pipelines/create/create.py | 3 +-- nf_core/pipelines/create/error.py | 33 ++++++++++++++++++++++++ nf_core/pipelines/create/finaldetails.py | 18 +++++++++++-- 4 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 nf_core/pipelines/create/error.py diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index f7b76ebae5..2f5b7b0434 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -5,6 +5,7 @@ from nf_core.pipelines.create.basicdetails import BasicDetails from nf_core.pipelines.create.completed import Completed from nf_core.pipelines.create.custompipeline import CustomPipeline +from nf_core.pipelines.create.error import ExistError from nf_core.pipelines.create.finaldetails import FinalDetails from nf_core.pipelines.create.githubexit import GithubExit from nf_core.pipelines.create.githubrepo import GithubRepo @@ -36,6 +37,7 @@ class PipelineCreateApp(App[CreateConfig]): "github_repo": GithubRepo(), "github_exit": GithubExit(), "completed_screen": Completed(), + "error_screen": ExistError(), } # Initialise config as empty diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index 51c115e2c6..e9761bcc4a 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -7,7 +7,6 @@ import random import re import shutil -import sys import time from pathlib import Path from typing import Optional, Union @@ -279,7 +278,7 @@ def render_template(self): else: log.error(f"Output directory '{self.outdir}' exists!") log.info("Use -f / --force to overwrite existing files") - sys.exit(1) + raise UserWarning(f"Output directory '{self.outdir}' exists!") os.makedirs(self.outdir) # Run jinja2 for each file in the template folder diff --git a/nf_core/pipelines/create/error.py b/nf_core/pipelines/create/error.py new file mode 100644 index 0000000000..a1d94e62f4 --- /dev/null +++ b/nf_core/pipelines/create/error.py @@ -0,0 +1,33 @@ +from textwrap import dedent + +from textual.app import ComposeResult +from textual.containers import Center +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Markdown, Static + + +class ExistError(Screen): + """A screen to show the final text and exit the app - when an error ocurred.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Static( + f"\n[green]{' ' * 40},--.[grey39]/[green],-." + + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + "\n[green] `._,._,'\n", + id="logo", + ) + + completed_text_markdown = f""" + A pipeline '`{self.parent.TEMPLATE_CONFIG.outdir + "/" + self.parent.TEMPLATE_CONFIG.org + "-" + self.parent.TEMPLATE_CONFIG.name}`' already exists. + Please select a different name or `force` the creation of the pipeline to override the existing one. + """ + + yield Markdown(dedent(completed_text_markdown)) + yield Center( + Button("Close App", id="close_app", variant="success"), + classes="cta", + ) diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 2fa25bec0b..4e16be0970 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -82,14 +82,28 @@ class PipelineCreated(Message): pass + class PipelineExists(Message): + """Custom message to indicate that the pipeline already exists.""" + + pass + @on(PipelineCreated) def stop_loading(self) -> None: self.screen.loading = False self.parent.switch_screen("github_repo_question") + @on(PipelineExists) + def stop_loading_error(self) -> None: + self.screen.loading = False + self.parent.switch_screen("error_screen") + @work(thread=True, exclusive=True) def _create_pipeline(self) -> None: """Create the pipeline.""" create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) - create_obj.init_pipeline() - self.post_message(self.PipelineCreated()) + try: + create_obj.init_pipeline() + except UserWarning: + self.post_message(self.PipelineExists()) + else: + self.post_message(self.PipelineCreated()) From 62c4b3ec6df0d0e4d3d8613864fc58852181ed48 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 8 Jan 2024 15:29:25 +0100 Subject: [PATCH 058/175] fix nf-core.pipelines.create import --- tests/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index 89c1328818..9a0fd0896f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -9,8 +9,8 @@ import responses -import nf_core.create import nf_core.modules +import nf_core.pipelines.create.create OLD_TRIMGALORE_SHA = "9b7a3bdefeaad5d42324aa7dd50f87bea1b04386" OLD_TRIMGALORE_BRANCH = "mimic-old-trimgalore" @@ -102,8 +102,8 @@ def create_tmp_pipeline() -> Tuple[str, str, str, str]: pipeline_name = "mypipeline" pipeline_dir = os.path.join(tmp_dir, pipeline_name) - nf_core.create.PipelineCreate( - pipeline_name, "it is mine", "me", no_git=True, outdir=pipeline_dir, plain=True + nf_core.pipelines.create.create.PipelineCreate( + pipeline_name, "it is mine", "me", no_git=True, outdir=pipeline_dir ).init_pipeline() # return values to instance variables for later use in test methods From f04ad5ea2a0526e5ab66d516bdeb62a371284088 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 8 Jan 2024 15:44:46 +0100 Subject: [PATCH 059/175] GHA use new nf-core pipelines create command and fixed default org --- .github/workflows/create-lint-wf.yml | 2 +- .github/workflows/create-test-lint-wf-template.yml | 2 +- .github/workflows/create-test-wf.yml | 2 +- nf_core/__main__.py | 5 +++-- nf_core/pipelines/create/create.py | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index 0119efcd41..ed1b0c4c69 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -59,7 +59,7 @@ jobs: run: | mkdir create-lint-wf && cd create-lint-wf export NXF_WORK=$(pwd) - nf-core --log-file log.txt create -n testpipeline -d "This pipeline is for testing" -a "Testing McTestface" --plain + nf-core --log-file log.txt pipelines create -n testpipeline -d "This pipeline is for testing" -a "Testing McTestface" # Try syncing it before we change anything - name: nf-core sync diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index 3805c1a240..758291be30 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -91,7 +91,7 @@ jobs: - name: create a pipeline from the template ${{ matrix.TEMPLATE }} run: | cd create-test-lint-wf - nf-core --log-file log.txt create -n testpipeline -d "This pipeline is for testing" -a "Testing McTestface" --template-yaml ${{ matrix.TEMPLATE }} + nf-core --log-file log.txt pipelines create -n testpipeline -d "This pipeline is for testing" -a "Testing McTestface" --template-yaml ${{ matrix.TEMPLATE }} - name: run the pipeline run: | diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index e128e16a36..0d03decd1b 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -54,7 +54,7 @@ jobs: run: | mkdir create-test-wf && cd create-test-wf export NXF_WORK=$(pwd) - nf-core --log-file log.txt create -n testpipeline -d "This pipeline is for testing" -a "Testing McTestface" --plain + nf-core --log-file log.txt pipelines create -n testpipeline -d "This pipeline is for testing" -a "Testing McTestface" nextflow run nf-core-testpipeline -profile test,self_hosted_runner --outdir ./results - name: Upload log file artifact diff --git a/nf_core/__main__.py b/nf_core/__main__.py index dfe1616eaa..013a7eb338 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -470,14 +470,15 @@ def pipelines(ctx): ) @click.option("-d", "--description", type=str, help="A short description of your pipeline") @click.option("-a", "--author", type=str, help="Name of the main author(s)") -@click.option("--version", type=str, help="The initial version number to use") +@click.option("--version", type=str, default="v1.0.0dev", help="The initial version number to use") @click.option("-f", "--force", is_flag=True, default=False, help="Overwrite output directory if it already exists") @click.option("-o", "--outdir", help="Output directory for new pipeline (default: pipeline name)") @click.option("-t", "--template-yaml", help="Pass a YAML file to customize the template") @click.option( "--organisation", type=str, - help="The name of the GitHub organisation where the pipeline will be hosted (default: nf-core", + default="nf-core", + help="The name of the GitHub organisation where the pipeline will be hosted (default: nf-core)", ) def create_pipeline(ctx, name, description, author, version, force, outdir, template_yaml, organisation): """ diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index e9761bcc4a..e5efe94515 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -49,7 +49,7 @@ def __init__( name: Optional[str] = None, description: Optional[str] = None, author: Optional[str] = None, - version: str = "1.0dev", + version: str = "1.0.0dev", no_git: bool = False, force: bool = False, outdir: Optional[str] = None, From baa3412c3d53099f3357a72824b1e39a552b1ae3 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 8 Jan 2024 16:37:28 +0100 Subject: [PATCH 060/175] fix pytests --- nf_core/__main__.py | 4 ++-- nf_core/pipelines/create/create.py | 2 +- tests/lint/multiqc_config.py | 5 +++-- tests/test_cli.py | 6 +++--- tests/test_modules.py | 10 +++------- tests/test_subworkflows.py | 9 ++------- 6 files changed, 14 insertions(+), 22 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 013a7eb338..7089cb3a45 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -470,7 +470,7 @@ def pipelines(ctx): ) @click.option("-d", "--description", type=str, help="A short description of your pipeline") @click.option("-a", "--author", type=str, help="Name of the main author(s)") -@click.option("--version", type=str, default="v1.0.0dev", help="The initial version number to use") +@click.option("--version", type=str, default="1.0dev", help="The initial version number to use") @click.option("-f", "--force", is_flag=True, default=False, help="Overwrite output directory if it already exists") @click.option("-o", "--outdir", help="Output directory for new pipeline (default: pipeline name)") @click.option("-t", "--template-yaml", help="Pass a YAML file to customize the template") @@ -508,7 +508,7 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp except UserWarning as e: log.error(e) sys.exit(1) - elif name or description or author or version or force or outdir or organisation: + elif name or description or author or version != "1.0dev" or force or outdir or organisation != "nf-core": log.error( "Command arguments are not accepted in interactive mode.\n" "Run with all command line arguments to avoid using an interactive interface" diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index e5efe94515..e9761bcc4a 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -49,7 +49,7 @@ def __init__( name: Optional[str] = None, description: Optional[str] = None, author: Optional[str] = None, - version: str = "1.0.0dev", + version: str = "1.0dev", no_git: bool = False, force: bool = False, outdir: Optional[str] = None, diff --git a/tests/lint/multiqc_config.py b/tests/lint/multiqc_config.py index 721560ce81..84eba15940 100644 --- a/tests/lint/multiqc_config.py +++ b/tests/lint/multiqc_config.py @@ -48,7 +48,7 @@ def test_multiqc_incorrect_export_plots(self): # Reset the file with open(Path(new_pipeline, "assets", "multiqc_config.yml"), "w") as fh: yaml.safe_dump(mqc_yml_tmp, fh) - assert result["failed"] == ["'assets/multiqc_config.yml' does not contain 'export_plots: true'."] + assert "'assets/multiqc_config.yml' does not contain 'export_plots: true'." in result["failed"] def test_multiqc_config_report_comment_fail(self): @@ -103,4 +103,5 @@ def test_multiqc_config_report_comment_release_succeed(self): # lint again lint_obj._load() result = lint_obj.multiqc_config() - assert "'assets/multiqc_config.yml' contains a matching 'report_comment'." in result["passed"] + print(result["passed"]) + assert "'assets/multiqc_config.yml' contains `report_comment`" in result["passed"] diff --git a/tests/test_cli.py b/tests/test_cli.py index 1c110cd6e8..c75a0ebc11 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -247,9 +247,9 @@ def test_create(self, mock_create): params["description"], params["author"], force="force" in params, - version=None, + version="1.0dev", outdir=params["outdir"], - organisation=None, + organisation="nf-core", ) mock_create.return_value.init_pipeline.assert_called_once() @@ -272,7 +272,7 @@ def test_create_app(self, mock_create): cmd = ["pipelines", "create"] result = self.invoke_cli(cmd) - assert result.exit_code == 0 + assert result.return_value == (0 or None) assert "Launching interactive nf-core pipeline creation tool." in result.output mock_create.assert_called_once_with() diff --git a/tests/test_modules.py b/tests/test_modules.py index 9c045f9d18..faa5499ca1 100644 --- a/tests/test_modules.py +++ b/tests/test_modules.py @@ -20,6 +20,7 @@ GITLAB_URL, OLD_TRIMGALORE_BRANCH, OLD_TRIMGALORE_SHA, + create_tmp_pipeline, mock_anaconda_api_calls, mock_biocontainers_api_calls, ) @@ -84,13 +85,8 @@ def setUp(self): self.component_type = "modules" # Set up the schema - root_repo_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - self.template_dir = os.path.join(root_repo_dir, "nf_core", "pipeline-template") - self.pipeline_name = "mypipeline" - self.pipeline_dir = os.path.join(self.tmp_dir, self.pipeline_name) - nf_core.pipelines.create.create.PipelineCreate( - self.pipeline_name, "it is mine", "me", no_git=True, outdir=self.pipeline_dir - ).init_pipeline() + self.tmp_dir, self.template_dir, self.pipeline_name, self.pipeline_dir = create_tmp_pipeline() + # Set up install objects self.mods_install = nf_core.modules.ModuleInstall(self.pipeline_dir, prompt=False, force=True) self.mods_install_old = nf_core.modules.ModuleInstall( diff --git a/tests/test_subworkflows.py b/tests/test_subworkflows.py index a7f3876616..dd9af04d95 100644 --- a/tests/test_subworkflows.py +++ b/tests/test_subworkflows.py @@ -15,6 +15,7 @@ GITLAB_SUBWORKFLOWS_ORG_PATH_BRANCH, GITLAB_URL, OLD_SUBWORKFLOWS_SHA, + create_tmp_pipeline, ) @@ -49,13 +50,7 @@ def setUp(self): self.component_type = "subworkflows" # Set up the pipeline structure - root_repo_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - self.template_dir = os.path.join(root_repo_dir, "nf_core", "pipeline-template") - self.pipeline_name = "mypipeline" - self.pipeline_dir = os.path.join(self.tmp_dir, self.pipeline_name) - nf_core.pipelines.create.create.PipelineCreate( - self.pipeline_name, "it is mine", "me", no_git=True, outdir=self.pipeline_dir - ).init_pipeline() + self.tmp_dir, self.template_dir, self.pipeline_name, self.pipeline_dir = create_tmp_pipeline() # Set up the nf-core/modules repo dummy self.nfcore_modules = create_modules_repo_dummy(self.tmp_dir) From acd72010d65d4c784357e93fb72d1a4b49bedc34 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 9 Jan 2024 12:52:06 +0100 Subject: [PATCH 061/175] add loading messages --- nf_core/pipelines/create/create.tcss | 5 ++++- nf_core/pipelines/create/finaldetails.py | 12 +++++++++++- nf_core/pipelines/create/githubrepo.py | 12 +++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index bb3690d815..c1c1974aa8 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -95,4 +95,7 @@ HorizontalScroll { display: block; } - +/* Loading message */ +LoadingIndicator { + border: solid white; +} diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 4e16be0970..9df7d23c25 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -6,7 +6,16 @@ from textual.containers import Center, Horizontal from textual.message import Message from textual.screen import Screen -from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch +from textual.widgets import ( + Button, + Footer, + Header, + Input, + LoadingIndicator, + Markdown, + Static, + Switch, +) from nf_core.pipelines.create.create import PipelineCreate from nf_core.pipelines.create.utils import TextInput @@ -102,6 +111,7 @@ def _create_pipeline(self) -> None: """Create the pipeline.""" create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) try: + self.query_one(LoadingIndicator).border_title = "Creating pipeline..." create_obj.init_pipeline() except UserWarning: self.post_message(self.PipelineExists()) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 74e96a7425..fb8e84cc04 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -11,7 +11,16 @@ from textual.containers import Center, Horizontal from textual.message import Message from textual.screen import Screen -from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch +from textual.widgets import ( + Button, + Footer, + Header, + Input, + LoadingIndicator, + Markdown, + Static, + Switch, +) from nf_core.pipelines.create.utils import TextInput @@ -163,6 +172,7 @@ def stop_loading(self) -> None: @work(thread=True, exclusive=True) def _create_repo_and_push(self, org, pipeline_repo, private, push): """Create a GitHub repository and push all branches.""" + self.query_one(LoadingIndicator).border_title = "Creating GitHub repo..." # Check if repo already exists try: repo = org.get_repo(self.parent.TEMPLATE_CONFIG.name) From 6b4ed9c09373a5f0675717c04a6496173f469b98 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 9 Jan 2024 12:59:34 +0100 Subject: [PATCH 062/175] default version to 1.0.0dev --- nf_core/__main__.py | 4 +- nf_core/pipelines/create/create.py | 6 +- nf_core/pipelines/create/finaldetails.py | 2 +- tests/__snapshots__/test_create_app.ambr | 242 +++++++++++------------ tests/lint/version_consistency.py | 2 +- tests/test_cli.py | 2 +- 6 files changed, 129 insertions(+), 129 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 7089cb3a45..ca4003d6f5 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -470,7 +470,7 @@ def pipelines(ctx): ) @click.option("-d", "--description", type=str, help="A short description of your pipeline") @click.option("-a", "--author", type=str, help="Name of the main author(s)") -@click.option("--version", type=str, default="1.0dev", help="The initial version number to use") +@click.option("--version", type=str, default="1.0.0dev", help="The initial version number to use") @click.option("-f", "--force", is_flag=True, default=False, help="Overwrite output directory if it already exists") @click.option("-o", "--outdir", help="Output directory for new pipeline (default: pipeline name)") @click.option("-t", "--template-yaml", help="Pass a YAML file to customize the template") @@ -508,7 +508,7 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp except UserWarning as e: log.error(e) sys.exit(1) - elif name or description or author or version != "1.0dev" or force or outdir or organisation != "nf-core": + elif name or description or author or version != "1.0.0dev" or force or outdir or organisation != "nf-core": log.error( "Command arguments are not accepted in interactive mode.\n" "Run with all command line arguments to avoid using an interactive interface" diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index e9761bcc4a..dc0c6c7960 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -33,7 +33,7 @@ class PipelineCreate: name (str): Name for the pipeline. description (str): Description for the pipeline. author (str): Authors name of the pipeline. - version (str): Version flag. Semantic versioning only. Defaults to `1.0dev`. + version (str): Version flag. Semantic versioning only. Defaults to `1.0.0dev`. no_git (bool): Prevents the creation of a local Git repository for the pipeline. Defaults to False. force (bool): Overwrites a given workflow directory with the same name. Defaults to False. Used for tests and sync command. May the force be with you. @@ -49,7 +49,7 @@ def __init__( name: Optional[str] = None, description: Optional[str] = None, author: Optional[str] = None, - version: str = "1.0dev", + version: str = "1.0.0dev", no_git: bool = False, force: bool = False, outdir: Optional[str] = None, @@ -167,7 +167,7 @@ def update_config(self, organisation, version, force, outdir): if self.config.org is None: self.config.org = organisation if self.config.version is None: - self.config.version = version if version else "1.0dev" + self.config.version = version if version else "1.0.0dev" if self.config.force is None: self.config.force = force if force else False if self.config.outdir is None: diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 9df7d23c25..5eb3122e6d 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -40,7 +40,7 @@ def compose(self) -> ComposeResult: "version", "Version", "First version of the pipeline", - "1.0dev", + "1.0.0dev", classes="column", ) yield TextInput( diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index 98bed6fc77..f72b735371 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1123,249 +1123,249 @@ font-weight: 700; } - .terminal-1778650725-matrix { + .terminal-3890482819-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1778650725-title { + .terminal-3890482819-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1778650725-r1 { fill: #c5c8c6 } - .terminal-1778650725-r2 { fill: #e3e3e3 } - .terminal-1778650725-r3 { fill: #989898 } - .terminal-1778650725-r4 { fill: #e1e1e1 } - .terminal-1778650725-r5 { fill: #121212 } - .terminal-1778650725-r6 { fill: #0053aa } - .terminal-1778650725-r7 { fill: #dde8f3;font-weight: bold } - .terminal-1778650725-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-1778650725-r9 { fill: #1e1e1e } - .terminal-1778650725-r10 { fill: #008139 } - .terminal-1778650725-r11 { fill: #e2e2e2 } - .terminal-1778650725-r12 { fill: #b93c5b } - .terminal-1778650725-r13 { fill: #7ae998 } - .terminal-1778650725-r14 { fill: #0a180e;font-weight: bold } - .terminal-1778650725-r15 { fill: #ddedf9 } + .terminal-3890482819-r1 { fill: #c5c8c6 } + .terminal-3890482819-r2 { fill: #e3e3e3 } + .terminal-3890482819-r3 { fill: #989898 } + .terminal-3890482819-r4 { fill: #e1e1e1 } + .terminal-3890482819-r5 { fill: #121212 } + .terminal-3890482819-r6 { fill: #0053aa } + .terminal-3890482819-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3890482819-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-3890482819-r9 { fill: #1e1e1e } + .terminal-3890482819-r10 { fill: #008139 } + .terminal-3890482819-r11 { fill: #e2e2e2 } + .terminal-3890482819-r12 { fill: #b93c5b } + .terminal-3890482819-r13 { fill: #7ae998 } + .terminal-3890482819-r14 { fill: #0a180e;font-weight: bold } + .terminal-3890482819-r15 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Final details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - First version of the pipelinePath to the output directory where the pipeline  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created - 1.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔If the pipeline output directory exists, remove it and continue. - - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Finish - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Final details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + First version of the pipelinePath to the output directory where the pipeline  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created + 1.0.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔If the pipeline output directory exists, remove it and continue. + + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Finish + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  diff --git a/tests/lint/version_consistency.py b/tests/lint/version_consistency.py index 6f70d67c40..4763020fb9 100644 --- a/tests/lint/version_consistency.py +++ b/tests/lint/version_consistency.py @@ -11,4 +11,4 @@ def test_version_consistency(self): result = lint_obj.version_consistency() assert result["passed"] == ["Version tags are numeric and consistent between container, release tag and config."] - assert result["failed"] == ["manifest.version was not numeric: 1.0dev!"] + assert result["failed"] == ["manifest.version was not numeric: 1.0.0dev!"] diff --git a/tests/test_cli.py b/tests/test_cli.py index c75a0ebc11..f76b5dcd92 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -247,7 +247,7 @@ def test_create(self, mock_create): params["description"], params["author"], force="force" in params, - version="1.0dev", + version="1.0.0dev", outdir=params["outdir"], organisation="nf-core", ) From 97bca8b8804d85d409d5d451f1d259a28acefaf0 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 19 Jan 2024 09:04:02 +0100 Subject: [PATCH 063/175] add logging instead of loading screen and see logging messages on real time --- nf_core/pipelines/create/__init__.py | 26 +- nf_core/pipelines/create/create.tcss | 5 - nf_core/pipelines/create/finaldetails.py | 34 +-- nf_core/pipelines/create/githubexit.py | 1 + nf_core/pipelines/create/githubrepo.py | 37 +-- .../pipelines/create/githubrepoquestion.py | 3 + nf_core/pipelines/create/loggingscreen.py | 38 +++ nf_core/pipelines/create/utils.py | 34 ++- tests/__snapshots__/test_create_app.ambr | 247 +++++++++--------- tests/test_create_app.py | 9 +- 10 files changed, 246 insertions(+), 188 deletions(-) create mode 100644 nf_core/pipelines/create/loggingscreen.py diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 2f5b7b0434..259fd9e332 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -1,4 +1,6 @@ """A Textual app to create a pipeline.""" +import logging + from textual.app import App from textual.widgets import Button @@ -10,11 +12,24 @@ from nf_core.pipelines.create.githubexit import GithubExit from nf_core.pipelines.create.githubrepo import GithubRepo from nf_core.pipelines.create.githubrepoquestion import GithubRepoQuestion +from nf_core.pipelines.create.loggingscreen import LoggingScreen from nf_core.pipelines.create.nfcorepipeline import NfcorePipeline from nf_core.pipelines.create.pipelinetype import ChoosePipelineType -from nf_core.pipelines.create.utils import CreateConfig +from nf_core.pipelines.create.utils import ( + CreateConfig, + CustomLogHandler, + LoggingConsole, +) from nf_core.pipelines.create.welcome import WelcomeScreen +log_handler = CustomLogHandler(console=LoggingConsole(), rich_tracebacks=True) +logging.basicConfig( + level="INFO", + handlers=[log_handler], + format="%(message)s", +) +log_handler.setLevel("INFO") + class PipelineCreateApp(App[CreateConfig]): """A Textual app to manage stopwatches.""" @@ -46,6 +61,11 @@ class PipelineCreateApp(App[CreateConfig]): # Initialise pipeline type PIPELINE_TYPE = None + # Log handler + LOG_HANDLER = log_handler + # Logging state + LOGGING_STATE = None + def on_mount(self) -> None: self.push_screen("welcome") @@ -63,8 +83,12 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.switch_screen("final_details") elif event.button.id == "github_repo": self.switch_screen("github_repo") + elif event.button.id == "close_screen": + self.switch_screen("github_repo_question") elif event.button.id == "exit": self.switch_screen("github_exit") + elif event.button.id == "show_logging": + self.switch_screen(LoggingScreen()) if event.button.id == "close_app": self.exit(return_code=0) diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index c1c1974aa8..df37e50ed8 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -94,8 +94,3 @@ HorizontalScroll { .displayed #hide_password { display: block; } - -/* Loading message */ -LoadingIndicator { - border: solid white; -} diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 5eb3122e6d..7186fd2b6e 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -6,19 +6,11 @@ from textual.containers import Center, Horizontal from textual.message import Message from textual.screen import Screen -from textual.widgets import ( - Button, - Footer, - Header, - Input, - LoadingIndicator, - Markdown, - Static, - Switch, -) +from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch from nf_core.pipelines.create.create import PipelineCreate -from nf_core.pipelines.create.utils import TextInput +from nf_core.pipelines.create.loggingscreen import LoggingScreen +from nf_core.pipelines.create.utils import ShowLogs, TextInput class FinalDetails(Screen): @@ -84,36 +76,24 @@ def on_button_pressed(self, event: Button.Pressed) -> None: # Create the new pipeline self._create_pipeline() - self.screen.loading = True - - class PipelineCreated(Message): - """Custom message to indicate that the pipeline has been created.""" - - pass + self.parent.LOGGING_STATE = "pipeline created" + self.parent.switch_screen(LoggingScreen()) class PipelineExists(Message): """Custom message to indicate that the pipeline already exists.""" pass - @on(PipelineCreated) - def stop_loading(self) -> None: - self.screen.loading = False - self.parent.switch_screen("github_repo_question") - @on(PipelineExists) - def stop_loading_error(self) -> None: - self.screen.loading = False + def show_pipeline_error(self) -> None: self.parent.switch_screen("error_screen") @work(thread=True, exclusive=True) def _create_pipeline(self) -> None: """Create the pipeline.""" + self.post_message(ShowLogs()) create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) try: - self.query_one(LoadingIndicator).border_title = "Creating pipeline..." create_obj.init_pipeline() except UserWarning: self.post_message(self.PipelineExists()) - else: - self.post_message(self.PipelineCreated()) diff --git a/nf_core/pipelines/create/githubexit.py b/nf_core/pipelines/create/githubexit.py index 04fc7cb0b4..96178fbcdf 100644 --- a/nf_core/pipelines/create/githubexit.py +++ b/nf_core/pipelines/create/githubexit.py @@ -36,5 +36,6 @@ def compose(self) -> ComposeResult: yield Markdown(exit_help_text_markdown) yield Center( Button("Close App", id="close_app", variant="success"), + Button("Show Logging", id="show_logging", variant="primary"), classes="cta", ) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index fb8e84cc04..22d52f4514 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -6,23 +6,14 @@ import git import yaml from github import Github, GithubException, UnknownObjectException -from textual import on, work +from textual import work from textual.app import ComposeResult from textual.containers import Center, Horizontal -from textual.message import Message from textual.screen import Screen -from textual.widgets import ( - Button, - Footer, - Header, - Input, - LoadingIndicator, - Markdown, - Static, - Switch, -) - -from nf_core.pipelines.create.utils import TextInput +from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch + +from nf_core.pipelines.create.loggingscreen import LoggingScreen +from nf_core.pipelines.create.utils import ShowLogs, TextInput log = logging.getLogger(__name__) @@ -144,7 +135,6 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self._create_repo_and_push( org, pipeline_repo, github_variables["private"], github_variables["push"] ) - self.screen.loading = True else: # Create the repo in the user's account log.info( @@ -153,26 +143,18 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self._create_repo_and_push( user, pipeline_repo, github_variables["private"], github_variables["push"] ) - self.screen.loading = True log.info(f"GitHub repository '{self.parent.TEMPLATE_CONFIG.name}' created successfully") except UserWarning as e: log.info(f"There was an error with message: {e}") self.parent.switch_screen("github_exit") - class RepoCreated(Message): - """Custom message to indicate that the GitHub repo has been created.""" - - pass - - @on(RepoCreated) - def stop_loading(self) -> None: - self.screen.loading = False - self.parent.switch_screen("completed_screen") + self.parent.LOGGING_STATE = "repo created" + self.parent.switch_screen(LoggingScreen()) @work(thread=True, exclusive=True) def _create_repo_and_push(self, org, pipeline_repo, private, push): """Create a GitHub repository and push all branches.""" - self.query_one(LoadingIndicator).border_title = "Creating GitHub repo..." + self.post_message(ShowLogs()) # Check if repo already exists try: repo = org.get_repo(self.parent.TEMPLATE_CONFIG.name) @@ -185,7 +167,6 @@ def _create_repo_and_push(self, org, pipeline_repo, private, push): repo_exists = True except UserWarning as e: # Repo already exists - self.post_message(self.RepoCreated()) log.info(e) return except UnknownObjectException: @@ -207,8 +188,6 @@ def _create_repo_and_push(self, org, pipeline_repo, private, push): if push: pipeline_repo.remotes.origin.push(all=True).raise_if_error() - self.post_message(self.RepoCreated()) - def _github_authentication(self, gh_username, gh_token): """Authenticate to GitHub""" log.debug(f"Authenticating GitHub as {gh_username}") diff --git a/nf_core/pipelines/create/githubrepoquestion.py b/nf_core/pipelines/create/githubrepoquestion.py index 72c5c4a81a..ea32597101 100644 --- a/nf_core/pipelines/create/githubrepoquestion.py +++ b/nf_core/pipelines/create/githubrepoquestion.py @@ -1,3 +1,4 @@ +import logging from textwrap import dedent from textual.app import ComposeResult @@ -5,6 +6,8 @@ from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown +log = logging.getLogger(__name__) + github_text_markdown = """ # Create a GitHub repo diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py new file mode 100644 index 0000000000..2a59e2bcc6 --- /dev/null +++ b/nf_core/pipelines/create/loggingscreen.py @@ -0,0 +1,38 @@ +from textual.app import ComposeResult +from textual.containers import Center +from textual.screen import Screen +from textual.widgets import Button, Footer, Header, Markdown, Static + +markdown = """ +# nf-core create + +Visualising logging output. +""" + + +class LoggingScreen(Screen): + """A screen to show the final logs.""" + + def compose(self) -> ComposeResult: + yield Header() + yield Footer() + yield Static( + f"\n[green]{' ' * 40},--.[grey39]/[green],-." + + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + "\n[green] `._,._,'\n", + id="logo", + ) + yield Markdown(markdown) + if self.parent.LOGGING_STATE == "repo created": + yield Center( + Button("Close App", id="close_app", variant="success"), + classes="cta", + ) + else: + yield Center( + Button("Close logging screen", id="close_screen", variant="success"), + classes="cta", + ) + yield Center(self.parent.LOG_HANDLER.console, classes="cta") diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 5c3b995b12..f3474e01cd 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -1,13 +1,18 @@ import re +from logging import LogRecord from pathlib import Path from typing import Optional, Union from pydantic import BaseModel, ConfigDict, ValidationError, field_validator +from rich.logging import RichHandler from textual import on +from textual._context import active_app from textual.app import ComposeResult from textual.containers import HorizontalScroll +from textual.message import Message from textual.validation import ValidationResult, Validator -from textual.widgets import Button, Input, Markdown, Static, Switch +from textual.widget import Widget +from textual.widgets import Button, Input, Markdown, RichLog, Static, Switch class CreateConfig(BaseModel): @@ -168,6 +173,33 @@ def compose(self) -> ComposeResult: yield HelpText(markdown=self.markdown, classes="help_box") +class LoggingConsole(RichLog): + file = False + console: Widget + + def print(self, content): + self.write(content) + + +class CustomLogHandler(RichHandler): + """A Logging handler which extends RichHandler to write to a Widget and handle a Textual App.""" + + def emit(self, record: LogRecord) -> None: + """Invoked by logging.""" + try: + _app = active_app.get() + except LookupError: + pass + else: + super().emit(record) + + +class ShowLogs(Message): + """Custom message to show the logging messages.""" + + pass + + ## Markdown text to reuse in different screens markdown_genomes = """ Nf-core pipelines are configured to use a copy of the most common reference genome files. diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index f72b735371..6ee9c9b9b1 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1673,250 +1673,253 @@ font-weight: 700; } - .terminal-2007955284-matrix { + .terminal-1481614550-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2007955284-title { + .terminal-1481614550-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2007955284-r1 { fill: #c5c8c6 } - .terminal-2007955284-r2 { fill: #e3e3e3 } - .terminal-2007955284-r3 { fill: #989898 } - .terminal-2007955284-r4 { fill: #e1e1e1 } - .terminal-2007955284-r5 { fill: #98a84b } - .terminal-2007955284-r6 { fill: #626262 } - .terminal-2007955284-r7 { fill: #608ab1 } - .terminal-2007955284-r8 { fill: #d0b344 } - .terminal-2007955284-r9 { fill: #4ebf71;font-weight: bold } - .terminal-2007955284-r10 { fill: #d2d2d2 } - .terminal-2007955284-r11 { fill: #82aaff } - .terminal-2007955284-r12 { fill: #eeffff } - .terminal-2007955284-r13 { fill: #7ae998 } - .terminal-2007955284-r14 { fill: #008139 } - .terminal-2007955284-r15 { fill: #dde8f3;font-weight: bold } - .terminal-2007955284-r16 { fill: #ddedf9 } + .terminal-1481614550-r1 { fill: #c5c8c6 } + .terminal-1481614550-r2 { fill: #e3e3e3 } + .terminal-1481614550-r3 { fill: #989898 } + .terminal-1481614550-r4 { fill: #e1e1e1 } + .terminal-1481614550-r5 { fill: #98a84b } + .terminal-1481614550-r6 { fill: #626262 } + .terminal-1481614550-r7 { fill: #608ab1 } + .terminal-1481614550-r8 { fill: #d0b344 } + .terminal-1481614550-r9 { fill: #4ebf71;font-weight: bold } + .terminal-1481614550-r10 { fill: #d2d2d2 } + .terminal-1481614550-r11 { fill: #82aaff } + .terminal-1481614550-r12 { fill: #eeffff } + .terminal-1481614550-r13 { fill: #7ae998 } + .terminal-1481614550-r14 { fill: #507bb3 } + .terminal-1481614550-r15 { fill: #dde6ed;font-weight: bold } + .terminal-1481614550-r16 { fill: #008139 } + .terminal-1481614550-r17 { fill: #001541 } + .terminal-1481614550-r18 { fill: #dde8f3;font-weight: bold } + .terminal-1481614550-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - - If you would like to create the GitHub repository later, you can do it manually by following - these steps: - -  1. Create a new GitHub repository -  2. Add the remote to your local repository - - - cd<pipeline_directory> - gitremoteaddorigingit@github.com:<username>/<repo_name>.git - - -  3. Push the code to the remote - - - gitpush--allorigin - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close App - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + + If you would like to create the GitHub repository later, you can do it manually by following + these steps: + +  1. Create a new GitHub repository +  2. Add the remote to your local repository + + + cd<pipeline_directory> + gitremoteaddorigingit@github.com:<username>/<repo_name>.git + + +  3. Push the code to the remote + + + gitpush--allorigin + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close AppShow Logging + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  diff --git a/tests/test_create_app.py b/tests/test_create_app.py index d226ea2da8..710359e945 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -196,7 +196,7 @@ def test_github_question(mock_init_pipeline, snap_compare): screen choose_type > press nf-core > screen basic_details > enter pipeline details > press next > screen type_nfcore > press continue > - screen final_details > press finish > + screen final_details > press finish > close logging screen > screen github_repo_question """ @@ -212,6 +212,7 @@ async def run_before(pilot) -> None: await pilot.click("#next") await pilot.click("#continue") await pilot.click("#finish") + await pilot.click("#close_screen") assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) @@ -224,7 +225,7 @@ def test_github_details(mock_init_pipeline, snap_compare): screen choose_type > press nf-core > screen basic_details > enter pipeline details > press next > screen type_nfcore > press continue > - screen final_details > press finish > + screen final_details > press finish > close logging screen > screen github_repo_question > press create repo > screen github_repo """ @@ -241,6 +242,7 @@ async def run_before(pilot) -> None: await pilot.click("#next") await pilot.click("#continue") await pilot.click("#finish") + await pilot.click("#close_screen") await pilot.click("#github_repo") assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) @@ -254,7 +256,7 @@ def test_github_exit_message(mock_init_pipeline, snap_compare): screen choose_type > press nf-core > screen basic_details > enter pipeline details > press next > screen type_nfcore > press continue > - screen final_details > press finish > + screen final_details > press finish > close logging screen > screen github_repo_question > press create repo > screen github_repo > press exit (close without creating a repo) > screen github_exit @@ -272,6 +274,7 @@ async def run_before(pilot) -> None: await pilot.click("#next") await pilot.click("#continue") await pilot.click("#finish") + await pilot.click("#close_screen") await pilot.click("#github_repo") await pilot.click("#exit") From 0525d9c1ffc2c9c091ead1d8ff1db908d23c84dd Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 19 Feb 2024 10:38:41 +0100 Subject: [PATCH 064/175] deprecation error if 'nf-core create' is used --- nf_core/__main__.py | 46 +++------------------------------------------ 1 file changed, 3 insertions(+), 43 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index ca4003d6f5..51eff26f73 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -542,54 +542,14 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp @click.option("--plain", is_flag=True, help="Use the standard nf-core template") def create(name, description, author, version, force, outdir, template_yaml, plain): """ + DEPRECATED Create a new pipeline using the nf-core template. Uses the nf-core template to make a skeleton Nextflow pipeline with all required files, boilerplate code and best-practices. """ - from nf_core.pipelines.create import PipelineCreateApp - from nf_core.pipelines.create.create import PipelineCreate - - if (name and description and author) or (template_yaml): - # If all command arguments are used, run without the interactive interface - try: - create_obj = PipelineCreate( - name, - description, - author, - version=version, - force=force, - outdir=outdir, - ) - create_obj.init_pipeline() - except UserWarning as e: - log.error(e) - sys.exit(1) - elif name or description or author or version or force or outdir or plain: - log.error( - "Command arguments are not accepted in interactive mode.\n" - "Run with all command line arguments to avoid using an interactive interface" - "or run without any command line arguments to use an interactive interface." - ) - sys.exit(1) - else: - if rich.prompt.Confirm.ask( - "[blue bold]?[/] [bold] [green]nf-core create[/] command is deprecated in favor of [green]nf-core pipelines create[/].[/]\n" - "[bold]Will launch an interactive interface. Do you want to continue?[/]" - ): - log.info( - "Launching interactive nf-core pipeline creation tool." - "\nRun with all command line arguments to avoid using an interactive interface." - ) - app = PipelineCreateApp() - try: - app.run() - sys.exit(app.return_code or 0) - except UserWarning as e: - log.error(e) - sys.exit(1) - else: - sys.exit(0) + log.error("[bold][green]nf-core create[/] command is deprecated. Use [green]nf-core pipelines create[/].[/]") + sys.exit(0) # nf-core modules subcommands From 29afad0a5a23bc5c5942500a21bf155a561caa52 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 19 Feb 2024 11:22:08 +0100 Subject: [PATCH 065/175] more formatting and docs --- nf_core/pipelines/create/__init__.py | 2 +- nf_core/pipelines/create/completed.py | 40 ------------------- nf_core/pipelines/create/create.tcss | 4 ++ nf_core/pipelines/create/custompipeline.py | 11 ++++- nf_core/pipelines/create/error.py | 7 ++++ nf_core/pipelines/create/finaldetails.py | 9 ++++- nf_core/pipelines/create/githubexit.py | 9 +++++ nf_core/pipelines/create/githubrepo.py | 23 ++++++++--- .../pipelines/create/githubrepoquestion.py | 7 ++++ nf_core/pipelines/create/loggingscreen.py | 11 ++++- nf_core/pipelines/create/nfcorepipeline.py | 11 ++++- nf_core/pipelines/create/welcome.py | 17 ++++++++ 12 files changed, 98 insertions(+), 53 deletions(-) delete mode 100644 nf_core/pipelines/create/completed.py diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 259fd9e332..d1a5484f8c 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -22,7 +22,7 @@ ) from nf_core.pipelines.create.welcome import WelcomeScreen -log_handler = CustomLogHandler(console=LoggingConsole(), rich_tracebacks=True) +log_handler = CustomLogHandler(console=LoggingConsole(highlight=True, markup=True), rich_tracebacks=True) logging.basicConfig( level="INFO", handlers=[log_handler], diff --git a/nf_core/pipelines/create/completed.py b/nf_core/pipelines/create/completed.py deleted file mode 100644 index 282dd76882..0000000000 --- a/nf_core/pipelines/create/completed.py +++ /dev/null @@ -1,40 +0,0 @@ -from textwrap import dedent - -from textual.app import ComposeResult -from textual.containers import Center -from textual.screen import Screen -from textual.widgets import Button, Footer, Header, Markdown, Static - - -class Completed(Screen): - """A screen to show the final text and exit the app.""" - - def compose(self) -> ComposeResult: - yield Header() - yield Footer() - yield Static( - f"\n[green]{' ' * 40},--.[grey39]/[green],-." - + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + "\n[green] `._,._,'\n", - id="logo", - ) - - completed_text_markdown = f""" - - A pipeline has been created at '`{self.parent.TEMPLATE_CONFIG.outdir + "/" + self.parent.TEMPLATE_CONFIG.org + "-" + self.parent.TEMPLATE_CONFIG.name}`'. - - A GitHub repository '`{self.parent.TEMPLATE_CONFIG.name}`' has been created in the {"user's" if self.parent.TEMPLATE_CONFIG.org == "nf-core" else ""} GitHub organisation account{ " `" + self.parent.TEMPLATE_CONFIG.org + "`" if self.parent.TEMPLATE_CONFIG.org != "nf-core" else ""}. - - !!!!!! IMPORTANT !!!!!! - - If you are interested in adding your pipeline to the nf-core community, - PLEASE COME AND TALK TO US IN THE NF-CORE SLACK BEFORE WRITING ANY CODE! - - - Please read: [https://nf-co.re/developers/adding_pipelines#join-the-community](https://nf-co.re/developers/adding_pipelines#join-the-community) - """ - - yield Markdown(dedent(completed_text_markdown)) - yield Center( - Button("Close App", id="close_app", variant="success"), - classes="cta", - ) diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index df37e50ed8..51ed5745fe 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -52,6 +52,10 @@ HorizontalScroll { color: grey; } +Vertical{ + height: auto; +} + /* Display help messages */ .help_box { diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 5cc2f87d95..440b900a3d 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -1,8 +1,10 @@ +from textwrap import dedent + from textual import on from textual.app import ComposeResult from textual.containers import Center, ScrollableContainer from textual.screen import Screen -from textual.widgets import Button, Footer, Header, Switch +from textual.widgets import Button, Footer, Header, Markdown, Switch from nf_core.pipelines.create.utils import PipelineFeature, markdown_genomes @@ -46,6 +48,13 @@ class CustomPipeline(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() + yield Markdown( + dedent( + """ + # Template features + """ + ) + ) yield ScrollableContainer( PipelineFeature( markdown_genomes, diff --git a/nf_core/pipelines/create/error.py b/nf_core/pipelines/create/error.py index a1d94e62f4..922b5ed544 100644 --- a/nf_core/pipelines/create/error.py +++ b/nf_core/pipelines/create/error.py @@ -12,6 +12,13 @@ class ExistError(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() + yield Markdown( + dedent( + """ + # Pipeline exists + """ + ) + ) yield Static( f"\n[green]{' ' * 40},--.[grey39]/[green],-." + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 7186fd2b6e..88008894cb 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -3,7 +3,7 @@ from textual import on, work from textual.app import ComposeResult -from textual.containers import Center, Horizontal +from textual.containers import Center, Horizontal, Vertical from textual.message import Message from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch @@ -44,7 +44,12 @@ def compose(self) -> ComposeResult: ) with Horizontal(): yield Switch(value=False, id="force") - yield Static("If the pipeline output directory exists, remove it and continue.", classes="custom_grid") + with Vertical(): + yield Static("Force", classes="custom_grid") + yield Static( + "If the pipeline output directory exists, remove it and continue.", + classes="feature_subtitle", + ) yield Center( Button("Finish", id="finish", variant="success"), diff --git a/nf_core/pipelines/create/githubexit.py b/nf_core/pipelines/create/githubexit.py index 96178fbcdf..9b2c54912e 100644 --- a/nf_core/pipelines/create/githubexit.py +++ b/nf_core/pipelines/create/githubexit.py @@ -1,3 +1,5 @@ +from textwrap import dedent + from textual.app import ComposeResult from textual.containers import Center from textual.screen import Screen @@ -25,6 +27,13 @@ class GithubExit(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() + yield Markdown( + dedent( + """ + # HowTo create a GitHub repository + """ + ) + ) yield Static( f"\n[green]{' ' * 40},--.[grey39]/[green],-." + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 22d52f4514..54581ebb1b 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -8,7 +8,7 @@ from github import Github, GithubException, UnknownObjectException from textual import work from textual.app import ComposeResult -from textual.containers import Center, Horizontal +from textual.containers import Center, Horizontal, Vertical from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch @@ -33,6 +33,13 @@ class GithubRepo(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() + yield Markdown( + dedent( + """ + # Create GitHub repository + """ + ) + ) yield Markdown(dedent(github_text_markdown)) with Horizontal(): gh_user, gh_token = self._get_github_credentials() @@ -56,13 +63,17 @@ def compose(self) -> ComposeResult: yield Markdown(dedent(repo_config_markdown)) with Horizontal(): yield Switch(value=False, id="private") - yield Static("Select if the new GitHub repo must be private.", classes="custom_grid") + with Vertical(): + yield Static("Private", classes="") + yield Static("Select if the new GitHub repo must be private.", classes="feature_subtitle") with Horizontal(): yield Switch(value=True, id="push") - yield Static( - "Select if you would like to push all the pipeline template files to your GitHub repo\nand all the branches required to keep the pipeline up to date with new releases of nf-core.", - classes="custom_grid", - ) + with Vertical(): + yield Static("Push files", classes="custom_grid") + yield Static( + "Select if you would like to push all the pipeline template files to your GitHub repo\nand all the branches required to keep the pipeline up to date with new releases of nf-core.", + classes="feature_subtitle", + ) yield Center( Button("Create GitHub repo", id="create_github", variant="success"), Button("Finish without creating a repo", id="exit", variant="primary"), diff --git a/nf_core/pipelines/create/githubrepoquestion.py b/nf_core/pipelines/create/githubrepoquestion.py index ea32597101..c866f859ac 100644 --- a/nf_core/pipelines/create/githubrepoquestion.py +++ b/nf_core/pipelines/create/githubrepoquestion.py @@ -23,6 +23,13 @@ class GithubRepoQuestion(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() + yield Markdown( + dedent( + """ + # Create GitHub repository + """ + ) + ) yield Markdown(dedent(github_text_markdown)) yield Center( Button("Create GitHub repo", id="github_repo", variant="success"), diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index 2a59e2bcc6..cb7b93291a 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -1,11 +1,11 @@ +from textwrap import dedent + from textual.app import ComposeResult from textual.containers import Center from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown, Static markdown = """ -# nf-core create - Visualising logging output. """ @@ -16,6 +16,13 @@ class LoggingScreen(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() + yield Markdown( + dedent( + """ + # Logging + """ + ) + ) yield Static( f"\n[green]{' ' * 40},--.[grey39]/[green],-." + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py index 10541ced04..2444b35154 100644 --- a/nf_core/pipelines/create/nfcorepipeline.py +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -1,8 +1,10 @@ +from textwrap import dedent + from textual import on from textual.app import ComposeResult from textual.containers import Center, ScrollableContainer from textual.screen import Screen -from textual.widgets import Button, Footer, Header, Switch +from textual.widgets import Button, Footer, Header, Markdown, Switch from nf_core.pipelines.create.utils import PipelineFeature, markdown_genomes @@ -13,6 +15,13 @@ class NfcorePipeline(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() + yield Markdown( + dedent( + """ + # Pipeline features + """ + ) + ) yield ScrollableContainer( PipelineFeature( markdown_genomes, diff --git a/nf_core/pipelines/create/welcome.py b/nf_core/pipelines/create/welcome.py index 0be70cc4c0..cb0d7468cb 100644 --- a/nf_core/pipelines/create/welcome.py +++ b/nf_core/pipelines/create/welcome.py @@ -1,3 +1,5 @@ +from textwrap import dedent + from textual.app import ComposeResult from textual.containers import Center from textual.screen import Screen @@ -15,6 +17,14 @@ However, this tool can also be used to create pipelines that will never be part of nf-core. You can still benefit from the community best practices for your own workflow. + +If you are planning to add a pipeline to the nf-core community, you need to be part of that community! +Please join us on Slack [https://nf-co.re/join](https://nf-co.re/join), +and ask to be added to the GitHub association through the #github-invitations channel. + +Come and discuss your plans with the nf-core community as early as possible. +Ideally before you make a start on your pipeline! +These topics are specifically discussed in the [#new-pipelines](https://nfcore.slack.com/channels/new-pipelines) channel. """ @@ -24,6 +34,13 @@ class WelcomeScreen(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() + yield Markdown( + dedent( + """ + # Create a pipeline from the nf-core template + """ + ) + ) yield Static( f"\n[green]{' ' * 40},--.[grey39]/[green],-." + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" From 2dcb0f1744bf2eec8852d92956d34e6594c1fe1f Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 19 Feb 2024 12:30:46 +0100 Subject: [PATCH 066/175] add button to go back --- nf_core/pipelines/create/__init__.py | 18 +++++++++--------- nf_core/pipelines/create/basicdetails.py | 5 +++-- nf_core/pipelines/create/custompipeline.py | 1 + nf_core/pipelines/create/finaldetails.py | 1 + nf_core/pipelines/create/githubrepo.py | 1 + nf_core/pipelines/create/githubrepoquestion.py | 1 + nf_core/pipelines/create/nfcorepipeline.py | 1 + 7 files changed, 17 insertions(+), 11 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index d1a5484f8c..b62f093978 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -5,7 +5,6 @@ from textual.widgets import Button from nf_core.pipelines.create.basicdetails import BasicDetails -from nf_core.pipelines.create.completed import Completed from nf_core.pipelines.create.custompipeline import CustomPipeline from nf_core.pipelines.create.error import ExistError from nf_core.pipelines.create.finaldetails import FinalDetails @@ -51,7 +50,6 @@ class PipelineCreateApp(App[CreateConfig]): "github_repo_question": GithubRepoQuestion(), "github_repo": GithubRepo(), "github_exit": GithubExit(), - "completed_screen": Completed(), "error_screen": ExistError(), } @@ -72,25 +70,27 @@ def on_mount(self) -> None: def on_button_pressed(self, event: Button.Pressed) -> None: """Handle all button pressed events.""" if event.button.id == "start": - self.switch_screen("choose_type") + self.push_screen("choose_type") elif event.button.id == "type_nfcore": self.PIPELINE_TYPE = "nfcore" - self.switch_screen("basic_details") + self.push_screen("basic_details") elif event.button.id == "type_custom": self.PIPELINE_TYPE = "custom" - self.switch_screen("basic_details") + self.push_screen("basic_details") elif event.button.id == "continue": - self.switch_screen("final_details") + self.push_screen("final_details") elif event.button.id == "github_repo": - self.switch_screen("github_repo") + self.push_screen("github_repo") elif event.button.id == "close_screen": - self.switch_screen("github_repo_question") + self.push_screen("github_repo_question") elif event.button.id == "exit": - self.switch_screen("github_exit") + self.push_screen("github_exit") elif event.button.id == "show_logging": self.switch_screen(LoggingScreen()) if event.button.id == "close_app": self.exit(return_code=0) + if event.button.id == "back": + self.pop_screen() def action_toggle_dark(self) -> None: """An action to toggle dark mode.""" diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py index da1b2bf45a..aa2886c1bf 100644 --- a/nf_core/pipelines/create/basicdetails.py +++ b/nf_core/pipelines/create/basicdetails.py @@ -50,6 +50,7 @@ def compose(self) -> ComposeResult: "Name of the main author / authors", ) yield Center( + Button("Back", id="back", variant="default"), Button("Next", id="next", variant="success"), classes="cta", ) @@ -69,8 +70,8 @@ def on_button_pressed(self, event: Button.Pressed) -> None: try: self.parent.TEMPLATE_CONFIG = CreateConfig(**config) if self.parent.PIPELINE_TYPE == "nfcore": - self.parent.switch_screen("type_nfcore") + self.parent.push_screen("type_nfcore") elif self.parent.PIPELINE_TYPE == "custom": - self.parent.switch_screen("type_custom") + self.parent.push_screen("type_custom") except ValueError: pass diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 440b900a3d..6fe878469b 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -82,6 +82,7 @@ def compose(self) -> ComposeResult: ), ) yield Center( + Button("Back", id="back", variant="default"), Button("Continue", id="continue", variant="success"), classes="cta", ) diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 88008894cb..9ffaaa9cfb 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -52,6 +52,7 @@ def compose(self) -> ComposeResult: ) yield Center( + Button("Back", id="back", variant="default"), Button("Finish", id="finish", variant="success"), classes="cta", ) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 54581ebb1b..c8a02e609a 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -75,6 +75,7 @@ def compose(self) -> ComposeResult: classes="feature_subtitle", ) yield Center( + Button("Back", id="back", variant="default"), Button("Create GitHub repo", id="create_github", variant="success"), Button("Finish without creating a repo", id="exit", variant="primary"), classes="cta", diff --git a/nf_core/pipelines/create/githubrepoquestion.py b/nf_core/pipelines/create/githubrepoquestion.py index c866f859ac..1279424856 100644 --- a/nf_core/pipelines/create/githubrepoquestion.py +++ b/nf_core/pipelines/create/githubrepoquestion.py @@ -32,6 +32,7 @@ def compose(self) -> ComposeResult: ) yield Markdown(dedent(github_text_markdown)) yield Center( + Button("Back", id="back", variant="default"), Button("Create GitHub repo", id="github_repo", variant="success"), Button("Finish without creating a repo", id="exit", variant="primary"), classes="cta", diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py index 2444b35154..f9bd45733c 100644 --- a/nf_core/pipelines/create/nfcorepipeline.py +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -31,6 +31,7 @@ def compose(self) -> ComposeResult: ), ) yield Center( + Button("Back", id="back", variant="default"), Button("Continue", id="continue", variant="success"), classes="cta", ) From 17bb9e9a6a4e4e585cc673a4a5ad1d2f64cf47dd Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 19 Feb 2024 15:39:11 +0100 Subject: [PATCH 067/175] disable button to close logs while pipeline is not created --- nf_core/pipelines/create/__init__.py | 2 +- nf_core/pipelines/create/finaldetails.py | 3 ++- nf_core/pipelines/create/loggingscreen.py | 2 +- nf_core/pipelines/create/utils.py | 6 ++++++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index b62f093978..86941c1242 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -21,7 +21,7 @@ ) from nf_core.pipelines.create.welcome import WelcomeScreen -log_handler = CustomLogHandler(console=LoggingConsole(highlight=True, markup=True), rich_tracebacks=True) +log_handler = CustomLogHandler(console=LoggingConsole(), rich_tracebacks=True, markup=True) logging.basicConfig( level="INFO", handlers=[log_handler], diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 9ffaaa9cfb..5af28cffa6 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -10,7 +10,7 @@ from nf_core.pipelines.create.create import PipelineCreate from nf_core.pipelines.create.loggingscreen import LoggingScreen -from nf_core.pipelines.create.utils import ShowLogs, TextInput +from nf_core.pipelines.create.utils import ShowLogs, TextInput, change_select_disabled class FinalDetails(Screen): @@ -101,5 +101,6 @@ def _create_pipeline(self) -> None: create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) try: create_obj.init_pipeline() + self.parent.call_from_thread(change_select_disabled, self.parent, "close_screen", False) except UserWarning: self.post_message(self.PipelineExists()) diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index cb7b93291a..3cfe3f8d8b 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -39,7 +39,7 @@ def compose(self) -> ComposeResult: ) else: yield Center( - Button("Close logging screen", id="close_screen", variant="success"), + Button("Close logging screen", id="close_screen", variant="success", disabled=True), classes="cta", ) yield Center(self.parent.LOG_HANDLER.console, classes="cta") diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index f3474e01cd..a1c9089523 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -200,6 +200,12 @@ class ShowLogs(Message): pass +## Functions +def change_select_disabled(app, widget_id: str, disabled: bool) -> None: + """Change the disabled state of a widget.""" + app.get_widget_by_id(widget_id).disabled = disabled + + ## Markdown text to reuse in different screens markdown_genomes = """ Nf-core pipelines are configured to use a copy of the most common reference genome files. From 5445b740515f00de6a4e809b1d9b41b9bb46bf51 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 20 Feb 2024 14:09:50 +0100 Subject: [PATCH 068/175] more tweaking of logging buttons and screen --- nf_core/pipelines/create/__init__.py | 5 ++++- nf_core/pipelines/create/githubrepoquestion.py | 3 --- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 86941c1242..126b3db62a 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -82,10 +82,13 @@ def on_button_pressed(self, event: Button.Pressed) -> None: elif event.button.id == "github_repo": self.push_screen("github_repo") elif event.button.id == "close_screen": - self.push_screen("github_repo_question") + # Switch screen (not push) to allow viewing old logging messages + self.switch_screen("github_repo_question") elif event.button.id == "exit": self.push_screen("github_exit") elif event.button.id == "show_logging": + # Set logging state to repo created to see the button for closing the logging screen + self.LOGGING_STATE = "repo created" self.switch_screen(LoggingScreen()) if event.button.id == "close_app": self.exit(return_code=0) diff --git a/nf_core/pipelines/create/githubrepoquestion.py b/nf_core/pipelines/create/githubrepoquestion.py index 1279424856..ded33d188a 100644 --- a/nf_core/pipelines/create/githubrepoquestion.py +++ b/nf_core/pipelines/create/githubrepoquestion.py @@ -9,8 +9,6 @@ log = logging.getLogger(__name__) github_text_markdown = """ -# Create a GitHub repo - After creating the pipeline template locally, we can create a GitHub repository and push the code to it. Do you want to create a GitHub repository? @@ -32,7 +30,6 @@ def compose(self) -> ComposeResult: ) yield Markdown(dedent(github_text_markdown)) yield Center( - Button("Back", id="back", variant="default"), Button("Create GitHub repo", id="github_repo", variant="success"), Button("Finish without creating a repo", id="exit", variant="primary"), classes="cta", From 536e3be0a8ceab419785c6b901a1884f9ff6bc8d Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 21 Feb 2024 15:24:52 +0100 Subject: [PATCH 069/175] update create app tests according to last changes --- nf-core-a | 1 + nf_core/pipelines/create/nfcorepipeline.py | 2 +- tests/__snapshots__/test_create_app.ambr | 2635 ++++++++++---------- tests/test_create_app.py | 5 + 4 files changed, 1339 insertions(+), 1304 deletions(-) create mode 160000 nf-core-a diff --git a/nf-core-a b/nf-core-a new file mode 160000 index 0000000000..6a887ed6eb --- /dev/null +++ b/nf-core-a @@ -0,0 +1 @@ +Subproject commit 6a887ed6ebd510b597a45c4acc505d830313950b diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py index f9bd45733c..8306e93263 100644 --- a/nf_core/pipelines/create/nfcorepipeline.py +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -18,7 +18,7 @@ def compose(self) -> ComposeResult: yield Markdown( dedent( """ - # Pipeline features + # Template features """ ) ) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index 6ee9c9b9b1..b0a306adc2 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -22,250 +22,253 @@ font-weight: 700; } - .terminal-2900179749-matrix { + .terminal-1527309810-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2900179749-title { + .terminal-1527309810-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2900179749-r1 { fill: #c5c8c6 } - .terminal-2900179749-r2 { fill: #e3e3e3 } - .terminal-2900179749-r3 { fill: #989898 } - .terminal-2900179749-r4 { fill: #e1e1e1 } - .terminal-2900179749-r5 { fill: #121212 } - .terminal-2900179749-r6 { fill: #0053aa } - .terminal-2900179749-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2900179749-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-2900179749-r9 { fill: #1e1e1e } - .terminal-2900179749-r10 { fill: #008139 } - .terminal-2900179749-r11 { fill: #e2e2e2 } - .terminal-2900179749-r12 { fill: #787878 } - .terminal-2900179749-r13 { fill: #b93c5b } - .terminal-2900179749-r14 { fill: #7ae998 } - .terminal-2900179749-r15 { fill: #0a180e;font-weight: bold } - .terminal-2900179749-r16 { fill: #ddedf9 } + .terminal-1527309810-r1 { fill: #c5c8c6 } + .terminal-1527309810-r2 { fill: #e3e3e3 } + .terminal-1527309810-r3 { fill: #989898 } + .terminal-1527309810-r4 { fill: #e1e1e1 } + .terminal-1527309810-r5 { fill: #121212 } + .terminal-1527309810-r6 { fill: #0053aa } + .terminal-1527309810-r7 { fill: #dde8f3;font-weight: bold } + .terminal-1527309810-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-1527309810-r9 { fill: #1e1e1e } + .terminal-1527309810-r10 { fill: #008139 } + .terminal-1527309810-r11 { fill: #e2e2e2 } + .terminal-1527309810-r12 { fill: #787878 } + .terminal-1527309810-r13 { fill: #b93c5b } + .terminal-1527309810-r14 { fill: #454a50 } + .terminal-1527309810-r15 { fill: #7ae998 } + .terminal-1527309810-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-1527309810-r17 { fill: #0a180e;font-weight: bold } + .terminal-1527309810-r18 { fill: #000000 } + .terminal-1527309810-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Next - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -295,253 +298,256 @@ font-weight: 700; } - .terminal-1441415707-matrix { + .terminal-2230840552-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1441415707-title { + .terminal-2230840552-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1441415707-r1 { fill: #c5c8c6 } - .terminal-1441415707-r2 { fill: #e3e3e3 } - .terminal-1441415707-r3 { fill: #989898 } - .terminal-1441415707-r4 { fill: #e1e1e1 } - .terminal-1441415707-r5 { fill: #121212 } - .terminal-1441415707-r6 { fill: #0053aa } - .terminal-1441415707-r7 { fill: #dde8f3;font-weight: bold } - .terminal-1441415707-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-1441415707-r9 { fill: #1e1e1e } - .terminal-1441415707-r10 { fill: #0f4e2a } - .terminal-1441415707-r11 { fill: #0178d4 } - .terminal-1441415707-r12 { fill: #a7a7a7 } - .terminal-1441415707-r13 { fill: #787878 } - .terminal-1441415707-r14 { fill: #e2e2e2 } - .terminal-1441415707-r15 { fill: #b93c5b } - .terminal-1441415707-r16 { fill: #7ae998 } - .terminal-1441415707-r17 { fill: #0a180e;font-weight: bold } - .terminal-1441415707-r18 { fill: #008139 } - .terminal-1441415707-r19 { fill: #ddedf9 } + .terminal-2230840552-r1 { fill: #c5c8c6 } + .terminal-2230840552-r2 { fill: #e3e3e3 } + .terminal-2230840552-r3 { fill: #989898 } + .terminal-2230840552-r4 { fill: #e1e1e1 } + .terminal-2230840552-r5 { fill: #121212 } + .terminal-2230840552-r6 { fill: #0053aa } + .terminal-2230840552-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2230840552-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-2230840552-r9 { fill: #1e1e1e } + .terminal-2230840552-r10 { fill: #0f4e2a } + .terminal-2230840552-r11 { fill: #0178d4 } + .terminal-2230840552-r12 { fill: #a7a7a7 } + .terminal-2230840552-r13 { fill: #787878 } + .terminal-2230840552-r14 { fill: #e2e2e2 } + .terminal-2230840552-r15 { fill: #b93c5b } + .terminal-2230840552-r16 { fill: #454a50 } + .terminal-2230840552-r17 { fill: #7ae998 } + .terminal-2230840552-r18 { fill: #e2e3e3;font-weight: bold } + .terminal-2230840552-r19 { fill: #0a180e;font-weight: bold } + .terminal-2230840552-r20 { fill: #000000 } + .terminal-2230840552-r21 { fill: #008139 } + .terminal-2230840552-r22 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Next - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -845,255 +851,257 @@ font-weight: 700; } - .terminal-3545740190-matrix { + .terminal-2112272033-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3545740190-title { + .terminal-2112272033-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3545740190-r1 { fill: #c5c8c6 } - .terminal-3545740190-r2 { fill: #e3e3e3 } - .terminal-3545740190-r3 { fill: #989898 } - .terminal-3545740190-r4 { fill: #1e1e1e } - .terminal-3545740190-r5 { fill: #0178d4 } - .terminal-3545740190-r6 { fill: #e1e1e1 } - .terminal-3545740190-r7 { fill: #454a50 } - .terminal-3545740190-r8 { fill: #e2e2e2 } - .terminal-3545740190-r9 { fill: #808080 } - .terminal-3545740190-r10 { fill: #e2e3e3;font-weight: bold } - .terminal-3545740190-r11 { fill: #000000 } - .terminal-3545740190-r12 { fill: #e4e4e4 } - .terminal-3545740190-r13 { fill: #14191f } - .terminal-3545740190-r14 { fill: #507bb3 } - .terminal-3545740190-r15 { fill: #dde6ed;font-weight: bold } - .terminal-3545740190-r16 { fill: #001541 } - .terminal-3545740190-r17 { fill: #7ae998 } - .terminal-3545740190-r18 { fill: #0a180e;font-weight: bold } - .terminal-3545740190-r19 { fill: #008139 } - .terminal-3545740190-r20 { fill: #dde8f3;font-weight: bold } - .terminal-3545740190-r21 { fill: #ddedf9 } + .terminal-2112272033-r1 { fill: #c5c8c6 } + .terminal-2112272033-r2 { fill: #e3e3e3 } + .terminal-2112272033-r3 { fill: #989898 } + .terminal-2112272033-r4 { fill: #e1e1e1 } + .terminal-2112272033-r5 { fill: #121212 } + .terminal-2112272033-r6 { fill: #0053aa } + .terminal-2112272033-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2112272033-r8 { fill: #1e1e1e } + .terminal-2112272033-r9 { fill: #0178d4 } + .terminal-2112272033-r10 { fill: #454a50 } + .terminal-2112272033-r11 { fill: #e2e2e2 } + .terminal-2112272033-r12 { fill: #808080 } + .terminal-2112272033-r13 { fill: #e2e3e3;font-weight: bold } + .terminal-2112272033-r14 { fill: #000000 } + .terminal-2112272033-r15 { fill: #e4e4e4 } + .terminal-2112272033-r16 { fill: #14191f } + .terminal-2112272033-r17 { fill: #507bb3 } + .terminal-2112272033-r18 { fill: #dde6ed;font-weight: bold } + .terminal-2112272033-r19 { fill: #001541 } + .terminal-2112272033-r20 { fill: #7ae998 } + .terminal-2112272033-r21 { fill: #0a180e;font-weight: bold } + .terminal-2112272033-r22 { fill: #008139 } + .terminal-2112272033-r23 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference genomesThe pipeline will be Hide help - ▁▁▁▁▁▁▁▁configured to use a copy ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - of the most common  - reference genome files  - from iGenomes - - - - Nf-core pipelines are configured to use a copy of the most common  - reference genome files. - - By selecting this option, your pipeline will include a configuration - file specifying the paths to these files. - - The required code to use these files will also be included in the  - template. When the pipeline user provides an appropriate genome key,▆▆ - the pipeline will automatically download the required reference  - files. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github CI testsThe pipeline will includeShow help - ▁▁▁▁▁▁▁▁several GitHub actions ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - for Continuous  - Integration (CI) testing - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github badgesThe README.md file of theShow help - ▁▁▁▁▁▁▁▁pipeline will include ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - GitHub badges - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add configuration filesThe pipeline will includeShow help - ▁▁▁▁▁▁▁▁configuration profiles ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - containing custom  - parameters requried to  - run nf-core pipelines at  - different institutions - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Continue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Template features + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference The pipeline will beHide help + ▁▁▁▁▁▁▁▁genomesconfigured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + copy of the most  + common reference  + genome files from  + iGenomes + + + + Nf-core pipelines are configured to use a copy of the most + common reference genome files. + + By selecting this option, your pipeline will include a  + configuration file specifying the paths to these files. + + The required code to use these files will also be included + in the template. When the pipeline user provides an ▆▆ + appropriate genome key, the pipeline will automatically  + download the required reference files. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github CI testsThe pipeline will Show help + ▁▁▁▁▁▁▁▁include several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + GitHub actions for  + Continuous  + Integration (CI)  + testing + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▂▂ + Add Github badgesThe README.md file Show help + ▁▁▁▁▁▁▁▁of the pipeline will▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + include GitHub  + badges + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add configuration The pipeline will Show help + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  @@ -1123,249 +1131,253 @@ font-weight: 700; } - .terminal-3890482819-matrix { + .terminal-2426593002-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3890482819-title { + .terminal-2426593002-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3890482819-r1 { fill: #c5c8c6 } - .terminal-3890482819-r2 { fill: #e3e3e3 } - .terminal-3890482819-r3 { fill: #989898 } - .terminal-3890482819-r4 { fill: #e1e1e1 } - .terminal-3890482819-r5 { fill: #121212 } - .terminal-3890482819-r6 { fill: #0053aa } - .terminal-3890482819-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3890482819-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-3890482819-r9 { fill: #1e1e1e } - .terminal-3890482819-r10 { fill: #008139 } - .terminal-3890482819-r11 { fill: #e2e2e2 } - .terminal-3890482819-r12 { fill: #b93c5b } - .terminal-3890482819-r13 { fill: #7ae998 } - .terminal-3890482819-r14 { fill: #0a180e;font-weight: bold } - .terminal-3890482819-r15 { fill: #ddedf9 } + .terminal-2426593002-r1 { fill: #c5c8c6 } + .terminal-2426593002-r2 { fill: #e3e3e3 } + .terminal-2426593002-r3 { fill: #989898 } + .terminal-2426593002-r4 { fill: #e1e1e1 } + .terminal-2426593002-r5 { fill: #121212 } + .terminal-2426593002-r6 { fill: #0053aa } + .terminal-2426593002-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2426593002-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-2426593002-r9 { fill: #1e1e1e } + .terminal-2426593002-r10 { fill: #008139 } + .terminal-2426593002-r11 { fill: #e2e2e2 } + .terminal-2426593002-r12 { fill: #b93c5b } + .terminal-2426593002-r13 { fill: #808080 } + .terminal-2426593002-r14 { fill: #454a50 } + .terminal-2426593002-r15 { fill: #7ae998 } + .terminal-2426593002-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-2426593002-r17 { fill: #0a180e;font-weight: bold } + .terminal-2426593002-r18 { fill: #000000 } + .terminal-2426593002-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Final details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - First version of the pipelinePath to the output directory where the pipeline  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created - 1.0.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔If the pipeline output directory exists, remove it and continue. - - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Finish - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Final details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + First version of the pipelinePath to the output directory where the pipeline  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created + 1.0.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔Force + If the pipeline output directory exists, remove it and continue. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackFinish + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -1395,255 +1407,257 @@ font-weight: 700; } - .terminal-4207832566-matrix { + .terminal-368636757-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4207832566-title { + .terminal-368636757-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4207832566-r1 { fill: #c5c8c6 } - .terminal-4207832566-r2 { fill: #e3e3e3 } - .terminal-4207832566-r3 { fill: #989898 } - .terminal-4207832566-r4 { fill: #e1e1e1 } - .terminal-4207832566-r5 { fill: #121212 } - .terminal-4207832566-r6 { fill: #0053aa } - .terminal-4207832566-r7 { fill: #dde8f3;font-weight: bold } - .terminal-4207832566-r8 { fill: #454a50 } - .terminal-4207832566-r9 { fill: #a5a5a5;font-style: italic; } - .terminal-4207832566-r10 { fill: #e2e3e3;font-weight: bold } - .terminal-4207832566-r11 { fill: #1e1e1e } - .terminal-4207832566-r12 { fill: #008139 } - .terminal-4207832566-r13 { fill: #000000 } - .terminal-4207832566-r14 { fill: #e2e2e2 } - .terminal-4207832566-r15 { fill: #b93c5b } - .terminal-4207832566-r16 { fill: #7ae998 } - .terminal-4207832566-r17 { fill: #507bb3 } - .terminal-4207832566-r18 { fill: #0a180e;font-weight: bold } - .terminal-4207832566-r19 { fill: #dde6ed;font-weight: bold } - .terminal-4207832566-r20 { fill: #001541 } - .terminal-4207832566-r21 { fill: #ddedf9 } + .terminal-368636757-r1 { fill: #c5c8c6 } + .terminal-368636757-r2 { fill: #e3e3e3 } + .terminal-368636757-r3 { fill: #989898 } + .terminal-368636757-r4 { fill: #e1e1e1 } + .terminal-368636757-r5 { fill: #121212 } + .terminal-368636757-r6 { fill: #0053aa } + .terminal-368636757-r7 { fill: #dde8f3;font-weight: bold } + .terminal-368636757-r8 { fill: #454a50 } + .terminal-368636757-r9 { fill: #a5a5a5;font-style: italic; } + .terminal-368636757-r10 { fill: #e2e3e3;font-weight: bold } + .terminal-368636757-r11 { fill: #1e1e1e } + .terminal-368636757-r12 { fill: #008139 } + .terminal-368636757-r13 { fill: #000000 } + .terminal-368636757-r14 { fill: #787878 } + .terminal-368636757-r15 { fill: #e2e2e2 } + .terminal-368636757-r16 { fill: #b93c5b } + .terminal-368636757-r17 { fill: #808080 } + .terminal-368636757-r18 { fill: #7ae998 } + .terminal-368636757-r19 { fill: #507bb3 } + .terminal-368636757-r20 { fill: #0a180e;font-weight: bold } + .terminal-368636757-r21 { fill: #dde6ed;font-weight: bold } + .terminal-368636757-r22 { fill: #001541 } + .terminal-368636757-r23 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create a GitHub repo - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - After creating the pipeline template locally, we can create a GitHub repository and push the - code to it. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Your GitHub usernameYour GitHub personal access token for Show - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔login.▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - mirpedrol▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁•••••••••••••••••••••••••••••••••••• - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Please select the the GitHub repository settings: - - - ▔▔▔▔▔▔▔▔Select if the new GitHub repo must be private. - - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔Select if you would like to push all the pipeline template files to your GitHub repo - and all the branches required to keep the pipeline up to date with new releases of nf-core - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Create GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create a GitHub repo + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + After creating the pipeline template locally, we can create a GitHub repository and push the + code to it. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Your GitHub usernameYour GitHub personal access token for Show + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔login.▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Please select the the GitHub repository settings: + + + ▔▔▔▔▔▔▔▔Private + Select if the new GitHub repo must be private. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔Push files + Select if you would like to push all the pipeline template files to your GitHub repo + ▁▁▁▁▁▁▁▁and all the branches required to keep the pipeline up to date with new releases of  + nf-core. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackCreate GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -1673,253 +1687,255 @@ font-weight: 700; } - .terminal-1481614550-matrix { + .terminal-1480303962-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1481614550-title { + .terminal-1480303962-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1481614550-r1 { fill: #c5c8c6 } - .terminal-1481614550-r2 { fill: #e3e3e3 } - .terminal-1481614550-r3 { fill: #989898 } - .terminal-1481614550-r4 { fill: #e1e1e1 } - .terminal-1481614550-r5 { fill: #98a84b } - .terminal-1481614550-r6 { fill: #626262 } - .terminal-1481614550-r7 { fill: #608ab1 } - .terminal-1481614550-r8 { fill: #d0b344 } - .terminal-1481614550-r9 { fill: #4ebf71;font-weight: bold } - .terminal-1481614550-r10 { fill: #d2d2d2 } - .terminal-1481614550-r11 { fill: #82aaff } - .terminal-1481614550-r12 { fill: #eeffff } - .terminal-1481614550-r13 { fill: #7ae998 } - .terminal-1481614550-r14 { fill: #507bb3 } - .terminal-1481614550-r15 { fill: #dde6ed;font-weight: bold } - .terminal-1481614550-r16 { fill: #008139 } - .terminal-1481614550-r17 { fill: #001541 } - .terminal-1481614550-r18 { fill: #dde8f3;font-weight: bold } - .terminal-1481614550-r19 { fill: #ddedf9 } + .terminal-1480303962-r1 { fill: #c5c8c6 } + .terminal-1480303962-r2 { fill: #e3e3e3 } + .terminal-1480303962-r3 { fill: #989898 } + .terminal-1480303962-r4 { fill: #e1e1e1 } + .terminal-1480303962-r5 { fill: #121212 } + .terminal-1480303962-r6 { fill: #0053aa } + .terminal-1480303962-r7 { fill: #dde8f3;font-weight: bold } + .terminal-1480303962-r8 { fill: #98a84b } + .terminal-1480303962-r9 { fill: #626262 } + .terminal-1480303962-r10 { fill: #608ab1 } + .terminal-1480303962-r11 { fill: #d0b344 } + .terminal-1480303962-r12 { fill: #4ebf71;font-weight: bold } + .terminal-1480303962-r13 { fill: #d2d2d2 } + .terminal-1480303962-r14 { fill: #82aaff } + .terminal-1480303962-r15 { fill: #eeffff } + .terminal-1480303962-r16 { fill: #7ae998 } + .terminal-1480303962-r17 { fill: #507bb3 } + .terminal-1480303962-r18 { fill: #dde6ed;font-weight: bold } + .terminal-1480303962-r19 { fill: #008139 } + .terminal-1480303962-r20 { fill: #001541 } + .terminal-1480303962-r21 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - - If you would like to create the GitHub repository later, you can do it manually by following - these steps: - -  1. Create a new GitHub repository -  2. Add the remote to your local repository - - - cd<pipeline_directory> - gitremoteaddorigingit@github.com:<username>/<repo_name>.git - - -  3. Push the code to the remote - - - gitpush--allorigin - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close AppShow Logging - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + HowTo create a GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + + If you would like to create the GitHub repository later, you can do it manually by following + these steps: + +  1. Create a new GitHub repository +  2. Add the remote to your local repository + + + cd<pipeline_directory> + gitremoteaddorigingit@github.com:<username>/<repo_name>.git + + +  3. Push the code to the remote + + + gitpush--allorigin + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close AppShow Logging + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -1949,248 +1965,248 @@ font-weight: 700; } - .terminal-3406096395-matrix { + .terminal-4165331380-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3406096395-title { + .terminal-4165331380-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3406096395-r1 { fill: #c5c8c6 } - .terminal-3406096395-r2 { fill: #e3e3e3 } - .terminal-3406096395-r3 { fill: #989898 } - .terminal-3406096395-r4 { fill: #e1e1e1 } - .terminal-3406096395-r5 { fill: #121212 } - .terminal-3406096395-r6 { fill: #0053aa } - .terminal-3406096395-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3406096395-r8 { fill: #7ae998 } - .terminal-3406096395-r9 { fill: #507bb3 } - .terminal-3406096395-r10 { fill: #4ebf71;font-weight: bold } - .terminal-3406096395-r11 { fill: #dde6ed;font-weight: bold } - .terminal-3406096395-r12 { fill: #008139 } - .terminal-3406096395-r13 { fill: #001541 } - .terminal-3406096395-r14 { fill: #ddedf9 } + .terminal-4165331380-r1 { fill: #c5c8c6 } + .terminal-4165331380-r2 { fill: #e3e3e3 } + .terminal-4165331380-r3 { fill: #989898 } + .terminal-4165331380-r4 { fill: #e1e1e1 } + .terminal-4165331380-r5 { fill: #121212 } + .terminal-4165331380-r6 { fill: #0053aa } + .terminal-4165331380-r7 { fill: #dde8f3;font-weight: bold } + .terminal-4165331380-r8 { fill: #7ae998 } + .terminal-4165331380-r9 { fill: #507bb3 } + .terminal-4165331380-r10 { fill: #4ebf71;font-weight: bold } + .terminal-4165331380-r11 { fill: #dde6ed;font-weight: bold } + .terminal-4165331380-r12 { fill: #008139 } + .terminal-4165331380-r13 { fill: #001541 } + .terminal-4165331380-r14 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create a GitHub repo - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - After creating the pipeline template locally, we can create a GitHub repository and push the - code to it. - - Do you want to create a GitHub repository? - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Create GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + After creating the pipeline template locally, we can create a GitHub repository and push the + code to it. + + Do you want to create a GitHub repository? + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Create GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -2220,249 +2236,254 @@ font-weight: 700; } - .terminal-2624233686-matrix { + .terminal-3762159600-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2624233686-title { + .terminal-3762159600-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2624233686-r1 { fill: #c5c8c6 } - .terminal-2624233686-r2 { fill: #e3e3e3 } - .terminal-2624233686-r3 { fill: #989898 } - .terminal-2624233686-r4 { fill: #1e1e1e } - .terminal-2624233686-r5 { fill: #e1e1e1 } - .terminal-2624233686-r6 { fill: #507bb3 } - .terminal-2624233686-r7 { fill: #e2e2e2 } - .terminal-2624233686-r8 { fill: #808080 } - .terminal-2624233686-r9 { fill: #dde6ed;font-weight: bold } - .terminal-2624233686-r10 { fill: #001541 } - .terminal-2624233686-r11 { fill: #7ae998 } - .terminal-2624233686-r12 { fill: #0a180e;font-weight: bold } - .terminal-2624233686-r13 { fill: #008139 } - .terminal-2624233686-r14 { fill: #dde8f3;font-weight: bold } - .terminal-2624233686-r15 { fill: #ddedf9 } + .terminal-3762159600-r1 { fill: #c5c8c6 } + .terminal-3762159600-r2 { fill: #e3e3e3 } + .terminal-3762159600-r3 { fill: #989898 } + .terminal-3762159600-r4 { fill: #e1e1e1 } + .terminal-3762159600-r5 { fill: #121212 } + .terminal-3762159600-r6 { fill: #0053aa } + .terminal-3762159600-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3762159600-r8 { fill: #1e1e1e } + .terminal-3762159600-r9 { fill: #507bb3 } + .terminal-3762159600-r10 { fill: #e2e2e2 } + .terminal-3762159600-r11 { fill: #808080 } + .terminal-3762159600-r12 { fill: #dde6ed;font-weight: bold } + .terminal-3762159600-r13 { fill: #001541 } + .terminal-3762159600-r14 { fill: #454a50 } + .terminal-3762159600-r15 { fill: #7ae998 } + .terminal-3762159600-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-3762159600-r17 { fill: #0a180e;font-weight: bold } + .terminal-3762159600-r18 { fill: #000000 } + .terminal-3762159600-r19 { fill: #008139 } + .terminal-3762159600-r20 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference genomesThe pipeline will be Show help - ▁▁▁▁▁▁▁▁configured to use a copy ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - of the most common  - reference genome files  - from iGenomes - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github CI testsThe pipeline will includeShow help - ▁▁▁▁▁▁▁▁several GitHub actions ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - for Continuous  - Integration (CI) testing - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github badgesThe README.md file of theShow help - ▁▁▁▁▁▁▁▁pipeline will include ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - GitHub badges - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add configuration filesThe pipeline will includeShow help - ▁▁▁▁▁▁▁▁configuration profiles ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - containing custom  - parameters requried to  - run nf-core pipelines at  - different institutions - - - - - - - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Continue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Template features + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference genomesThe pipeline will be Show help + ▁▁▁▁▁▁▁▁configured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + copy of the most  + common reference  + genome files from  + iGenomes + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github CI testsThe pipeline will Show help + ▁▁▁▁▁▁▁▁include several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + GitHub actions for  + Continuous  + Integration (CI)  + testing + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github badgesThe README.md file ofShow help + ▁▁▁▁▁▁▁▁the pipeline will ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + include GitHub badges + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add configuration The pipeline will Show help + ▁▁▁▁▁▁▁▁filesinclude configuration▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + profiles containing  + custom parameters  + requried to run  + nf-core pipelines at  + different  + institutions + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  @@ -2492,249 +2513,254 @@ font-weight: 700; } - .terminal-1728001786-matrix { + .terminal-1488796558-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1728001786-title { + .terminal-1488796558-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1728001786-r1 { fill: #c5c8c6 } - .terminal-1728001786-r2 { fill: #e3e3e3 } - .terminal-1728001786-r3 { fill: #989898 } - .terminal-1728001786-r4 { fill: #1e1e1e } - .terminal-1728001786-r5 { fill: #e1e1e1 } - .terminal-1728001786-r6 { fill: #507bb3 } - .terminal-1728001786-r7 { fill: #e2e2e2 } - .terminal-1728001786-r8 { fill: #808080 } - .terminal-1728001786-r9 { fill: #dde6ed;font-weight: bold } - .terminal-1728001786-r10 { fill: #001541 } - .terminal-1728001786-r11 { fill: #7ae998 } - .terminal-1728001786-r12 { fill: #0a180e;font-weight: bold } - .terminal-1728001786-r13 { fill: #008139 } - .terminal-1728001786-r14 { fill: #dde8f3;font-weight: bold } - .terminal-1728001786-r15 { fill: #ddedf9 } + .terminal-1488796558-r1 { fill: #c5c8c6 } + .terminal-1488796558-r2 { fill: #e3e3e3 } + .terminal-1488796558-r3 { fill: #989898 } + .terminal-1488796558-r4 { fill: #e1e1e1 } + .terminal-1488796558-r5 { fill: #121212 } + .terminal-1488796558-r6 { fill: #0053aa } + .terminal-1488796558-r7 { fill: #dde8f3;font-weight: bold } + .terminal-1488796558-r8 { fill: #1e1e1e } + .terminal-1488796558-r9 { fill: #507bb3 } + .terminal-1488796558-r10 { fill: #e2e2e2 } + .terminal-1488796558-r11 { fill: #808080 } + .terminal-1488796558-r12 { fill: #dde6ed;font-weight: bold } + .terminal-1488796558-r13 { fill: #001541 } + .terminal-1488796558-r14 { fill: #454a50 } + .terminal-1488796558-r15 { fill: #7ae998 } + .terminal-1488796558-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-1488796558-r17 { fill: #0a180e;font-weight: bold } + .terminal-1488796558-r18 { fill: #000000 } + .terminal-1488796558-r19 { fill: #008139 } + .terminal-1488796558-r20 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference genomesThe pipeline will be Show help - ▁▁▁▁▁▁▁▁configured to use a copy ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - of the most common  - reference genome files  - from iGenomes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Continue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Template features + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference genomesThe pipeline will be Show help + ▁▁▁▁▁▁▁▁configured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + copy of the most  + common reference  + genome files from  + iGenomes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  @@ -2764,253 +2790,256 @@ font-weight: 700; } - .terminal-2559761451-matrix { + .terminal-2179958535-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2559761451-title { + .terminal-2179958535-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2559761451-r1 { fill: #c5c8c6 } - .terminal-2559761451-r2 { fill: #e3e3e3 } - .terminal-2559761451-r3 { fill: #989898 } - .terminal-2559761451-r4 { fill: #e1e1e1 } - .terminal-2559761451-r5 { fill: #121212 } - .terminal-2559761451-r6 { fill: #0053aa } - .terminal-2559761451-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2559761451-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-2559761451-r9 { fill: #1e1e1e } - .terminal-2559761451-r10 { fill: #0f4e2a } - .terminal-2559761451-r11 { fill: #7b3042 } - .terminal-2559761451-r12 { fill: #a7a7a7 } - .terminal-2559761451-r13 { fill: #787878 } - .terminal-2559761451-r14 { fill: #e2e2e2 } - .terminal-2559761451-r15 { fill: #b93c5b } - .terminal-2559761451-r16 { fill: #166d39 } - .terminal-2559761451-r17 { fill: #3c8b54;font-weight: bold } - .terminal-2559761451-r18 { fill: #5aa86f } - .terminal-2559761451-r19 { fill: #ddedf9 } + .terminal-2179958535-r1 { fill: #c5c8c6 } + .terminal-2179958535-r2 { fill: #e3e3e3 } + .terminal-2179958535-r3 { fill: #989898 } + .terminal-2179958535-r4 { fill: #e1e1e1 } + .terminal-2179958535-r5 { fill: #121212 } + .terminal-2179958535-r6 { fill: #0053aa } + .terminal-2179958535-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2179958535-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-2179958535-r9 { fill: #1e1e1e } + .terminal-2179958535-r10 { fill: #0f4e2a } + .terminal-2179958535-r11 { fill: #7b3042 } + .terminal-2179958535-r12 { fill: #a7a7a7 } + .terminal-2179958535-r13 { fill: #787878 } + .terminal-2179958535-r14 { fill: #e2e2e2 } + .terminal-2179958535-r15 { fill: #b93c5b } + .terminal-2179958535-r16 { fill: #454a50 } + .terminal-2179958535-r17 { fill: #166d39 } + .terminal-2179958535-r18 { fill: #e2e3e3;font-weight: bold } + .terminal-2179958535-r19 { fill: #3c8b54;font-weight: bold } + .terminal-2179958535-r20 { fill: #000000 } + .terminal-2179958535-r21 { fill: #5aa86f } + .terminal-2179958535-r22 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Must be lowercase without  - punctuation. - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Cannot be left empty. - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Cannot be left empty. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Next - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Must be lowercase without  + punctuation. + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -3040,145 +3069,145 @@ font-weight: 700; } - .terminal-2319623653-matrix { + .terminal-2481518089-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2319623653-title { + .terminal-2481518089-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2319623653-r1 { fill: #c5c8c6 } - .terminal-2319623653-r2 { fill: #e3e3e3 } - .terminal-2319623653-r3 { fill: #989898 } - .terminal-2319623653-r4 { fill: #1e1e1e } - .terminal-2319623653-r5 { fill: #e1e1e1 } - .terminal-2319623653-r6 { fill: #98a84b } - .terminal-2319623653-r7 { fill: #626262 } - .terminal-2319623653-r8 { fill: #608ab1 } - .terminal-2319623653-r9 { fill: #d0b344 } - .terminal-2319623653-r10 { fill: #121212 } - .terminal-2319623653-r11 { fill: #0053aa } - .terminal-2319623653-r12 { fill: #dde8f3;font-weight: bold } - .terminal-2319623653-r13 { fill: #e1e1e1;text-decoration: underline; } - .terminal-2319623653-r14 { fill: #14191f } - .terminal-2319623653-r15 { fill: #ddedf9 } + .terminal-2481518089-r1 { fill: #c5c8c6 } + .terminal-2481518089-r2 { fill: #e3e3e3 } + .terminal-2481518089-r3 { fill: #989898 } + .terminal-2481518089-r4 { fill: #1e1e1e } + .terminal-2481518089-r5 { fill: #e1e1e1 } + .terminal-2481518089-r6 { fill: #121212 } + .terminal-2481518089-r7 { fill: #0053aa } + .terminal-2481518089-r8 { fill: #dde8f3;font-weight: bold } + .terminal-2481518089-r9 { fill: #98a84b } + .terminal-2481518089-r10 { fill: #626262 } + .terminal-2481518089-r11 { fill: #608ab1 } + .terminal-2481518089-r12 { fill: #d0b344 } + .terminal-2481518089-r13 { fill: #14191f } + .terminal-2481518089-r14 { fill: #e1e1e1;text-decoration: underline; } + .terminal-2481518089-r15 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pip… - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - nf-core create - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - This app will help you create a new nf-core pipeline. It uses the  - nf-core pipeline template, which is kept within the nf-core/tools  - repository. - - Using this tool is mandatory when making a pipeline that may be part  - of the nf-core community collection at some point. However, this tool  - can also be used to create pipelines that will never be part of ▁▁ - nf-core. You can still benefit from the community best practices for  - your own workflow. - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pip… + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create a pipeline from the nf-core template + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + +                                         ,--./,-. +         ___     __   __   __   ___     /,-._.--~\ + |\ | |__  __ /  ` /  \ |__) |__         }  { +    | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                        `._,._,' + ▇▇ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + nf-core create + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This app will help you create a new nf-core pipeline. It uses the  + nf-core pipeline template, which is kept within the nf-core/tools  + repository. + +  D Toggle dark mode  Q  Quit  diff --git a/tests/test_create_app.py b/tests/test_create_app.py index 710359e945..b6b05ab58f 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -231,6 +231,7 @@ def test_github_details(mock_init_pipeline, snap_compare): """ async def run_before(pilot) -> None: + delete = ["backspace"] * 50 await pilot.click("#start") await pilot.click("#type_nfcore") await pilot.click("#name") @@ -244,6 +245,10 @@ async def run_before(pilot) -> None: await pilot.click("#finish") await pilot.click("#close_screen") await pilot.click("#github_repo") + await pilot.click("#gh_username") + await pilot.press(*delete) # delete field automatically filled using github CLI + await pilot.press("tab") + await pilot.press(*delete) assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) From 2943098ce9d74e3a363dcd12832b209793b2894d Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 6 Mar 2024 15:48:23 +0100 Subject: [PATCH 070/175] some fixes after merging dev to textual-create branch --- .github/actions/create-lint-wf/action.yml | 2 +- tests/lint/template_strings.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/actions/create-lint-wf/action.yml b/.github/actions/create-lint-wf/action.yml index fba0ff3434..5b7dbfffeb 100644 --- a/.github/actions/create-lint-wf/action.yml +++ b/.github/actions/create-lint-wf/action.yml @@ -27,7 +27,7 @@ runs: run: | mkdir -p create-lint-wf && cd create-lint-wf export NXF_WORK=$(pwd) - nf-core --log-file log.txt pipelines create -n testpipeline -d "This pipeline is for testing" -a "Testing McTestface" --plain + nf-core --log-file log.txt pipelines create -n testpipeline -d "This pipeline is for testing" -a "Testing McTestface" # Try syncing it before we change anything - name: nf-core sync diff --git a/tests/lint/template_strings.py b/tests/lint/template_strings.py index ac0ae01681..50c956b217 100644 --- a/tests/lint/template_strings.py +++ b/tests/lint/template_strings.py @@ -1,8 +1,8 @@ import subprocess from pathlib import Path -import nf_core.create import nf_core.lint +import nf_core.pipelines.create def test_template_strings(self): @@ -16,7 +16,6 @@ def test_template_strings(self): lint_obj = nf_core.lint.PipelineLint(new_pipeline) lint_obj._load() result = lint_obj.template_strings() - print(result["failed"]) assert len(result["failed"]) == 1 assert len(result["ignored"]) == 0 From 3cfdc783fe4f6ec9eb811825f04294b198fa69f9 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 6 Mar 2024 16:35:39 +0100 Subject: [PATCH 071/175] fix packaging. Thanks @mashehu for the debugging help --- MANIFEST.in | 1 + nf_core/__main__.py | 8 +++++++- nf_core/pipelines/__init__.py | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 nf_core/pipelines/__init__.py diff --git a/MANIFEST.in b/MANIFEST.in index 5ec177b783..68f115d97f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -9,3 +9,4 @@ include nf_core/assets/logo/nf-core-repo-logo-base-lightbg.png include nf_core/assets/logo/nf-core-repo-logo-base-darkbg.png include nf_core/assets/logo/placeholder_logo.svg include nf_core/assets/logo/MavenPro-Bold.ttf +include nf_core/pipelines/create/create.tcss diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 937f55ef8d..ea3a24c3d5 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -44,7 +44,7 @@ { "name": "Commands for developers", "commands": [ - "create", + "pipelines", "lint", "modules", "subworkflows", @@ -55,6 +55,12 @@ ], }, ], + "nf-core pipelines": [ + { + "name": "Pipeline commands", + "commands": ["create"], + }, + ], "nf-core modules": [ { "name": "For pipelines", diff --git a/nf_core/pipelines/__init__.py b/nf_core/pipelines/__init__.py new file mode 100644 index 0000000000..bc981c449f --- /dev/null +++ b/nf_core/pipelines/__init__.py @@ -0,0 +1 @@ +from .create import PipelineCreateApp From e7687e94464ee52aa4190c8c12572dfd4e4bf920 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 7 Mar 2024 13:46:50 +0100 Subject: [PATCH 072/175] add changed from dev branch to create.py script --- .../assets/multiqc_config.yml | 4 +- nf_core/pipelines/create/create.py | 90 ++++++------------- 2 files changed, 30 insertions(+), 64 deletions(-) diff --git a/nf_core/pipeline-template/assets/multiqc_config.yml b/nf_core/pipeline-template/assets/multiqc_config.yml index b13b7ae074..cd4e539b31 100644 --- a/nf_core/pipeline-template/assets/multiqc_config.yml +++ b/nf_core/pipeline-template/assets/multiqc_config.yml @@ -1,11 +1,11 @@ report_comment: > {% if 'dev' in version -%} This report has been generated by the {{ name }} - analysis pipeline.{% if branded %} For information about how to interpret these results, please see the + analysis pipeline.{% if is_nfcore %} For information about how to interpret these results, please see the documentation.{% endif %} {%- else %} This report has been generated by the {{ name }} - analysis pipeline.{% if branded %} For information about how to interpret these results, please see the + analysis pipeline.{% if is_nfcore %} For information about how to interpret these results, please see the documentation.{% endif %} {% endif %} report_section_order: diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index dc0c6c7960..51e7da6baf 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -4,22 +4,19 @@ import configparser import logging import os -import random import re import shutil -import time from pathlib import Path from typing import Optional, Union -import filetype # type: ignore import git import jinja2 -import requests import yaml import nf_core import nf_core.schema import nf_core.utils +from nf_core.create_logo import create_logo from nf_core.lint_utils import run_prettier_on_file from nf_core.pipelines.create.utils import CreateConfig @@ -271,15 +268,13 @@ def render_template(self): # Check if the output directory exists if self.outdir.exists(): if self.force: - log.warning( - f"Output directory '{self.outdir}' exists - removing the existing directory as --force specified" - ) - shutil.rmtree(self.outdir) + log.warning(f"Output directory '{self.outdir}' exists - continuing as --force specified") else: log.error(f"Output directory '{self.outdir}' exists!") log.info("Use -f / --force to overwrite existing files") raise UserWarning(f"Output directory '{self.outdir}' exists!") - os.makedirs(self.outdir) + else: + os.makedirs(self.outdir) # Run jinja2 for each file in the template folder env = jinja2.Environment( @@ -296,7 +291,7 @@ def render_template(self): short_name = self.jinja_params["short_name"] rename_files = { "workflows/pipeline.nf": f"workflows/{short_name}.nf", - "lib/WorkflowPipeline.groovy": f"lib/Workflow{short_name.title()}.groovy", + "subworkflows/local/utils_nfcore_pipeline_pipeline/main.nf": f"subworkflows/local/utils_nfcore_{short_name}_pipeline/main.nf", } # Set the paths to skip according to customization @@ -508,57 +503,13 @@ def fix_linting(self): def make_pipeline_logo(self): """Fetch a logo for the new pipeline from the nf-core website""" - - logo_url = f"https://nf-co.re/logo/{self.jinja_params['short_name']}?theme=light" - log.debug(f"Fetching logo from {logo_url}") - - email_logo_path = self.outdir / "assets" / f"{self.jinja_params['name_noslash']}_logo_light.png" - self.download_pipeline_logo(f"{logo_url}?w=600&theme=light", email_logo_path) + email_logo_path = Path(self.outdir) / "assets" + create_logo(text=self.jinja_params["short_name"], dir=email_logo_path, theme="light", force=self.force) for theme in ["dark", "light"]: - readme_logo_url = f"{logo_url}?w=600&theme={theme}" - readme_logo_path = self.outdir / "docs" / "images" / f"{self.jinja_params['name_noslash']}_logo_{theme}.png" - self.download_pipeline_logo(readme_logo_url, readme_logo_path) - - def download_pipeline_logo(self, url, img_fn): - """Attempt to download a logo from the website. Retry if it fails.""" - os.makedirs(os.path.dirname(img_fn), exist_ok=True) - attempt = 0 - max_attempts = 10 - retry_delay = 0 # x up to 10 each time, so first delay will be 1-100 seconds - while attempt < max_attempts: - # If retrying, wait a while - if retry_delay > 0: - log.info(f"Waiting {retry_delay} seconds before next image fetch attempt") - time.sleep(retry_delay) - - attempt += 1 - # Use a random number to avoid the template sync hitting the website simultaneously for all pipelines - retry_delay = random.randint(1, 100) * attempt - log.debug(f"Fetching logo '{img_fn}' (attempt {attempt})") - try: - # Try to fetch the logo from the website - r = requests.get(url, timeout=180) - if r.status_code != 200: - raise UserWarning(f"Got status code {r.status_code}") - # Check that the returned image looks right - - except (ConnectionError, UserWarning) as e: - # Something went wrong - try again - log.warning(e) - log.error("Connection error - retrying") - continue - - # Write the new logo to the file - with open(img_fn, "wb") as fh: - fh.write(r.content) - # Check that the file looks valid - image_type = filetype.guess(img_fn).extension - if image_type != "png": - log.error(f"Logo from the website didn't look like an image: '{image_type}'") - continue - - # Got this far, presumably it's good - break the retry loop - break + readme_logo_path = Path(self.outdir) / "docs" / "images" + create_logo( + text=self.jinja_params["short_name"], dir=readme_logo_path, width=600, theme=theme, force=self.force + ) def git_init_pipeline(self): """Initialises the new pipeline as a Git repository and submits first commit. @@ -587,8 +538,23 @@ def git_init_pipeline(self): repo.index.commit(f"initial template build from nf-core/tools, version {nf_core.__version__}") if default_branch: repo.active_branch.rename(default_branch) - repo.git.branch("TEMPLATE") - repo.git.branch("dev") + try: + repo.git.branch("TEMPLATE") + repo.git.branch("dev") + + except git.GitCommandError as e: + if "already exists" in e.stderr: + log.debug("Branches 'TEMPLATE' and 'dev' already exist") + if self.force: + log.debug("Force option set - deleting branches") + repo.git.branch("-D", "TEMPLATE") + repo.git.branch("-D", "dev") + repo.git.branch("TEMPLATE") + repo.git.branch("dev") + else: + raise UserWarning( + "Branches 'TEMPLATE' and 'dev' already exist. Use --force to overwrite existing branches." + ) log.info( "Done. Remember to add a remote and push to GitHub:\n" f"[white on grey23] cd {self.outdir} \n" From 1debc4b4b1759e1f9562bb9516e3b5cff1e6817b Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 7 Mar 2024 13:53:02 +0100 Subject: [PATCH 073/175] fix back button after validation of basic details --- nf-core-a | 1 - nf_core/pipelines/create/basicdetails.py | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 160000 nf-core-a diff --git a/nf-core-a b/nf-core-a deleted file mode 160000 index 6a887ed6eb..0000000000 --- a/nf-core-a +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6a887ed6ebd510b597a45c4acc505d830313950b diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py index aa2886c1bf..e4f36e4035 100644 --- a/nf_core/pipelines/create/basicdetails.py +++ b/nf_core/pipelines/create/basicdetails.py @@ -69,9 +69,10 @@ def on_button_pressed(self, event: Button.Pressed) -> None: text_input.query_one(".validation_msg").update("") try: self.parent.TEMPLATE_CONFIG = CreateConfig(**config) - if self.parent.PIPELINE_TYPE == "nfcore": - self.parent.push_screen("type_nfcore") - elif self.parent.PIPELINE_TYPE == "custom": - self.parent.push_screen("type_custom") + if event.button.id == "next": + if self.parent.PIPELINE_TYPE == "nfcore": + self.parent.push_screen("type_nfcore") + elif self.parent.PIPELINE_TYPE == "custom": + self.parent.push_screen("type_custom") except ValueError: pass From 41e99a16b5a9721041474daf6ec6f084aaa8ff84 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 7 Mar 2024 14:10:51 +0100 Subject: [PATCH 074/175] move button to close logging screen to the bottom --- nf_core/pipelines/create/__init__.py | 2 +- nf_core/pipelines/create/create.tcss | 6 ++++++ nf_core/pipelines/create/loggingscreen.py | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 126b3db62a..feff20659d 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -21,7 +21,7 @@ ) from nf_core.pipelines.create.welcome import WelcomeScreen -log_handler = CustomLogHandler(console=LoggingConsole(), rich_tracebacks=True, markup=True) +log_handler = CustomLogHandler(console=LoggingConsole(classes="log_console"), rich_tracebacks=True, markup=True) logging.basicConfig( level="INFO", handlers=[log_handler], diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index 51ed5745fe..46b3989017 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -98,3 +98,9 @@ Vertical{ .displayed #hide_password { display: block; } + +/* Logging console */ + +.log_console { + height: auto; +} diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index 3cfe3f8d8b..68b65619c5 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -32,6 +32,7 @@ def compose(self) -> ComposeResult: id="logo", ) yield Markdown(markdown) + yield Center(self.parent.LOG_HANDLER.console) if self.parent.LOGGING_STATE == "repo created": yield Center( Button("Close App", id="close_app", variant="success"), @@ -39,7 +40,6 @@ def compose(self) -> ComposeResult: ) else: yield Center( - Button("Close logging screen", id="close_screen", variant="success", disabled=True), + Button("Continue", id="close_screen", variant="success", disabled=True), classes="cta", ) - yield Center(self.parent.LOG_HANDLER.console, classes="cta") From 67db794a5540307889fed9f04f1d4c0c965c3797 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 7 Mar 2024 14:24:15 +0100 Subject: [PATCH 075/175] Merge branch 'dev' of https://github.com/nf-core/tools into textual-create --- .pre-commit-config.yaml | 4 +- CHANGELOG.md | 3 + nf_core/__init__.py | 2 +- nf_core/__main__.py | 3 +- nf_core/components/components_test.py | 7 +- nf_core/components/create.py | 1 - nf_core/components/lint/__init__.py | 1 - nf_core/components/nfcore_component.py | 1 + nf_core/launch.py | 3 +- nf_core/licences.py | 1 - nf_core/lint/nextflow_config.py | 5 +- nf_core/list.py | 1 - nf_core/modules/bump_versions.py | 1 - nf_core/modules/lint/__init__.py | 1 - nf_core/modules/lint/module_changes.py | 1 + nf_core/modules/lint/module_tests.py | 1 + nf_core/params_file.py | 3 +- .../.github/workflows/ci.yml | 2 +- .../.github/workflows/download_pipeline.yml | 2 +- .../.github/workflows/linting.yml | 2 +- .../pipeline-template/.pre-commit-config.yaml | 3 + nf_core/pipelines/create/create.py | 1 + nf_core/schema.py | 66 ++++++++----------- nf_core/subworkflows/lint/__init__.py | 1 - .../subworkflows/lint/subworkflow_changes.py | 1 + .../subworkflows/lint/subworkflow_tests.py | 1 + nf_core/sync.py | 3 +- nf_core/utils.py | 1 + tests/components/generate_snapshot.py | 1 + tests/components/snapshot_test.py | 1 + tests/test_bump_version.py | 4 +- tests/test_cli.py | 2 +- tests/test_components.py | 3 +- tests/test_create.py | 4 +- tests/test_download.py | 3 +- tests/test_launch.py | 3 +- tests/test_licenses.py | 3 +- tests/test_lint.py | 4 +- tests/test_list.py | 3 +- tests/test_modules.py | 3 +- tests/test_refgenie.py | 3 +- tests/test_schema.py | 3 +- tests/test_subworkflows.py | 3 +- tests/test_sync.py | 3 +- tests/test_utils.py | 3 +- 45 files changed, 79 insertions(+), 92 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 03fbb7bedf..b618e00837 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.2.2 + rev: v0.3.1 hooks: - id: ruff # linter args: [--fix, --exit-non-zero-on-fix] # sort imports and fix @@ -9,6 +9,8 @@ repos: rev: "v3.1.0" hooks: - id: prettier + additional_dependencies: + - prettier@3.2.5 - repo: https://github.com/editorconfig-checker/editorconfig-checker.python rev: "2.7.3" diff --git a/CHANGELOG.md b/CHANGELOG.md index 14ff84e937..2b7ff2ef6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Template +- Update templates to use nf-core/setup-nextflow v2 + ### Linting ### Components @@ -12,6 +14,7 @@ - Update CI to use nf-core/setup-nextflow v2 - Changelog bot: handle also patch version before dev suffix ([#2820](https://github.com/nf-core/tools/pull/2820)) +- update prettier to 3.2.5 ([#2830](https://github.com/nf-core/tools/pull/2830)) - Update GitHub Actions ([#2827](https://github.com/nf-core/tools/pull/2827)) ## [v2.13.1 - Tin Puppy Patch](https://github.com/nf-core/tools/releases/tag/2.13) - [2024-02-29] diff --git a/nf_core/__init__.py b/nf_core/__init__.py index d96be73f3d..2d4fe45a0a 100644 --- a/nf_core/__init__.py +++ b/nf_core/__init__.py @@ -1,4 +1,4 @@ -""" Main nf_core module file. +"""Main nf_core module file. Shouldn't do much, as everything is under subcommands. """ diff --git a/nf_core/__main__.py b/nf_core/__main__.py index ea3a24c3d5..ed256d8fb1 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -1,5 +1,6 @@ #!/usr/bin/env python -""" nf-core: Helper tools for use with nf-core Nextflow pipelines. """ +"""nf-core: Helper tools for use with nf-core Nextflow pipelines.""" + import logging import os import sys diff --git a/nf_core/components/components_test.py b/nf_core/components/components_test.py index f1a9e7c401..9b81f54f06 100644 --- a/nf_core/components/components_test.py +++ b/nf_core/components/components_test.py @@ -2,7 +2,6 @@ The ComponentsTest class handles the generation and testing of nf-test snapshots. """ - import logging import os import re @@ -91,9 +90,9 @@ def run(self) -> None: """Run build steps""" self.check_inputs() os.environ["NFT_DIFF"] = "pdiff" # set nf-test differ to pdiff to get a better diff output - os.environ[ - "NFT_DIFF_ARGS" - ] = "--line-numbers --expand-tabs=2" # taken from https://code.askimed.com/nf-test/docs/assertions/snapshots/#snapshot-differences + os.environ["NFT_DIFF_ARGS"] = ( + "--line-numbers --expand-tabs=2" # taken from https://code.askimed.com/nf-test/docs/assertions/snapshots/#snapshot-differences + ) with nf_core.utils.set_wd(Path(self.dir)): self.check_snapshot_stability() if len(self.errors) > 0: diff --git a/nf_core/components/create.py b/nf_core/components/create.py index c4b477a0ab..d2169e3a72 100644 --- a/nf_core/components/create.py +++ b/nf_core/components/create.py @@ -2,7 +2,6 @@ The ComponentCreate class handles generating of module and subworkflow templates """ - import glob import json import logging diff --git a/nf_core/components/lint/__init__.py b/nf_core/components/lint/__init__.py index 3c2fb9dde3..c99934bca3 100644 --- a/nf_core/components/lint/__init__.py +++ b/nf_core/components/lint/__init__.py @@ -3,7 +3,6 @@ in nf-core pipelines """ - import logging import operator import os diff --git a/nf_core/components/nfcore_component.py b/nf_core/components/nfcore_component.py index 2f73afe9d3..d9731ba7c9 100644 --- a/nf_core/components/nfcore_component.py +++ b/nf_core/components/nfcore_component.py @@ -1,6 +1,7 @@ """ The NFCoreComponent class holds information and utility functions for a single module or subworkflow """ + import logging import re from pathlib import Path diff --git a/nf_core/launch.py b/nf_core/launch.py index 25bb4c150c..bc0cd58aec 100644 --- a/nf_core/launch.py +++ b/nf_core/launch.py @@ -1,5 +1,4 @@ -""" Launch a pipeline, interactively collecting params """ - +"""Launch a pipeline, interactively collecting params""" import copy import json diff --git a/nf_core/licences.py b/nf_core/licences.py index a8a35334dd..be737280f8 100644 --- a/nf_core/licences.py +++ b/nf_core/licences.py @@ -1,6 +1,5 @@ """Lists software licences for a given workflow.""" - import json import logging import os diff --git a/nf_core/lint/nextflow_config.py b/nf_core/lint/nextflow_config.py index d3e29d2363..2e142cde6e 100644 --- a/nf_core/lint/nextflow_config.py +++ b/nf_core/lint/nextflow_config.py @@ -245,10 +245,9 @@ def nextflow_config(self): raise AssertionError() except (AssertionError, IndexError): failed.append( - "Config variable ``manifest.homePage`` did not begin with https://github.com/nf-core/:\n {}".format( - manifest_homepage - ) + f"Config variable ``manifest.homePage`` did not begin with https://github.com/nf-core/:\n {manifest_homepage}" ) + else: passed.append("Config variable ``manifest.homePage`` began with https://github.com/nf-core/") diff --git a/nf_core/list.py b/nf_core/list.py index 67d1a76878..658f4dc6d2 100644 --- a/nf_core/list.py +++ b/nf_core/list.py @@ -1,6 +1,5 @@ """Lists available nf-core pipelines and versions.""" - import json import logging import os diff --git a/nf_core/modules/bump_versions.py b/nf_core/modules/bump_versions.py index b9003be974..9b54174d5a 100644 --- a/nf_core/modules/bump_versions.py +++ b/nf_core/modules/bump_versions.py @@ -3,7 +3,6 @@ or for a single module """ - import logging import os import re diff --git a/nf_core/modules/lint/__init__.py b/nf_core/modules/lint/__init__.py index 866e6312aa..b2816dab6a 100644 --- a/nf_core/modules/lint/__init__.py +++ b/nf_core/modules/lint/__init__.py @@ -6,7 +6,6 @@ nf-core modules lint """ - import logging import os diff --git a/nf_core/modules/lint/module_changes.py b/nf_core/modules/lint/module_changes.py index ee8cabebe1..eb76f4b88b 100644 --- a/nf_core/modules/lint/module_changes.py +++ b/nf_core/modules/lint/module_changes.py @@ -1,6 +1,7 @@ """ Check whether the content of a module has changed compared to the original repository """ + import shutil import tempfile from pathlib import Path diff --git a/nf_core/modules/lint/module_tests.py b/nf_core/modules/lint/module_tests.py index 520f8cf0a2..b1a611d70a 100644 --- a/nf_core/modules/lint/module_tests.py +++ b/nf_core/modules/lint/module_tests.py @@ -1,6 +1,7 @@ """ Lint the tests of a module in nf-core/modules """ + import json import logging from pathlib import Path diff --git a/nf_core/params_file.py b/nf_core/params_file.py index 267fe7086a..78798b065e 100644 --- a/nf_core/params_file.py +++ b/nf_core/params_file.py @@ -1,5 +1,4 @@ -""" Create a YAML parameter file """ - +"""Create a YAML parameter file""" import json import logging diff --git a/nf_core/pipeline-template/.github/workflows/ci.yml b/nf_core/pipeline-template/.github/workflows/ci.yml index 84c727f60d..3880b2c4dc 100644 --- a/nf_core/pipeline-template/.github/workflows/ci.yml +++ b/nf_core/pipeline-template/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - name: Install Nextflow - uses: nf-core/setup-nextflow@v1 + uses: nf-core/setup-nextflow@v2 with: version: "{% raw %}${{ matrix.NXF_VER }}{% endraw %}" diff --git a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml index dcd7caabfc..4fdec4e243 100644 --- a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml +++ b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Nextflow - uses: nf-core/setup-nextflow@v1 + uses: nf-core/setup-nextflow@v2 - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5 with: diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index 59b85f95fc..612467ff6e 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -35,7 +35,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - name: Install Nextflow - uses: nf-core/setup-nextflow@v1 + uses: nf-core/setup-nextflow@v2 - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5 with: diff --git a/nf_core/pipeline-template/.pre-commit-config.yaml b/nf_core/pipeline-template/.pre-commit-config.yaml index af57081f60..4dc0f1dcd7 100644 --- a/nf_core/pipeline-template/.pre-commit-config.yaml +++ b/nf_core/pipeline-template/.pre-commit-config.yaml @@ -3,6 +3,9 @@ repos: rev: "v3.1.0" hooks: - id: prettier + additional_dependencies: + - prettier@3.2.5 + - repo: https://github.com/editorconfig-checker/editorconfig-checker.python rev: "2.7.3" hooks: diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index 51e7da6baf..9347b7e678 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -1,6 +1,7 @@ """Creates a nf-core pipeline matching the current organization's specification based on a template. """ + import configparser import logging import os diff --git a/nf_core/schema.py b/nf_core/schema.py index df04dc5a1e..373f8bbaa1 100644 --- a/nf_core/schema.py +++ b/nf_core/schema.py @@ -1,5 +1,4 @@ -""" Code to deal with pipeline JSON Schema """ - +"""Code to deal with pipeline JSON Schema""" import copy import json @@ -84,16 +83,13 @@ def load_lint_schema(self): self.get_schema_defaults() self.validate_default_params() if len(self.invalid_nextflow_config_default_parameters) > 0: + params = "\n --".join( + [f"{param}: {msg}" for param, msg in self.invalid_nextflow_config_default_parameters.items()] + ) log.info( - "[red][✗] Invalid default parameters found:\n --{}\n\nNOTE: Use null in config for no default.".format( - "\n --".join( - [ - f"{param}: {msg}" - for param, msg in self.invalid_nextflow_config_default_parameters.items() - ] - ) - ) + f"[red][✗] Invalid default parameters found:\n {params} \n\nNOTE: Use null in config for no default." ) + else: log.info(f"[green][✓] Pipeline schema looks valid[/] [dim](found {num_params} params)") except json.decoder.JSONDecodeError as e: @@ -282,9 +278,9 @@ def validate_default_params(self): if param in self.pipeline_params: self.validate_config_default_parameter(param, group_properties[param], self.pipeline_params[param]) else: - self.invalid_nextflow_config_default_parameters[ - param - ] = "Not in pipeline parameters. Check `nextflow.config`." + self.invalid_nextflow_config_default_parameters[param] = ( + "Not in pipeline parameters. Check `nextflow.config`." + ) # Go over ungrouped params if any exist ungrouped_properties = self.schema.get("properties") @@ -297,9 +293,9 @@ def validate_default_params(self): param, ungrouped_properties[param], self.pipeline_params[param] ) else: - self.invalid_nextflow_config_default_parameters[ - param - ] = "Not in pipeline parameters. Check `nextflow.config`." + self.invalid_nextflow_config_default_parameters[param] = ( + "Not in pipeline parameters. Check `nextflow.config`." + ) def validate_config_default_parameter(self, param, schema_param, config_default): """ @@ -314,9 +310,9 @@ def validate_config_default_parameter(self, param, schema_param, config_default) ): # Check that we are not deferring the execution of this parameter in the schema default with squiggly brakcets if schema_param["type"] != "string" or "{" not in schema_param["default"]: - self.invalid_nextflow_config_default_parameters[ - param - ] = f"Schema default (`{schema_param['default']}`) does not match the config default (`{config_default}`)" + self.invalid_nextflow_config_default_parameters[param] = ( + f"Schema default (`{schema_param['default']}`) does not match the config default (`{config_default}`)" + ) return # if default is null, we're good @@ -326,28 +322,28 @@ def validate_config_default_parameter(self, param, schema_param, config_default) # Check variable types in nextflow.config if schema_param["type"] == "string": if str(config_default) in ["false", "true", "''"]: - self.invalid_nextflow_config_default_parameters[ - param - ] = f"String should not be set to `{config_default}`" + self.invalid_nextflow_config_default_parameters[param] = ( + f"String should not be set to `{config_default}`" + ) if schema_param["type"] == "boolean": if str(config_default) not in ["false", "true"]: - self.invalid_nextflow_config_default_parameters[ - param - ] = f"Booleans should only be true or false, not `{config_default}`" + self.invalid_nextflow_config_default_parameters[param] = ( + f"Booleans should only be true or false, not `{config_default}`" + ) if schema_param["type"] == "integer": try: int(config_default) except ValueError: - self.invalid_nextflow_config_default_parameters[ - param - ] = f"Does not look like an integer: `{config_default}`" + self.invalid_nextflow_config_default_parameters[param] = ( + f"Does not look like an integer: `{config_default}`" + ) if schema_param["type"] == "number": try: float(config_default) except ValueError: - self.invalid_nextflow_config_default_parameters[ - param - ] = f"Does not look like a number (float): `{config_default}`" + self.invalid_nextflow_config_default_parameters[param] = ( + f"Does not look like a number (float): `{config_default}`" + ) def validate_schema(self, schema=None): """ @@ -647,17 +643,13 @@ def build_schema(self, pipeline_dir, no_prompts, web_only, url): # Extra help for people running offline if "Could not connect" in e.args[0]: log.info( - "If you're working offline, now copy your schema ({}) and paste at https://nf-co.re/pipeline_schema_builder".format( - self.schema_filename - ) + f"If you're working offline, now copy your schema ({self.schema_filename}) and paste at https://nf-co.re/pipeline_schema_builder" ) log.info("When you're finished, you can paste the edited schema back into the same file") if self.web_schema_build_web_url: log.info( "To save your work, open {}\n" - "Click the blue 'Finished' button, copy the schema and paste into this file: {}".format( - self.web_schema_build_web_url, self.schema_filename - ) + f"Click the blue 'Finished' button, copy the schema and paste into this file: { self.web_schema_build_web_url, self.schema_filename}" ) return False diff --git a/nf_core/subworkflows/lint/__init__.py b/nf_core/subworkflows/lint/__init__.py index 3a87190422..96d2e0ab92 100644 --- a/nf_core/subworkflows/lint/__init__.py +++ b/nf_core/subworkflows/lint/__init__.py @@ -6,7 +6,6 @@ nf-core subworkflows lint """ - import logging import os diff --git a/nf_core/subworkflows/lint/subworkflow_changes.py b/nf_core/subworkflows/lint/subworkflow_changes.py index b7fa13d931..a9c9616a21 100644 --- a/nf_core/subworkflows/lint/subworkflow_changes.py +++ b/nf_core/subworkflows/lint/subworkflow_changes.py @@ -1,6 +1,7 @@ """ Check whether the content of a subworkflow has changed compared to the original repository """ + from pathlib import Path import nf_core.modules.modules_repo diff --git a/nf_core/subworkflows/lint/subworkflow_tests.py b/nf_core/subworkflows/lint/subworkflow_tests.py index f7284320ea..796a56d018 100644 --- a/nf_core/subworkflows/lint/subworkflow_tests.py +++ b/nf_core/subworkflows/lint/subworkflow_tests.py @@ -1,6 +1,7 @@ """ Lint the tests of a subworkflow in nf-core/modules """ + import json import logging from pathlib import Path diff --git a/nf_core/sync.py b/nf_core/sync.py index 4057461bcf..d1dee9a545 100644 --- a/nf_core/sync.py +++ b/nf_core/sync.py @@ -1,5 +1,4 @@ -"""Synchronise a pipeline TEMPLATE branch with the template. -""" +"""Synchronise a pipeline TEMPLATE branch with the template.""" import json import logging diff --git a/nf_core/utils.py b/nf_core/utils.py index e1778b55b3..8ea6f418aa 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -1,6 +1,7 @@ """ Common utility functions for the nf-core python package. """ + import concurrent.futures import datetime import errno diff --git a/tests/components/generate_snapshot.py b/tests/components/generate_snapshot.py index c5067d7210..50024a8ebb 100644 --- a/tests/components/generate_snapshot.py +++ b/tests/components/generate_snapshot.py @@ -1,4 +1,5 @@ """Test generate a snapshot""" + import json from pathlib import Path from unittest.mock import MagicMock diff --git a/tests/components/snapshot_test.py b/tests/components/snapshot_test.py index d774618476..b3fc259770 100644 --- a/tests/components/snapshot_test.py +++ b/tests/components/snapshot_test.py @@ -1,4 +1,5 @@ """Test the 'modules test' or 'subworkflows test' command which runs nf-test test.""" + import shutil from pathlib import Path diff --git a/tests/test_bump_version.py b/tests/test_bump_version.py index 77edd4bfd0..059e18e92e 100644 --- a/tests/test_bump_version.py +++ b/tests/test_bump_version.py @@ -1,5 +1,5 @@ -"""Some tests covering the bump_version code. -""" +"""Some tests covering the bump_version code.""" + import os import yaml diff --git a/tests/test_cli.py b/tests/test_cli.py index 64c024025d..28be5c2a73 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,4 +1,4 @@ -""" Tests covering the command-line code. +"""Tests covering the command-line code. Most tests check the cli arguments are passed along and that some action is taken. diff --git a/tests/test_components.py b/tests/test_components.py index b7f67eb51d..eaf999c3c3 100644 --- a/tests/test_components.py +++ b/tests/test_components.py @@ -1,5 +1,4 @@ -""" Tests covering the modules commands -""" +"""Tests covering the modules commands""" import os import shutil diff --git a/tests/test_create.py b/tests/test_create.py index 5dfd9244c8..313b6f5354 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -1,5 +1,5 @@ -"""Some tests covering the pipeline creation sub command. -""" +"""Some tests covering the pipeline creation sub command.""" + import os import unittest from pathlib import Path diff --git a/tests/test_download.py b/tests/test_download.py index 9d3c285dd5..48ba88f3c9 100644 --- a/tests/test_download.py +++ b/tests/test_download.py @@ -1,5 +1,4 @@ -"""Tests for the download subcommand of nf-core tools -""" +"""Tests for the download subcommand of nf-core tools""" import os import re diff --git a/tests/test_launch.py b/tests/test_launch.py index 7b3ff7d9d4..043055a2d5 100644 --- a/tests/test_launch.py +++ b/tests/test_launch.py @@ -1,5 +1,4 @@ -""" Tests covering the pipeline launch code. -""" +"""Tests covering the pipeline launch code.""" import json import os diff --git a/tests/test_licenses.py b/tests/test_licenses.py index 4fb58a107c..8023c9e891 100644 --- a/tests/test_licenses.py +++ b/tests/test_licenses.py @@ -1,5 +1,4 @@ -"""Some tests covering the pipeline creation sub command. -""" +"""Some tests covering the pipeline creation sub command.""" # import json # import os # import tempfile diff --git a/tests/test_lint.py b/tests/test_lint.py index 558dac8459..31923ea889 100644 --- a/tests/test_lint.py +++ b/tests/test_lint.py @@ -1,5 +1,5 @@ -"""Some tests covering the linting code. -""" +"""Some tests covering the linting code.""" + import fnmatch import json import os diff --git a/tests/test_list.py b/tests/test_list.py index c1f51e03e0..c78276b41d 100644 --- a/tests/test_list.py +++ b/tests/test_list.py @@ -1,5 +1,4 @@ -""" Tests covering the workflow listing code. -""" +"""Tests covering the workflow listing code.""" import json import os diff --git a/tests/test_modules.py b/tests/test_modules.py index 2a3d8795f7..7955d8efa7 100644 --- a/tests/test_modules.py +++ b/tests/test_modules.py @@ -1,5 +1,4 @@ -""" Tests covering the modules commands -""" +"""Tests covering the modules commands""" import os import shutil diff --git a/tests/test_refgenie.py b/tests/test_refgenie.py index 5440c1c477..23cc0dd14a 100644 --- a/tests/test_refgenie.py +++ b/tests/test_refgenie.py @@ -1,5 +1,4 @@ -""" Tests covering the refgenie integration code -""" +"""Tests covering the refgenie integration code""" import os import shlex diff --git a/tests/test_schema.py b/tests/test_schema.py index aab5b5bbb6..d7f4f4d648 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -1,5 +1,4 @@ -""" Tests covering the pipeline schema code. -""" +"""Tests covering the pipeline schema code.""" import json import os diff --git a/tests/test_subworkflows.py b/tests/test_subworkflows.py index f9419ea7ab..23ec98db46 100644 --- a/tests/test_subworkflows.py +++ b/tests/test_subworkflows.py @@ -1,5 +1,4 @@ -""" Tests covering the subworkflows commands -""" +"""Tests covering the subworkflows commands""" import os import shutil diff --git a/tests/test_sync.py b/tests/test_sync.py index 0b9be7353e..f15676f08b 100644 --- a/tests/test_sync.py +++ b/tests/test_sync.py @@ -1,5 +1,4 @@ -""" Tests covering the sync command -""" +"""Tests covering the sync command""" import json import os diff --git a/tests/test_utils.py b/tests/test_utils.py index d0af75bfe3..85f4e3c548 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,5 +1,4 @@ -""" Tests covering for utility functions. -""" +"""Tests covering for utility functions.""" import os import shutil From ed70990a254359325035aeb22dad4b348a5a0590 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Tue, 2 Apr 2024 22:37:12 +0200 Subject: [PATCH 076/175] Remove duplicate lines in changelog from merge conflict resolution --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3679af8235..cbfef3bcc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,6 @@ - Add a cleanup action to `download_pipeline.yml` to fix failures caused by inadequate storage space on the runner ([#2849](https://github.com/nf-core/tools/pull/2849)) - Update python to 3.12 ([#2805](https://github.com/nf-core/tools/pull/2805)) - Remove `pyproject.toml` from template root -- Update templates to use nf-core/setup-nextflow v2 ### Linting @@ -31,7 +30,6 @@ - Changelog bot: handle also patch version before dev suffix ([#2820](https://github.com/nf-core/tools/pull/2820)) - Fix path in component update script ([#2823](https://github.com/nf-core/tools/pull/2823)) - Update prettier to 3.2.5 ([#2830](https://github.com/nf-core/tools/pull/2830)) -- update prettier to 3.2.5 ([#2830](https://github.com/nf-core/tools/pull/2830)) - Update GitHub Actions ([#2827](https://github.com/nf-core/tools/pull/2827)) - Switch to setup-nf-test ([#2834](https://github.com/nf-core/tools/pull/2834)) - Update pre-commit hook astral-sh/ruff-pre-commit to v0.3.2 ([#2836](https://github.com/nf-core/tools/pull/2836)) From 3a540235c74cd4934427ded891ea20261264672c Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Tue, 2 Apr 2024 22:42:38 +0200 Subject: [PATCH 077/175] Raw strings for nf-core ascii artwork Avoids warnings about invalid escape sequences --- nf_core/pipelines/create/error.py | 10 +++++----- nf_core/pipelines/create/githubexit.py | 10 +++++----- nf_core/pipelines/create/loggingscreen.py | 10 +++++----- nf_core/pipelines/create/welcome.py | 10 +++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/nf_core/pipelines/create/error.py b/nf_core/pipelines/create/error.py index 922b5ed544..b738b2a9d2 100644 --- a/nf_core/pipelines/create/error.py +++ b/nf_core/pipelines/create/error.py @@ -20,11 +20,11 @@ def compose(self) -> ComposeResult: ) ) yield Static( - f"\n[green]{' ' * 40},--.[grey39]/[green],-." - + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + "\n[green] `._,._,'\n", + rf"\n[green]{' ' * 40},--.[grey39]/[green],-." + + r"\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + r"\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + r"\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + r"\n[green] `._,._,'\n", id="logo", ) diff --git a/nf_core/pipelines/create/githubexit.py b/nf_core/pipelines/create/githubexit.py index 9b2c54912e..102edabe37 100644 --- a/nf_core/pipelines/create/githubexit.py +++ b/nf_core/pipelines/create/githubexit.py @@ -35,11 +35,11 @@ def compose(self) -> ComposeResult: ) ) yield Static( - f"\n[green]{' ' * 40},--.[grey39]/[green],-." - + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + "\n[green] `._,._,'\n", + rf"\n[green]{' ' * 40},--.[grey39]/[green],-." + + r"\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + r"\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + r"\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + r"\n[green] `._,._,'\n", id="logo", ) yield Markdown(exit_help_text_markdown) diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index 68b65619c5..6c8f774060 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -24,11 +24,11 @@ def compose(self) -> ComposeResult: ) ) yield Static( - f"\n[green]{' ' * 40},--.[grey39]/[green],-." - + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + "\n[green] `._,._,'\n", + rf"\n[green]{' ' * 40},--.[grey39]/[green],-." + + r"\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + r"\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + r"\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + r"\n[green] `._,._,'\n", id="logo", ) yield Markdown(markdown) diff --git a/nf_core/pipelines/create/welcome.py b/nf_core/pipelines/create/welcome.py index cb0d7468cb..a5839b7410 100644 --- a/nf_core/pipelines/create/welcome.py +++ b/nf_core/pipelines/create/welcome.py @@ -42,11 +42,11 @@ def compose(self) -> ComposeResult: ) ) yield Static( - f"\n[green]{' ' * 40},--.[grey39]/[green],-." - + "\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + "\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + "\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + "\n[green] `._,._,'\n", + rf"\n[green]{' ' * 40},--.[grey39]/[green],-." + + r"\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" + + r"\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" + + r"\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," + + r"\n[green] `._,._,'\n", id="logo", ) yield Markdown(markdown) From bfaf3b10dfa9234caca0ed63425214f147d34fe5 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Tue, 2 Apr 2024 22:47:15 +0200 Subject: [PATCH 078/175] Simplify log messages about CLI flags --- nf_core/__main__.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 4fbbf3586e..c1bdab2227 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -670,16 +670,13 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp sys.exit(1) elif name or description or author or version != "1.0.0dev" or force or outdir or organisation != "nf-core": log.error( - "Command arguments are not accepted in interactive mode.\n" - "Run with all command line arguments to avoid using an interactive interface" - "or run without any command line arguments to use an interactive interface." + "[red]Partial arguments supplied.[/] " + "Run without [i]any[/] arguments for an interactive interface, " + "or with at least name + description + author to use non-interactively." ) sys.exit(1) else: - log.info( - "Launching interactive nf-core pipeline creation tool." - "\nRun with all command line arguments to avoid using an interactive interface." - ) + log.info("Launching interactive nf-core pipeline creation tool.") app = PipelineCreateApp() app.run() sys.exit(app.return_code or 0) From ea99d690688775728d2fd340e0f67b7f0dff2331 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Tue, 2 Apr 2024 22:59:40 +0200 Subject: [PATCH 079/175] Move logo to utils, fix alignment --- nf_core/__main__.py | 24 +++++------------------ nf_core/pipelines/create/create.tcss | 4 +++- nf_core/pipelines/create/error.py | 8 +++----- nf_core/pipelines/create/githubexit.py | 8 +++----- nf_core/pipelines/create/loggingscreen.py | 8 +++----- nf_core/pipelines/create/welcome.py | 8 +++----- nf_core/utils.py | 9 +++++++++ 7 files changed, 29 insertions(+), 40 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index c1bdab2227..6435865ad1 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -17,7 +17,7 @@ from nf_core.download import DownloadError from nf_core.modules.modules_repo import NF_CORE_MODULES_REMOTE from nf_core.params_file import ParamsFileBuilder -from nf_core.utils import check_if_outdated, rich_force_colors, setup_nfcore_dir +from nf_core.utils import check_if_outdated, nfcore_logo, rich_force_colors, setup_nfcore_dir # Set up logging as the root logger # Submodules should all traverse back to this @@ -121,25 +121,11 @@ def run_nf_core(): # print nf-core header if environment variable is not set if os.environ.get("_NF_CORE_COMPLETE") is None: # Print nf-core header - stderr.print(f"\n[green]{' ' * 42},--.[grey39]/[green],-.", highlight=False) - stderr.print( - "[blue] ___ __ __ __ ___ [green]/,-._.--~\\", - highlight=False, - ) - stderr.print( - r"[blue] |\ | |__ __ / ` / \ |__) |__ [yellow] } {", - highlight=False, - ) - stderr.print( - r"[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-,", - highlight=False, - ) - stderr.print( - "[green] `._,._,'\n", - highlight=False, - ) + stderr.print("\n") + for line in nfcore_logo: + stderr.print(line, highlight=False) stderr.print( - f"[grey39] nf-core/tools version {__version__} - [link=https://nf-co.re]https://nf-co.re[/]", + f"\n[grey39] nf-core/tools version {__version__} - [link=https://nf-co.re]https://nf-co.re[/]", highlight=False, ) try: diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index 46b3989017..c3a52a4be8 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -1,5 +1,7 @@ #logo { - text-align:center; + width: 100%; + content-align-horizontal: center; + content-align-vertical: middle; } .cta { layout: horizontal; diff --git a/nf_core/pipelines/create/error.py b/nf_core/pipelines/create/error.py index b738b2a9d2..67c67aa1c2 100644 --- a/nf_core/pipelines/create/error.py +++ b/nf_core/pipelines/create/error.py @@ -5,6 +5,8 @@ from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown, Static +from nf_core.utils import nfcore_logo + class ExistError(Screen): """A screen to show the final text and exit the app - when an error ocurred.""" @@ -20,11 +22,7 @@ def compose(self) -> ComposeResult: ) ) yield Static( - rf"\n[green]{' ' * 40},--.[grey39]/[green],-." - + r"\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + r"\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + r"\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + r"\n[green] `._,._,'\n", + "\n" + "\n".join(nfcore_logo) + "\n", id="logo", ) diff --git a/nf_core/pipelines/create/githubexit.py b/nf_core/pipelines/create/githubexit.py index 102edabe37..3294c40f3b 100644 --- a/nf_core/pipelines/create/githubexit.py +++ b/nf_core/pipelines/create/githubexit.py @@ -5,6 +5,8 @@ from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown, Static +from nf_core.utils import nfcore_logo + exit_help_text_markdown = """ If you would like to create the GitHub repository later, you can do it manually by following these steps: @@ -35,11 +37,7 @@ def compose(self) -> ComposeResult: ) ) yield Static( - rf"\n[green]{' ' * 40},--.[grey39]/[green],-." - + r"\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + r"\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + r"\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + r"\n[green] `._,._,'\n", + "\n" + "\n".join(nfcore_logo) + "\n", id="logo", ) yield Markdown(exit_help_text_markdown) diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index 6c8f774060..89a848f83f 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -5,6 +5,8 @@ from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown, Static +from nf_core.utils import nfcore_logo + markdown = """ Visualising logging output. """ @@ -24,11 +26,7 @@ def compose(self) -> ComposeResult: ) ) yield Static( - rf"\n[green]{' ' * 40},--.[grey39]/[green],-." - + r"\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + r"\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + r"\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + r"\n[green] `._,._,'\n", + "\n" + "\n".join(nfcore_logo) + "\n", id="logo", ) yield Markdown(markdown) diff --git a/nf_core/pipelines/create/welcome.py b/nf_core/pipelines/create/welcome.py index a5839b7410..c23b659534 100644 --- a/nf_core/pipelines/create/welcome.py +++ b/nf_core/pipelines/create/welcome.py @@ -5,6 +5,8 @@ from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown, Static +from nf_core.utils import nfcore_logo + markdown = """ # nf-core create @@ -42,11 +44,7 @@ def compose(self) -> ComposeResult: ) ) yield Static( - rf"\n[green]{' ' * 40},--.[grey39]/[green],-." - + r"\n[blue] ___ __ __ __ ___ [green]/,-._.--~\\" - + r"\n[blue]|\ | |__ __ / ` / \ |__) |__ [yellow] } {" - + r"\n[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-," - + r"\n[green] `._,._,'\n", + "\n" + "\n".join(nfcore_logo) + "\n", id="logo", ) yield Markdown(markdown) diff --git a/nf_core/utils.py b/nf_core/utils.py index 4271e971a1..ec8eac700e 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -36,6 +36,15 @@ log = logging.getLogger(__name__) +# ASCII nf-core logo +nfcore_logo = [ + r"[green] ,--.[grey39]/[green],-.", + r"[blue] ___ __ __ __ ___ [green]/,-._.--~\ ", + r"[blue] |\ | |__ __ / ` / \ |__) |__ [yellow] } {", + r"[blue] | \| | \__, \__/ | \ |___ [green]\`-._,-`-,", + r"[green] `._,._,'", +] + # Custom style for questionary nfcore_question_style = prompt_toolkit.styles.Style( [ From d89218f8742b70673bf0ec7c0c7635987da0d25f Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Tue, 2 Apr 2024 23:42:38 +0200 Subject: [PATCH 080/175] Tweaks for welcome and pipeline type pages --- nf_core/pipelines/create/create.tcss | 18 ++++++---- nf_core/pipelines/create/pipelinetype.py | 43 ++++++++++++++---------- nf_core/pipelines/create/welcome.py | 37 +++++++------------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index c3a52a4be8..836437a2c2 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -3,13 +3,14 @@ content-align-horizontal: center; content-align-vertical: middle; } -.cta { - layout: horizontal; - margin-bottom: 1; + +.mb-0 { + margin: 0 2; } -.cta Button { - margin-left: 3; - margin-right: 3; + +.pipeline-type-grid { + height: auto; + margin-bottom: 2; } .custom_grid { @@ -106,3 +107,8 @@ Vertical{ .log_console { height: auto; } + +/* Layouts */ +.col-2 { + grid-size: 2 1; +} diff --git a/nf_core/pipelines/create/pipelinetype.py b/nf_core/pipelines/create/pipelinetype.py index 98d5acc97a..48914e8555 100644 --- a/nf_core/pipelines/create/pipelinetype.py +++ b/nf_core/pipelines/create/pipelinetype.py @@ -1,36 +1,37 @@ from textual.app import ComposeResult -from textual.containers import Center +from textual.containers import Center, Grid from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown markdown_intro = """ -# To nf-core or not to nf-core? - -Next, we need to know what kind of pipeline this will be. +# Choose pipeline type +""" -Choose _"nf-core"_ if: +markdown_type_nfcore = """ +## Choose _"nf-core"_ if: * You want your pipeline to be part of the nf-core community * You think that there's an outside chance that it ever _could_ be part of nf-core - -Choose _"Custom"_ if: +""" +markdown_type_custom = """ +## Choose _"Custom"_ if: * Your pipeline will _never_ be part of nf-core * You want full control over *all* features that are included from the template - (including those that are mandatory for nf-core). + (including those that are mandatory for nf-core). """ markdown_details = """ -## Not sure? What's the difference? +## What's the difference? Choosing _"nf-core"_ effectively pre-selects the following template features: -* GitHub Actions Continuous Integration (CI) configuration for the following: - * Small-scale (GitHub) and large-scale (AWS) tests - * Code format linting with prettier - * Auto-fix functionality using @nf-core-bot +* GitHub Actions continuous-integration configuration files: + * Pipeline test runs: Small-scale (GitHub) and large-scale (AWS) + * Code formatting checks with [Prettier](https://prettier.io/) + * Auto-fix linting functionality using [@nf-core-bot](https://github.com/nf-core-bot) * Marking old issues as stale -* Inclusion of shared nf-core config profiles +* Inclusion of [shared nf-core configuration profiles](https://nf-co.re/configs) """ @@ -41,9 +42,15 @@ def compose(self) -> ComposeResult: yield Header() yield Footer() yield Markdown(markdown_intro) - yield Center( - Button("nf-core", id="type_nfcore", variant="success"), - Button("Custom", id="type_custom", variant="primary"), - classes="cta", + yield Grid( + Center( + Markdown(markdown_type_nfcore), + Center(Button("nf-core", id="type_nfcore", variant="success")), + ), + Center( + Markdown(markdown_type_custom), + Center(Button("Custom", id="type_custom", variant="primary")), + ), + classes="col-2 pipeline-type-grid", ) yield Markdown(markdown_details) diff --git a/nf_core/pipelines/create/welcome.py b/nf_core/pipelines/create/welcome.py index c23b659534..38f29b0411 100644 --- a/nf_core/pipelines/create/welcome.py +++ b/nf_core/pipelines/create/welcome.py @@ -1,5 +1,3 @@ -from textwrap import dedent - from textual.app import ComposeResult from textual.containers import Center from textual.screen import Screen @@ -8,25 +6,21 @@ from nf_core.utils import nfcore_logo markdown = """ -# nf-core create - -This app will help you create a new nf-core pipeline. -It uses the nf-core pipeline template, which is kept -within the [nf-core/tools repository](https://github.com/nf-core/tools). +# Welcome to the nf-core pipeline creation wizard -Using this tool is mandatory when making a pipeline that may -be part of the nf-core community collection at some point. -However, this tool can also be used to create pipelines that will -never be part of nf-core. You can still benefit from the community -best practices for your own workflow. +This app will help you create a new Nextflow pipeline +from the nf-core pipeline template, part of the +[nf-core/tools repository](https://github.com/nf-core/tools). -If you are planning to add a pipeline to the nf-core community, you need to be part of that community! -Please join us on Slack [https://nf-co.re/join](https://nf-co.re/join), -and ask to be added to the GitHub association through the #github-invitations channel. +The template _must_ be used for nf-core pipelines, but hopefully +helps all Nextflow developers benefit from nf-core best practices. -Come and discuss your plans with the nf-core community as early as possible. -Ideally before you make a start on your pipeline! -These topics are specifically discussed in the [#new-pipelines](https://nfcore.slack.com/channels/new-pipelines) channel. +If you want to add a pipeline to nf-core, please +[join on Slack](https://nf-co.re/join) and discuss your plans with the +community as early as possible; _**ideally before you start on your pipeline!**_ +See the [nf-core guidelines](https://nf-co.re/docs/contributing/guidelines) +and the [#new-pipelines](https://nfcore.slack.com/channels/new-pipelines) +Slack channel for more information. """ @@ -36,13 +30,6 @@ class WelcomeScreen(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - yield Markdown( - dedent( - """ - # Create a pipeline from the nf-core template - """ - ) - ) yield Static( "\n" + "\n".join(nfcore_logo) + "\n", id="logo", From 19a614483bfc63f0f1a12074826d0dce5c97fe7f Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Wed, 3 Apr 2024 00:08:18 +0200 Subject: [PATCH 081/175] Display tweaks --- nf_core/pipelines/create/__init__.py | 9 ++++++++- nf_core/pipelines/create/create.py | 21 +++++++++++++-------- nf_core/pipelines/create/create.tcss | 20 +++++++++++++++----- nf_core/pipelines/create/custompipeline.py | 1 + nf_core/pipelines/create/finaldetails.py | 10 +++++++--- nf_core/pipelines/create/loggingscreen.py | 6 +----- nf_core/pipelines/create/nfcorepipeline.py | 1 + 7 files changed, 46 insertions(+), 22 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index feff20659d..15670ac5df 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -1,4 +1,5 @@ """A Textual app to create a pipeline.""" + import logging from textual.app import App @@ -21,7 +22,13 @@ ) from nf_core.pipelines.create.welcome import WelcomeScreen -log_handler = CustomLogHandler(console=LoggingConsole(classes="log_console"), rich_tracebacks=True, markup=True) +log_handler = CustomLogHandler( + console=LoggingConsole(classes="log_console"), + rich_tracebacks=True, + show_time=False, + show_path=False, + markup=True, +) logging.basicConfig( level="INFO", handlers=[log_handler], diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index 9347b7e678..ff1d488b1a 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -55,6 +55,7 @@ def __init__( organisation: str = "nf-core", from_config_file: bool = False, default_branch: Optional[str] = None, + is_interactive: bool = False, ): if isinstance(template_config, CreateConfig): self.config = template_config @@ -102,6 +103,7 @@ def __init__( # Set fields used by the class methods self.no_git = no_git self.default_branch = default_branch + self.is_interactive = is_interactive self.force = self.config.force if outdir is None: outdir = os.path.join(os.getcwd(), self.jinja_params["name_noslash"]) @@ -253,7 +255,7 @@ def init_pipeline(self): if not self.no_git: self.git_init_pipeline() - if self.config.is_nfcore: + if self.config.is_nfcore and not self.is_interactive: log.info( "[green bold]!!!!!! IMPORTANT !!!!!!\n\n" "[green not bold]If you are interested in adding your pipeline to the nf-core community,\n" @@ -556,10 +558,13 @@ def git_init_pipeline(self): raise UserWarning( "Branches 'TEMPLATE' and 'dev' already exist. Use --force to overwrite existing branches." ) - log.info( - "Done. Remember to add a remote and push to GitHub:\n" - f"[white on grey23] cd {self.outdir} \n" - " git remote add origin git@github.com:USERNAME/REPO_NAME.git \n" - " git push --all origin " - ) - log.info("This will also push your newly created dev branch and the TEMPLATE branch for syncing.") + if self.is_interactive: + log.info(f"Pipeline created: ./{self.outdir.relative_to(Path.cwd())}") + else: + log.info( + "Done. Remember to add a remote and push to GitHub:\n" + f"[white on grey23] cd {self.outdir} \n" + " git remote add origin git@github.com:USERNAME/REPO_NAME.git \n" + " git push --all origin " + ) + log.info("This will also push your newly created dev branch and the TEMPLATE branch for syncing.") diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index 836437a2c2..ad1b99d58c 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -3,9 +3,12 @@ content-align-horizontal: center; content-align-vertical: middle; } - -.mb-0 { - margin: 0 2; +.cta { + layout: horizontal; + margin-bottom: 1; +} +.cta Button { + margin: 0 3; } .pipeline-type-grid { @@ -59,12 +62,16 @@ Vertical{ height: auto; } +.features-container { + padding: 0 4 1 4; +} + /* Display help messages */ .help_box { background: #333333; - padding: 1 5; - margin: 1 10; + padding: 1 3 0 3; + margin: 0 5 2 5; overflow-y: auto; transition: height 50ms; display: none; @@ -106,6 +113,9 @@ Vertical{ .log_console { height: auto; + background: #333333; + padding: 1 3; + margin: 0 4 2 4; } /* Layouts */ diff --git a/nf_core/pipelines/create/custompipeline.py b/nf_core/pipelines/create/custompipeline.py index 6fe878469b..7d460db65d 100644 --- a/nf_core/pipelines/create/custompipeline.py +++ b/nf_core/pipelines/create/custompipeline.py @@ -80,6 +80,7 @@ def compose(self) -> ComposeResult: "The pipeline will include configuration profiles containing custom parameters requried to run nf-core pipelines at different institutions", "nf_core_configs", ), + classes="features-container", ) yield Center( Button("Back", id="back", variant="default"), diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 5af28cffa6..c621a425ab 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -1,4 +1,5 @@ """A Textual app to create a pipeline.""" + from textwrap import dedent from textual import on, work @@ -45,9 +46,9 @@ def compose(self) -> ComposeResult: with Horizontal(): yield Switch(value=False, id="force") with Vertical(): - yield Static("Force", classes="custom_grid") + yield Static("Force creation", classes="custom_grid") yield Static( - "If the pipeline output directory exists, remove it and continue.", + "Overwrite any existing pipeline output directories.", classes="feature_subtitle", ) @@ -98,7 +99,10 @@ def show_pipeline_error(self) -> None: def _create_pipeline(self) -> None: """Create the pipeline.""" self.post_message(ShowLogs()) - create_obj = PipelineCreate(template_config=self.parent.TEMPLATE_CONFIG) + create_obj = PipelineCreate( + template_config=self.parent.TEMPLATE_CONFIG, + is_interactive=True, + ) try: create_obj.init_pipeline() self.parent.call_from_thread(change_select_disabled, self.parent, "close_screen", False) diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index 89a848f83f..4c863b1643 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -7,10 +7,6 @@ from nf_core.utils import nfcore_logo -markdown = """ -Visualising logging output. -""" - class LoggingScreen(Screen): """A screen to show the final logs.""" @@ -29,7 +25,7 @@ def compose(self) -> ComposeResult: "\n" + "\n".join(nfcore_logo) + "\n", id="logo", ) - yield Markdown(markdown) + yield Markdown("Creating pipeline..") yield Center(self.parent.LOG_HANDLER.console) if self.parent.LOGGING_STATE == "repo created": yield Center( diff --git a/nf_core/pipelines/create/nfcorepipeline.py b/nf_core/pipelines/create/nfcorepipeline.py index 8306e93263..49cc1f8f86 100644 --- a/nf_core/pipelines/create/nfcorepipeline.py +++ b/nf_core/pipelines/create/nfcorepipeline.py @@ -29,6 +29,7 @@ def compose(self) -> ComposeResult: "The pipeline will be configured to use a copy of the most common reference genome files from iGenomes", "igenomes", ), + classes="features-container", ) yield Center( Button("Back", id="back", variant="default"), From 0bfae29aed2b5e89021530b9705e20f67789c000 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Wed, 3 Apr 2024 00:22:56 +0200 Subject: [PATCH 082/175] Tidy up design for GitHub repo creation page --- nf_core/__main__.py | 4 +++- nf_core/pipelines/create/create.tcss | 7 +++++++ nf_core/pipelines/create/githubexit.py | 23 ++++++++++++----------- nf_core/pipelines/create/githubrepo.py | 21 ++++++++------------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 6435865ad1..c123787316 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -691,7 +691,9 @@ def create(name, description, author, version, force, outdir, template_yaml, pla Uses the nf-core template to make a skeleton Nextflow pipeline with all required files, boilerplate code and best-practices. """ - log.error("[bold][green]nf-core create[/] command is deprecated. Use [green]nf-core pipelines create[/].[/]") + log.error( + "The `[magenta]nf-core create[/]` command is deprecated. Use `[magenta]nf-core pipelines create[/]` instead." + ) sys.exit(0) diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index ad1b99d58c..b2355e1335 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -122,3 +122,10 @@ Vertical{ .col-2 { grid-size: 2 1; } + +.ghrepo-cols { + margin: 0 4; +} +.ghrepo-cols Button { + margin-top: 2; +} diff --git a/nf_core/pipelines/create/githubexit.py b/nf_core/pipelines/create/githubexit.py index 3294c40f3b..10346d030b 100644 --- a/nf_core/pipelines/create/githubexit.py +++ b/nf_core/pipelines/create/githubexit.py @@ -11,15 +11,16 @@ If you would like to create the GitHub repository later, you can do it manually by following these steps: 1. Create a new GitHub repository -2. Add the remote to your local repository -```bash -cd -git remote add origin git@github.com:/.git -``` -3. Push the code to the remote -```bash -git push --all origin -``` +2. Add the remote to your local repository: + ```bash + cd + git remote add origin git@github.com:/.git + ``` +3. Push the code to the remote: + ```bash + git push --all origin + ``` + * Note the `--all` flag: this is needed to push all branches to the remote. """ @@ -42,7 +43,7 @@ def compose(self) -> ComposeResult: ) yield Markdown(exit_help_text_markdown) yield Center( - Button("Close App", id="close_app", variant="success"), - Button("Show Logging", id="show_logging", variant="primary"), + Button("Close", id="close_app", variant="success"), + Button("Show pipeline creation log", id="show_logging", variant="primary"), classes="cta", ) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index c8a02e609a..aee4b39dce 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -18,12 +18,8 @@ log = logging.getLogger(__name__) github_text_markdown = """ -# Create a GitHub repo - -After creating the pipeline template locally, we can create a GitHub repository and push the code to it. -""" -repo_config_markdown = """ -Please select the the GitHub repository settings: +Now that we have created a new pipeline locally, we can create a new +GitHub repository using the GitHub API and push the code to it. """ @@ -41,7 +37,7 @@ def compose(self) -> ComposeResult: ) ) yield Markdown(dedent(github_text_markdown)) - with Horizontal(): + with Horizontal(classes="ghrepo-cols"): gh_user, gh_token = self._get_github_credentials() yield TextInput( "gh_username", @@ -53,25 +49,24 @@ def compose(self) -> ComposeResult: yield TextInput( "token", "GitHub token", - "Your GitHub personal access token for login.", + "Your GitHub [link=https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens]personal access token[/link] for login.", default=gh_token if gh_token is not None else "GitHub token", password=True, classes="column", ) yield Button("Show", id="show_password") yield Button("Hide", id="hide_password") - yield Markdown(dedent(repo_config_markdown)) - with Horizontal(): + with Horizontal(classes="ghrepo-cols"): yield Switch(value=False, id="private") with Vertical(): yield Static("Private", classes="") - yield Static("Select if the new GitHub repo must be private.", classes="feature_subtitle") - with Horizontal(): + yield Static("Select to make the new GitHub repo private.", classes="feature_subtitle") + with Horizontal(classes="ghrepo-cols"): yield Switch(value=True, id="push") with Vertical(): yield Static("Push files", classes="custom_grid") yield Static( - "Select if you would like to push all the pipeline template files to your GitHub repo\nand all the branches required to keep the pipeline up to date with new releases of nf-core.", + "Select to push pipeline files and branches to your GitHub repo.", classes="feature_subtitle", ) yield Center( From a1d8916e434e6b07057ce05a279224617675c17c Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Wed, 3 Apr 2024 08:27:57 +0000 Subject: [PATCH 083/175] [automated] Fix code linting --- nf_core/pipelines/create/basicdetails.py | 1 + tests/test_create_app.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py index e4f36e4035..3f319b58f6 100644 --- a/nf_core/pipelines/create/basicdetails.py +++ b/nf_core/pipelines/create/basicdetails.py @@ -1,4 +1,5 @@ """A Textual app to create a pipeline.""" + from textwrap import dedent from textual import on diff --git a/tests/test_create_app.py b/tests/test_create_app.py index b6b05ab58f..124078cec1 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -1,4 +1,5 @@ -""" Test Pipeline Create App """ +"""Test Pipeline Create App""" + from unittest import mock import pytest From 7a96212dadd504b4be5c80856850fb6a97f68388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 3 Apr 2024 09:41:19 +0000 Subject: [PATCH 084/175] update create app snapshots --- tests/__snapshots__/test_create_app.ambr | 2915 +++++++++++----------- tests/lint/configs.py | 2 +- tests/lint/nfcore_yml.py | 2 +- 3 files changed, 1462 insertions(+), 1457 deletions(-) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index b0a306adc2..50beceecc0 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -22,253 +22,253 @@ font-weight: 700; } - .terminal-1527309810-matrix { + .terminal-3000245001-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1527309810-title { + .terminal-3000245001-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1527309810-r1 { fill: #c5c8c6 } - .terminal-1527309810-r2 { fill: #e3e3e3 } - .terminal-1527309810-r3 { fill: #989898 } - .terminal-1527309810-r4 { fill: #e1e1e1 } - .terminal-1527309810-r5 { fill: #121212 } - .terminal-1527309810-r6 { fill: #0053aa } - .terminal-1527309810-r7 { fill: #dde8f3;font-weight: bold } - .terminal-1527309810-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-1527309810-r9 { fill: #1e1e1e } - .terminal-1527309810-r10 { fill: #008139 } - .terminal-1527309810-r11 { fill: #e2e2e2 } - .terminal-1527309810-r12 { fill: #787878 } - .terminal-1527309810-r13 { fill: #b93c5b } - .terminal-1527309810-r14 { fill: #454a50 } - .terminal-1527309810-r15 { fill: #7ae998 } - .terminal-1527309810-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-1527309810-r17 { fill: #0a180e;font-weight: bold } - .terminal-1527309810-r18 { fill: #000000 } - .terminal-1527309810-r19 { fill: #ddedf9 } + .terminal-3000245001-r1 { fill: #c5c8c6 } + .terminal-3000245001-r2 { fill: #e3e3e3 } + .terminal-3000245001-r3 { fill: #989898 } + .terminal-3000245001-r4 { fill: #e1e1e1 } + .terminal-3000245001-r5 { fill: #121212 } + .terminal-3000245001-r6 { fill: #0053aa } + .terminal-3000245001-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3000245001-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-3000245001-r9 { fill: #1e1e1e } + .terminal-3000245001-r10 { fill: #008139 } + .terminal-3000245001-r11 { fill: #e2e2e2 } + .terminal-3000245001-r12 { fill: #787878 } + .terminal-3000245001-r13 { fill: #b93c5b } + .terminal-3000245001-r14 { fill: #454a50 } + .terminal-3000245001-r15 { fill: #7ae998 } + .terminal-3000245001-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-3000245001-r17 { fill: #0a180e;font-weight: bold } + .terminal-3000245001-r18 { fill: #000000 } + .terminal-3000245001-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackNext - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -298,256 +298,256 @@ font-weight: 700; } - .terminal-2230840552-matrix { + .terminal-2776506879-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2230840552-title { + .terminal-2776506879-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2230840552-r1 { fill: #c5c8c6 } - .terminal-2230840552-r2 { fill: #e3e3e3 } - .terminal-2230840552-r3 { fill: #989898 } - .terminal-2230840552-r4 { fill: #e1e1e1 } - .terminal-2230840552-r5 { fill: #121212 } - .terminal-2230840552-r6 { fill: #0053aa } - .terminal-2230840552-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2230840552-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-2230840552-r9 { fill: #1e1e1e } - .terminal-2230840552-r10 { fill: #0f4e2a } - .terminal-2230840552-r11 { fill: #0178d4 } - .terminal-2230840552-r12 { fill: #a7a7a7 } - .terminal-2230840552-r13 { fill: #787878 } - .terminal-2230840552-r14 { fill: #e2e2e2 } - .terminal-2230840552-r15 { fill: #b93c5b } - .terminal-2230840552-r16 { fill: #454a50 } - .terminal-2230840552-r17 { fill: #7ae998 } - .terminal-2230840552-r18 { fill: #e2e3e3;font-weight: bold } - .terminal-2230840552-r19 { fill: #0a180e;font-weight: bold } - .terminal-2230840552-r20 { fill: #000000 } - .terminal-2230840552-r21 { fill: #008139 } - .terminal-2230840552-r22 { fill: #ddedf9 } + .terminal-2776506879-r1 { fill: #c5c8c6 } + .terminal-2776506879-r2 { fill: #e3e3e3 } + .terminal-2776506879-r3 { fill: #989898 } + .terminal-2776506879-r4 { fill: #e1e1e1 } + .terminal-2776506879-r5 { fill: #121212 } + .terminal-2776506879-r6 { fill: #0053aa } + .terminal-2776506879-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2776506879-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-2776506879-r9 { fill: #1e1e1e } + .terminal-2776506879-r10 { fill: #0f4e2a } + .terminal-2776506879-r11 { fill: #0178d4 } + .terminal-2776506879-r12 { fill: #a7a7a7 } + .terminal-2776506879-r13 { fill: #787878 } + .terminal-2776506879-r14 { fill: #e2e2e2 } + .terminal-2776506879-r15 { fill: #b93c5b } + .terminal-2776506879-r16 { fill: #454a50 } + .terminal-2776506879-r17 { fill: #7ae998 } + .terminal-2776506879-r18 { fill: #e2e3e3;font-weight: bold } + .terminal-2776506879-r19 { fill: #0a180e;font-weight: bold } + .terminal-2776506879-r20 { fill: #000000 } + .terminal-2776506879-r21 { fill: #008139 } + .terminal-2776506879-r22 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackNext - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -577,251 +577,253 @@ font-weight: 700; } - .terminal-828318910-matrix { + .terminal-1170633481-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-828318910-title { + .terminal-1170633481-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-828318910-r1 { fill: #c5c8c6 } - .terminal-828318910-r2 { fill: #e3e3e3 } - .terminal-828318910-r3 { fill: #989898 } - .terminal-828318910-r4 { fill: #e1e1e1 } - .terminal-828318910-r5 { fill: #121212 } - .terminal-828318910-r6 { fill: #0053aa } - .terminal-828318910-r7 { fill: #dde8f3;font-weight: bold } - .terminal-828318910-r8 { fill: #e1e1e1;font-style: italic; } - .terminal-828318910-r9 { fill: #4ebf71;font-weight: bold } - .terminal-828318910-r10 { fill: #7ae998 } - .terminal-828318910-r11 { fill: #507bb3 } - .terminal-828318910-r12 { fill: #dde6ed;font-weight: bold } - .terminal-828318910-r13 { fill: #008139 } - .terminal-828318910-r14 { fill: #001541 } - .terminal-828318910-r15 { fill: #24292f } - .terminal-828318910-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-828318910-r17 { fill: #ddedf9 } + .terminal-1170633481-r1 { fill: #c5c8c6 } + .terminal-1170633481-r2 { fill: #e3e3e3 } + .terminal-1170633481-r3 { fill: #989898 } + .terminal-1170633481-r4 { fill: #e1e1e1 } + .terminal-1170633481-r5 { fill: #121212 } + .terminal-1170633481-r6 { fill: #0053aa } + .terminal-1170633481-r7 { fill: #dde8f3;font-weight: bold } + .terminal-1170633481-r8 { fill: #24292f } + .terminal-1170633481-r9 { fill: #e2e3e3;font-weight: bold } + .terminal-1170633481-r10 { fill: #e2e3e3;font-weight: bold;font-style: italic; } + .terminal-1170633481-r11 { fill: #4ebf71;font-weight: bold } + .terminal-1170633481-r12 { fill: #e1e1e1;font-style: italic; } + .terminal-1170633481-r13 { fill: #7ae998 } + .terminal-1170633481-r14 { fill: #008139 } + .terminal-1170633481-r15 { fill: #507bb3 } + .terminal-1170633481-r16 { fill: #dde6ed;font-weight: bold } + .terminal-1170633481-r17 { fill: #001541 } + .terminal-1170633481-r18 { fill: #e1e1e1;text-decoration: underline; } + .terminal-1170633481-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - To nf-core or not to nf-core? - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Next, we need to know what kind of pipeline this will be. - - Choose "nf-core" if: - - ● You want your pipeline to be part of the nf-core community - ● You think that there's an outside chance that it ever could be part of nf-core - - Choose "Custom" if: - - ● Your pipeline will never be part of nf-core - ● You want full control over all features that are included from the template (including  - those that are mandatory for nf-core). - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-coreCustom - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -                             Not sure? What's the difference?                             - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Choosing "nf-core" effectively pre-selects the following template features: - - ● GitHub Actions Continuous Integration (CI) configuration for the following: - ▪ Small-scale (GitHub) and large-scale (AWS) tests - ▪ Code format linting with prettier - ▪ Auto-fix functionality using @nf-core-bot - ▪ Marking old issues as stale - ● Inclusion of shared nf-core config profiles - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Choose pipeline type + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +          Choose "nf-core" if:                  Choose "Custom" if:           + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ● You want your pipeline to be part of the● Your pipeline will never be part of  + nf-core communitynf-core + ● You think that there's an outside chance● You want full control over all features  + that it ever could be part of nf-corethat are included from the template  + (including those that are mandatory for  + nf-core). + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-core + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Custom + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +                                  What's the difference?                                  + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Choosing "nf-core" effectively pre-selects the following template features: + + ● GitHub Actions continuous-integration configuration files: + ▪ Pipeline test runs: Small-scale (GitHub) and large-scale (AWS) + ▪ Code formatting checks with Prettier + ▪ Auto-fix linting functionality using @nf-core-bot + ▪ Marking old issues as stale + ● Inclusion of shared nf-core configuration profiles + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -851,257 +853,257 @@ font-weight: 700; } - .terminal-2112272033-matrix { + .terminal-3272111277-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2112272033-title { + .terminal-3272111277-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2112272033-r1 { fill: #c5c8c6 } - .terminal-2112272033-r2 { fill: #e3e3e3 } - .terminal-2112272033-r3 { fill: #989898 } - .terminal-2112272033-r4 { fill: #e1e1e1 } - .terminal-2112272033-r5 { fill: #121212 } - .terminal-2112272033-r6 { fill: #0053aa } - .terminal-2112272033-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2112272033-r8 { fill: #1e1e1e } - .terminal-2112272033-r9 { fill: #0178d4 } - .terminal-2112272033-r10 { fill: #454a50 } - .terminal-2112272033-r11 { fill: #e2e2e2 } - .terminal-2112272033-r12 { fill: #808080 } - .terminal-2112272033-r13 { fill: #e2e3e3;font-weight: bold } - .terminal-2112272033-r14 { fill: #000000 } - .terminal-2112272033-r15 { fill: #e4e4e4 } - .terminal-2112272033-r16 { fill: #14191f } - .terminal-2112272033-r17 { fill: #507bb3 } - .terminal-2112272033-r18 { fill: #dde6ed;font-weight: bold } - .terminal-2112272033-r19 { fill: #001541 } - .terminal-2112272033-r20 { fill: #7ae998 } - .terminal-2112272033-r21 { fill: #0a180e;font-weight: bold } - .terminal-2112272033-r22 { fill: #008139 } - .terminal-2112272033-r23 { fill: #ddedf9 } + .terminal-3272111277-r1 { fill: #c5c8c6 } + .terminal-3272111277-r2 { fill: #e3e3e3 } + .terminal-3272111277-r3 { fill: #989898 } + .terminal-3272111277-r4 { fill: #e1e1e1 } + .terminal-3272111277-r5 { fill: #121212 } + .terminal-3272111277-r6 { fill: #0053aa } + .terminal-3272111277-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3272111277-r8 { fill: #1e1e1e } + .terminal-3272111277-r9 { fill: #0178d4 } + .terminal-3272111277-r10 { fill: #454a50 } + .terminal-3272111277-r11 { fill: #e2e2e2 } + .terminal-3272111277-r12 { fill: #808080 } + .terminal-3272111277-r13 { fill: #e2e3e3;font-weight: bold } + .terminal-3272111277-r14 { fill: #000000 } + .terminal-3272111277-r15 { fill: #e4e4e4 } + .terminal-3272111277-r16 { fill: #14191f } + .terminal-3272111277-r17 { fill: #507bb3 } + .terminal-3272111277-r18 { fill: #dde6ed;font-weight: bold } + .terminal-3272111277-r19 { fill: #001541 } + .terminal-3272111277-r20 { fill: #7ae998 } + .terminal-3272111277-r21 { fill: #0a180e;font-weight: bold } + .terminal-3272111277-r22 { fill: #008139 } + .terminal-3272111277-r23 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Template features - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference The pipeline will beHide help - ▁▁▁▁▁▁▁▁genomesconfigured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - copy of the most  - common reference  - genome files from  - iGenomes - - - - Nf-core pipelines are configured to use a copy of the most - common reference genome files. - - By selecting this option, your pipeline will include a  - configuration file specifying the paths to these files. - - The required code to use these files will also be included - in the template. When the pipeline user provides an ▆▆ - appropriate genome key, the pipeline will automatically  - download the required reference files. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github CI testsThe pipeline will Show help - ▁▁▁▁▁▁▁▁include several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - GitHub actions for  - Continuous  - Integration (CI)  - testing - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▂▂ - Add Github badgesThe README.md file Show help - ▁▁▁▁▁▁▁▁of the pipeline will▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - include GitHub  - badges - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add configuration The pipeline will Show help - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackContinue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Template features + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference The pipeline will beHide help + ▁▁▁▁▁▁▁▁genomesconfigured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + copy of the most  + common reference  + genome files from  + iGenomes + + + Nf-core pipelines are configured to use a copy of the most common  + reference genome files. + + By selecting this option, your pipeline will include a configuration  + file specifying the paths to these files. + + The required code to use these files will also be included in the  + template. When the pipeline user provides an appropriate genome key, the + pipeline will automatically download the required reference files. + ▅▅ + For more information about reference genomes in nf-core pipelines, see  + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github CI testsThe pipeline will Show help + ▁▁▁▁▁▁▁▁include several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + GitHub actions for  + Continuous  + Integration (CI)  + testing + ▆▆ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github badgesThe README.md file Show help + ▁▁▁▁▁▁▁▁of the pipeline will▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + include GitHub  + badges + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  @@ -1131,253 +1133,253 @@ font-weight: 700; } - .terminal-2426593002-matrix { + .terminal-3970307065-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2426593002-title { + .terminal-3970307065-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2426593002-r1 { fill: #c5c8c6 } - .terminal-2426593002-r2 { fill: #e3e3e3 } - .terminal-2426593002-r3 { fill: #989898 } - .terminal-2426593002-r4 { fill: #e1e1e1 } - .terminal-2426593002-r5 { fill: #121212 } - .terminal-2426593002-r6 { fill: #0053aa } - .terminal-2426593002-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2426593002-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-2426593002-r9 { fill: #1e1e1e } - .terminal-2426593002-r10 { fill: #008139 } - .terminal-2426593002-r11 { fill: #e2e2e2 } - .terminal-2426593002-r12 { fill: #b93c5b } - .terminal-2426593002-r13 { fill: #808080 } - .terminal-2426593002-r14 { fill: #454a50 } - .terminal-2426593002-r15 { fill: #7ae998 } - .terminal-2426593002-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-2426593002-r17 { fill: #0a180e;font-weight: bold } - .terminal-2426593002-r18 { fill: #000000 } - .terminal-2426593002-r19 { fill: #ddedf9 } + .terminal-3970307065-r1 { fill: #c5c8c6 } + .terminal-3970307065-r2 { fill: #e3e3e3 } + .terminal-3970307065-r3 { fill: #989898 } + .terminal-3970307065-r4 { fill: #e1e1e1 } + .terminal-3970307065-r5 { fill: #121212 } + .terminal-3970307065-r6 { fill: #0053aa } + .terminal-3970307065-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3970307065-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-3970307065-r9 { fill: #1e1e1e } + .terminal-3970307065-r10 { fill: #008139 } + .terminal-3970307065-r11 { fill: #e2e2e2 } + .terminal-3970307065-r12 { fill: #b93c5b } + .terminal-3970307065-r13 { fill: #808080 } + .terminal-3970307065-r14 { fill: #454a50 } + .terminal-3970307065-r15 { fill: #7ae998 } + .terminal-3970307065-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-3970307065-r17 { fill: #0a180e;font-weight: bold } + .terminal-3970307065-r18 { fill: #000000 } + .terminal-3970307065-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Final details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - First version of the pipelinePath to the output directory where the pipeline  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created - 1.0.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔Force - If the pipeline output directory exists, remove it and continue. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackFinish - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Final details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + First version of the pipelinePath to the output directory where the pipeline  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created + 1.0.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔Force creation + Overwrite any existing pipeline output directories. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackFinish + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -1407,257 +1409,257 @@ font-weight: 700; } - .terminal-368636757-matrix { + .terminal-3041904966-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-368636757-title { + .terminal-3041904966-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-368636757-r1 { fill: #c5c8c6 } - .terminal-368636757-r2 { fill: #e3e3e3 } - .terminal-368636757-r3 { fill: #989898 } - .terminal-368636757-r4 { fill: #e1e1e1 } - .terminal-368636757-r5 { fill: #121212 } - .terminal-368636757-r6 { fill: #0053aa } - .terminal-368636757-r7 { fill: #dde8f3;font-weight: bold } - .terminal-368636757-r8 { fill: #454a50 } - .terminal-368636757-r9 { fill: #a5a5a5;font-style: italic; } - .terminal-368636757-r10 { fill: #e2e3e3;font-weight: bold } - .terminal-368636757-r11 { fill: #1e1e1e } - .terminal-368636757-r12 { fill: #008139 } - .terminal-368636757-r13 { fill: #000000 } - .terminal-368636757-r14 { fill: #787878 } - .terminal-368636757-r15 { fill: #e2e2e2 } - .terminal-368636757-r16 { fill: #b93c5b } - .terminal-368636757-r17 { fill: #808080 } - .terminal-368636757-r18 { fill: #7ae998 } - .terminal-368636757-r19 { fill: #507bb3 } - .terminal-368636757-r20 { fill: #0a180e;font-weight: bold } - .terminal-368636757-r21 { fill: #dde6ed;font-weight: bold } - .terminal-368636757-r22 { fill: #001541 } - .terminal-368636757-r23 { fill: #ddedf9 } + .terminal-3041904966-r1 { fill: #c5c8c6 } + .terminal-3041904966-r2 { fill: #e3e3e3 } + .terminal-3041904966-r3 { fill: #989898 } + .terminal-3041904966-r4 { fill: #e1e1e1 } + .terminal-3041904966-r5 { fill: #121212 } + .terminal-3041904966-r6 { fill: #0053aa } + .terminal-3041904966-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3041904966-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-3041904966-r9 { fill: #1e1e1e } + .terminal-3041904966-r10 { fill: #008139 } + .terminal-3041904966-r11 { fill: #454a50 } + .terminal-3041904966-r12 { fill: #787878 } + .terminal-3041904966-r13 { fill: #e2e2e2 } + .terminal-3041904966-r14 { fill: #e2e3e3;font-weight: bold } + .terminal-3041904966-r15 { fill: #000000 } + .terminal-3041904966-r16 { fill: #b93c5b } + .terminal-3041904966-r17 { fill: #808080 } + .terminal-3041904966-r18 { fill: #7ae998 } + .terminal-3041904966-r19 { fill: #507bb3 } + .terminal-3041904966-r20 { fill: #0a180e;font-weight: bold } + .terminal-3041904966-r21 { fill: #dde6ed;font-weight: bold } + .terminal-3041904966-r22 { fill: #001541 } + .terminal-3041904966-r23 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create a GitHub repo - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - After creating the pipeline template locally, we can create a GitHub repository and push the - code to it. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Your GitHub usernameYour GitHub personal access token for Show - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔login.▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Please select the the GitHub repository settings: - - - ▔▔▔▔▔▔▔▔Private - Select if the new GitHub repo must be private. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔Push files - Select if you would like to push all the pipeline template files to your GitHub repo - ▁▁▁▁▁▁▁▁and all the branches required to keep the pipeline up to date with new releases of  - nf-core. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackCreate GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + Now that we have created a new pipeline locally, we can create a new GitHub repository using + the GitHub API and push the code to it. + + + + Your GitHub usernameYour GitHub personal access token + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔Private + Select to make the new GitHub repo private. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔Push files + Select to push pipeline files and branches to your GitHub repo. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackCreate GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -1687,255 +1689,256 @@ font-weight: 700; } - .terminal-1480303962-matrix { + .terminal-4130924772-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1480303962-title { + .terminal-4130924772-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1480303962-r1 { fill: #c5c8c6 } - .terminal-1480303962-r2 { fill: #e3e3e3 } - .terminal-1480303962-r3 { fill: #989898 } - .terminal-1480303962-r4 { fill: #e1e1e1 } - .terminal-1480303962-r5 { fill: #121212 } - .terminal-1480303962-r6 { fill: #0053aa } - .terminal-1480303962-r7 { fill: #dde8f3;font-weight: bold } - .terminal-1480303962-r8 { fill: #98a84b } - .terminal-1480303962-r9 { fill: #626262 } - .terminal-1480303962-r10 { fill: #608ab1 } - .terminal-1480303962-r11 { fill: #d0b344 } - .terminal-1480303962-r12 { fill: #4ebf71;font-weight: bold } - .terminal-1480303962-r13 { fill: #d2d2d2 } - .terminal-1480303962-r14 { fill: #82aaff } - .terminal-1480303962-r15 { fill: #eeffff } - .terminal-1480303962-r16 { fill: #7ae998 } - .terminal-1480303962-r17 { fill: #507bb3 } - .terminal-1480303962-r18 { fill: #dde6ed;font-weight: bold } - .terminal-1480303962-r19 { fill: #008139 } - .terminal-1480303962-r20 { fill: #001541 } - .terminal-1480303962-r21 { fill: #ddedf9 } + .terminal-4130924772-r1 { fill: #c5c8c6 } + .terminal-4130924772-r2 { fill: #e3e3e3 } + .terminal-4130924772-r3 { fill: #989898 } + .terminal-4130924772-r4 { fill: #e1e1e1 } + .terminal-4130924772-r5 { fill: #121212 } + .terminal-4130924772-r6 { fill: #0053aa } + .terminal-4130924772-r7 { fill: #dde8f3;font-weight: bold } + .terminal-4130924772-r8 { fill: #98e024 } + .terminal-4130924772-r9 { fill: #626262 } + .terminal-4130924772-r10 { fill: #9d65ff } + .terminal-4130924772-r11 { fill: #fd971f } + .terminal-4130924772-r12 { fill: #4ebf71;font-weight: bold } + .terminal-4130924772-r13 { fill: #d2d2d2 } + .terminal-4130924772-r14 { fill: #82aaff } + .terminal-4130924772-r15 { fill: #eeffff } + .terminal-4130924772-r16 { fill: #939393;font-weight: bold } + .terminal-4130924772-r17 { fill: #7ae998 } + .terminal-4130924772-r18 { fill: #507bb3 } + .terminal-4130924772-r19 { fill: #dde6ed;font-weight: bold } + .terminal-4130924772-r20 { fill: #008139 } + .terminal-4130924772-r21 { fill: #001541 } + .terminal-4130924772-r22 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - HowTo create a GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - - If you would like to create the GitHub repository later, you can do it manually by following - these steps: - -  1. Create a new GitHub repository -  2. Add the remote to your local repository - - - cd<pipeline_directory> - gitremoteaddorigingit@github.com:<username>/<repo_name>.git - - -  3. Push the code to the remote - - - gitpush--allorigin - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close AppShow Logging - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + HowTo create a GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + +                                           ,--./,-. +           ___     __   __   __   ___     /,-._.--~\  +     |\ | |__  __ /  ` /  \ |__) |__         }  { +     | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                           `._,._,' + + If you would like to create the GitHub repository later, you can do it manually by following + these steps: + +  1. Create a new GitHub repository +  2. Add the remote to your local repository: + + + cd<pipeline_directory> + gitremoteaddorigingit@github.com:<username>/<repo_name>.git + + +  3. Push the code to the remote: + + + gitpush--allorigin + + + ● Note the --all flag: this is needed to push all branches to the remote. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + CloseShow pipeline creation log + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -1965,248 +1968,248 @@ font-weight: 700; } - .terminal-4165331380-matrix { + .terminal-3308461771-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4165331380-title { + .terminal-3308461771-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4165331380-r1 { fill: #c5c8c6 } - .terminal-4165331380-r2 { fill: #e3e3e3 } - .terminal-4165331380-r3 { fill: #989898 } - .terminal-4165331380-r4 { fill: #e1e1e1 } - .terminal-4165331380-r5 { fill: #121212 } - .terminal-4165331380-r6 { fill: #0053aa } - .terminal-4165331380-r7 { fill: #dde8f3;font-weight: bold } - .terminal-4165331380-r8 { fill: #7ae998 } - .terminal-4165331380-r9 { fill: #507bb3 } - .terminal-4165331380-r10 { fill: #4ebf71;font-weight: bold } - .terminal-4165331380-r11 { fill: #dde6ed;font-weight: bold } - .terminal-4165331380-r12 { fill: #008139 } - .terminal-4165331380-r13 { fill: #001541 } - .terminal-4165331380-r14 { fill: #ddedf9 } + .terminal-3308461771-r1 { fill: #c5c8c6 } + .terminal-3308461771-r2 { fill: #e3e3e3 } + .terminal-3308461771-r3 { fill: #989898 } + .terminal-3308461771-r4 { fill: #e1e1e1 } + .terminal-3308461771-r5 { fill: #121212 } + .terminal-3308461771-r6 { fill: #0053aa } + .terminal-3308461771-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3308461771-r8 { fill: #7ae998 } + .terminal-3308461771-r9 { fill: #507bb3 } + .terminal-3308461771-r10 { fill: #4ebf71;font-weight: bold } + .terminal-3308461771-r11 { fill: #dde6ed;font-weight: bold } + .terminal-3308461771-r12 { fill: #008139 } + .terminal-3308461771-r13 { fill: #001541 } + .terminal-3308461771-r14 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - After creating the pipeline template locally, we can create a GitHub repository and push the - code to it. - - Do you want to create a GitHub repository? - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Create GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + After creating the pipeline template locally, we can create a GitHub repository and push the + code to it. + + Do you want to create a GitHub repository? + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Create GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -2236,254 +2239,254 @@ font-weight: 700; } - .terminal-3762159600-matrix { + .terminal-1734914007-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3762159600-title { + .terminal-1734914007-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3762159600-r1 { fill: #c5c8c6 } - .terminal-3762159600-r2 { fill: #e3e3e3 } - .terminal-3762159600-r3 { fill: #989898 } - .terminal-3762159600-r4 { fill: #e1e1e1 } - .terminal-3762159600-r5 { fill: #121212 } - .terminal-3762159600-r6 { fill: #0053aa } - .terminal-3762159600-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3762159600-r8 { fill: #1e1e1e } - .terminal-3762159600-r9 { fill: #507bb3 } - .terminal-3762159600-r10 { fill: #e2e2e2 } - .terminal-3762159600-r11 { fill: #808080 } - .terminal-3762159600-r12 { fill: #dde6ed;font-weight: bold } - .terminal-3762159600-r13 { fill: #001541 } - .terminal-3762159600-r14 { fill: #454a50 } - .terminal-3762159600-r15 { fill: #7ae998 } - .terminal-3762159600-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-3762159600-r17 { fill: #0a180e;font-weight: bold } - .terminal-3762159600-r18 { fill: #000000 } - .terminal-3762159600-r19 { fill: #008139 } - .terminal-3762159600-r20 { fill: #ddedf9 } + .terminal-1734914007-r1 { fill: #c5c8c6 } + .terminal-1734914007-r2 { fill: #e3e3e3 } + .terminal-1734914007-r3 { fill: #989898 } + .terminal-1734914007-r4 { fill: #e1e1e1 } + .terminal-1734914007-r5 { fill: #121212 } + .terminal-1734914007-r6 { fill: #0053aa } + .terminal-1734914007-r7 { fill: #dde8f3;font-weight: bold } + .terminal-1734914007-r8 { fill: #1e1e1e } + .terminal-1734914007-r9 { fill: #507bb3 } + .terminal-1734914007-r10 { fill: #e2e2e2 } + .terminal-1734914007-r11 { fill: #808080 } + .terminal-1734914007-r12 { fill: #dde6ed;font-weight: bold } + .terminal-1734914007-r13 { fill: #001541 } + .terminal-1734914007-r14 { fill: #454a50 } + .terminal-1734914007-r15 { fill: #7ae998 } + .terminal-1734914007-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-1734914007-r17 { fill: #0a180e;font-weight: bold } + .terminal-1734914007-r18 { fill: #000000 } + .terminal-1734914007-r19 { fill: #008139 } + .terminal-1734914007-r20 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Template features - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference genomesThe pipeline will be Show help - ▁▁▁▁▁▁▁▁configured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - copy of the most  - common reference  - genome files from  - iGenomes - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github CI testsThe pipeline will Show help - ▁▁▁▁▁▁▁▁include several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - GitHub actions for  - Continuous  - Integration (CI)  - testing - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github badgesThe README.md file ofShow help - ▁▁▁▁▁▁▁▁the pipeline will ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - include GitHub badges - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add configuration The pipeline will Show help - ▁▁▁▁▁▁▁▁filesinclude configuration▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - profiles containing  - custom parameters  - requried to run  - nf-core pipelines at  - different  - institutions - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackContinue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Template features + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference genomesThe pipeline will be Show help + ▁▁▁▁▁▁▁▁configured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + copy of the most  + common reference  + genome files from  + iGenomes + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github CI testsThe pipeline will Show help + ▁▁▁▁▁▁▁▁include several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + GitHub actions for  + Continuous  + Integration (CI)  + testing + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github badgesThe README.md file ofShow help + ▁▁▁▁▁▁▁▁the pipeline will ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + include GitHub badges + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add configuration The pipeline will Show help + ▁▁▁▁▁▁▁▁filesinclude configuration▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + profiles containing  + custom parameters  + requried to run  + nf-core pipelines at  + different  + institutions + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  @@ -2513,254 +2516,254 @@ font-weight: 700; } - .terminal-1488796558-matrix { + .terminal-182709094-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1488796558-title { + .terminal-182709094-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1488796558-r1 { fill: #c5c8c6 } - .terminal-1488796558-r2 { fill: #e3e3e3 } - .terminal-1488796558-r3 { fill: #989898 } - .terminal-1488796558-r4 { fill: #e1e1e1 } - .terminal-1488796558-r5 { fill: #121212 } - .terminal-1488796558-r6 { fill: #0053aa } - .terminal-1488796558-r7 { fill: #dde8f3;font-weight: bold } - .terminal-1488796558-r8 { fill: #1e1e1e } - .terminal-1488796558-r9 { fill: #507bb3 } - .terminal-1488796558-r10 { fill: #e2e2e2 } - .terminal-1488796558-r11 { fill: #808080 } - .terminal-1488796558-r12 { fill: #dde6ed;font-weight: bold } - .terminal-1488796558-r13 { fill: #001541 } - .terminal-1488796558-r14 { fill: #454a50 } - .terminal-1488796558-r15 { fill: #7ae998 } - .terminal-1488796558-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-1488796558-r17 { fill: #0a180e;font-weight: bold } - .terminal-1488796558-r18 { fill: #000000 } - .terminal-1488796558-r19 { fill: #008139 } - .terminal-1488796558-r20 { fill: #ddedf9 } + .terminal-182709094-r1 { fill: #c5c8c6 } + .terminal-182709094-r2 { fill: #e3e3e3 } + .terminal-182709094-r3 { fill: #989898 } + .terminal-182709094-r4 { fill: #e1e1e1 } + .terminal-182709094-r5 { fill: #121212 } + .terminal-182709094-r6 { fill: #0053aa } + .terminal-182709094-r7 { fill: #dde8f3;font-weight: bold } + .terminal-182709094-r8 { fill: #1e1e1e } + .terminal-182709094-r9 { fill: #507bb3 } + .terminal-182709094-r10 { fill: #e2e2e2 } + .terminal-182709094-r11 { fill: #808080 } + .terminal-182709094-r12 { fill: #dde6ed;font-weight: bold } + .terminal-182709094-r13 { fill: #001541 } + .terminal-182709094-r14 { fill: #454a50 } + .terminal-182709094-r15 { fill: #7ae998 } + .terminal-182709094-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-182709094-r17 { fill: #0a180e;font-weight: bold } + .terminal-182709094-r18 { fill: #000000 } + .terminal-182709094-r19 { fill: #008139 } + .terminal-182709094-r20 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Template features - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference genomesThe pipeline will be Show help - ▁▁▁▁▁▁▁▁configured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - copy of the most  - common reference  - genome files from  - iGenomes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackContinue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Template features + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference genomesThe pipeline will be Show help + ▁▁▁▁▁▁▁▁configured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + copy of the most  + common reference  + genome files from  + iGenomes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  @@ -2790,256 +2793,256 @@ font-weight: 700; } - .terminal-2179958535-matrix { + .terminal-2320153615-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2179958535-title { + .terminal-2320153615-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2179958535-r1 { fill: #c5c8c6 } - .terminal-2179958535-r2 { fill: #e3e3e3 } - .terminal-2179958535-r3 { fill: #989898 } - .terminal-2179958535-r4 { fill: #e1e1e1 } - .terminal-2179958535-r5 { fill: #121212 } - .terminal-2179958535-r6 { fill: #0053aa } - .terminal-2179958535-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2179958535-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-2179958535-r9 { fill: #1e1e1e } - .terminal-2179958535-r10 { fill: #0f4e2a } - .terminal-2179958535-r11 { fill: #7b3042 } - .terminal-2179958535-r12 { fill: #a7a7a7 } - .terminal-2179958535-r13 { fill: #787878 } - .terminal-2179958535-r14 { fill: #e2e2e2 } - .terminal-2179958535-r15 { fill: #b93c5b } - .terminal-2179958535-r16 { fill: #454a50 } - .terminal-2179958535-r17 { fill: #166d39 } - .terminal-2179958535-r18 { fill: #e2e3e3;font-weight: bold } - .terminal-2179958535-r19 { fill: #3c8b54;font-weight: bold } - .terminal-2179958535-r20 { fill: #000000 } - .terminal-2179958535-r21 { fill: #5aa86f } - .terminal-2179958535-r22 { fill: #ddedf9 } + .terminal-2320153615-r1 { fill: #c5c8c6 } + .terminal-2320153615-r2 { fill: #e3e3e3 } + .terminal-2320153615-r3 { fill: #989898 } + .terminal-2320153615-r4 { fill: #e1e1e1 } + .terminal-2320153615-r5 { fill: #121212 } + .terminal-2320153615-r6 { fill: #0053aa } + .terminal-2320153615-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2320153615-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-2320153615-r9 { fill: #1e1e1e } + .terminal-2320153615-r10 { fill: #0f4e2a } + .terminal-2320153615-r11 { fill: #7b3042 } + .terminal-2320153615-r12 { fill: #a7a7a7 } + .terminal-2320153615-r13 { fill: #787878 } + .terminal-2320153615-r14 { fill: #e2e2e2 } + .terminal-2320153615-r15 { fill: #b93c5b } + .terminal-2320153615-r16 { fill: #454a50 } + .terminal-2320153615-r17 { fill: #166d39 } + .terminal-2320153615-r18 { fill: #e2e3e3;font-weight: bold } + .terminal-2320153615-r19 { fill: #3c8b54;font-weight: bold } + .terminal-2320153615-r20 { fill: #000000 } + .terminal-2320153615-r21 { fill: #5aa86f } + .terminal-2320153615-r22 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Must be lowercase without  - punctuation. - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Cannot be left empty. - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Cannot be left empty. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackNext - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Must be lowercase without  + punctuation. + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -3069,145 +3072,147 @@ font-weight: 700; } - .terminal-2481518089-matrix { + .terminal-2790734285-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2481518089-title { + .terminal-2790734285-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2481518089-r1 { fill: #c5c8c6 } - .terminal-2481518089-r2 { fill: #e3e3e3 } - .terminal-2481518089-r3 { fill: #989898 } - .terminal-2481518089-r4 { fill: #1e1e1e } - .terminal-2481518089-r5 { fill: #e1e1e1 } - .terminal-2481518089-r6 { fill: #121212 } - .terminal-2481518089-r7 { fill: #0053aa } - .terminal-2481518089-r8 { fill: #dde8f3;font-weight: bold } - .terminal-2481518089-r9 { fill: #98a84b } - .terminal-2481518089-r10 { fill: #626262 } - .terminal-2481518089-r11 { fill: #608ab1 } - .terminal-2481518089-r12 { fill: #d0b344 } - .terminal-2481518089-r13 { fill: #14191f } - .terminal-2481518089-r14 { fill: #e1e1e1;text-decoration: underline; } - .terminal-2481518089-r15 { fill: #ddedf9 } + .terminal-2790734285-r1 { fill: #c5c8c6 } + .terminal-2790734285-r2 { fill: #e3e3e3 } + .terminal-2790734285-r3 { fill: #989898 } + .terminal-2790734285-r4 { fill: #1e1e1e } + .terminal-2790734285-r5 { fill: #98e024 } + .terminal-2790734285-r6 { fill: #626262 } + .terminal-2790734285-r7 { fill: #9d65ff } + .terminal-2790734285-r8 { fill: #fd971f } + .terminal-2790734285-r9 { fill: #e1e1e1 } + .terminal-2790734285-r10 { fill: #121212 } + .terminal-2790734285-r11 { fill: #0053aa } + .terminal-2790734285-r12 { fill: #dde8f3;font-weight: bold } + .terminal-2790734285-r13 { fill: #e1e1e1;text-decoration: underline; } + .terminal-2790734285-r14 { fill: #e1e1e1;font-style: italic; } + .terminal-2790734285-r15 { fill: #14191f } + .terminal-2790734285-r16 { fill: #e1e1e1;font-weight: bold;font-style: italic; } + .terminal-2790734285-r17 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pip… - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create a pipeline from the nf-core template - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - -                                         ,--./,-. -         ___     __   __   __   ___     /,-._.--~\ - |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                        `._,._,' - ▇▇ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - nf-core create - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - This app will help you create a new nf-core pipeline. It uses the  - nf-core pipeline template, which is kept within the nf-core/tools  - repository. - -  D Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pip… + +                                           ,--./,-. +           ___     __   __   __   ___     /,-._.--~\  +     |\ | |__  __ /  ` /  \ |__) |__         }  { +     | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                           `._,._,' + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Welcome to the nf-core pipeline creation wizard + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This app will help you create a new Nextflow pipeline from the nf-core + pipeline template, part of the nf-core/tools repository. + + The template must be used for nf-core pipelines, but hopefully helps  + all Nextflow developers benefit from nf-core best practices. + + If you want to add a pipeline to nf-core, please join on Slack and ▆▆ + discuss your plans with the community as early as possible; ideally  + before you start on your pipeline! See the nf-core guidelines and the  + #new-pipelines Slack channel for more information. +  D Toggle dark mode  Q  Quit  diff --git a/tests/lint/configs.py b/tests/lint/configs.py index b50a1393aa..8610910cd8 100644 --- a/tests/lint/configs.py +++ b/tests/lint/configs.py @@ -2,8 +2,8 @@ import yaml -import nf_core.create import nf_core.lint +import nf_core.pipelines.create def test_withname_in_modules_config(self): diff --git a/tests/lint/nfcore_yml.py b/tests/lint/nfcore_yml.py index 474ccd48fc..9d745a6346 100644 --- a/tests/lint/nfcore_yml.py +++ b/tests/lint/nfcore_yml.py @@ -1,8 +1,8 @@ import re from pathlib import Path -import nf_core.create import nf_core.lint +import nf_core.pipelines.create def test_nfcore_yml_pass(self): From eaedeb75c780451b427201bec8a556816b2ee7ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 3 Apr 2024 10:06:10 +0000 Subject: [PATCH 085/175] fix providing a prefix twitha template yaml --- nf_core/__main__.py | 1 + nf_core/pipelines/create/create.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index c123787316..8d066b0ec2 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -648,6 +648,7 @@ def create_pipeline(ctx, name, description, author, version, force, outdir, temp version=version, force=force, outdir=outdir, + template_config=template_yaml, organisation=organisation, ) create_obj.init_pipeline() diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index ff1d488b1a..b5136cf8b1 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -132,9 +132,13 @@ def check_template_yaml_info(self, template_yaml, name, description, author): with open(template_yaml) as f: template_yaml = yaml.safe_load(f) config = CreateConfig(**template_yaml) + # Allow giving a prefix through a template + if template_yaml["prefix"] is not None and config.org is None: + config.org = template_yaml["prefix"] except FileNotFoundError: raise UserWarning(f"Template YAML file '{template_yaml}' not found.") + # Check required fields missing_fields = [] if config.name is None and name is None: missing_fields.append("name") From 682d9b35f603c162946bd4eb9891e14f02419d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 3 Apr 2024 10:07:29 +0000 Subject: [PATCH 086/175] update error message in create pipeline test --- tests/test_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 29fb703f20..f3e111a58a 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -265,7 +265,7 @@ def test_create_error(self, mock_create): result = self.invoke_cli(cmd) assert result.exit_code == 1 - assert "Command arguments are not accepted in interactive mode." in result.output + assert "Partial arguments supplied." in result.output @mock.patch("nf_core.pipelines.create.PipelineCreateApp") def test_create_app(self, mock_create): From 3aa383c5c8bbbf35d15dd00ac2f07129bfc15ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 3 Apr 2024 11:45:24 +0000 Subject: [PATCH 087/175] not show pipeline logging when creating a repo --- nf_core/pipelines/create/__init__.py | 4 - nf_core/pipelines/create/githubexit.py | 1 - nf_core/pipelines/create/githubrepo.py | 4 +- nf_core/pipelines/create/loggingscreen.py | 6 +- tests/__snapshots__/test_create_app.ambr | 253 +++++++++++----------- 5 files changed, 132 insertions(+), 136 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 15670ac5df..05589d5d26 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -93,10 +93,6 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.switch_screen("github_repo_question") elif event.button.id == "exit": self.push_screen("github_exit") - elif event.button.id == "show_logging": - # Set logging state to repo created to see the button for closing the logging screen - self.LOGGING_STATE = "repo created" - self.switch_screen(LoggingScreen()) if event.button.id == "close_app": self.exit(return_code=0) if event.button.id == "back": diff --git a/nf_core/pipelines/create/githubexit.py b/nf_core/pipelines/create/githubexit.py index 10346d030b..79421813f3 100644 --- a/nf_core/pipelines/create/githubexit.py +++ b/nf_core/pipelines/create/githubexit.py @@ -44,6 +44,5 @@ def compose(self) -> ComposeResult: yield Markdown(exit_help_text_markdown) yield Center( Button("Close", id="close_app", variant="success"), - Button("Show pipeline creation log", id="show_logging", variant="primary"), classes="cta", ) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index aee4b39dce..656f8c51ea 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -150,7 +150,6 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self._create_repo_and_push( user, pipeline_repo, github_variables["private"], github_variables["push"] ) - log.info(f"GitHub repository '{self.parent.TEMPLATE_CONFIG.name}' created successfully") except UserWarning as e: log.info(f"There was an error with message: {e}") self.parent.switch_screen("github_exit") @@ -174,7 +173,7 @@ def _create_repo_and_push(self, org, pipeline_repo, private, push): repo_exists = True except UserWarning as e: # Repo already exists - log.info(e) + log.error(e) return except UnknownObjectException: # Repo doesn't exist @@ -185,6 +184,7 @@ def _create_repo_and_push(self, org, pipeline_repo, private, push): repo = org.create_repo( self.parent.TEMPLATE_CONFIG.name, description=self.parent.TEMPLATE_CONFIG.description, private=private ) + log.info(f"GitHub repository '{self.parent.TEMPLATE_CONFIG.name}' created successfully") # Add the remote and push try: diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index 4c863b1643..89a9b595c8 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -25,7 +25,11 @@ def compose(self) -> ComposeResult: "\n" + "\n".join(nfcore_logo) + "\n", id="logo", ) - yield Markdown("Creating pipeline..") + if self.parent.LOGGING_STATE == "repo created": + yield Markdown("Creating GitHub repository..") + else: + yield Markdown("Creating pipeline..") + self.parent.LOG_HANDLER.console.clear() yield Center(self.parent.LOG_HANDLER.console) if self.parent.LOGGING_STATE == "repo created": yield Center( diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index 50beceecc0..7d3cf9d129 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1689,256 +1689,253 @@ font-weight: 700; } - .terminal-4130924772-matrix { + .terminal-2633126699-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4130924772-title { + .terminal-2633126699-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4130924772-r1 { fill: #c5c8c6 } - .terminal-4130924772-r2 { fill: #e3e3e3 } - .terminal-4130924772-r3 { fill: #989898 } - .terminal-4130924772-r4 { fill: #e1e1e1 } - .terminal-4130924772-r5 { fill: #121212 } - .terminal-4130924772-r6 { fill: #0053aa } - .terminal-4130924772-r7 { fill: #dde8f3;font-weight: bold } - .terminal-4130924772-r8 { fill: #98e024 } - .terminal-4130924772-r9 { fill: #626262 } - .terminal-4130924772-r10 { fill: #9d65ff } - .terminal-4130924772-r11 { fill: #fd971f } - .terminal-4130924772-r12 { fill: #4ebf71;font-weight: bold } - .terminal-4130924772-r13 { fill: #d2d2d2 } - .terminal-4130924772-r14 { fill: #82aaff } - .terminal-4130924772-r15 { fill: #eeffff } - .terminal-4130924772-r16 { fill: #939393;font-weight: bold } - .terminal-4130924772-r17 { fill: #7ae998 } - .terminal-4130924772-r18 { fill: #507bb3 } - .terminal-4130924772-r19 { fill: #dde6ed;font-weight: bold } - .terminal-4130924772-r20 { fill: #008139 } - .terminal-4130924772-r21 { fill: #001541 } - .terminal-4130924772-r22 { fill: #ddedf9 } + .terminal-2633126699-r1 { fill: #c5c8c6 } + .terminal-2633126699-r2 { fill: #e3e3e3 } + .terminal-2633126699-r3 { fill: #989898 } + .terminal-2633126699-r4 { fill: #e1e1e1 } + .terminal-2633126699-r5 { fill: #121212 } + .terminal-2633126699-r6 { fill: #0053aa } + .terminal-2633126699-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2633126699-r8 { fill: #98e024 } + .terminal-2633126699-r9 { fill: #626262 } + .terminal-2633126699-r10 { fill: #9d65ff } + .terminal-2633126699-r11 { fill: #fd971f } + .terminal-2633126699-r12 { fill: #4ebf71;font-weight: bold } + .terminal-2633126699-r13 { fill: #d2d2d2 } + .terminal-2633126699-r14 { fill: #82aaff } + .terminal-2633126699-r15 { fill: #eeffff } + .terminal-2633126699-r16 { fill: #939393;font-weight: bold } + .terminal-2633126699-r17 { fill: #7ae998 } + .terminal-2633126699-r18 { fill: #008139 } + .terminal-2633126699-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - HowTo create a GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - -                                           ,--./,-. -           ___     __   __   __   ___     /,-._.--~\  -     |\ | |__  __ /  ` /  \ |__) |__         }  { -     | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                           `._,._,' - - If you would like to create the GitHub repository later, you can do it manually by following - these steps: - -  1. Create a new GitHub repository -  2. Add the remote to your local repository: - - - cd<pipeline_directory> - gitremoteaddorigingit@github.com:<username>/<repo_name>.git - - -  3. Push the code to the remote: - - - gitpush--allorigin - - - ● Note the --all flag: this is needed to push all branches to the remote. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - CloseShow pipeline creation log - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + HowTo create a GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + +                                           ,--./,-. +           ___     __   __   __   ___     /,-._.--~\  +     |\ | |__  __ /  ` /  \ |__) |__         }  { +     | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                           `._,._,' + + If you would like to create the GitHub repository later, you can do it manually by following + these steps: + +  1. Create a new GitHub repository +  2. Add the remote to your local repository: + + + cd<pipeline_directory> + gitremoteaddorigingit@github.com:<username>/<repo_name>.git + + +  3. Push the code to the remote: + + + gitpush--allorigin + + + ● Note the --all flag: this is needed to push all branches to the remote. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  From d8283bb91556e5a1556c103003f3768b275fe0a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 3 Apr 2024 12:19:11 +0000 Subject: [PATCH 088/175] fix pipeline create tests --- nf_core/pipelines/create/create.py | 2 +- tests/test_cli.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index b5136cf8b1..be3ef6849d 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -133,7 +133,7 @@ def check_template_yaml_info(self, template_yaml, name, description, author): template_yaml = yaml.safe_load(f) config = CreateConfig(**template_yaml) # Allow giving a prefix through a template - if template_yaml["prefix"] is not None and config.org is None: + if "prefix" in template_yaml and config.org is None: config.org = template_yaml["prefix"] except FileNotFoundError: raise UserWarning(f"Template YAML file '{template_yaml}' not found.") diff --git a/tests/test_cli.py b/tests/test_cli.py index f3e111a58a..4f1e1d564c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -250,6 +250,7 @@ def test_create(self, mock_create): force="force" in params, version="1.0.0dev", outdir=params["outdir"], + template_config=None, organisation="nf-core", ) mock_create.return_value.init_pipeline.assert_called_once() From 241bc207c8285650847e5acf3f6e1bb3f1f57637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 3 Apr 2024 12:48:02 +0000 Subject: [PATCH 089/175] use org instead of prefix in pipeline template --- .github/workflows/create-test-lint-wf-template.yml | 10 +++++----- nf_core/lint/files_unchanged.py | 2 +- nf_core/pipelines/create/create.py | 5 +---- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index 035ae86e0b..83559113a2 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -84,23 +84,23 @@ jobs: run: | mkdir create-test-lint-wf export NXF_WORK=$(pwd) - printf "prefix: my-prefix\nskip: ['ci', 'github_badges', 'igenomes', 'nf_core_configs']" > create-test-lint-wf/template_skip_all.yml + printf "org: my-prefix\nskip: ['ci', 'github_badges', 'igenomes', 'nf_core_configs']" > create-test-lint-wf/template_skip_all.yml - name: Create template skip github_badges run: | - printf "prefix: my-prefix\nskip: github_badges" > create-test-lint-wf/template_skip_github_badges.yml + printf "org: my-prefix\nskip: github_badges" > create-test-lint-wf/template_skip_github_badges.yml - name: Create template skip igenomes run: | - printf "prefix: my-prefix\nskip: igenomes" > create-test-lint-wf/template_skip_igenomes.yml + printf "org: my-prefix\nskip: igenomes" > create-test-lint-wf/template_skip_igenomes.yml - name: Create template skip ci run: | - printf "prefix: my-prefix\nskip: ci" > create-test-lint-wf/template_skip_ci.yml + printf "org: my-prefix\nskip: ci" > create-test-lint-wf/template_skip_ci.yml - name: Create template skip nf_core_configs run: | - printf "prefix: my-prefix\nskip: nf_core_configs" > create-test-lint-wf/template_skip_nf_core_configs.yml + printf "org: my-prefix\nskip: nf_core_configs" > create-test-lint-wf/template_skip_nf_core_configs.yml # Create a pipeline from the template - name: create a pipeline from the template ${{ matrix.TEMPLATE }} diff --git a/nf_core/lint/files_unchanged.py b/nf_core/lint/files_unchanged.py index e78ae77875..50332e925d 100644 --- a/nf_core/lint/files_unchanged.py +++ b/nf_core/lint/files_unchanged.py @@ -119,7 +119,7 @@ def files_unchanged(self) -> Dict[str, Union[List[str], bool]]: "name": short_name, "description": self.nf_config["manifest.description"].strip("\"'"), "author": self.nf_config["manifest.author"].strip("\"'"), - "prefix": prefix, + "org": prefix, } template_yaml_path = Path(tmp_dir, "template.yaml") diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index be3ef6849d..1fd4601ee7 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -132,9 +132,6 @@ def check_template_yaml_info(self, template_yaml, name, description, author): with open(template_yaml) as f: template_yaml = yaml.safe_load(f) config = CreateConfig(**template_yaml) - # Allow giving a prefix through a template - if "prefix" in template_yaml and config.org is None: - config.org = template_yaml["prefix"] except FileNotFoundError: raise UserWarning(f"Template YAML file '{template_yaml}' not found.") @@ -177,7 +174,7 @@ def update_config(self, organisation, version, force, outdir): if self.config.outdir is None: self.config.outdir = outdir if outdir else "." if self.config.is_nfcore is None: - self.config.is_nfcore = organisation == "nf-core" + self.config.is_nfcore = self.config.org == "nf-core" def obtain_jinja_params_dict(self, features_to_skip, pipeline_dir): """Creates a dictionary of parameters for the new pipeline. From 6f2a59b4a9e33ff7725196271e503186ada130d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Fri, 5 Apr 2024 09:23:39 +0000 Subject: [PATCH 090/175] add 'back' button if the pipeline exists --- nf_core/pipelines/create/__init__.py | 2 -- nf_core/pipelines/create/error.py | 38 ----------------------- nf_core/pipelines/create/finaldetails.py | 5 +-- nf_core/pipelines/create/loggingscreen.py | 1 + 4 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 nf_core/pipelines/create/error.py diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 05589d5d26..96f027e9fc 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -7,7 +7,6 @@ from nf_core.pipelines.create.basicdetails import BasicDetails from nf_core.pipelines.create.custompipeline import CustomPipeline -from nf_core.pipelines.create.error import ExistError from nf_core.pipelines.create.finaldetails import FinalDetails from nf_core.pipelines.create.githubexit import GithubExit from nf_core.pipelines.create.githubrepo import GithubRepo @@ -57,7 +56,6 @@ class PipelineCreateApp(App[CreateConfig]): "github_repo_question": GithubRepoQuestion(), "github_repo": GithubRepo(), "github_exit": GithubExit(), - "error_screen": ExistError(), } # Initialise config as empty diff --git a/nf_core/pipelines/create/error.py b/nf_core/pipelines/create/error.py deleted file mode 100644 index 67c67aa1c2..0000000000 --- a/nf_core/pipelines/create/error.py +++ /dev/null @@ -1,38 +0,0 @@ -from textwrap import dedent - -from textual.app import ComposeResult -from textual.containers import Center -from textual.screen import Screen -from textual.widgets import Button, Footer, Header, Markdown, Static - -from nf_core.utils import nfcore_logo - - -class ExistError(Screen): - """A screen to show the final text and exit the app - when an error ocurred.""" - - def compose(self) -> ComposeResult: - yield Header() - yield Footer() - yield Markdown( - dedent( - """ - # Pipeline exists - """ - ) - ) - yield Static( - "\n" + "\n".join(nfcore_logo) + "\n", - id="logo", - ) - - completed_text_markdown = f""" - A pipeline '`{self.parent.TEMPLATE_CONFIG.outdir + "/" + self.parent.TEMPLATE_CONFIG.org + "-" + self.parent.TEMPLATE_CONFIG.name}`' already exists. - Please select a different name or `force` the creation of the pipeline to override the existing one. - """ - - yield Markdown(dedent(completed_text_markdown)) - yield Center( - Button("Close App", id="close_app", variant="success"), - classes="cta", - ) diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index c621a425ab..7f0f5d9187 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -91,10 +91,6 @@ class PipelineExists(Message): pass - @on(PipelineExists) - def show_pipeline_error(self) -> None: - self.parent.switch_screen("error_screen") - @work(thread=True, exclusive=True) def _create_pipeline(self) -> None: """Create the pipeline.""" @@ -108,3 +104,4 @@ def _create_pipeline(self) -> None: self.parent.call_from_thread(change_select_disabled, self.parent, "close_screen", False) except UserWarning: self.post_message(self.PipelineExists()) + self.parent.call_from_thread(change_select_disabled, self.parent, "back", False) diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index 89a9b595c8..dcb9fce7e6 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -38,6 +38,7 @@ def compose(self) -> ComposeResult: ) else: yield Center( + Button("Back", id="back", variant="default", disabled=True), Button("Continue", id="close_screen", variant="success", disabled=True), classes="cta", ) From 24704a7ee856546f929ba254920bb52ba375da3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Fri, 5 Apr 2024 09:48:30 +0000 Subject: [PATCH 091/175] add option to set repo name --- nf_core/pipelines/create/githubrepo.py | 36 ++++++++++++++++++-------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 656f8c51ea..461f41272b 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -56,6 +56,14 @@ def compose(self) -> ComposeResult: ) yield Button("Show", id="show_password") yield Button("Hide", id="hide_password") + with Horizontal(classes="ghrepo-cols"): + yield TextInput( + "repo_name", + "Repository name", + "The name of the new GitHub repository", + default=self.parent.TEMPLATE_CONFIG.name, + classes="column", + ) with Horizontal(classes="ghrepo-cols"): yield Switch(value=False, id="private") with Vertical(): @@ -89,7 +97,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: elif event.button.id == "create_github": # Create a GitHub repo - # Save GitHub username and token + # Save GitHub username, token and repo name github_variables = {} for text_input in self.query("TextInput"): this_input = text_input.query_one(Input) @@ -101,7 +109,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: # Pipeline git repo pipeline_repo = git.Repo.init( Path(self.parent.TEMPLATE_CONFIG.outdir) - / Path(self.parent.TEMPLATE_CONFIG.org + "-" + self.parent.TEMPLATE_CONFIG.name) + / Path(self.parent.TEMPLATE_CONFIG.org + "-" + github_variables["repo_name"]) ) # GitHub authentication @@ -140,7 +148,11 @@ def on_button_pressed(self, event: Button.Pressed) -> None: try: if org: self._create_repo_and_push( - org, pipeline_repo, github_variables["private"], github_variables["push"] + org, + github_variables["repo_name"], + pipeline_repo, + github_variables["private"], + github_variables["push"], ) else: # Create the repo in the user's account @@ -148,7 +160,11 @@ def on_button_pressed(self, event: Button.Pressed) -> None: f"Repo will be created in the GitHub organisation account '{github_variables['gh_username']}'" ) self._create_repo_and_push( - user, pipeline_repo, github_variables["private"], github_variables["push"] + user, + github_variables["repo_name"], + pipeline_repo, + github_variables["private"], + github_variables["push"], ) except UserWarning as e: log.info(f"There was an error with message: {e}") @@ -158,16 +174,16 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.parent.switch_screen(LoggingScreen()) @work(thread=True, exclusive=True) - def _create_repo_and_push(self, org, pipeline_repo, private, push): + def _create_repo_and_push(self, org, repo_name, pipeline_repo, private, push): """Create a GitHub repository and push all branches.""" self.post_message(ShowLogs()) # Check if repo already exists try: - repo = org.get_repo(self.parent.TEMPLATE_CONFIG.name) + repo = org.get_repo(repo_name) # Check if it has a commit history try: repo.get_commits().totalCount - raise UserWarning(f"GitHub repository '{self.parent.TEMPLATE_CONFIG.name}' already exists") + raise UserWarning(f"GitHub repository '{repo_name}' already exists") except GithubException: # Repo is empty repo_exists = True @@ -181,10 +197,8 @@ def _create_repo_and_push(self, org, pipeline_repo, private, push): # Create the repo if not repo_exists: - repo = org.create_repo( - self.parent.TEMPLATE_CONFIG.name, description=self.parent.TEMPLATE_CONFIG.description, private=private - ) - log.info(f"GitHub repository '{self.parent.TEMPLATE_CONFIG.name}' created successfully") + repo = org.create_repo(repo_name, description=self.parent.TEMPLATE_CONFIG.description, private=private) + log.info(f"GitHub repository '{repo_name}' created successfully") # Add the remote and push try: From 5add94be701033401e0c2087adc0d55021d57198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Fri, 5 Apr 2024 11:45:19 +0000 Subject: [PATCH 092/175] show help if repo already exists --- nf_core/pipelines/create/githubrepo.py | 13 +++++++++++-- nf_core/pipelines/create/loggingscreen.py | 3 ++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 461f41272b..02545e0182 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -9,11 +9,12 @@ from textual import work from textual.app import ComposeResult from textual.containers import Center, Horizontal, Vertical +from textual.message import Message from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch from nf_core.pipelines.create.loggingscreen import LoggingScreen -from nf_core.pipelines.create.utils import ShowLogs, TextInput +from nf_core.pipelines.create.utils import ShowLogs, TextInput, change_select_disabled log = logging.getLogger(__name__) @@ -167,12 +168,17 @@ def on_button_pressed(self, event: Button.Pressed) -> None: github_variables["push"], ) except UserWarning as e: - log.info(f"There was an error with message: {e}") + log.error(f"There was an error with message: {e}") self.parent.switch_screen("github_exit") self.parent.LOGGING_STATE = "repo created" self.parent.switch_screen(LoggingScreen()) + class RepoExists(Message): + """Custom message to indicate that the GitHub repo already exists.""" + + pass + @work(thread=True, exclusive=True) def _create_repo_and_push(self, org, repo_name, pipeline_repo, private, push): """Create a GitHub repository and push all branches.""" @@ -190,6 +196,8 @@ def _create_repo_and_push(self, org, repo_name, pipeline_repo, private, push): except UserWarning as e: # Repo already exists log.error(e) + self.parent.call_from_thread(self.post_message, self.RepoExists()) + self.parent.call_from_thread(change_select_disabled, self.parent, "exit", False) return except UnknownObjectException: # Repo doesn't exist @@ -199,6 +207,7 @@ def _create_repo_and_push(self, org, repo_name, pipeline_repo, private, push): if not repo_exists: repo = org.create_repo(repo_name, description=self.parent.TEMPLATE_CONFIG.description, private=private) log.info(f"GitHub repository '{repo_name}' created successfully") + self.parent.call_from_thread(change_select_disabled, self.parent, "close_app", False) # Add the remote and push try: diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index dcb9fce7e6..a862852d75 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -33,7 +33,8 @@ def compose(self) -> ComposeResult: yield Center(self.parent.LOG_HANDLER.console) if self.parent.LOGGING_STATE == "repo created": yield Center( - Button("Close App", id="close_app", variant="success"), + Button("Continue", id="exit", variant="success", disabled=True), + Button("Close App", id="close_app", variant="success", disabled=True), classes="cta", ) else: From 5d9ebbd3d349d3d7c8455787900cd50ab17be6c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Fri, 5 Apr 2024 12:45:29 +0000 Subject: [PATCH 093/175] hide buttons not used in logging screen --- nf_core/pipelines/create/create.tcss | 4 ++++ nf_core/pipelines/create/finaldetails.py | 4 +++- nf_core/pipelines/create/githubrepo.py | 4 +++- nf_core/pipelines/create/utils.py | 5 +++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/nf_core/pipelines/create/create.tcss b/nf_core/pipelines/create/create.tcss index b2355e1335..67394a9de3 100644 --- a/nf_core/pipelines/create/create.tcss +++ b/nf_core/pipelines/create/create.tcss @@ -118,6 +118,10 @@ Vertical{ margin: 0 4 2 4; } +.hide { + display: none; +} + /* Layouts */ .col-2 { grid-size: 2 1; diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 7f0f5d9187..b822c09f8a 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -11,7 +11,7 @@ from nf_core.pipelines.create.create import PipelineCreate from nf_core.pipelines.create.loggingscreen import LoggingScreen -from nf_core.pipelines.create.utils import ShowLogs, TextInput, change_select_disabled +from nf_core.pipelines.create.utils import ShowLogs, TextInput, add_hide_class, change_select_disabled class FinalDetails(Screen): @@ -102,6 +102,8 @@ def _create_pipeline(self) -> None: try: create_obj.init_pipeline() self.parent.call_from_thread(change_select_disabled, self.parent, "close_screen", False) + add_hide_class(self.parent, "back") except UserWarning: self.post_message(self.PipelineExists()) self.parent.call_from_thread(change_select_disabled, self.parent, "back", False) + add_hide_class(self.parent, "close_screen") diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 02545e0182..d32380de0d 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -14,7 +14,7 @@ from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch from nf_core.pipelines.create.loggingscreen import LoggingScreen -from nf_core.pipelines.create.utils import ShowLogs, TextInput, change_select_disabled +from nf_core.pipelines.create.utils import ShowLogs, TextInput, add_hide_class, change_select_disabled log = logging.getLogger(__name__) @@ -198,6 +198,7 @@ def _create_repo_and_push(self, org, repo_name, pipeline_repo, private, push): log.error(e) self.parent.call_from_thread(self.post_message, self.RepoExists()) self.parent.call_from_thread(change_select_disabled, self.parent, "exit", False) + add_hide_class(self.parent, "close_app") return except UnknownObjectException: # Repo doesn't exist @@ -208,6 +209,7 @@ def _create_repo_and_push(self, org, repo_name, pipeline_repo, private, push): repo = org.create_repo(repo_name, description=self.parent.TEMPLATE_CONFIG.description, private=private) log.info(f"GitHub repository '{repo_name}' created successfully") self.parent.call_from_thread(change_select_disabled, self.parent, "close_app", False) + add_hide_class(self.parent, "exit") # Add the remote and push try: diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index a1c9089523..7b332615fa 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -206,6 +206,11 @@ def change_select_disabled(app, widget_id: str, disabled: bool) -> None: app.get_widget_by_id(widget_id).disabled = disabled +def add_hide_class(app, widget_id: str) -> None: + """Add class 'hide' to a widget. Not display widget.""" + app.get_widget_by_id(widget_id).add_class("hide") + + ## Markdown text to reuse in different screens markdown_genomes = """ Nf-core pipelines are configured to use a copy of the most common reference genome files. From 5a0aa4629e5d531f9904aa7b12b34d3fc2d00916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Fri, 5 Apr 2024 13:12:20 +0000 Subject: [PATCH 094/175] fix threads and messages --- nf_core/pipelines/create/finaldetails.py | 7 +++++-- nf_core/pipelines/create/githubrepo.py | 11 +++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index b822c09f8a..86b93423fd 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -91,6 +91,11 @@ class PipelineExists(Message): pass + @on(PipelineExists) + def show_back_button(self) -> None: + change_select_disabled(self.parent, "back", False) + add_hide_class(self.parent, "close_screen") + @work(thread=True, exclusive=True) def _create_pipeline(self) -> None: """Create the pipeline.""" @@ -105,5 +110,3 @@ def _create_pipeline(self) -> None: add_hide_class(self.parent, "back") except UserWarning: self.post_message(self.PipelineExists()) - self.parent.call_from_thread(change_select_disabled, self.parent, "back", False) - add_hide_class(self.parent, "close_screen") diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index d32380de0d..768f77f7af 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -6,7 +6,7 @@ import git import yaml from github import Github, GithubException, UnknownObjectException -from textual import work +from textual import on, work from textual.app import ComposeResult from textual.containers import Center, Horizontal, Vertical from textual.message import Message @@ -179,6 +179,11 @@ class RepoExists(Message): pass + @on(RepoExists) + def show_github_info_button(self) -> None: + change_select_disabled(self.parent, "exit", False) + add_hide_class(self.parent, "close_app") + @work(thread=True, exclusive=True) def _create_repo_and_push(self, org, repo_name, pipeline_repo, private, push): """Create a GitHub repository and push all branches.""" @@ -196,9 +201,7 @@ def _create_repo_and_push(self, org, repo_name, pipeline_repo, private, push): except UserWarning as e: # Repo already exists log.error(e) - self.parent.call_from_thread(self.post_message, self.RepoExists()) - self.parent.call_from_thread(change_select_disabled, self.parent, "exit", False) - add_hide_class(self.parent, "close_app") + self.post_message(self.RepoExists()) return except UnknownObjectException: # Repo doesn't exist From 48d6ea17c3216ba9950d8bd4888075f6788f2419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Fri, 5 Apr 2024 13:18:37 +0000 Subject: [PATCH 095/175] update test snapshots --- tests/__snapshots__/test_create_app.ambr | 258 +++++++++++------------ 1 file changed, 129 insertions(+), 129 deletions(-) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index 7d3cf9d129..3f4b2f35c9 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1409,257 +1409,257 @@ font-weight: 700; } - .terminal-3041904966-matrix { + .terminal-2065381799-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3041904966-title { + .terminal-2065381799-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3041904966-r1 { fill: #c5c8c6 } - .terminal-3041904966-r2 { fill: #e3e3e3 } - .terminal-3041904966-r3 { fill: #989898 } - .terminal-3041904966-r4 { fill: #e1e1e1 } - .terminal-3041904966-r5 { fill: #121212 } - .terminal-3041904966-r6 { fill: #0053aa } - .terminal-3041904966-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3041904966-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-3041904966-r9 { fill: #1e1e1e } - .terminal-3041904966-r10 { fill: #008139 } - .terminal-3041904966-r11 { fill: #454a50 } - .terminal-3041904966-r12 { fill: #787878 } - .terminal-3041904966-r13 { fill: #e2e2e2 } - .terminal-3041904966-r14 { fill: #e2e3e3;font-weight: bold } - .terminal-3041904966-r15 { fill: #000000 } - .terminal-3041904966-r16 { fill: #b93c5b } - .terminal-3041904966-r17 { fill: #808080 } - .terminal-3041904966-r18 { fill: #7ae998 } - .terminal-3041904966-r19 { fill: #507bb3 } - .terminal-3041904966-r20 { fill: #0a180e;font-weight: bold } - .terminal-3041904966-r21 { fill: #dde6ed;font-weight: bold } - .terminal-3041904966-r22 { fill: #001541 } - .terminal-3041904966-r23 { fill: #ddedf9 } + .terminal-2065381799-r1 { fill: #c5c8c6 } + .terminal-2065381799-r2 { fill: #e3e3e3 } + .terminal-2065381799-r3 { fill: #989898 } + .terminal-2065381799-r4 { fill: #e1e1e1 } + .terminal-2065381799-r5 { fill: #121212 } + .terminal-2065381799-r6 { fill: #0053aa } + .terminal-2065381799-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2065381799-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-2065381799-r9 { fill: #1e1e1e } + .terminal-2065381799-r10 { fill: #008139 } + .terminal-2065381799-r11 { fill: #454a50 } + .terminal-2065381799-r12 { fill: #787878 } + .terminal-2065381799-r13 { fill: #e2e2e2 } + .terminal-2065381799-r14 { fill: #e2e3e3;font-weight: bold } + .terminal-2065381799-r15 { fill: #000000 } + .terminal-2065381799-r16 { fill: #b93c5b } + .terminal-2065381799-r17 { fill: #808080 } + .terminal-2065381799-r18 { fill: #7ae998 } + .terminal-2065381799-r19 { fill: #507bb3 } + .terminal-2065381799-r20 { fill: #0a180e;font-weight: bold } + .terminal-2065381799-r21 { fill: #dde6ed;font-weight: bold } + .terminal-2065381799-r22 { fill: #001541 } + .terminal-2065381799-r23 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - Now that we have created a new pipeline locally, we can create a new GitHub repository using - the GitHub API and push the code to it. - - - - Your GitHub usernameYour GitHub personal access token - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔Private - Select to make the new GitHub repo private. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔Push files - Select to push pipeline files and branches to your GitHub repo. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackCreate GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + Now that we have created a new pipeline locally, we can create a new GitHub repository using + the GitHub API and push the code to it. + + + + Your GitHub usernameYour GitHub personal access token + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + The name of the new GitHub repository + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + mypipeline + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔Private + Select to make the new GitHub repo private. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔Push files + Select to push pipeline files and branches to your GitHub repo. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackCreate GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  From 01481db2bb23ee682a68180ff1668d9dd1564091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Fri, 5 Apr 2024 14:21:44 +0000 Subject: [PATCH 096/175] allow selecting a github organisation --- nf_core/pipelines/create/githubrepo.py | 23 +- tests/__snapshots__/test_create_app.ambr | 258 +++++++++++------------ 2 files changed, 148 insertions(+), 133 deletions(-) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 768f77f7af..481bd44371 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -22,6 +22,12 @@ Now that we have created a new pipeline locally, we can create a new GitHub repository using the GitHub API and push the code to it. """ +github_org_help = """ +You can't create a repository to the nf-core organisation. +Please create the pipeline repo to an organisation where you have access or use your user account. +A core-team member will be able to transfer the repo to nf-core once the development has started. +You user account will be used by default if 'nf-core' is provided. +""" class GithubRepo(Screen): @@ -58,6 +64,13 @@ def compose(self) -> ComposeResult: yield Button("Show", id="show_password") yield Button("Hide", id="hide_password") with Horizontal(classes="ghrepo-cols"): + yield TextInput( + "repo_org", + "Organisation name", + "The name of the organisation where the GitHub repo will be cretaed", + default=self.parent.TEMPLATE_CONFIG.org, + classes="column", + ) yield TextInput( "repo_name", "Repository name", @@ -65,6 +78,8 @@ def compose(self) -> ComposeResult: default=self.parent.TEMPLATE_CONFIG.name, classes="column", ) + if self.parent.TEMPLATE_CONFIG.is_nfcore: + yield Markdown(dedent(github_org_help)) with Horizontal(classes="ghrepo-cols"): yield Switch(value=False, id="private") with Vertical(): @@ -110,7 +125,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: # Pipeline git repo pipeline_repo = git.Repo.init( Path(self.parent.TEMPLATE_CONFIG.outdir) - / Path(self.parent.TEMPLATE_CONFIG.org + "-" + github_variables["repo_name"]) + / Path(self.parent.TEMPLATE_CONFIG.org + "-" + self.parent.TEMPLATE_CONFIG.name) ) # GitHub authentication @@ -136,11 +151,11 @@ def on_button_pressed(self, event: Button.Pressed) -> None: # Check if organisation exists # If the organisation is nf-core or it doesn't exist, the repo will be created in the user account - if self.parent.TEMPLATE_CONFIG.org != "nf-core": + if github_variables["repo_org"] != "nf-core": try: - org = github_auth.get_organization(self.parent.TEMPLATE_CONFIG.org) + org = github_auth.get_organization(github_variables["repo_org"]) log.info( - f"Repo will be created in the GitHub organisation account '{self.parent.TEMPLATE_CONFIG.org}'" + f"Repo will be created in the GitHub organisation account '{github_variables['repo_org']}'" ) except UnknownObjectException: pass diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index 3f4b2f35c9..3477a381a4 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1409,257 +1409,257 @@ font-weight: 700; } - .terminal-2065381799-matrix { + .terminal-3368911015-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2065381799-title { + .terminal-3368911015-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2065381799-r1 { fill: #c5c8c6 } - .terminal-2065381799-r2 { fill: #e3e3e3 } - .terminal-2065381799-r3 { fill: #989898 } - .terminal-2065381799-r4 { fill: #e1e1e1 } - .terminal-2065381799-r5 { fill: #121212 } - .terminal-2065381799-r6 { fill: #0053aa } - .terminal-2065381799-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2065381799-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-2065381799-r9 { fill: #1e1e1e } - .terminal-2065381799-r10 { fill: #008139 } - .terminal-2065381799-r11 { fill: #454a50 } - .terminal-2065381799-r12 { fill: #787878 } - .terminal-2065381799-r13 { fill: #e2e2e2 } - .terminal-2065381799-r14 { fill: #e2e3e3;font-weight: bold } - .terminal-2065381799-r15 { fill: #000000 } - .terminal-2065381799-r16 { fill: #b93c5b } - .terminal-2065381799-r17 { fill: #808080 } - .terminal-2065381799-r18 { fill: #7ae998 } - .terminal-2065381799-r19 { fill: #507bb3 } - .terminal-2065381799-r20 { fill: #0a180e;font-weight: bold } - .terminal-2065381799-r21 { fill: #dde6ed;font-weight: bold } - .terminal-2065381799-r22 { fill: #001541 } - .terminal-2065381799-r23 { fill: #ddedf9 } + .terminal-3368911015-r1 { fill: #c5c8c6 } + .terminal-3368911015-r2 { fill: #e3e3e3 } + .terminal-3368911015-r3 { fill: #989898 } + .terminal-3368911015-r4 { fill: #e1e1e1 } + .terminal-3368911015-r5 { fill: #121212 } + .terminal-3368911015-r6 { fill: #0053aa } + .terminal-3368911015-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3368911015-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-3368911015-r9 { fill: #1e1e1e } + .terminal-3368911015-r10 { fill: #008139 } + .terminal-3368911015-r11 { fill: #454a50 } + .terminal-3368911015-r12 { fill: #787878 } + .terminal-3368911015-r13 { fill: #e2e2e2 } + .terminal-3368911015-r14 { fill: #e2e3e3;font-weight: bold } + .terminal-3368911015-r15 { fill: #000000 } + .terminal-3368911015-r16 { fill: #b93c5b } + .terminal-3368911015-r17 { fill: #808080 } + .terminal-3368911015-r18 { fill: #7ae998 } + .terminal-3368911015-r19 { fill: #507bb3 } + .terminal-3368911015-r20 { fill: #0a180e;font-weight: bold } + .terminal-3368911015-r21 { fill: #dde6ed;font-weight: bold } + .terminal-3368911015-r22 { fill: #001541 } + .terminal-3368911015-r23 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - Now that we have created a new pipeline locally, we can create a new GitHub repository using - the GitHub API and push the code to it. - - - - Your GitHub usernameYour GitHub personal access token - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - The name of the new GitHub repository - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - mypipeline - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔Private - Select to make the new GitHub repo private. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔Push files - Select to push pipeline files and branches to your GitHub repo. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackCreate GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + Now that we have created a new pipeline locally, we can create a new GitHub repository using + the GitHub API and push the code to it. + + + + Your GitHub usernameYour GitHub personal access token + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + The name of the organisation where the The name of the new GitHub repository + GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline + nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + You can't create a repository to the nf-core organisation. Please create the pipeline repo  + to an organisation where you have access or use your user account. A core-team member will  + be able to transfer the repo to nf-core once the development has started. You user account  + will be used by default if 'nf-core' is provided. + + + ▔▔▔▔▔▔▔▔Private + Select to make the new GitHub repo private. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔Push files + Select to push pipeline files and branches to your GitHub repo. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackCreate GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + +  D  Toggle dark mode  Q  Quit  From 6f7d0d16930598500f4a3a3014ab8c3bb740ed56 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Fri, 5 Apr 2024 16:42:47 +0200 Subject: [PATCH 097/175] Rip out the docs to put in the website repo --- README.md | 1227 +---------------- docs/images/nf-core-bump-version.svg | 187 --- docs/images/nf-core-create-logo.svg | 107 -- docs/images/nf-core-create.svg | 162 --- docs/images/nf-core-download-tree.svg | 190 --- docs/images/nf-core-download.svg | 139 -- docs/images/nf-core-launch-rnaseq.svg | 120 -- docs/images/nf-core-licences.svg | 107 -- docs/images/nf-core-lint.svg | 208 --- docs/images/nf-core-list-rna.svg | 172 --- docs/images/nf-core-list-stars.svg | 141 -- docs/images/nf-core-list.svg | 145 -- docs/images/nf-core-logo.png | Bin 17930 -> 0 bytes docs/images/nf-core-modules-bump-version.svg | 144 -- docs/images/nf-core-modules-create.svg | 123 -- docs/images/nf-core-modules-info.svg | 240 ---- docs/images/nf-core-modules-install.svg | 126 -- docs/images/nf-core-modules-lint.svg | 114 -- docs/images/nf-core-modules-list-local.svg | 155 --- docs/images/nf-core-modules-list-remote.svg | 169 --- docs/images/nf-core-modules-patch.svg | 193 --- docs/images/nf-core-modules-remove.svg | 110 -- docs/images/nf-core-modules-test.svg | 110 -- docs/images/nf-core-modules-update.svg | 122 -- docs/images/nf-core-schema-build.svg | 119 -- docs/images/nf-core-schema-lint.svg | 114 -- docs/images/nf-core-schema-validate.svg | 118 -- docs/images/nf-core-subworkflows-create.svg | 143 -- docs/images/nf-core-subworkflows-info.svg | 172 --- docs/images/nf-core-subworkflows-install.svg | 126 -- docs/images/nf-core-subworkflows-lint.svg | 341 ----- .../nf-core-subworkflows-list-local.svg | 168 --- .../nf-core-subworkflows-list-remote.svg | 169 --- docs/images/nf-core-subworkflows-remove.svg | 158 --- docs/images/nf-core-subworkflows-test.svg | 110 -- docs/images/nf-core-subworkflows-update.svg | 126 -- docs/images/nf-core-sync.svg | 145 -- docs/images/nfcore-tools_logo_dark.png | Bin 64937 -> 0 bytes docs/images/nfcore-tools_logo_light.png | Bin 64856 -> 0 bytes 39 files changed, 9 insertions(+), 6511 deletions(-) delete mode 100644 docs/images/nf-core-bump-version.svg delete mode 100644 docs/images/nf-core-create-logo.svg delete mode 100644 docs/images/nf-core-create.svg delete mode 100644 docs/images/nf-core-download-tree.svg delete mode 100644 docs/images/nf-core-download.svg delete mode 100644 docs/images/nf-core-launch-rnaseq.svg delete mode 100644 docs/images/nf-core-licences.svg delete mode 100644 docs/images/nf-core-lint.svg delete mode 100644 docs/images/nf-core-list-rna.svg delete mode 100644 docs/images/nf-core-list-stars.svg delete mode 100644 docs/images/nf-core-list.svg delete mode 100644 docs/images/nf-core-logo.png delete mode 100644 docs/images/nf-core-modules-bump-version.svg delete mode 100644 docs/images/nf-core-modules-create.svg delete mode 100644 docs/images/nf-core-modules-info.svg delete mode 100644 docs/images/nf-core-modules-install.svg delete mode 100644 docs/images/nf-core-modules-lint.svg delete mode 100644 docs/images/nf-core-modules-list-local.svg delete mode 100644 docs/images/nf-core-modules-list-remote.svg delete mode 100644 docs/images/nf-core-modules-patch.svg delete mode 100644 docs/images/nf-core-modules-remove.svg delete mode 100644 docs/images/nf-core-modules-test.svg delete mode 100644 docs/images/nf-core-modules-update.svg delete mode 100644 docs/images/nf-core-schema-build.svg delete mode 100644 docs/images/nf-core-schema-lint.svg delete mode 100644 docs/images/nf-core-schema-validate.svg delete mode 100644 docs/images/nf-core-subworkflows-create.svg delete mode 100644 docs/images/nf-core-subworkflows-info.svg delete mode 100644 docs/images/nf-core-subworkflows-install.svg delete mode 100644 docs/images/nf-core-subworkflows-lint.svg delete mode 100644 docs/images/nf-core-subworkflows-list-local.svg delete mode 100644 docs/images/nf-core-subworkflows-list-remote.svg delete mode 100644 docs/images/nf-core-subworkflows-remove.svg delete mode 100644 docs/images/nf-core-subworkflows-test.svg delete mode 100644 docs/images/nf-core-subworkflows-update.svg delete mode 100644 docs/images/nf-core-sync.svg delete mode 100644 docs/images/nfcore-tools_logo_dark.png delete mode 100644 docs/images/nfcore-tools_logo_light.png diff --git a/README.md b/README.md index a5e6799861..4ed5e63734 100644 --- a/README.md +++ b/README.md @@ -16,64 +16,17 @@ A python package with helper tools for the nf-core community. -> **Read this documentation on the nf-core website: [https://nf-co.re/tools](https://nf-co.re/tools)** - -## Table of contents - -- [`nf-core` tools installation](#installation) -- [`nf-core` tools update](#update-tools) -- [`nf-core list` - List available pipelines](#listing-pipelines) -- [`nf-core launch` - Run a pipeline with interactive parameter prompts](#launch-a-pipeline) -- [`nf-core create-params-file` - Create a parameter file](#create-a-parameter-file) -- [`nf-core download` - Download a pipeline for offline use](#downloading-pipelines-for-offline-use) -- [`nf-core licences` - List software licences in a pipeline](#pipeline-software-licences) -- [`nf-core create` - Create a new pipeline with the nf-core template](#creating-a-new-pipeline) -- [`nf-core lint` - Check pipeline code against nf-core guidelines](#linting-a-workflow) -- [`nf-core schema` - Work with pipeline schema files](#pipeline-schema) -- [`nf-core bump-version` - Update nf-core pipeline version number](#bumping-a-pipeline-version-number) -- [`nf-core sync` - Synchronise pipeline TEMPLATE branches](#sync-a-pipeline-with-the-template) -- [`nf-core create-logo` - Create an nf-core pipeline logo](#create-an-nf-core-pipeline-logo) -- [`nf-core tui` - Explore the nf-core command line graphically](#tools-cli-tui) -- [`nf-core modules` - commands for dealing with DSL2 modules](#modules) - - - [`modules list` - List available modules](#list-modules) - - [`modules list remote` - List remote modules](#list-remote-modules) - - [`modules list local` - List installed modules](#list-installed-modules) - - [`modules info` - Show information about a module](#show-information-about-a-module) - - [`modules install` - Install modules in a pipeline](#install-modules-in-a-pipeline) - - [`modules update` - Update modules in a pipeline](#update-modules-in-a-pipeline) - - [`modules remove` - Remove a module from a pipeline](#remove-a-module-from-a-pipeline) - - [`modules patch` - Create a patch file for a module](#create-a-patch-file-for-a-module) - - [`modules create` - Create a module from the template](#create-a-new-module) - - [`modules lint` - Check a module against nf-core guidelines](#check-a-module-against-nf-core-guidelines) - - [`modules test` - Run the tests for a module](#run-the-tests-for-a-module-using-pytest) - - [`modules bump-versions` - Bump software versions of modules](#bump-bioconda-and-container-versions-of-modules-in) - -- [`nf-core subworkflows` - commands for dealing with subworkflows](#subworkflows) - - [`subworkflows list` - List available subworkflows](#list-subworkflows) - - [`subworkflows list remote` - List remote subworkflows](#list-remote-subworkflows) - - [`subworkflows list local` - List installed subworkflows](#list-installed-subworkflows) - - [`subworkflows info` - Show information about a subworkflow](#show-information-about-a-subworkflow) - - [`subworkflows install` - Install subworkflows in a pipeline](#install-subworkflows-in-a-pipeline) - - [`subworkflows update` - Update subworkflows in a pipeline](#update-subworkflows-in-a-pipeline) - - [`subworkflows remove` - Remove a subworkflow from a pipeline](#remove-a-subworkflow-from-a-pipeline) - - [`subworkflows create` - Create a subworkflow from the template](#create-a-new-subworkflow) - - [`subworkflows lint` - Check a subworkflow against nf-core guidelines](#check-a-subworkflow-against-nf-core-guidelines) - - [`subworkflows test` - Run the tests for a subworkflow](#run-the-tests-for-a-subworkflow-using-pytest) -- [Citation](#citation) - The nf-core tools package is written in Python and can be imported and used within other packages. For documentation of the internal Python functions, please refer to the [Tools Python API docs](https://nf-co.re/tools/docs/). ## Installation -### Bioconda +For full installation instructions, please see the [nf-core documentation](https://nf-co.re/docs/usage/tools). +Below is a quick-start for those who know what they're doing: -You can install `nf-core/tools` from [bioconda](https://bioconda.github.io/recipes/nf-core/README.html). +### Bioconda -First, install conda and configure the channels to use bioconda -(see the [bioconda documentation](https://bioconda.github.io/index.html#usage)). -Then, just run the conda installation command: +Install [from Bioconda](https://bioconda.github.io/recipes/nf-core/README.html): ```bash conda install nf-core @@ -88,1191 +41,29 @@ conda activate nf-core ### Python Package Index -`nf-core/tools` can also be installed from [PyPI](https://pypi.python.org/pypi/nf-core/) using pip as follows: +Install [from PyPI](https://pypi.python.org/pypi/nf-core/): ```bash pip install nf-core ``` -### Docker image - -There is a docker image that you can use to run `nf-core/tools` that has all of the requirements packaged (including Nextflow) and so should work out of the box. It is called [`nfcore/tools`](https://hub.docker.com/r/nfcore/tools) _**(NB: no hyphen!)**_ - -You can use this container on the command line as follows: - -```bash -docker run -itv `pwd`:`pwd` -w `pwd` -u $(id -u):$(id -g) nfcore/tools -``` - -- `-i` and `-t` are needed for the interactive cli prompts to work (this tells Docker to use a pseudo-tty with stdin attached) -- The `-v` argument tells Docker to bind your current working directory (`pwd`) to the same path inside the container, so that files created there will be saved to your local file system outside of the container. -- `-w` sets the working directory in the container to this path, so that it's the same as your working directory outside of the container. -- `-u` sets your local user account as the user inside the container, so that any files created have the correct ownership permissions - -After the above base command, you can use the regular command line flags that you would use with other types of installation. -For example, to launch the `viralrecon` pipeline: - -```bash -docker run -itv `pwd`:`pwd` -w `pwd` -u $(id -u):$(id -g) nfcore/tools launch viralrecon -r 1.1.0 -``` - -If you use `$NXF_SINGULARITY_CACHEDIR` for downloads, you'll also need to make this folder and environment variable available to the continer: - -```bash -docker run -itv `pwd`:`pwd` -w `pwd` -u $(id -u):$(id -g) -v $NXF_SINGULARITY_CACHEDIR:$NXF_SINGULARITY_CACHEDIR -e NXF_SINGULARITY_CACHEDIR nfcore/tools launch viralrecon -r 1.1.0 -``` - -#### Docker bash alias - -The above base command is a bit of a mouthful to type, to say the least. -To make it easier to use, we highly recommend adding the following bash alias to your `~/.bashrc` file: - -```bash -alias nf-core="docker run -itv `pwd`:`pwd` -w `pwd` -u $(id -u):$(id -g) nfcore/tools" -``` - -Once applied (you may need to reload your shell) you can just use the `nf-core` command instead: - -```bash -nf-core list -``` - -#### Docker versions - -You can use docker image tags to specify the version you would like to use. For example, `nfcore/tools:dev` for the latest development version of the code, or `nfcore/tools:1.14` for version `1.14` of tools. -If you omit this, it will default to `:latest`, which should be the latest stable release. - -If you need a specific version of Nextflow inside the container, you can build an image yourself. -Clone the repo locally and check out whatever version of nf-core/tools that you need. -Then build using the `--build-arg NXF_VER` flag as follows: - -```bash -docker build -t nfcore/tools:dev . --build-arg NXF_VER=20.04.0 -``` - ### Development version -If you would like the latest development version of tools, the command is: - ```bash pip install --upgrade --force-reinstall git+https://github.com/nf-core/tools.git@dev ``` -If you intend to make edits to the code, first make a fork of the repository and then clone it locally. -Go to the cloned directory and install with pip (also installs development requirements): +If editing, fork and clone the repo, then install as follows: ```bash pip install --upgrade -r requirements-dev.txt -e . ``` -### Using a specific Python interpreter - -If you prefer, you can also run tools with a specific Python interpreter. -The command line usage and flags are then exactly the same as if you ran with the `nf-core` command. -Note that the module is `nf_core` with an underscore, not a hyphen like the console command. - -For example: - -```bash -python -m nf_core --help -python3 -m nf_core list -~/my_env/bin/python -m nf_core create --name mypipeline --description "This is a new skeleton pipeline" -``` - -### Using with your own Python scripts - -The tools functionality is written in such a way that you can import it into your own scripts. -For example, if you would like to get a list of all available nf-core pipelines: - -```python -import nf_core.list -wfs = nf_core.list.Workflows() -wfs.get_remote_workflows() -for wf in wfs.remote_workflows: - print(wf.full_name) -``` - -Please see [https://nf-co.re/tools/docs/](https://nf-co.re/tools/docs/) for the function documentation. - -### Automatic version check - -nf-core/tools automatically checks the web to see if there is a new version of nf-core/tools available. -If you would prefer to skip this check, set the environment variable `NFCORE_NO_VERSION_CHECK`. For example: - -```bash -export NFCORE_NO_VERSION_CHECK=1 -``` - -### Update tools - -It is advisable to keep nf-core/tools updated to the most recent version. The command to update depends on the system used to install it, for example if you have installed it with conda you can use: - -```bash -conda update nf-core -``` - -if you used pip: - -```bash -pip install --upgrade nf-core -``` - -Please refer to the respective documentation for further details to manage packages, as for example [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-pkgs.html#updating-packages) or [pip](https://packaging.python.org/en/latest/tutorials/installing-packages/#upgrading-packages). - -### Activate shell completions for nf-core/tools - -Auto-completion for the `nf-core` command is available for bash, zsh and fish. To activate it, add the following lines to the respective shell config files. - -| shell | shell config file | command | -| ----- | ----------------------------------------- | -------------------------------------------------- | -| bash | `~/.bashrc` | `eval "$(_NF_CORE_COMPLETE=bash_source nf-core)"` | -| zsh | `~/.zshrc` | `eval "$(_NF_CORE_COMPLETE=zsh_source nf-core)"` | -| fish | `~/.config/fish/completions/nf-core.fish` | `eval (env _NF_CORE_COMPLETE=fish_source nf-core)` | - -After a restart of the shell session you should have auto-completion for the `nf-core` command and all its sub-commands and options. - -> [!NOTE] -> The added line will run the command `nf-core` (which will also slow down startup time of your shell). You should therefore either have the nf-core/tools installed globally. -> You can also wrap it inside `if type nf-core > /dev/null; then ` \ `fi` for bash and zsh or `if command -v nf-core &> /dev/null eval (env _NF_CORE_COMPLETE=fish_source nf-core) end` for fish. You need to then source the config in your environment for the completions to be activated. - -> [!TIP] -> If you see the error `command not found compdef` , be sure that your config file contains the line `autoload -Uz compinit && compinit` before the eval line. - -## Listing pipelines - -The command `nf-core list` shows all available nf-core pipelines along with their latest version, when that was published and how recently the pipeline code was pulled to your local system (if at all). - -An example of the output from the command is as follows: - - - -![`nf-core list`](docs/images/nf-core-list.svg) - -To narrow down the list, supply one or more additional keywords to filter the pipelines based on matches in titles, descriptions and topics: - -![`nf-core list rna rna-seq`](docs/images/nf-core-list-rna.svg) - -You can sort the results by latest release (`-s release`, default), -when you last pulled a local copy (`-s pulled`), -alphabetically (`-s name`), -or number of GitHub stars (`-s stars`). - - - -![`nf-core list -s stars`](docs/images/nf-core-list-stars.svg) - -To return results as JSON output for downstream use, use the `--json` flag. - -Archived pipelines are not returned by default. To include them, use the `--show_archived` flag. - -## Launch a pipeline - -Some nextflow pipelines have a considerable number of command line flags that can be used. -To help with this, you can use the `nf-core launch` command. -You can choose between a web-based graphical interface or an interactive command-line wizard tool to enter the pipeline parameters for your run. -Both interfaces show documentation alongside each parameter and validate your inputs. - -The tool uses the `nextflow_schema.json` file from a pipeline to give parameter descriptions, defaults and grouping. -If no file for the pipeline is found, one will be automatically generated at runtime. - -Nextflow `params` variables are saved in to a JSON file called `nf-params.json` and used by nextflow with the `-params-file` flag. -This makes it easier to reuse these in the future. - -The command takes one argument - either the name of an nf-core pipeline which will be pulled automatically, -or the path to a directory containing a Nextflow pipeline _(can be any pipeline, doesn't have to be nf-core)_. - - - -![`nf-core launch rnaseq -r 3.8.1`](docs/images/nf-core-launch-rnaseq.svg) - -Once complete, the wizard will ask you if you want to launch the Nextflow run. -If not, you can copy and paste the Nextflow command with the `nf-params.json` file of your inputs. - -```console -INFO [✓] Input parameters look valid -INFO Nextflow command: - nextflow run nf-core/rnaseq -params-file "nf-params.json" - - -Do you want to run this command now? [y/n]: -``` - -### Launch tool options - -- `-r`, `--revision` - - Specify a pipeline release (or branch / git commit sha) of the project to run -- `-i`, `--id` - - You can use the web GUI for nf-core pipelines by clicking _"Launch"_ on the website. Once filled in you will be given an ID to use with this command which is used to retrieve your inputs. -- `-c`, `--command-only` - - If you prefer not to save your inputs in a JSON file and use `-params-file`, this option will specify all entered params directly in the nextflow command. -- `-p`, `--params-in PATH` - - To use values entered in a previous pipeline run, you can supply the `nf-params.json` file previously generated. - - This will overwrite the pipeline schema defaults before the wizard is launched. -- `-o`, `--params-out PATH` - - Path to save parameters JSON file to. (Default: `nf-params.json`) -- `-a`, `--save-all` - - Without this option the pipeline will ignore any values that match the pipeline schema defaults. - - This option saves _all_ parameters found to the JSON file. -- `-h`, `--show-hidden` - - A pipeline JSON schema can define some parameters as 'hidden' if they are rarely used or for internal pipeline use only. - - This option forces the wizard to show all parameters, including those labelled as 'hidden'. -- `--url` - - Change the URL used for the graphical interface, useful for development work on the website. - -## Create a parameter file - -Sometimes it is easier to manually edit a parameter file than to use the web interface or interactive commandline wizard -provided by `nf-core launch`, for example when running a pipeline with many options on a remote server without a graphical interface. - -You can create a parameter file with all parameters of a pipeline with the `nf-core create-params-file` command. -This file can then be passed to `nextflow` with the `-params-file` flag. - -This command takes one argument - either the name of a nf-core pipeline which will be pulled automatically, -or the path to a directory containing a Nextflow pipeline _(can be any pipeline, doesn't have to be nf-core)_. - -The generated YAML file contains all parameters set to the pipeline default value along with their description in comments. -This template can then be used by uncommenting and modifying the value of parameters you want to pass to a pipline run. - -Hidden options are not included by default, but can be included using the `-x`/`--show-hidden` flag. - -## Downloading pipelines for offline use - -Sometimes you may need to run an nf-core pipeline on a server or HPC system that has no internet connection. -In this case you will need to fetch the pipeline files first, then manually transfer them to your system. - -To make this process easier and ensure accurate retrieval of correctly versioned code and software containers, we have written a download helper tool. - -The `nf-core download` command will download both the pipeline code and the [institutional nf-core/configs](https://github.com/nf-core/configs) files. It can also optionally download any singularity image files that are required. - -If run without any arguments, the download tool will interactively prompt you for the required information. -Each option has a flag, if all are supplied then it will run without any user input needed. - - - -![`nf-core download rnaseq -r 3.8 --outdir nf-core-rnaseq -x none -s none -d`](docs/images/nf-core-download.svg) - -Once downloaded, you will see something like the following file structure for the downloaded pipeline: - - - -![`tree -L 2 nf-core-rnaseq/`](docs/images/nf-core-download-tree.svg) - -You can run the pipeline by simply providing the directory path for the `workflow` folder to your `nextflow run` command: - -```bash -nextflow run /path/to/download/nf-core-rnaseq-dev/workflow/ --input mydata.csv --outdir results # usual parameters here -``` - -> [!NOTE] -> If you downloaded Singularity container images, you will need to use `-profile singularity` or have it enabled in your config file. - -### Downloaded nf-core configs - -The pipeline files are automatically updated (`params.custom_config_base` is set to `../configs`), so that the local copy of institutional configs are available when running the pipeline. -So using `-profile ` should work if available within [nf-core/configs](https://github.com/nf-core/configs). - -> [!WARNING] -> This option is not available when downloading a pipeline for use with [Seqera Platform](#adapting-downloads-to-seqera-platform) because the application manages all configurations separately. - -### Downloading Apptainer containers - -If you're using [Singularity](https://apptainer.org) (Apptainer), the `nf-core download` command can also fetch the required container images for you. -To do this, select `singularity` in the prompt or specify `--container-system singularity` in the command. -Your archive / target output directory will then also include a separate folder `singularity-containers`. - -The downloaded workflow files are again edited to add the following line to the end of the pipeline's `nextflow.config` file: - -```nextflow -singularity.cacheDir = "${projectDir}/../singularity-images/" -``` - -This tells Nextflow to use the `singularity-containers` directory relative to the workflow for the singularity image cache directory. -All images should be downloaded there, so Nextflow will use them instead of trying to pull from the internet. - -#### Singularity cache directory - -We highly recommend setting the `$NXF_SINGULARITY_CACHEDIR` environment variable on your system, even if that is a different system to where you will be running Nextflow. - -If found, the tool will fetch the Singularity images to this directory first before copying to the target output archive / directory. -Any images previously fetched will be found there and copied directly - this includes images that may be shared with other pipelines or previous pipeline version downloads or download attempts. - -If you are running the download on the same system where you will be running the pipeline (eg. a shared filesystem where Nextflow won't have an internet connection at a later date), you can choose to _only_ use the cache via a prompt or cli options `--container-cache-utilisation amend`. This instructs `nf-core download` to fetch all Singularity images to the `$NXF_SINGULARITY_CACHEDIR` directory but does _not_ copy them to the workflow archive / directory. The workflow config file is _not_ edited. This means that when you later run the workflow, Nextflow will just use the cache folder directly. - -If you are downloading a workflow for a different system, you can provide information about the contents of its image cache to `nf-core download`. To avoid unnecessary container image downloads, choose `--container-cache-utilisation remote` and provide a list of already available images as plain text file to `--container-cache-index my_list_of_remotely_available_images.txt`. To generate this list on the remote system, run `find $NXF_SINGULARITY_CACHEDIR -name "*.img" > my_list_of_remotely_available_images.txt`. The tool will then only download and copy images into your output directory, which are missing on the remote system. - -#### How the Singularity image downloads work - -The Singularity image download finds containers using two methods: - -1. It runs `nextflow config` on the downloaded workflow to look for a `process.container` statement for the whole pipeline. - This is the typical method used for DSL1 pipelines. -2. It scrapes any files it finds with a `.nf` file extension in the workflow `modules` directory for lines - that look like `container = "xxx"`. This is the typical method for DSL2 pipelines, which have one container per process. - -Some DSL2 modules have container addresses for docker (eg. `biocontainers/fastqc:0.11.9--0`) and also URLs for direct downloads of a Singularity container (eg. `https://depot.galaxyproject.org/singularity/fastqc:0.11.9--0`). -Where both are found, the download URL is preferred. - -Once a full list of containers is found, they are processed in the following order: - -1. If the target image already exists, nothing is done (eg. with `$NXF_SINGULARITY_CACHEDIR` and `--container-cache-utilisation amend` specified) -2. If found in `$NXF_SINGULARITY_CACHEDIR` and `--container-cache-utilisation copy` is specified, they are copied to the output directory -3. If they start with `http` they are downloaded directly within Python (default 4 at a time, you can customise this with `--parallel-downloads`) -4. If they look like a Docker image name, they are fetched using a `singularity pull` command. Choose the container libraries (registries) queried by providing one or multiple `--container-library` parameter(s). For example, if you call `nf-core download` with `-l quay.io -l ghcr.io -l docker.io`, every image will be pulled from `quay.io` unless an error is encountered. Subsequently, `ghcr.io` and then `docker.io` will be queried for any image that has failed before. - - This requires Singularity/Apptainer to be installed on the system and is substantially slower - -Note that compressing many GBs of binary files can be slow, so specifying `--compress none` is recommended when downloading Singularity images that are copied to the output directory. - -If the download speeds are much slower than your internet connection is capable of, you can set `--parallel-downloads` to a large number to download loads of images at once. - -### Adapting downloads to Seqera Platform - -[Seqera Platform](https://seqera.io/platform/) (formerly _"Nextflow Tower"_) provides a graphical user interface to oversee pipeline runs, gather statistics and configure compute resources. While pipelines added to _Seqera Platform_ are preferably hosted at a Git service, providing them as disconnected, self-reliant repositories is also possible for premises with restricted network access. Choosing the `--platform` flag will download the pipeline in an appropriate form. - -Subsequently, the `*.git` folder can be moved to it's final destination and linked with a pipeline in _Seqera Platform_ using the `file:/` prefix. - -> [!TIP] -> Also without access to Seqera Platform, pipelines downloaded with the `--platform` flag can be run if the _absolute_ path is specified: `nextflow run -r 2.5 file:/path/to/pipelinedownload.git`. Downloads in this format allow you to include multiple revisions of a pipeline in a single file, but require that the revision (e.g. `-r 2.5`) is always explicitly specified. - -## Pipeline software licences - -Sometimes it's useful to see the software licences of the tools used in a pipeline. -You can use the `licences` subcommand to fetch and print the software licence from each conda / PyPI package used in an nf-core pipeline. - -> [!WARNING] -> This command does not currently work for newer DSL2 pipelines. This will hopefully be addressed [soon](https://github.com/nf-core/tools/issues/1155). - - - -![`nf-core licences deepvariant`](docs/images/nf-core-licences.svg) - -## Creating a new pipeline - -The `create` subcommand makes a new pipeline using the nf-core base template. -With a given pipeline name, description and author, it makes a starter pipeline which follows nf-core best practices. - -After creating the files, the command initialises the folder as a git repository and makes an initial commit. -This first "vanilla" commit which is identical to the output from the templating tool is important, as it allows us to keep your pipeline in sync with the base template in the future. -See the [nf-core syncing docs](https://nf-co.re/developers/sync) for more information. - - - -![` nf-core create -n nextbigthing -d "This pipeline analyses data from the next big omics technique" -a "Big Steve" --plain`](docs/images/nf-core-create.svg) - -Once you have run the command, create a new empty repository on GitHub under your username (not the `nf-core` organisation, yet) and push the commits from your computer using the example commands in the above log. -You can then continue to edit, commit and push normally as you build your pipeline. - -Please see the [nf-core documentation](https://nf-co.re/developers/adding_pipelines) for a full walkthrough of how to create a new nf-core workflow. - -> [!TIP] -> As the log output says, remember to come and discuss your idea for a pipeline as early as possible! -> See the [documentation](https://nf-co.re/developers/adding_pipelines#join-the-community) for instructions. - -Note that if the required arguments for `nf-core create` are not given, it will interactively prompt for them. If you prefer, you can supply them as command line arguments. See `nf-core create --help` for more information. - -### Customizing the creation of a pipeline - -The `nf-core create` command comes with a number of options that allow you to customize the creation of a pipeline if you intend to not publish it as an -nf-core pipeline. This can be done in two ways: by using interactive prompts, or by supplying a `template.yml` file using the `--template-yaml ` option. -Both options allow you to specify a custom pipeline prefix to use instead of the common `nf-core`, as well as selecting parts of the template to be excluded during pipeline creation. -The interactive prompts will guide you through the pipeline creation process. An example of a `template.yml` file is shown below. - -```yaml -name: coolpipe -description: A cool pipeline -author: me -prefix: myorg -skip: - - github - - ci - - github_badges - - igenomes - - nf_core_configs -``` - -This will create a pipeline called `coolpipe` in the directory `myorg-coolpipe` (`-`) with `me` as the author. It will exclude all possible parts of the template: - -- `github`: removed all files required for GitHub hosting of the pipeline. Specifically, the `.github` folder and `.gitignore` file. -- `ci`: removes the GitHub continuous integration tests from the pipeline. Specifically, the `.github/workflows/` folder. -- `github_badges`: removes GitHub badges from the `README.md` file. -- `igenomes`: removes pipeline options related to iGenomes. Including the `conf/igenomes.config` file and all references to it. -- `nf_core_configs`: excludes `nf_core/configs` repository options, which make multiple config profiles for various institutional clusters available. - -To run the pipeline creation silently (i.e. without any prompts) with the nf-core template, you can use the `--plain` option. - -## Linting a workflow - -The `lint` subcommand checks a given pipeline for all nf-core community guidelines. -This is the same test that is used on the automated continuous integration tests. - -For example, the current version looks something like this: - - - -![`nf-core lint`](docs/images/nf-core-lint.svg) - -You can use the `-k` / `--key` flag to run only named tests for faster debugging, eg: `nf-core lint -k files_exist -k files_unchanged`. The `nf-core lint` command lints the current working directory by default, to specify another directory you can use `--dir `. - -### Linting documentation - -Each test result name on the left is a terminal hyperlink. -In most terminals you can ctrl + click ( cmd + click) these -links to open documentation specific to this test in your browser. - -Alternatively visit and find your test to read more. - -### Linting config - -It's sometimes desirable to disable certain lint tests, especially if you're using nf-core/tools with your -own pipeline that is outside of nf-core. - -To help with this, you can add a tools config file to your pipeline called `.nf-core.yml` in the pipeline root directory (previously: `.nf-core-lint.yml`). -Here you can list the names of any tests that you would like to disable and set them to `False`, for example: - -```yaml -lint: - actions_awsfulltest: False - pipeline_todos: False -``` - -Some lint tests allow greater granularity, for example skipping a test only for a specific file. -This is documented in the test-specific docs but generally involves passing a list, for example: - -```yaml -lint: - files_exist: - - CODE_OF_CONDUCT.md - files_unchanged: - - assets/email_template.html - - CODE_OF_CONDUCT.md -``` - -Note that you have to list all configurations for the `nf-core lint` command under the `lint:` field in the `.nf-core.yml` file, as this file is also used for configuration of other commands. - -### Automatically fix errors - -Some lint tests can try to automatically fix any issues they find. To enable this functionality, use the `--fix` flag. -The pipeline must be a `git` repository with no uncommitted changes for this to work. -This is so that any automated changes can then be reviewed and undone (`git checkout .`) if you disagree. - -### Lint results output - -The output from `nf-core lint` is designed to be viewed on the command line and is deliberately succinct. -You can view all passed tests with `--show-passed` or generate JSON / markdown results with the `--json` and `--markdown` flags. - -## Pipeline schema - -nf-core pipelines have a `nextflow_schema.json` file in their root which describes the different parameters used by the workflow. -These files allow automated validation of inputs when running the pipeline, are used to generate command line help and can be used to build interfaces to launch pipelines. -Pipeline schema files are built according to the [JSONSchema specification](https://json-schema.org/) (Draft 7). - -To help developers working with pipeline schema, nf-core tools has three `schema` sub-commands: - -- `nf-core schema validate` -- `nf-core schema build` -- `nf-core schema docs` -- `nf-core schema lint` - -### Validate pipeline parameters - -Nextflow can take input parameters in a JSON or YAML file when running a pipeline using the `-params-file` option. -This command validates such a file against the pipeline schema. - -Usage is `nf-core schema validate `. eg with the pipeline downloaded [above](#download-pipeline), you can run: - - - -![`nf-core schema validate nf-core-rnaseq/3_8 nf-params.json`](docs/images/nf-core-schema-validate.svg) - -The `pipeline` option can be a directory containing a pipeline, a path to a schema file or the name of an nf-core pipeline (which will be downloaded using `nextflow pull`). - -### Build a pipeline schema - -Manually building JSONSchema documents is not trivial and can be very error prone. -Instead, the `nf-core schema build` command collects your pipeline parameters and gives interactive prompts about any missing or unexpected params. -If no existing schema is found it will create one for you. - -Once built, the tool can send the schema to the nf-core website so that you can use a graphical interface to organise and fill in the schema. -The tool checks the status of your schema on the website and once complete, saves your changes locally. - -Usage is `nf-core schema build -d `, eg: - - - -![`nf-core schema build --no-prompts`](docs/images/nf-core-schema-build.svg) - -There are four flags that you can use with this command: - -- `--dir `: Specify a pipeline directory other than the current working directory -- `--no-prompts`: Make changes without prompting for confirmation each time. Does not launch web tool. -- `--web-only`: Skips comparison of the schema against the pipeline parameters and only launches the web tool. -- `--url `: Supply a custom URL for the online tool. Useful when testing locally. - -### Display the documentation for a pipeline schema - -To get an impression about the current pipeline schema you can display the content of the `nextflow_schema.json` with `nf-core schema docs `. This will print the content of your schema in Markdown format to the standard output. - -There are four flags that you can use with this command: - -- `--output `: Output filename. Defaults to standard out. -- `--format [markdown|html]`: Format to output docs in. -- `--force`: Overwrite existing files -- `--columns `: CSV list of columns to include in the parameter tables - -### Add new parameters to the pipeline schema - -If you want to add a parameter to the schema, you first have to add the parameter and its default value to the `nextflow.config` file with the `params` scope. Afterwards, you run the command `nf-core schema build` to add the parameters to your schema and open the graphical interface to easily modify the schema. - -The graphical interface is oganzised in groups and within the groups the single parameters are stored. For a better overview you can collapse all groups with the `Collapse groups` button, then your new parameters will be the only remaining one at the bottom of the page. Now you can either create a new group with the `Add group` button or drag and drop the paramters in an existing group. Therefor the group has to be expanded. The group title will be displayed, if you run your pipeline with the `--help` flag and its description apears on the parameter page of your pipeline. - -Now you can start to change the parameter itself. The `ID` of a new parameter should be defined in small letters without whitespaces. The description is a short free text explanation about the parameter, that appears if you run your pipeline with the `--help` flag. By clicking on the dictionary icon you can add a longer explanation for the parameter page of your pipeline. Usually, they contain a small paragraph about the parameter settings or a used datasource, like databases or references. If you want to specify some conditions for your parameter, like the file extension, you can use the nut icon to open the settings. This menu depends on the `type` you assigned to your parameter. For integers you can define a min and max value, and for strings the file extension can be specified. - -The `type` field is one of the most important points in your pipeline schema, since it defines the datatype of your input and how it will be interpreted. This allows extensive testing prior to starting the pipeline. - -The basic datatypes for a pipeline schema are: - -- `string` -- `number` -- `integer` -- `boolean` - -For the `string` type you have three different options in the settings (nut icon): `enumerated values`, `pattern` and `format`. The first option, `enumerated values`, allows you to specify a list of specific input values. The list has to be separated with a pipe. The `pattern` and `format` settings can depend on each other. The `format` has to be either a directory or a file path. Depending on the `format` setting selected, specifying the `pattern` setting can be the most efficient and time saving option, especially for `file paths`. The `number` and `integer` types share the same settings. Similarly to `string`, there is an `enumerated values` option with the possibility of specifying a `min` and `max` value. For the `boolean` there is no further settings and the default value is usually `false`. The `boolean` value can be switched to `true` by adding the flag to the command. This parameter type is often used to skip specific sections of a pipeline. - -After filling the schema, click on the `Finished` button in the top right corner, this will automatically update your `nextflow_schema.json`. If this is not working, the schema can be copied from the graphical interface and pasted in your `nextflow_schema.json` file. - -### Update existing pipeline schema - -It's important to change the default value of a parameter in the `nextflow.config` file first and then in the pipeline schema, because the value in the config file overwrites the value in the pipeline schema. To change any other parameter use `nf-core schema build --web-only` to open the graphical interface without rebuilding the pipeline schema. Now, the parameters can be changed as mentioned above but keep in mind that changing the parameter datatype depends on the default value specified in the `nextflow.config` file. - -### Linting a pipeline schema - -The pipeline schema is linted as part of the main pipeline `nf-core lint` command, -however sometimes it can be useful to quickly check the syntax of the JSONSchema without running a full lint run. - -Usage is `nf-core schema lint ` (defaulting to `nextflow_schema.json`), eg: - - - -![`nf-core schema lint`](docs/images/nf-core-schema-lint.svg) - -## Bumping a pipeline version number - -When releasing a new version of a nf-core pipeline, version numbers have to be updated in several different places. The helper command `nf-core bump-version` automates this for you to avoid manual errors (and frustration!). - -The command uses results from the linting process, so will only work with workflows that pass these tests. - -Usage is `nf-core bump-version `, eg: - - - -![`nf-core bump-version 1.1`](docs/images/nf-core-bump-version.svg) - -You can change the directory from the current working directory by specifying `--dir `. To change the required version of Nextflow instead of the pipeline version number, use the flag `--nextflow`. - -## Sync a pipeline with the template - -Over time, the main nf-core pipeline template is updated. To keep all nf-core pipelines up to date, -we synchronise these updates automatically when new versions of nf-core/tools are released. -This is done by maintaining a special `TEMPLATE` branch, containing a vanilla copy of the nf-core template -with only the variables used when it first ran (name, description etc.). This branch is updated and a -pull-request can be made with just the updates from the main template code. - -Note that pipeline synchronisation happens automatically each time nf-core/tools is released, creating an automated pull-request on each pipeline. -**As such, you do not normally need to run this command yourself!** - -This command takes a pipeline directory and attempts to run this synchronisation. -Usage is `nf-core sync`, eg: - - - -![`nf-core sync`](docs/images/nf-core-sync.svg) - -The sync command tries to check out the `TEMPLATE` branch from the `origin` remote or an existing local branch called `TEMPLATE`. -It will fail if it cannot do either of these things. -The `nf-core create` command should make this template automatically when you first start your pipeline. -Please see the [nf-core website sync documentation](https://nf-co.re/developers/sync) if you have difficulties. - -To specify a directory to sync other than the current working directory, use the `--dir `. - -By default, the tool will collect workflow variables from the current branch in your pipeline directory. -You can supply the `--from-branch` flag to specific a different branch. - -Finally, if you give the `--pull-request` flag, the command will push any changes to the remote and attempt to create a pull request using the GitHub API. -The GitHub username and repository name will be fetched from the remote url (see `git remote -v | grep origin`), or can be supplied with `--username` and `--github-repository`. - -To create the pull request, a personal access token is required for API authentication. -These can be created at [https://github.com/settings/tokens](https://github.com/settings/tokens). -Supply this using the `--auth-token` flag. - -## Create an nf-core pipeline logo - -The `nf-core create-logo` command creates a logo for your pipeline based on the nf-core template and the pipeline name. You can specify the width of the logo in pixels with the `--width` flag. Additionally, you can specify the output format to be either `png` or `svg` with the `--format` flag. The default format is `png`. - -Usage is `nf-core create-logo `, eg: - - - -![`nf-core create-logo nextbigthing`](docs/images/nf-core-create-logo.svg) - -## Tools CLI TUI - -_CLI:_ Command line interface -_TUI:_ Terminal user interface - -The `nf-core` command line interface is fairly large, with a lot of commands and options. -To make it easier to explore and use, run `nf-core tui` to launch a graphical terminal interface. - -This functionality works using [Textualize/trogon](https://github.com/Textualize/trogon) -and is based on the underlying CLI implementation that uses [Click](https://click.palletsprojects.com/). - -## Modules - -With the advent of [Nextflow DSL2](https://www.nextflow.io/docs/latest/dsl2.html), we are creating a centralised repository of modules. -These are software tool process definitions that can be imported into any pipeline. -This allows multiple pipelines to use the same code for share tools and gives a greater degree of granulairy and unit testing. - -The nf-core DSL2 modules repository is at - -### Custom remote modules - -The modules supercommand comes with two flags for specifying a custom remote: - -- `--git-remote `: Specify the repository from which the modules should be fetched as a git URL. Defaults to the github repository of `nf-core/modules`. -- `--branch `: Specify the branch from which the modules should be fetched. Defaults to the default branch of your repository. - -For example, if you want to install the `fastqc` module from the repository `nf-core/modules-test` hosted at `gitlab.com`, you can use the following command: - -```terminal -nf-core modules --git-remote git@gitlab.com:nf-core/modules-test.git install fastqc -``` - -Note that a custom remote must follow a similar directory structure to that of `nf-core/moduleś` for the `nf-core modules` commands to work properly. - -The directory where modules are installed will be prompted or obtained from `org_path` in the `.nf-core.yml` file if available. If your modules are located at `modules/my-folder/TOOL/SUBTOOL` your `.nf-core.yml` should have: - -```yaml -org_path: my-folder -``` - -Please avoid installing the same tools from two different remotes, as this can lead to further errors. - -The modules commands will during initalisation try to pull changes from the remote repositories. If you want to disable this, for example -due to performance reason or if you want to run the commands offline, you can use the flag `--no-pull`. Note however that the commands will -still need to clone repositories that have previously not been used. - -### Private remote repositories - -You can use the modules command with private remote repositories. Make sure that your local `git` is correctly configured with your private remote -and then specify the remote the same way you would do with a public remote repository. - -### List modules - -The `nf-core modules list` command provides the subcommands `remote` and `local` for listing modules installed in a remote repository and in the local pipeline respectively. Both subcommands allow to use a pattern for filtering the modules by keywords eg: `nf-core modules list `. - -#### List remote modules - -To list all modules available on [nf-core/modules](https://github.com/nf-core/modules), you can use -`nf-core modules list remote`, which will print all available modules to the terminal. - - - -![`nf-core modules list remote`](docs/images/nf-core-modules-list-remote.svg) - -#### List installed modules - -To list modules installed in a local pipeline directory you can use `nf-core modules list local`. This will list the modules install in the current working directory by default. If you want to specify another directory, use the `--dir ` flag. - - - -![`nf-core modules list local`](docs/images/nf-core-modules-list-local.svg) - -## Show information about a module - -For quick help about how a module works, use `nf-core modules info `. -This shows documentation about the module on the command line, similar to what's available on the -[nf-core website](https://nf-co.re/modules). - - - -![`nf-core modules info abacas`](docs/images/nf-core-modules-info.svg) - -### Install modules in a pipeline - -You can install modules from [nf-core/modules](https://github.com/nf-core/modules) in your pipeline using `nf-core modules install`. -A module installed this way will be installed to the `./modules/nf-core/modules` directory. - - - -![`nf-core modules install abacas`](docs/images/nf-core-modules-install.svg) - -You can pass the module name as an optional argument to `nf-core modules install` instead of using the cli prompt, eg: `nf-core modules install fastqc`. You can specify a pipeline directory other than the current working directory by using the `--dir `. - -There are three additional flags that you can use when installing a module: - -- `--force`: Overwrite a previously installed version of the module. -- `--prompt`: Select the module version using a cli prompt. -- `--sha `: Install the module at a specific commit. - -### Update modules in a pipeline - -You can update modules installed from a remote repository in your pipeline using `nf-core modules update`. - - - -![`nf-core modules update --all --no-preview`](docs/images/nf-core-modules-update.svg) - -You can pass the module name as an optional argument to `nf-core modules update` instead of using the cli prompt, eg: `nf-core modules update fastqc`. You can specify a pipeline directory other than the current working directory by using the `--dir `. - -There are five additional flags that you can use with this command: - -- `--force`: Reinstall module even if it appears to be up to date -- `--prompt`: Select the module version using a cli prompt. -- `--sha `: Install the module at a specific commit from the `nf-core/modules` repository. -- `--preview/--no-preview`: Show the diff between the installed files and the new version before installing. -- `--save-diff `: Save diffs to a file instead of updating in place. The diffs can then be applied with `git apply `. -- `--all`: Use this flag to run the command on all modules in the pipeline. - -If you don't want to update certain modules or want to update them to specific versions, you can make use of the `.nf-core.yml` configuration file. For example, you can prevent the `star/align` module installed from `nf-core/modules` from being updated by adding the following to the `.nf-core.yml` file: - -```yaml -update: - https://github.com/nf-core/modules.git: - nf-core: - star/align: False -``` - -If you want this module to be updated only to a specific version (or downgraded), you could instead specifiy the version: - -```yaml -update: - https://github.com/nf-core/modules.git: - nf-core: - star/align: "e937c7950af70930d1f34bb961403d9d2aa81c7" -``` - -This also works at the repository level. For example, if you want to exclude all modules installed from `nf-core/modules` from being updated you could add: - -```yaml -update: - https://github.com/nf-core/modules.git: - nf-core: False -``` - -or if you want all modules in `nf-core/modules` at a specific version: - -```yaml -update: - https://github.com/nf-core/modules.git: - nf-core: "e937c7950af70930d1f34bb961403d9d2aa81c7" -``` - -Note that the module versions specified in the `.nf-core.yml` file has higher precedence than versions specified with the command line flags, thus aiding you in writing reproducible pipelines. - -### Remove a module from a pipeline - -To delete a module from your pipeline, run `nf-core modules remove`. - - - -![`nf-core modules remove abacas`](docs/images/nf-core-modules-remove.svg) - -You can pass the module name as an optional argument to `nf-core modules remove` instead of using the cli prompt, eg: `nf-core modules remove fastqc`. To specify the pipeline directory, use `--dir `. - -### Create a patch file for a module - -If you want to make a minor change to a locally installed module but still keep it up date with the remote version, you can create a patch file using `nf-core modules patch`. - - - -![`nf-core modules patch fastqc`](docs/images/nf-core-modules-patch.svg) - -The generated patches work with `nf-core modules update`: when you install a new version of the module, the command tries to apply -the patch automatically. The patch application fails if the new version of the module modifies the same lines as the patch. In this case, -the patch new version is installed but the old patch file is preserved. - -When linting a patched module, the linting command will check the validity of the patch. When running other lint tests the patch is applied in reverse, and the original files are linted. - -### Create a new module - -This command creates a new nf-core module from the nf-core module template. -This ensures that your module follows the nf-core guidelines. -The template contains extensive `TODO` messages to walk you through the changes you need to make to the template. - -You can create a new module using `nf-core modules create`. - -This command can be used both when writing a module for the shared [nf-core/modules](https://github.com/nf-core/modules) repository, -and also when creating local modules for a pipeline. - -Which type of repository you are working in is detected by the `repository_type` flag in a `.nf-core.yml` file in the root directory, -set to either `pipeline` or `modules`. -The command will automatically look through parent directories for this file to set the root path, so that you can run the command in a subdirectory. -It will start in the current working directory, or whatever is specified with `--dir `. - -The `nf-core modules create` command will prompt you with the relevant questions in order to create all of the necessary module files. - - - -![`cd modules && nf-core modules create fastqc --author @nf-core-bot --label process_low --meta --force`](docs/images/nf-core-modules-create.svg) - -### Check a module against nf-core guidelines - -Run the `nf-core modules lint` command to check modules in the current working directory (pipeline or nf-core/modules clone) against nf-core guidelines. - -Use the `--all` flag to run linting on all modules found. Use `--dir ` to specify another directory than the current working directory. - - - -![`nf-core modules lint multiqc`](docs/images/nf-core-modules-lint.svg) - -### Create a test for a module - -All modules on [nf-core/modules](https://github.com/nf-core/modules) have a strict requirement of being unit tested using minimal test data. We use [nf-test](https://code.askimed.com/nf-test/) as our testing framework. -Each module comes already with a template for the test file in `test/main.nf.test`. Replace the placeholder code in that file with your specific input, output and proces. In order to generate the corresponding snapshot after writing your test, you can use the `nf-core modules test` command. This command will run `nf-test test` twice, to also check for snapshot stability, i.e. that the same snapshot is generated on multiple runs. - -You can specify the module name in the form TOOL/SUBTOOL in the command or provide it later through interactive prompts. - - - -![`nf-core modules test fastqc --no-prompts`](docs/images/nf-core-modules-test.svg) - -In case you changed something in the test and want to update the snapshot, run - -```bash -nf-core modules test --update -``` - -If you want to run the test only once without checking for snapshot stability, you can use the `--once` flag. - -### Bump bioconda and container versions of modules in - -If you are contributing to the `nf-core/modules` repository and want to bump bioconda and container versions of certain modules, you can use the `nf-core modules bump-versions` helper tool. This will bump the bioconda version of a single or all modules to the latest version and also fetch the correct Docker and Singularity container tags. - - - -![`nf-core modules bump-versions fastqc`](docs/images/nf-core-modules-bump-version.svg) - -If you don't want to update certain modules or want to update them to specific versions, you can make use of the `.nf-core.yml` configuration file. For example, you can prevent the `star/align` module from being updated by adding the following to the `.nf-core.yml` file: - -```yaml -bump-versions: - star/align: False -``` - -If you want this module to be updated only to a specific version (or downgraded), you could instead specifiy the version: - -```yaml -bump-versions: - star/align: "2.6.1d" -``` - -## Subworkflows - -After the launch of nf-core modules, we can provide now also nf-core subworkflows to fully utilize the power of DSL2 modularization. -Subworkflows are chains of multiple module definitions that can be imported into any pipeline. -This allows multiple pipelines to use the same code for a the same tasks, and gives a greater degree of reusability and unit testing. - -To allow us to test modules and subworkflows together we put the nf-core DSL2 subworkflows into the `subworkflows` directory of the modules repository is at . - -### Custom remote subworkflows - -The subworkflows supercommand released in nf-core/tools version 2.7 comes with two flags for specifying a custom remote repository: - -- `--git-remote `: Specify the repository from which the subworkflows should be fetched as a git URL. Defaults to the github repository of `nf-core/modules`. -- `--branch `: Specify the branch from which the subworkflows should be fetched. Defaults to the default branch of your repository. - -For example, if you want to install the `bam_stats_samtools` subworkflow from the repository `nf-core/modules-test` hosted at `gitlab.com` in the branch `subworkflows`, you can use the following command: - -```bash -nf-core subworkflows --git-remote git@gitlab.com:nf-core/modules-test.git --branch subworkflows install bam_stats_samtools -``` - -Note that a custom remote must follow a similar directory structure to that of `nf-core/modules` for the `nf-core subworkflows` commands to work properly. - -The directory where subworkflows are installed will be prompted or obtained from `org_path` in the `.nf-core.yml` file if available. If your subworkflows are located at `subworkflows/my-folder/SUBWORKFLOW_NAME` your `.nf-core.yml` file should have: - -```yaml -org_path: my-folder -``` - -Please avoid installing the same tools from two different remotes, as this can lead to further errors. - -The subworkflows commands will during initalisation try to pull changes from the remote repositories. If you want to disable this, for example due to performance reason or if you want to run the commands offline, you can use the flag `--no-pull`. Note however that the commands will still need to clone repositories that have previously not been used. - -### Private remote repositories - -You can use the subworkflows command with private remote repositories. Make sure that your local `git` is correctly configured with your private remote -and then specify the remote the same way you would do with a public remote repository. - -### List subworkflows - -The `nf-core subworkflows list` command provides the subcommands `remote` and `local` for listing subworkflows installed in a remote repository and in the local pipeline respectively. Both subcommands allow to use a pattern for filtering the subworkflows by keywords eg: `nf-core subworkflows list `. - -#### List remote subworkflows - -To list all subworkflows available on [nf-core/modules](https://github.com/nf-core/modules), you can use -`nf-core subworkflows list remote`, which will print all available subworkflows to the terminal. - - - -![`nf-core subworkflows list remote`](docs/images/nf-core-subworkflows-list-remote.svg) - -#### List installed subworkflows - -To list subworkflows installed in a local pipeline directory you can use `nf-core subworkflows list local`. This will list the subworkflows install in the current working directory by default. If you want to specify another directory, use the `--dir ` flag. - - - -![`nf-core subworkflows list local`](docs/images/nf-core-subworkflows-list-local.svg) - -## Show information about a subworkflow - -For quick help about how a subworkflow works, use `nf-core subworkflows info `. -This shows documentation about the subworkflow on the command line, similar to what's available on the -[nf-core website](https://nf-co.re/subworkflows). - - - -![`nf-core subworkflows info bam_rseqc`](docs/images/nf-core-subworkflows-info.svg) - -### Install subworkflows in a pipeline - -You can install subworkflows from [nf-core/modules](https://github.com/nf-core/modules) in your pipeline using `nf-core subworkflows install`. -A subworkflow installed this way will be installed to the `./subworkflows/nf-core` directory. - - - -![`nf-core subworkflows install bam_rseqc`](docs/images/nf-core-subworkflows-install.svg) - -You can pass the subworkflow name as an optional argument to `nf-core subworkflows install` like above or select it from a list of available subworkflows by only running `nf-core subworkflows install`. - -There are four additional flags that you can use when installing a subworkflow: - -- `--dir`: Pipeline directory, the default is the current working directory. -- `--force`: Overwrite a previously installed version of the subworkflow. -- `--prompt`: Select the subworkflow version using a cli prompt. -- `--sha `: Install the subworkflow at a specific commit. - -### Update subworkflows in a pipeline - -You can update subworkflows installed from a remote repository in your pipeline using `nf-core subworkflows update`. - - - -![`nf-core subworkflows update --all --no-preview`](docs/images/nf-core-subworkflows-update.svg) - -You can pass the subworkflow name as an optional argument to `nf-core subworkflows update` like above or select it from the list of available subworkflows by only running `nf-core subworkflows update`. - -There are six additional flags that you can use with this command: - -- `--dir`: Pipeline directory, the default is the current working directory. -- `--force`: Reinstall subworkflow even if it appears to be up to date -- `--prompt`: Select the subworkflow version using a cli prompt. -- `--sha `: Install the subworkflow at a specific commit from the `nf-core/modules` repository. -- `--preview/--no-preview`: Show the diff between the installed files and the new version before installing. -- `--save-diff `: Save diffs to a file instead of updating in place. The diffs can then be applied with `git apply `. -- `--all`: Use this flag to run the command on all subworkflows in the pipeline. -- `--update-deps`: Use this flag to automatically update all dependencies of a subworkflow. - -If you don't want to update certain subworkflows or want to update them to specific versions, you can make use of the `.nf-core.yml` configuration file. For example, you can prevent the `bam_rseqc` subworkflow installed from `nf-core/modules` from being updated by adding the following to the `.nf-core.yml` file: - -```yaml -update: - https://github.com/nf-core/modules.git: - nf-core: - bam_rseqc: False -``` - -If you want this subworkflow to be updated only to a specific version (or downgraded), you could instead specifiy the version: - -```yaml -update: - https://github.com/nf-core/modules.git: - nf-core: - bam_rseqc: "36a77f7c6decf2d1fb9f639ae982bc148d6828aa" -``` - -This also works at the repository level. For example, if you want to exclude all modules and subworkflows installed from `nf-core/modules` from being updated you could add: - -```yaml -update: - https://github.com/nf-core/modules.git: - nf-core: False -``` - -or if you want all subworkflows in `nf-core/modules` at a specific version: - -```yaml -update: - https://github.com/nf-core/modules.git: - nf-core: "e937c7950af70930d1f34bb961403d9d2aa81c7" -``` - -Note that the subworkflow versions specified in the `.nf-core.yml` file has higher precedence than versions specified with the command line flags, thus aiding you in writing reproducible pipelines. - -### Remove a subworkflow from a pipeline - -To delete a subworkflow from your pipeline, run `nf-core subworkflows remove`. - - - -![`nf-core subworkflows remove bam_rseqc`](docs/images/nf-core-subworkflows-remove.svg) - -You can pass the subworkflow name as an optional argument to `nf-core subworkflows remove` like above or select it from the list of available subworkflows by only running `nf-core subworkflows remove`. To specify the pipeline directory, use `--dir `. - -### Create a new subworkflow - -This command creates a new nf-core subworkflow from the nf-core subworkflow template. -This ensures that your subworkflow follows the nf-core guidelines. -The template contains extensive `TODO` messages to walk you through the changes you need to make to the template. -See the [subworkflow documentation](https://nf-co.re/docs/contributing/subworkflows) for more details around creating a new subworkflow, including rules about nomenclature and a step-by-step guide. - -You can create a new subworkflow using `nf-core subworkflows create`. - -This command can be used both when writing a subworkflow for the shared [nf-core/modules](https://github.com/nf-core/modules) repository, -and also when creating local subworkflows for a pipeline. - -Which type of repository you are working in is detected by the `repository_type` flag in a `.nf-core.yml` file in the root directory, -set to either `pipeline` or `modules`. -The command will automatically look through parent directories for this file to set the root path, so that you can run the command in a subdirectory. -It will start in the current working directory, or whatever is specified with `--dir `. - -The `nf-core subworkflows create` command will prompt you with the relevant questions in order to create all of the necessary subworkflow files. - - - -![`nf-core subworkflows create bam_stats_samtools --author @nf-core-bot --force`](docs/images/nf-core-subworkflows-create.svg) - -### Create a test for a subworkflow - -All subworkflows on [nf-core/modules](https://github.com/nf-core/modules) have a strict requirement of being unit tested using minimal test data. We use [nf-test](https://code.askimed.com/nf-test/) as our testing framework. -Each subworkflow comes already with a template for the test file in `test/main.nf.test`. Replace the placeholder code in that file with your specific input, output and proces. In order to generate the corresponding snapshot after writing your test, you can use the `nf-core subworkflows test` command. This command will run `nf-test test` twice, to also check for snapshot stability, i.e. that the same snapshot is generated on multiple runs. - -You can specify the subworkflow name in the command or provide it later through interactive prompts. - - - -![`nf-core subworkflows test bam_rseqc --no-prompts`](docs/images/nf-core-subworkflows-test.svg) - -In case you changed something in the test and want to update the snapshot, run - -```bash -nf-core subworkflows test --update -``` - -If you want to run the test only once without checking for snapshot stability, you can use the `--once` flag. - -### Check a subworkflow against nf-core guidelines - -Run the `nf-core subworkflows lint` command to check subworkflows in the current working directory (a pipeline or a clone of nf-core/modules) against nf-core guidelines. - -Use the `--all` flag to run linting on all subworkflows found. Use `--dir ` to specify a different directory than the current working directory. +## Contributions and Support - +If you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md). -![`nf-core subworkflows lint bam_stats_samtools`](docs/images/nf-core-subworkflows-lint.svg) +For further information or help, don't hesitate to get in touch on the [Slack `#tools` channel](https://nfcore.slack.com/channels/tools) (you can join with [this invite](https://nf-co.re/join/slack)). ## Citation diff --git a/docs/images/nf-core-bump-version.svg b/docs/images/nf-core-bump-version.svg deleted file mode 100644 index 70171475d9..0000000000 --- a/docs/images/nf-core-bump-version.svg +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core bump-version 1.1 - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -INFO     Changing version number from '1.0dev' to '1.1' -INFO     Updated version in 'nextflow.config' - - version         = '1.0dev' - + version         = '1.1' - - -INFO     Updated version in 'assets/multiqc_config.yml' - - This report has been generated by the <a  -href="https://github.com/nf-core/nextbigthing/tree/dev" target="_blank">nf-core/nextbigthing</a> - + This report has been generated by the <a  -href="https://github.com/nf-core/nextbigthing/releases/tag/1.1"  -target="_blank">nf-core/nextbigthing</a> - - -INFO     Updated version in 'assets/multiqc_config.yml' - - <a href="https://nf-co.re/nextbigthing/dev/docs/output"  -target="_blank">documentation</a>. - + <a href="https://nf-co.re/nextbigthing/1.1/docs/output"  -target="_blank">documentation</a>. - - - - - - diff --git a/docs/images/nf-core-create-logo.svg b/docs/images/nf-core-create-logo.svg deleted file mode 100644 index c6e7269363..0000000000 --- a/docs/images/nf-core-create-logo.svg +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core create-logo nextbigthing - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -INFO     Created logo: nf-core-nextbigthing_logo_light.png - - - - diff --git a/docs/images/nf-core-create.svg b/docs/images/nf-core-create.svg deleted file mode 100644 index 422e6734ce..0000000000 --- a/docs/images/nf-core-create.svg +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core create -n nextbigthing -d "This pipeline analyses data from the next big omics technique"  --a "Big Steve" --plain - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -INFO     Creating new nf-core pipeline: 'nf-core/nextbigthing' -INFO     Initialising pipeline git repository                                                        -INFO     Done. Remember to add a remote and push to GitHub:                                          - cd /home/runner/work/tools/tools/tmp/nf-core-nextbigthing - git remote add origin git@github.com:USERNAME/REPO_NAME.git  - git push --all origin                                        -INFO     This will also push your newly created dev branch and the TEMPLATE branch for syncing.      -INFO    !!!!!! IMPORTANT !!!!!! - -If you are interested in adding your pipeline to the nf-core community, -PLEASE COME AND TALK TO US IN THE NF-CORE SLACK BEFORE WRITING ANY CODE! - -Please read: https://nf-co.re/developers/adding_pipelines#join-the-community - - - - diff --git a/docs/images/nf-core-download-tree.svg b/docs/images/nf-core-download-tree.svg deleted file mode 100644 index fc9585c8c9..0000000000 --- a/docs/images/nf-core-download-tree.svg +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ tree -L 2 nf-core-rnaseq/ -nf-core-rnaseq/ -├── 3_8 -│   ├── CHANGELOG.md -│   ├── CITATIONS.md -│   ├── CODE_OF_CONDUCT.md -│   ├── LICENSE -│   ├── README.md -│   ├── assets -│   ├── bin -│   ├── conf -│   ├── docs -│   ├── lib -│   ├── main.nf -│   ├── modules -│   ├── modules.json -│   ├── nextflow.config -│   ├── nextflow_schema.json -│   ├── subworkflows -│   ├── tower.yml -│   └── workflows -└── configs -    ├── CITATION.cff -    ├── LICENSE -    ├── README.md -    ├── bin -    ├── conf -    ├── configtest.nf -    ├── docs -    ├── nextflow.config -    ├── nfcore_custom.config -    └── pipeline - -14 directories, 16 files - - - - diff --git a/docs/images/nf-core-download.svg b/docs/images/nf-core-download.svg deleted file mode 100644 index 5594930fa7..0000000000 --- a/docs/images/nf-core-download.svg +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core download rnaseq -r 3.8 --outdir nf-core-rnaseq -x none -s none -d - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -WARNING  Could not find GitHub authentication token. Some API requests may fail.                     -INFO     Saving 'nf-core/rnaseq' -          Pipeline revision: '3.8' -          Use containers: 'none' -          Container library: 'quay.io' -          Output directory: 'nf-core-rnaseq' -          Include default institutional configuration: 'True' -INFO     Downloading centralised configs from GitHub                                                 -INFO     Downloading workflow files from GitHub                                                      - - - - diff --git a/docs/images/nf-core-launch-rnaseq.svg b/docs/images/nf-core-launch-rnaseq.svg deleted file mode 100644 index f2608fe76f..0000000000 --- a/docs/images/nf-core-launch-rnaseq.svg +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core launch rnaseq -r 3.8.1 - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -INFO     NOTE: This tool ignores any pipeline parameter defaults overwritten by Nextflow config      -         files or profiles                                                                           - -INFO     Downloading workflow: nf-core/rnaseq (3.8.1) - - - - diff --git a/docs/images/nf-core-licences.svg b/docs/images/nf-core-licences.svg deleted file mode 100644 index 8cc00c351b..0000000000 --- a/docs/images/nf-core-licences.svg +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core licences deepvariant - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -INFO     Fetching licence information for 8 tools                                                    - - - - diff --git a/docs/images/nf-core-lint.svg b/docs/images/nf-core-lint.svg deleted file mode 100644 index 2e55a7e11e..0000000000 --- a/docs/images/nf-core-lint.svg +++ /dev/null @@ -1,208 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core lint - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Testing pipeline: . - - -╭─[?] 1 Pipeline Test Ignored────────────────────────────────────────────────────────────────────╮ - -pipeline_todos: pipeline_todos                                                                   - -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ -╭─[!] 1 Pipeline Test Warning────────────────────────────────────────────────────────────────────╮ - -readme: README contains the placeholder zenodo.XXXXXXX. This should be replaced with the zenodo  -doi (after the first release).                                                                   - -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ - - -╭──────────────────────╮ -LINT RESULTS SUMMARY -├──────────────────────┤ -[✔] 188 Tests Passed -[?]   1 Test Ignored -[!]   1 Test Warning -[✗]   0 Tests Failed -╰──────────────────────╯ - - - - diff --git a/docs/images/nf-core-list-rna.svg b/docs/images/nf-core-list-rna.svg deleted file mode 100644 index 643545c6fc..0000000000 --- a/docs/images/nf-core-list-rna.svg +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core list rna rna-seq - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓ -Have latest         -Pipeline Name       StarsLatest Release    ReleasedLast Pulledrelease?            -┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩ -│ rnaseq               │   742 │         3.14.0 │ 2 months ago │           - │ -                   │ -│ differentialabundan… │    38 │          1.4.0 │ 3 months ago │           - │ -                   │ -│ smrnaseq             │    64 │          2.3.0 │   6 days ago │           - │ -                   │ -│ rnasplice            │    25 │          1.0.3 │   6 days ago │           - │ -                   │ -│ circrna              │    34 │            dev │  1 weeks ago │           - │ -                   │ -│ scrnaseq             │   125 │          2.5.1 │ 1 months ago │           - │ -                   │ -│ rnafusion            │   126 │          3.0.1 │ 3 months ago │           - │ -                   │ -│ spatialtranscriptom… │    36 │            dev │  4 weeks ago │           - │ -                   │ -│ dualrnaseq           │    16 │          1.0.0 │  3 years ago │           - │ -                   │ -│ marsseq              │     5 │          1.0.3 │ 8 months ago │           - │ -                   │ -│ lncpipe              │    28 │            dev │  1 years ago │           - │ -                   │ -│ scflow               │    24 │            dev │  3 years ago │           - │ -                   │ -└──────────────────────┴───────┴────────────────┴──────────────┴─────────────┴─────────────────────┘ - - - - diff --git a/docs/images/nf-core-list-stars.svg b/docs/images/nf-core-list-stars.svg deleted file mode 100644 index 8ea120599f..0000000000 --- a/docs/images/nf-core-list-stars.svg +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core list -s stars - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓ -Have latest         -Pipeline Name      StarsLatest Release     ReleasedLast Pulledrelease?            -┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩ -│ rnaseq              │   742 │         3.14.0 │  2 months ago │           - │ -                   │ -│ sarek               │   320 │          3.4.0 │  4 months ago │           - │ -                   │ -│ mag                 │   175 │          2.5.4 │   2 weeks ago │           - │ -                   │ -│ chipseq             │   161 │          2.0.0 │   1 years ago │           - │ -                   │ -[..truncated..] - - - - diff --git a/docs/images/nf-core-list.svg b/docs/images/nf-core-list.svg deleted file mode 100644 index 5e4939f746..0000000000 --- a/docs/images/nf-core-list.svg +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core list - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓ -Have latest         -Pipeline Name      StarsLatest Release     ReleasedLast Pulledrelease?            -┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩ -│ raredisease         │    65 │          1.1.1 │  7 months ago │           - │ -                   │ -│ fetchngs            │   101 │         1.11.0 │  4 months ago │           - │ -                   │ -│ sarek               │   320 │          3.4.0 │  4 months ago │           - │ -                   │ -│ methylseq           │   126 │          2.6.0 │  2 months ago │           - │ -                   │ -│ rnaseq              │   742 │         3.14.0 │  2 months ago │           - │ -                   │ -[..truncated..] - - - - diff --git a/docs/images/nf-core-logo.png b/docs/images/nf-core-logo.png deleted file mode 100644 index 95a519194b5d59677304317ce84d9a2d72abf4ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17930 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 I&MBb@0Dk*Wz5oCK diff --git a/docs/images/nf-core-modules-bump-version.svg b/docs/images/nf-core-modules-bump-version.svg deleted file mode 100644 index 093a0cebc6..0000000000 --- a/docs/images/nf-core-modules-bump-version.svg +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core modules bump-versions fastqc - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - - -╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ -[!] 1 Module version up to date. -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ -╭──────────────────────────────────────────┬───────────────────────────────────────────────────────╮ -Module name                             Update Message                                        -├──────────────────────────────────────────┼───────────────────────────────────────────────────────┤ - fastqc                                    Module version up to date: fastqc                      -╰──────────────────────────────────────────┴───────────────────────────────────────────────────────╯ - - - - diff --git a/docs/images/nf-core-modules-create.svg b/docs/images/nf-core-modules-create.svg deleted file mode 100644 index caa9c389f0..0000000000 --- a/docs/images/nf-core-modules-create.svg +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core modules create fastqc --author @nf-core-bot  --label process_low --meta --force - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Repository type: modules -INFO    Press enter to use default values (shown in brackets)or type your own responses.  -ctrl+click underlined text to open links. -INFO     Using Bioconda package: 'bioconda::fastqc=0.12.1' - - - - diff --git a/docs/images/nf-core-modules-info.svg b/docs/images/nf-core-modules-info.svg deleted file mode 100644 index 255c595e7c..0000000000 --- a/docs/images/nf-core-modules-info.svg +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core modules info abacas - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -╭─ Module: abacas  ────────────────────────────────────────────────────────────────────────────────╮ -│ 🌐 Repository: https://github.com/nf-core/modules.git                                            │ -│ 🔧 Tools: abacas                                                                                 │ -│ 📖 Description: contiguate draft genome assembly                                                 │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ -                  ╷                                                                   ╷              -📥 Inputs        Description                                                             Pattern -╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━╸ - meta  (map)     │Groovy Map containing sample information e.g. [ id:'test',         │ -                  │single_end:false ]                                                 │ -╶─────────────────┼───────────────────────────────────────────────────────────────────┼────────────╴ - scaffold  (file)│Fasta file containing scaffold                                     │*.{fasta,fa} -╶─────────────────┼───────────────────────────────────────────────────────────────────┼────────────╴ - fasta  (file)   │FASTA reference file                                               │*.{fasta,fa} -                  ╵                                                                   ╵              -                  ╷                                                                   ╷              -📤 Outputs       Description                                                             Pattern -╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━╸ - meta  (map)     │Groovy Map containing sample information e.g. [ id:'test',         │ -                  │single_end:false ]                                                 │ -╶─────────────────┼───────────────────────────────────────────────────────────────────┼────────────╴ - results  (file) │List containing abacas output files [ 'test.abacas.bin',           │ *.{abacas}* -                  │'test.abacas.fasta', 'test.abacas.gaps', 'test.abacas.gaps.tab',   │ -                  │'test.abacas.nucmer.delta', 'test.abacas.nucmer.filtered.delta',   │ -                  │'test.abacas.nucmer.tiling', 'test.abacas.tab',                    │ -                  │'test.abacas.unused.contigs.out', 'test.abacas.MULTIFASTA.fa' ]    │ -╶─────────────────┼───────────────────────────────────────────────────────────────────┼────────────╴ - versions  (file)│File containing software versions                                  │versions.yml -                  ╵                                                                   ╵              - - 💻  Installation command: nf-core modules install abacas - - - - - diff --git a/docs/images/nf-core-modules-install.svg b/docs/images/nf-core-modules-install.svg deleted file mode 100644 index 2b0331bcaa..0000000000 --- a/docs/images/nf-core-modules-install.svg +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core modules install abacas - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Installing 'abacas' -INFO     Use the following statement to include this module:                                         - - include { ABACAS } from '../modules/nf-core/abacas/main'                                            - - - - - diff --git a/docs/images/nf-core-modules-lint.svg b/docs/images/nf-core-modules-lint.svg deleted file mode 100644 index 2809eeee22..0000000000 --- a/docs/images/nf-core-modules-lint.svg +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core modules lint multiqc - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Linting modules repo: '.' -INFO     Linting module: 'multiqc' - - - - diff --git a/docs/images/nf-core-modules-list-local.svg b/docs/images/nf-core-modules-list-local.svg deleted file mode 100644 index ecb9ed499a..0000000000 --- a/docs/images/nf-core-modules-list-local.svg +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core modules list local - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Modules installed in '.':                                                                   - -self.repo_type='pipeline' -┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ -Module NameRepository           Version SHA          Message              Date       -┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ -│ fastqc      │ https://github.com/n… │ f4ae1d942bd50c5c0b9b… │ Update FASTQC to use  │ 2024-01-31 │ -│             │                       │                       │ unique names for      │            │ -│             │                       │                       │ snapshots (#4825)     │            │ -│ multiqc     │ https://github.com/n… │ b7ebe95761cd389603f9… │ Update MQC container  │ 2024-02-29 │ -│             │                       │                       │ (#5006)               │            │ -└─────────────┴───────────────────────┴───────────────────────┴───────────────────────┴────────────┘ - - - - diff --git a/docs/images/nf-core-modules-list-remote.svg b/docs/images/nf-core-modules-list-remote.svg deleted file mode 100644 index 138be73068..0000000000 --- a/docs/images/nf-core-modules-list-remote.svg +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core modules list remote - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Modules available from https://github.com/nf-core/modules.git(master):                     - -┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -Module Name                                           -┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ -│ abacas                                                │ -│ abricate/run                                          │ -│ abricate/summary                                      │ -│ abritamr/run                                          │ -│ adapterremoval                                        │ -│ adapterremovalfixprefix                               │ -│ admixture                                             │ -│ affy/justrma                                          │ -│ agat/convertspgff2gtf                                 │ -[..truncated..] - - - - diff --git a/docs/images/nf-core-modules-patch.svg b/docs/images/nf-core-modules-patch.svg deleted file mode 100644 index 5ed5e2f4d1..0000000000 --- a/docs/images/nf-core-modules-patch.svg +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core modules patch fastqc - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Changes in module 'nf-core/fastqc' -INFO    'modules/nf-core/fastqc/environment.yml' is unchanged                                       -INFO    'modules/nf-core/fastqc/meta.yml' is unchanged                                              -INFO     Changes in 'fastqc/main.nf':                                                                - ---- modules/nf-core/fastqc/main.nf -+++ modules/nf-core/fastqc/main.nf -@@ -1,6 +1,6 @@ -process FASTQC {                                                                                   -    tag "$meta.id"                                                                                 --    label 'process_medium' -+    label 'process_low' - -    conda "${moduleDir}/environment.yml"                                                           -    container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_  - - -INFO    'modules/nf-core/fastqc/tests/tags.yml' is unchanged                                        -INFO    'modules/nf-core/fastqc/tests/main.nf.test' is unchanged                                    -INFO    'modules/nf-core/fastqc/tests/main.nf.test.snap' is unchanged                               -INFO     Patch file of 'modules/nf-core/fastqc' written to 'modules/nf-core/fastqc/fastqc.diff' - - - - diff --git a/docs/images/nf-core-modules-remove.svg b/docs/images/nf-core-modules-remove.svg deleted file mode 100644 index 91f7020043..0000000000 --- a/docs/images/nf-core-modules-remove.svg +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core modules remove abacas - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Removed files for 'abacas' and its dependencies 'abacas'.                                   - - - - diff --git a/docs/images/nf-core-modules-test.svg b/docs/images/nf-core-modules-test.svg deleted file mode 100644 index 52e86ba826..0000000000 --- a/docs/images/nf-core-modules-test.svg +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core modules test fastqc --no-prompts - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Generating nf-test snapshot                                                                 - - - - diff --git a/docs/images/nf-core-modules-update.svg b/docs/images/nf-core-modules-update.svg deleted file mode 100644 index 23d9931ce2..0000000000 --- a/docs/images/nf-core-modules-update.svg +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core modules update --all --no-preview - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO    'modules/nf-core/abacas' is already up to date                                              -INFO    'modules/nf-core/fastqc' is already up to date                                              -INFO    'modules/nf-core/multiqc' is already up to date                                             -INFO     Updates complete ✨                                                                         - - - - diff --git a/docs/images/nf-core-schema-build.svg b/docs/images/nf-core-schema-build.svg deleted file mode 100644 index 7236440a0d..0000000000 --- a/docs/images/nf-core-schema-build.svg +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core schema build --no-prompts - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -INFO    [] Default parameters match schema validation -INFO    [] Pipeline schema looks valid(found 30 params) -INFO     Writing schema with 31 params: 'nextflow_schema.json' - - - - diff --git a/docs/images/nf-core-schema-lint.svg b/docs/images/nf-core-schema-lint.svg deleted file mode 100644 index d08a01144b..0000000000 --- a/docs/images/nf-core-schema-lint.svg +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core schema lint - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -INFO    [] Default parameters match schema validation -INFO    [] Pipeline schema looks valid(found 31 params) - - - - diff --git a/docs/images/nf-core-schema-validate.svg b/docs/images/nf-core-schema-validate.svg deleted file mode 100644 index 33984ccbeb..0000000000 --- a/docs/images/nf-core-schema-validate.svg +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core schema validate nf-core-rnaseq/3_8 nf-params.json - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -INFO    [] Default parameters match schema validation -INFO    [] Pipeline schema looks valid(found 93 params) -INFO    [] Input parameters look valid - - - - diff --git a/docs/images/nf-core-subworkflows-create.svg b/docs/images/nf-core-subworkflows-create.svg deleted file mode 100644 index fd20914cfe..0000000000 --- a/docs/images/nf-core-subworkflows-create.svg +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core subworkflows create bam_stats_samtools --author @nf-core-bot --force - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Repository type: modules -INFO    Press enter to use default values (shown in brackets)or type your own responses.  -ctrl+click underlined text to open links. -INFO     Created component template: 'bam_stats_samtools' -INFO     Created following files:                                                                    -           subworkflows/nf-core/bam_stats_samtools/main.nf                                           -           subworkflows/nf-core/bam_stats_samtools/meta.yml                                          -           subworkflows/nf-core/bam_stats_samtools/tests/tags.yml                                    -           subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test                                - - - - diff --git a/docs/images/nf-core-subworkflows-info.svg b/docs/images/nf-core-subworkflows-info.svg deleted file mode 100644 index b3f4f38ed3..0000000000 --- a/docs/images/nf-core-subworkflows-info.svg +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core subworkflows info bam_rseqc - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -╭─ Subworkflow: bam_rseqc  ────────────────────────────────────────────────────────────────────────╮ -│ 🌐 Repository: https://github.com/nf-core/modules.git                                            │ -│ 📖 Description: Subworkflow to run multiple commands in the RSeqC package                        │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ -[..truncated..] - readduplication_rscript  (file)    │script to reproduce the plot       │                      *.R -╶────────────────────────────────────┼───────────────────────────────────┼─────────────────────────╴ - tin_txt  (file)                    │TXT file containing tin.py results │                    *.txt -                                     │summary                            │ -╶────────────────────────────────────┼───────────────────────────────────┼─────────────────────────╴ - versions  (file)                   │File containing software versions  │             versions.yml -                                     ╵                                   ╵                           - - 💻  Installation command: nf-core subworkflows install bam_rseqc - - - - - diff --git a/docs/images/nf-core-subworkflows-install.svg b/docs/images/nf-core-subworkflows-install.svg deleted file mode 100644 index 8c86c3a7e4..0000000000 --- a/docs/images/nf-core-subworkflows-install.svg +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core subworkflows install bam_rseqc - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Installing 'bam_rseqc' -INFO     Use the following statement to include this subworkflow:                                    - - include { BAM_RSEQC } from '../subworkflows/nf-core/bam_rseqc/main'                                 - - - - - diff --git a/docs/images/nf-core-subworkflows-lint.svg b/docs/images/nf-core-subworkflows-lint.svg deleted file mode 100644 index 7e827661ac..0000000000 --- a/docs/images/nf-core-subworkflows-lint.svg +++ /dev/null @@ -1,341 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core subworkflows lint bam_stats_samtools - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Linting modules repo: '.' -INFO     Linting subworkflow: 'bam_stats_samtools' - -╭─[!] 14 Subworkflow Test Warnings───────────────────────────────────────────────────────────────╮ -                     ╷                                     ╷                                       -Subworkflow name   File path                          Test message                         -╶────────────────────┼─────────────────────────────────────┼─────────────────────────────────────╴ -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in main.nf.test//Add  -all required assertions to verify  -the test output. -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in main.nf.testAdd  -tags for all modules used within  -this subworkflow. Example: -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in main.nf.testChange  -the test name preferably indicating  -the test-data and file-format used -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in main.nf.testOnce  -you have added the required tests,  -please run the following command to  -build this file: -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in main.nf.testdefine  -inputs of the workflow here.  -Example: -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in main.nf -subworkflow SHOULD import at least  -two modules -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in main.nfIf in doubt  -look at other nf-core/subworkflows  -to see how we are doing things! :) -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in main.nfedit emitted -channels -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in main.nfedit input  -(take) channels -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in main.nfsubstitute  -modules here for the modules of your -subworkflow -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in meta.yml#Add a  -description of the subworkflow and  -list keywords -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in meta.yml#Add a list -of the modules and/or subworkflows  -used in the subworkflow -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in meta.yml#List all  -of the channels used as input with a -description and their structure -bam_stats_samtools subworkflows/nf-core/bam_stats_sam…TODO string in meta.yml#List all  -of the channels used as output with  -a descriptions and their structure -                     ╵                                     ╵                                       -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ -╭───────────────────────╮ -LINT RESULTS SUMMARY -├───────────────────────┤ -[✔]  42 Tests Passed  -[!]  14 Test Warnings -[✗]   0 Tests Failed  -╰───────────────────────╯ - - - - diff --git a/docs/images/nf-core-subworkflows-list-local.svg b/docs/images/nf-core-subworkflows-list-local.svg deleted file mode 100644 index 6bec883e1f..0000000000 --- a/docs/images/nf-core-subworkflows-list-local.svg +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core subworkflows list local - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Subworkflows installed in '.':                                                              - -self.repo_type='pipeline' -┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ -Subworkflow Name   Repository        Version SHA        Message           Date       -┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ -│ utils_nextflow_pip… │ https://github.co… │ 5caf7640a9ef1d18d7… │ remove             │ 2024-02-28 │ -│                     │                    │                     │ params.outdir from │            │ -│                     │                    │                     │ modules and        │            │ -│                     │                    │                     │ subworfklows tests │            │ -│                     │                    │                     │ (#5007)            │            │ -│ utils_nfcore_pipel… │ https://github.co… │ 5caf7640a9ef1d18d7… │ remove             │ 2024-02-28 │ -│                     │                    │                     │ params.outdir from │            │ -│                     │                    │                     │ modules and        │            │ -[..truncated..] - - - - diff --git a/docs/images/nf-core-subworkflows-list-remote.svg b/docs/images/nf-core-subworkflows-list-remote.svg deleted file mode 100644 index 704c2e9a45..0000000000 --- a/docs/images/nf-core-subworkflows-list-remote.svg +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core subworkflows list remote - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Subworkflows available from https://github.com/nf-core/modules.git(master):                - -┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -Subworkflow Name                              -┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ -│ bam_cnv_wisecondorx                           │ -│ bam_create_som_pon_gatk                       │ -│ bam_dedup_stats_samtools_umitools             │ -│ bam_docounts_contamination_angsd              │ -│ bam_markduplicates_picard                     │ -│ bam_markduplicates_samtools                   │ -│ bam_ngscheckmate                              │ -│ bam_qc_picard                                 │ -│ bam_rseqc                                     │ -[..truncated..] - - - - diff --git a/docs/images/nf-core-subworkflows-remove.svg b/docs/images/nf-core-subworkflows-remove.svg deleted file mode 100644 index 42c576f4c5..0000000000 --- a/docs/images/nf-core-subworkflows-remove.svg +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core subworkflows remove bam_rseqc - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Removed files for 'rseqc/bamstat' and its dependencies 'rseqc/bamstat'.                     -INFO     Removed files for 'rseqc/inferexperiment' and its dependencies 'rseqc/inferexperiment'.     -INFO     Removed files for 'rseqc/innerdistance' and its dependencies 'rseqc/innerdistance'.         -INFO     Removed files for 'rseqc/junctionannotation' and its dependencies                           -'rseqc/junctionannotation'.                                                                 -INFO     Removed files for 'rseqc/junctionsaturation' and its dependencies                           -'rseqc/junctionsaturation'.                                                                 -INFO     Removed files for 'rseqc/readdistribution' and its dependencies 'rseqc/readdistribution'.   -INFO     Removed files for 'rseqc/readduplication' and its dependencies 'rseqc/readduplication'.     -INFO     Removed files for 'rseqc/tin' and its dependencies 'rseqc/tin'.                             -INFO     Removed files for 'bam_rseqc' and its dependencies 'bam_rseqc, rseqc_bamstat,  -rseqc_inferexperiment, rseqc_innerdistance, rseqc_junctionannotation,  -rseqc_junctionsaturation, rseqc_readdistribution, rseqc_readduplication, rseqc_tin'.        - - - - diff --git a/docs/images/nf-core-subworkflows-test.svg b/docs/images/nf-core-subworkflows-test.svg deleted file mode 100644 index 9cda6beda6..0000000000 --- a/docs/images/nf-core-subworkflows-test.svg +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core subworkflows test bam_rseqc --no-prompts - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO     Generating nf-test snapshot                                                                 - - - - diff --git a/docs/images/nf-core-subworkflows-update.svg b/docs/images/nf-core-subworkflows-update.svg deleted file mode 100644 index 3398899b7e..0000000000 --- a/docs/images/nf-core-subworkflows-update.svg +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core subworkflows update --all --no-preview - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - - -INFO    'subworkflows/nf-core/bam_rseqc' is already up to date                                      -INFO    'subworkflows/nf-core/utils_nextflow_pipeline' is already up to date                        -INFO    'subworkflows/nf-core/utils_nfcore_pipeline' is already up to date                          -INFO    'subworkflows/nf-core/utils_nfvalidation_plugin' is already up to date                      -INFO     Updates complete ✨                                                                         - - - - diff --git a/docs/images/nf-core-sync.svg b/docs/images/nf-core-sync.svg deleted file mode 100644 index b2c6d734fc..0000000000 --- a/docs/images/nf-core-sync.svg +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $ nf-core sync - -                                          ,--./,-. -          ___     __   __   __   ___     /,-._.--~\ -    |\ | |__  __ /  ` /  \ |__) |__         }  { -    | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                          `._,._,' - -    nf-core/tools version 2.13.1 - https://nf-co.re - - -WARNING  Could not find GitHub authentication token. Some API requests may fail.                     -INFO     Pipeline directory: /home/runner/work/tools/tools/tmp/nf-core-nextbigthing -INFO     Original pipeline repository branch is 'master' -INFO     Deleting all files in 'TEMPLATE' branch                                                     -INFO     Making a new template pipeline using pipeline variables                                     -INFO     Committed changes to 'TEMPLATE' branch                                                      -INFO     Checking out original branch: 'master' -INFO     Now try to merge the updates in to your pipeline:                                           -           cd /home/runner/work/tools/tools/tmp/nf-core-nextbigthing -           git merge TEMPLATE                                                                        - - - - diff --git a/docs/images/nfcore-tools_logo_dark.png b/docs/images/nfcore-tools_logo_dark.png deleted file mode 100644 index 1b9cc02b17522232a22912d2e069f87db0ed823e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64937 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%0D6Aha9ZZvy3Owj0R@{kHIA1_W(q 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 diff --git a/docs/images/nfcore-tools_logo_light.png b/docs/images/nfcore-tools_logo_light.png deleted file mode 100644 index cc4ccea1cb12e60311b513bc7de0c339ebd591cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64856 zcmeEt`9IX_`~RRQS?ZKSWhn*~p=96c5GGq9OZHNfecuPCQz(&w!1jG0qM))u18{N;szxKLnntC7*Z0~7*=;B1!jv^4p5Gb_^hQ29NgTYTSd@O|5 zS3HI44fR<@BwC_WweNAg^K`t?ay|Ua^`zuS;o*5X;p5j0nLR_3TdTw-*C$<<{Vk$; z9`%au>-b1%=CCl=x~!Jp!Br{RFpzjKp!3X+Tb;*QRKss@Kb){h^c+@seV?p-3zMBT zv9)Zlu({<`v3Pc z_~QTk@G~L)&kz6ShyTBGp!b^mFYH1%8g&}PE+NMRdy{Rgwkaa9QvrRQY2HJz)6`6H z9;J$!8p?T$p0J;N*Ye!J#ykH8M)iUCxVX5E!@pK|Rzc1t45Gxe-2E^GvsRWhY(8G+ zqQw!LH!;zIl^)J$8$X^IcCItbD!;xEnF(K*M&+X@JSfW~(%%?AjAD}I{FvT)!b;+< zT`3RVvHyDV#tr{F?pFSzX|tN{P8k1QHN6RI-9sVD@-lUEm%l0Eg`Uqb{CpIznVgoC zqUmmd=@Irb{U+;BnnF@S4JpEd=f8=bxA|}L4A?vsm9JMY?xEj%PSrz{(B9T6zCrD{ z5aNCa{cB^cli-wq*o{Dpv7Lu_ua|VKlQa68K&C3~Q72#9XybNMzba}b4=Acza~8q2n+%iDoFDn0jDk39X?^7A)!^mJ;E z5ekGVYdquWg)k>J@LX5^<&$Ub>jptvS20#izP!}h(}bdq;~{4o<`Z~-?Z6?eBvmOx zsE#!^me;!Al9p_BB9-oh+Bc@3zYqDCn3hx{MhJ+VI+>dJOaT*E;koA-_dUK}Uzf&# zH;{fF7_10)<{MQM8t=)+Bc#9Hzz?%a`@_R0){SISt$Kn@K8L}>h6mZ|Sq!BZKB@H20kftU}^PiE` z)c*Xdd@3S@t0+sw_uO~aLtzgUG2d;xQ1Q*1H#0qHdV%)wP1#8svyWz%C}A74L_x?B3pf9H&Y@2X=|G$}7iYO?E5Lr+QZ zunjfr@njOx!!AI9VRd9th^kl#?3g$t5Dxfn?H4g>K($Nt+fHaOY#hv@QlJIXl)td!4Cw33#odkl6Y zV>S|OhL=y33;S(CMLA9S@}2)++OhBFrXf0zRg_T_+T~HTPwd7xJV6cPBJX{fB~&hK zs$Fc?B(tfBkrDJu$X3Q1{1zTNRk(@T;z!+JtsYJ#VQFEI95Bp+1d)p+`Gk3TG-5Wg zkhB!>_0%li8!7wS)(5l@KDF!}dm%NoRf{a39g|I_D;7#><0*1`M%3kp01AB_Dq!Zg z8ht}kcgMfVhs)|`f(tl+ixNr3KYnoDKRVH}!H24qCWtT&%xd}zW+opB3MoDNJ0-8f zNvx7d#yy3T+j3B!o%L;!;b>EGDQXB~+h}0EX^k<%)ZBpGVwTz%Bc=Z{6LNVVmQ)Zs z#qHX&f?Rw4S8Pz4H6Vlw2CL`ph1rxV>T3%^&1h1dBkPo8>RjJw|7HE<#P4E!4_OE` zO$@0HI!7pPZx!b@3)8f7f(6Vl`(n8hAxh@*>=H@8QQ)g9oK9SqBFr%3t$}fQ3U0|& zMTUI5{BLzyt1e{`H?CqHGJTzP#T38;zV<;^=nNbG6N-_k!KrUQDx)Z|AC(bG|5a8Z zB*H@M#uON%NKm+sWqkHO`)aB@we3grs9;DMV?Q{%PqLj~`hASTUIF*q`ZO5WR)wVFI`G?Zxevi{$Td5LndKR;aC(U=|9wR~L8w;+zr-%IHsbY> zUgGTk{6DWrVb zYX7qj`>+ae$t5+}$|T_!B3=Erhn`P}k1ai*^PzUqmU{4eDXuat%oMLHRxej$e~5m@ z@ADVp?D3O)y6!#xyXd$s{yrf~zYM$Yrd~^{xM%^*VgG&MleV6Y&|SUNwG!INi~rl; z<-XXdqpn!99)UghSN}nCVm|NOx&~&TmiGceJ?{6R>laTmSZ>pxJbelcMsk4R0F=Ar(?q*%!}BhZw%+9K`8y{Yh!MT%%c;Bib&k(wxLRjmW=N{ro zoje;XgQ^~##P@&C)S#ViS*=Lu%Jg6vf7wA7B1zehn!53h9Ut=hiFVdZ2A1)BWO+Or zT}sR*gJqqhOx-8b1SCR0`&Ue?BhO8gDxoY*R=fY z+Cyn|_k)xr7Y`wB{C-T)JdQ-^IL_#4Kt|xti;{O2Uif`>)vlM+z~WAes&vp2#~e;> zaP#^zhn)Ghwj{nES?XIu)mFnEPiGi7&MHYgMRFdBqLYyRcM0|3NrSwRzt{zDC$Q16 z*lJ*$9KIG@s!K*lv(_p8gm-n5bjuuJKPNIbLluNw9-=Anc+g>>{ftA1)Liqyomg7G z0lZGlRAqUVOzOE5hF~nSdqkDH#ahTn%b<|fSG~?U$lf?xD}R^!j=>M6H8HyWF6y2} zPGPZ%iKNdTp7uW4JWgAQE8vm;X_WJc)Enn#$({*pabQ-s4krlc*`UTUP?m@IrR(4uk6XT&bDN%A5aA~}3fQZ}+Rd6c3 z*IAG-N{$P(j4Q>Srfr2tpV8=0h{!#~3-AoOv!u9tWom_0YBxR+7|^?x3!H1(U)HeMcJvM;GiZDK%TC8~?<`}ApK9*l&Oz?(AV;afU?!7R7^1E3 zn(zjAZ>L6+)k_BZ;z(Js8zvb4U#rVK@}KTN_B?4j^DOxi6XO26e;wx5>Meq@OeH16 zPKhP&D9lsS_dDnqJvA_TPayL?T-&Eo4MaN$Vsh~LOFAw$sP98vj^)e3erB(Ix)0Ed zcRcmT-^mAK97kIoOzJos^3BBIn=oowuyWRsVNp-Q8QI%4?47^vYmBj55kB(7-5G-Jw=*jed)*MV}zlKa?!7quxNI9Dqv5~0*qxF{ z-|ays&_rj1kTx$F^uK@^zBGGr$N8@D5U_4!fjHEh%d}?#HzMqS1VBYf&^KYut?s3z z#x(Dl-G0}fkFA#VYCT#)Cajcq(Xx9}P9Gs}$ynv!cB`zU=s>7GEmrr*<+Gsc;!_6q z1=Fl1&esa#1l?YLx5t#zFs9X%$7g7LW1T&4gw?plYc~G0M)WlGL4fi~%|d=l{ONR0 z(ExtJ#m(uPIko8AUgyCi5<6xC?H?P${GQ>p{S!2bzAysv+#gde=;uWi-SN!d&Z0cl z=Vxa<6L=w~xspnfYZmT}S`g$EU~=c)X2)i+nZgjfLi{{7BR9A9V@M?IiAzae66wR{ zbVBUFuw%J$iY49n2)JM4(tQT$^3x(BBAJp1iSJ3%-4{`4VM1nRNn{A0Wy;eaWAc95 zmX5rTQxA~AmcS{swE)2-o_n~AHzPLsJI(%{&@RtXp}uWD?G!-#W|yZ}HlXQ(*l93tqTy}~zd~*$CAgPi|Hx9G?WY5}M z02i&|#Gzt|tMhtL2iunNy9`lKjcFtdl5U(c0=}qQSucG4Onn{mfpPuC~ zUODq^;@FC~c)^rubE~#vvhN#etKRV16JtlmZIYdM@X)Bpn0CtGAJ@B}v82Whya624 zAWNK=gJR5mxMhoFA9d`R9<}|+y@96bmehO5?J{6J#mA%^uw=C3g0&=Yhgqk{lD6Pl zA2MNCrS_F=zGQJRW^*O@TbhT;+S9Ov8I?CaYg*B%^XJm?+K0UD#yYZ6KNnk=2?@=p zc=mdfEVeY#XB$fMFMFYgxxJ-=GENxkH(mxUP$i=}qjnpYz~jsE$`XWx{Ko z{su~~zYEKQH!jQXa{LphLJz|!xE7Bz&XW0HhkW@%MrHfMT?G}tx!TNXzI;CFJ5KS| z+d?rqica4@b;u}fj(?1w;vxQs=2i$^nPv}O^2q1a?fY1*LTE(|m4YKGJh`lI0QgB5 zLd7Q`gSl>EmtO3M%k!8F{Q_tbt)Q?GgUEKEQ{K}&yDmX?P&-6cwO7Pf5_I02N$U;D z^>}L)h~66K!L}xBeQR1XE4$^_To%#xacxYw<_$IFVFHr~HRaRStq6wUxxh^9K{nwv zGSbBg62eHHrLdO9f=R$peChd;#blkTAnf=uz@z{+E z09mH;dkVd2@B;WHFHWdCk-9TsY`B4HF0mG@Y0w_n%lfxep=Py_`>pF8HAic zI5>Dzt5K|fzC3L9WK7<5F*_$RAK>TKRTAWIyYol#>f`FxkO*AF7vCO4Eh?p$q_x59cLmsMlbT+}V zaI|PtAk*V&lNx5bTV?I&R}u~D-glvDnrJQ!d9;*d={1AV_H|(ab9o^1DGx zEg*8wH=cWZ&jMWl(Bb3=VVJ2CsbSv&R{t)jDfS@mUP+~{)vZwNT@_+ChG}txxpgN5 zoEUkoKQHx6+acPT(tX;P1!#WopOG#Ay=mGdgRh0xa7Yzn`F)du8^WH4JELXyeXy9XZNETOysflQOlCGBF*;iJnGrL6%1H`;Ol5>#tPMvU^qdFg6f+ zJ15{3Uw%mDwl9BEHY@WzC}z+7&<^JkfyR=ThRTwkPyL*}H=xoj`;$p= zzvcr(!zV$+TpgsJOE5~&Iu_a!B5G-Szdsm3JB-9Fv?8G!dg;0Im|<{;?oNIT>Mw_u zc)4N9LGY&l#N!Pr@+CYtT`7<%?rS-11^B9A3X|D zz`k>awRwQ!@Zpjy&@Rq`BKE}8fF_hR1+je_VFF#Pw4WYkP`_+9>`NqEb*gHg1zKK# z9$UEbB;f-%d{2K8i4zlOMLs6c2Alex9lj=y7xD?ln8j|GV)T%Ht{_O8$oT_~^dpxb zh6WP}2HLBBFTy$k4vuWXZp^LOJN}+>so%B{$y?m^&t!i3t`;ZptDkukl%4!I;I-4amD{4_C|db zZO)L6QpS)3z?ueRT_Op~KDooYukNekjPxi;Afr7!vZ@W`8FH7KQEehTFy}6Xhdg}Bj%BxLhz^5<=~ zrJ&XZ1!n?b)vw=MrncjT`pUz!c7_Mm_2vn-!H_(%@uWNm`l$j4BYD3>1G>f&!KDEh zuXthGF+96Nj(Oc46AUNoKh0wc3yq*^&k*k3OQ%^>h~DYB_{L#K11?8(IF=tl4VlX` zMOG$&kXWFZlMd!&o2S^Ck@w$&+a4-RQxde8 zhGZVKLiQTS?|R%5$A%c8!MMTUp3#~rR4ufb%a_T=gv~&9CX$k42Q1}xh5@QxJ5-Se zO<11i9!(6?i7+79&@ktMc#3qHQhSn3jY# zn()HALZ!onAgu|0NiBT3VTe(OOFYa_MqYyO+Igr4F>MH!VT0Sdb_l2_5AA)BkRplz zY67NS#Pi%uH)8<~6fiX}J=utEmR9nJ$b(Slx}(J%bj-eu-&-8ZJ$G2ML6xQA zAn$*S1b*Nrux5H7vK9w{fGcQ-XFC?hb{WqE`jYR|FDtK<7QdrH5269ZQVSZR5JsC% zYD*y4oDl33NA7(pbp}7Lf=ANz3oMdIKMMhB_~RphsVuLXpoz@ncSX`BrMlA2&3=Le zr=R#GVf5O_Xw@XE`ka;gE+ojMDkPy4EYh2}2^PujSTtg^Dwjxl`x8^S*#Bo-a)~MA z>X3;%V(y9P{#itTa%OHjdaY7hm6%u0FA6rueZa!(z z55fR4_!W(|Y)7QOjkW(ASX(RZ05^mIM!wMa#KRYB6NL2nLt0$|L~%@$H13UkWcF=r z`R6Sb*U{lvTj&`WWK&2m$Hbo+Hj_uVHq@qrle~7EG{CIF^po4H9ib5MAw#`nF)#2a zskzw?mkZ`ZT3m&w({4j*Y3f&}v`ym3{rX>ST8FkF4wX+EYy#6Da?BGl^l2ksF*uF_ zSf~FIiseqVB)Xk7I-U)Z3xPLz)#r(2_XdOp+Q|V>M&R-JqC5!o-U^;CyNQJ96Fkol z0ui+IH8F;9L=Cclw!91!P9v0{6Ux$3o=Kw61;|qUDTx1^F2F78u$?LlqwQc#!YOyj z3wao0qG>yrwC#IMe%(Q5{p2e7gCJtkB>*DP;%-TMG&e^bSEfYxsr6E4u8>&@`vA)k zxdcFVEn&Lu2qsQM&ZGW+Xv1=NzHkVxy8(U~=QJ_fFaS@1l%flfx{Z7aNx5?ikptdu z{Iz(pIxZe5Lz~Z)10m7UbOc0FEs_(8Gq;xm5{Y)7VO{DbvU5p+_xE>uE!9gj!Iaau z%TFIXWBQcl8QS$m&d-|+{G1^WoC~bS1nb3WC$J$>;x_+XN(!O`AFjVa!rEXG5`K;b zLkucjdLoFq=2sw)uk#>uh1rhcpfy5-0i{s0rF|25=m!O-h2=Vit8$brH`j`EeQw`? zL6`I+b)0m}!FGYHzOt7qDQX zIS6n~695KoovaVSl!6c;GgU4mm$Y?s0f=D8&_)T~62QOo>)(U|a=<8| zmh<}3Vo5buv9oOvSK7;t4{f@qTbfzW%O{eaBbhLPRl$D5)gGw(des^iu6^*W01VD= zV`SCyCXV!F^g(CP^s5eD;YpQ(DVV+nE2t1WsC?LjMo#~>30v%zN7F=bEEDaTetXht zD1o#E_J1y^GsUSdbxb#c*pR9T1iLgE)cIhl2K;)5od|btFs`W=y+@_Ni2Go$G z@Q{h=CgX5+t#?(wO8mjy&(d?s1W;^(en=qu=JwRZH31Ya4A+#T-}62FOj(4Ize6K}@W6YZr^?Dem#2jOqCXeRmww! zGoXHbb(q>X%pi-d^xzQ?UExb;e0Y9E7+$IvUKF2wG*%JQ^{QuCsPZgsEN-9sivbU` z^o-vqspl3owq}(i0*$Rkr}*|_c^%3<0OR+;sp0(+>IjV)o+Gz$AOr8Yi18q}9&GBb zhCVk~4W$D)%R_z?rKpk>Y~a!^-}tp}xLZErW@WFlQsU52v7F)kHR6QLkLPa`e7PWu zP*($;n`-Gse6jdZF{fFHdOy&oao;`%FPORU1nYRZVCpQF<}Y*}i+P1BV@o7}St8x_r>2-9wNP;M8 zcD9UX^E6p$%+jaBD+&%Za`9O#c7)A0(g;|qKb}NcWL6&jTBlfN|LX0O_N>=8LS}~s zEG>-LxD6U{;Q6zLS7gq*oU)Xj)4UHIuOt8#v3%G9OgVIN1CN5DR`a*hn4WcMhgXDB zET3mhL~RFhA}g0OW>3rX=Z(1R8A>B*u+jHze?P<-rw@NK&kIl&y4o0 z%LA25?zFbbb0q!k(@9RF=!8@GnzM3FN?D7!<#~RA`YxsQ0HN@LgA74Kd!kPf;JS7( z{bOMTc9-*QcbLo2OA#@Kh`ezN@SyqA0S*o(*?$tUfu^W(7FFBZ2>=wKiV0x*H62-`5Fclu*L zA~Ipi-Mq2=6WV6m{YiUEZ;SypCJhiu0!L}LK>g?tkyI=$n*VCQQ_2pQKnKvZ`dcf( zW!^7Wh9_W1bPC5%$)`mLLn%YIqI6mGFsa$VK&*8n>!rELxi1ZUF(i)7X}Hj`zyj*c{HII61u=Y<{rl8{jrhqkAEU5q=%DQdXOIh0xDvYHV8Foh+13dBI$3Yd4~3b%RKPN&QF6obt$IcIBy*HauFFq|vp$<%f`KJ5a8XFyi<8}qXRuV}*ahZQ{g zB#I4Eenr^N1*2yg6?F<4vjkE^Y?n-RvKCWFXJJauev8uSfw0=yUMsh4+Z)tnp0TtN zhyM5PYvE0}LBHz<(y1Rt%#K}6GXFh~JA5SnU z(4kC|If7CaB`fZtoKX}kjSw>H4J{xGWQ8v&vsvc129b3({jj$U9dAK)8^_krX6J!# zIxW_rTP7Mp)wT=zd62oUF0=NxDXnf+`wUUv71&SpDi__ySdKB&|8%(&Ba<$!0N(do?Y0_U~$B}&=QlWP~%Hr~FH$qctY?fm)58_koMPp*h( zJn3j+J$KN@k#?RE6iF6U1l#d{Cx%pb1cTHP~un?rQDjRQ5zSi@)HkbH|YsJFE} z%IdEucy<51w_zb#xgMV1E)d6-W~&UlNK=dTyp9)j12D5bqpWdPHZl%RmduPR=4A;e0bB0cAG9A(?*V0)a!t%S*Pumi8vLLfTp)urZ-phYc`kn znQgB;!M50G<(_T&5zyFZTCoXVP2ukAo;;Y=wPf?8DSysHM5M?H_ zM?Wme+|<<6)Qt}@hB3?{hFEjUbOat=K2*|1U#4c`%Hy{-#+zE$7d#W!Jx0&BJ4!lA zfa!-QG4}*ZK9e$>O|?5TBlv}c?B5%;0m^F+?`B+!rxzE*;;)*`YcRhV4_Pc=nV4M|q$8`7S9o({=o;ipR}!KWvPa>3ogeEH1k6m9Ibd z*&c6fMz6k4v9uNlNMFG7E4_Rd&GH2dKT9!=t9!6PxVA|wDCi6ghLEN0zV&88OHD1q zXW-+DVY*u(O|nr_*!s|ws&Z<�ev`Q}H7y#R1zKkC5n?0_OP7^FqWWeXhX0t0pNK z(bt$TL*ehNPtM(;VA@5R9zN!e8~K<~cX3NnUF1p*`5e(DU1F8lRX-)8KbL`E|L`3V zNx2$Zf1S7Do%}yd%DH81m#>ET4sG1bNkca-B!p$@$27Ju`3?2uL@BKov2V<7mu!_y zZ{zyp_2QITSG-eP=P-{N#gu#(3@bdT4+KZJNda3|h8Nf=HS=!63yn&_8xd=3Jkhf$ z!}BGTsS9Rf-o-Z?Q?|cG3CC|q^rGJn>M0i8LCYqr+E3?cMnhr-$;c_-;y3nImk_jg z*SB>)9>F^Z*<}?lDtFvDC)3w(;J|^ymifdvBjSktDB*-0?<&&u_8~@@7`@G>U0<++ z9+SbA7tkuQpQRryewLjRBRYX|j#Qk}?Z|6*YO7K~og$D#s)y)BWmu8L?D||OjOHli z(rd40>4_~TSlT+@@R3Vwl4m533X}aO_w!RFZu2~QpnL7?*4I%LpD*2+wLVo|@%I8{ zzZ*2>_N_CqtE}T$qqCAa_KGgmtQr5qR1iS0X_i)@emeG`q0wmFbyr~nZu(wbqnm8n zm>_weO@nuHR=8~I#88`0`PS5U9d(wcUZTt7AX?2|`@=qRC83w>Mlt@JqGP!z*B~9k zLWkYhn<%5xrfan)FuTkCh{hk_05N^8n#jP+e{_`}<+~B3W?CiNuAua}a_MTdYyUEu zusJz*oM-`=N*{Piw?l43yLb=$GNYte%b+5I@-V7dC>B1^m zR*$`EP?Yr|V3rCL9eeM`ru`w7D!cmZMv3U8-`dIMVpnov@J7;{b@x9^3m-Z3Y{Z&* zD_zX0=I>)SdOkw+&z36W$kA!;9RD64IRcJ9N)qO^ytsAe+9S#M%>(p0L@&TU7Z<6d zXj3LQe0J3d7TseiYm0wOit-x`{PWm{J|RZs<&$+&Hgo2h z5yoyB+HQt44OJ{z%<^Nov&O3L_s`N7xT*-x6tM{ij1IE&RK^F;>C|9s3ZaVQ%s1ZD z&nS+C*X#c67*TD{>-$e&9F_U?(pP^n73=qY;t~6n@8+=ca8aLp%dr}3!iDJCk?<^K z&vypzO3_=}Gj~EnkD5>38d&H~S$*Q#8lks$jjwQi7#*)n;Y=>q4V;``tYFUD_J8e# zh|!nSX8$YmI;3~P|A88khWk?zH-)?If|Hk_xY3dxFKoZ2t zJhyn*p%TVmg-uCC^US3grB{BCe;gjJc~y-@ArHqhvcIIv>?>x{3Ka?IQMYkLr(_(> zW9Yhih|wXG9m5&4$o+&R?gWb^T_Edb8q`Plm^+Gd%I_1>MvGg_x>l(|hG zXL8v{RZZI(QAKaWHr5s{+1W7^G~V*hY!i97m?+bvfBkF?1U{OvO;CKD`v$kh#Mp6S zW}dnS&g=07uy2cfao?kBg`l52EM{x5^{qZ9WVy(?lQ9ObhGymV&M6W5@vZoDNTGn5;{NXx zX<|J~8H=}B&gYFdI$k|n(j)EUEB-F--tzpx?lX!kjav~2haKue-^}@3(<2`l9v*%V zpct`r=&rGCgdyq>V-|xIQ&eFazpBmQxvNAkeJ+~rNaF6(0Q}arT=aY7^=HiHH|9($ z2FqKi7a4zW5&2$7`1++}teA$yJok{Vzq)`Pmy%Nml3Kg-F zXgU?f+Q^T}S6DR=!9a6CFTM63I1qE;!8>bUFzl|a`*)PGkDYY|aNoPCe2S{MV#&TC z!F=~d-rdNg6D;BHXbe@$z9Ddm+VuDVjk-}hr>I}r58#I@|Hf&`?C6on@5rDQ;BtN* zCm#GK9DZNG)n!xr>vw+e68-Re^a17vyB)GrmOgb32YfBAX7Z}B^qsjdl3ZJRYm~<- zu>14DocgGES;E)15;iXQOAcTgE-RVS%WN{_ViKsrj|B?;TuuS3;|dS!u*jwlru ztBk1E6!us{JY>%V92A6y^0s)NzF5~my5ZE6)b0sJz-@?W8pFoHx$16HHPOny-p6#g{Jl;f&|&AJU;;%xQ`;X{=fW1tN4U72f4 zG2cMw-+5+3LoqX^{p5EUUI>9<26SbY{c>rF%o(YY8`tmLVq6s@K1cKBOl@2}*jRT~ zwnF^kOUr9N0z8a!ueni;qm=x6K}x5od!>a{9A3?Y6I!_mV$%j)A(Y*B&e?@v8S-a( zSs!W+gCwB|RuzEbEPOpaAT+ZfMs4{P_i7&;wmSDNBc#h04lydP z5hC|$bEW#=|eu-u>CWszC&qFp66I!fh(Y*Z8a;X4HJEb(E8rIV;uNI`YuH-0LG z_x|L@M;I=omg$aE(ovAcYk2X;oS)P(zTYR)WiNgO zyKe)d4l{1;mgU^sK2|@v0DmngV>`~z-{GLowF<(4%{)|B5!HIprtr|JB(XfNq)F41 zdBg7zqyK>m2|zW_rj-*ODz_K43Ai6K?;X2D^odN@Trxj!?`>nAs;1XPoBi~&g)}9R z%Mk9FZFTg7bZi1w?Ot=Hz}>6#t^$S6^%~71Rd%7%yXx;S_t zt$ev7PH)oT_RV1JM{E6CffG#%%Bw8`QG6>kQr&(jVIfv&iAif$%O5ydUwiap6W<&v z6Fcmpmhs~C*}t_NH&TIG85T<+5v{-jE2d1K8R0F3_wzj=JtlSsiU1_P;jIu^rVt_$ z12*~{@dWX^EGlooFiB*1lh^f3mtR~?6WXJ5B!8FTMy%2r1aV71x1-&JDdv*D$fk(E zVm%|}?A;~_a#xV!!8snvf{hP7d)bjzB}+edZ+|(zqRkJa54CYhAB$vW9i)=5Jb1Td zsKHz4h5CdIc?r6d&$A<`fhL|44`p0}NYs9xL{5hW#nr+3gyFT9ae7LB7N1huo;yjb z&wqUL-Jo$kkm45a9E#{1v?(hCYS$&-Bp%v6bD5a*gN`dT>3kVm>-w&YhaNy*!&?ij985sS&kCNa*JE8-5_j zl*)Ynf_EvK>~Nl0&OdOB-Lk>%-s?G}==9cy*Z4c0bLjG)or+@Iy6*0Mt>7%jftcqU z_udxaRbCWFgPc{vTfq-3ZDye=9>R0)Bi@CaU_mpj1{f~K9QZafW~F|U&y<^Q)&CHq zFo4D-zr(JPUg2U$d;*Q;!ZuHD4D6}d<7)|w^W(gcEkIi(h^Cp!=CPKa!I7uay&pJ8vY}rHdBkJ~S=vi+eT$}~wv;e%L7}&a*03xDe z641-lqNOI{=)U4uT~qf@4QM{Q=j=M%-eZ{#(dJS=iu^w{4uPI2(A91YbOkq5dnMu^ z15m)6Dz4IgZaQj_0FM0W-{F6{QB$+Ehc;Vmu4mC%2G{h-{o+HBkP?7|AROl^&*XlN zc{98Ncz*GL$dj#;uK8Yn9=-%52mw7idF*<#&aI$(UQuEe&OGOBRZcJaVH|)#IH90w zbu(d01*q~5_r>ReULX$yb~x$fg?8DnBhL)Ur!y5BcXn#3)B#SIPF@jTO#X+%}kW$rp4 z3HUieI@rAoBzq4wsev^5inv}1Sydf6MvtALXt@YrrxxtnRhJqC@h{PQq)%?!|2&PT zpP5>5)3pHS*KMqIO&W(WVY_EfVp{Cxd02)`XoJK9h!XVb@0(q4F2# zJ}mNy&+|Bnmlqv1P4hM{I*^EWBi?`d-6?cN$lB^``8zBA%$r;9tA!NF3I$fVIxVhD(!OdjKfxSyz0@J8@s*BK_WI$@|uGw$m!mVLT+5xsx z{KGk7{QTE}Jx58gK}JV44rH?!|6Sc8AJ)Wgapd0HBQ)FW>n>WJ;vmc9Ex!(h$pqqc z8QU$FAE6>prrggQ0J;1iHDkRVI|CX7z+Xi`kvVmn`a8x4e!nt|yE*#)L1tRH72FwP zy}zc8@yNOTAu%*!f}4v0+e|0--z5ooD6v-%V({(K1kI(3Hm*lpE4|pVS;4rleR&L?aN7Kv{&uC*`91Y|dCsl=N?)>V1R&soy^VyDmb4<38D)!4InyyH&6 z0f16w;%OKKXPivp?+|A&o!mWFCBUZO|8%zX^pC0=yn*wtvWC$=-ao&Z+91td6AYAd z!l-jeHRp2*41eHtPKGkGu>*&tXe0PnR3d5W%~sw)$Ql@8vJhADJi-kl%mUo*d9lT8 zdO|NQ3VcSJDtZcmSOat* zd%gvZvK$-FccrVC9p44n&2AF*>TduE);a!3ZvJ$2;kOrUzvKx9m&SqQ!UN^W&SlX+ z_Hcl^&Kr0c z2vJj0bsAlsEv3mQa4tNe+GnM*KG3D{Q6u-#U4aBKIj{YuYvU4kcx;N)(KzJ_={MjAFuLS?R3PHnijg*CMuZ5>*2TkknWmFH2nAKDBSVjNthgj z441SWzajgc%#wb9c|*XjDC@+^q1o~Vlsx-%@yuDGtMxmaxH4MIRjAOva6YW< zFzABA!sNW}3mFRe+N-*g+!j?W@*&}0ItKAZ)+U!^?=F6e$Ue;R>Y}Z+=M``$sRg*X z9$@rO*o*(H{6N!|M=q5ABL$mP{Yh>C$9-$4KFZ$y)1!4et}IvZ0*zuhK_@)7;<(0tx5Cm_Jqrzhea(H>C6xM|;cjg@1w zuhx7IF^WgVevuFJ96L?gU2apvTk)CZr*?qQ0T>mo@y@AFigJ|DC6+=ZF1>);wJ#Cu zDa?V5@}Slt@1I~fKZ#UZR_hF6Yx$E1Q;krj-qL{*Dcz1rXXlpGW8$14M)cyxf&+86 zb*Tj>$~LRK_QxFY6Hb~b5oSkV5zY@{Jq_yE{tzZJQm%6JAS#yb&kA8{GXB0jbBM@+ zZ-sfD+rX?hr|H;u2ge6bu>%Jfg6}b_?6b%wEAyYV2h7wQtU*A5!NroL-j;1`xMFXl zSIF@ao{GJz(ymN%m&LQ_-=mTq*Y&xolD`)q0IyOuhKmz0DmK-x?U?ez%3%;&B#Y{S zcKR?(;6!&T+oz`g-5p!NRnzvJ6bzS72tE*=SBRT1B(eV_cWQj_)tsbu+pee*w$Jyt zRxwb!*;1R4{axORv&G?Db8yEHS>c3Nrx=?IqPE^|29fmMJMR9n$Ws#wzY1@%hl{Me zuGwB}y&sGyjixIdegma38z|1h&!9G$bc@^0?E2B9rCdj+sHEFr^(c06LKYQpZMio= z76r-X?~#%*%On(P#i*>Itgrc}#_nA)Z+(Sb|M3cE_KU1Bq~yw?3QE%!Ve8I z9KS)gws75Rc>?g|TG-=@N6W~{#?UmcP!q$slAzUy+*sozSkNX+A83(}7TO4(!uk=9 z6Va5j?R6NedEbwrGJ0r_1||=l28w=M_x-k9VG9n6&^?A#^Z4V4!Jvb%UYl;`opV4| z;Z1V^!i5d;YOIR%0~g^wrmm@n+sVsiG`f6x8kvy1M}m&KHhD$QV>bF&@P?OfaBbW* zxC}sWl=Du-BRX~mTduC%3r-Ub)*q5Be2=qg>HmW=_D4LO-pQbvta6x_UG5C>KBJ-hc}&vz zZ?nwzsH)wou7?;C7=js7Y?7NI*=tx=u?=#zFkCg+SJMYG01Dn zo%MX{qLuA=X@pPb$z?@^;@3Ope7MJ1t2@9nbhOCgCt?bRQ_wPD-e}3QosK=x7I`@6u*Y&)f*YmpW*O8rQDj_T- z@}h93a%r@n4-iJLCjaHc3#jMD1SXhc+xbu3*;h{e`x*=6qom#zvWJ(#VRL)Mwh5FD zA0d`5DcpW``T@6y6l!V5ZR^l;J}ey_*!gm4(E^kZCR_v6K-n{-9Et|1+Lt*&ziqBQ$XXl>)uE;ekq^JE{zl2xhx>V^#t*KS+K zP0(&@ExRQ?$zXr$n%Dj#=U@Uz?nRyL=HXx`y4PR$SGem;yYr-~-?)EOog~+FoJ9S! z^}+KTC^n_Om%rQps2kVDz7Uj}>*sq300^hGGECx5S4OgZFRLSaA!}pE*q3yI3#(9Rwg zftY|o_2f243lz7s_IJkF&Y(}!ocZ|lN`{4U@K+-xfF@Axau+YY$CebSMlT85x3iTz6X+C|GlUiRiaRrN50`ZGJoy6g(1VHJP#d@Y%C0_2v zeYdcGU4|6zDE%cm!D{w4ai~PwHdO55>o4ybp>NxXRH^@{QnUNOWCB8!qO7Z$VqlOW zNasf1dlf(7u?<}0-|N+PPrsxK%R}dMt#wXIJ?7yJFwIe&*6ct5cq>Lx?JcV_@!1{5 zxQbJ)?BL5ZN@}2fTBX#POz(p`#V@-&1#e4weCz*<|E{ISg{KUPtp!_k}9@K1@mB7?>dG`_Z5$0R*ozIiaia!mt8GUhq z$~EQA9U*yf>BGuLPvX+Nw}Pz%q-T)V;^sF5ss~VD zy(CckI%aWcUnxOK?KOdRL_cF%NM6DF>OnbFKnx7&sH1Oa-U2g%&U+c!W{%+fc|@ZG zC4(%NFXpT@8&G^Sczd)3|3bNxP89@WTy0DehHRe*kQdMvQ_?#%_3v1zbOlB&+#4n^Bg7TZuyFk@ec%HdtcvOyuuyy_98 z1PLHr`$^>|ztey~!)%SAfT}ZiL3!FB2_vRVRpq1)N5sK|07RG#oIm)D_~ze2iXy3G=N#aGe$H}bppmCMKC15urD zBYDNQzvwY8e425y&2uCm)}6k=6p`>XSWXF~5a^BTO{bq#+6H+A{qeP@6X&}5nAUNN zu#wG1-AjyIyfBOrU-5N3DVgPM z3?=KCa-{Ojnx35U%-EKTxru8&E)k9df36s%fJ!BD+8tlXH;z1b(E6P8j_&lu1UG#3 ziZ8MVA<1mE}kilZE7d-S>a7_8p1orxsQgIJ+HwbBgyuar`a415jpG?foKE=+Qi zH>gOEyM)rngbbfAs~q2F`i1cmdLq)-MqBZ%tTP;?n==}492R#!+*R%jtSj!lOF9w2 zc4kh5HvcqN0Stt3%=2$3O1;sIOWl7K7v-z*1_DR`k4D~9+SBRYjmHZK)JkY*{l&gF zghnKz|6Y#^4qHzZl5Zzv@i{V&%lH{rgsg{nRRMju4Jq}g9vostXa33?lm!U5zCHOo z&cJS+b>H$hWH@>g>YV=g7?GF@ogKeFu0s`Zt~pibL;h%{eQl?}S8J#7HJix_NC^gz zh6GiYtN(!a`*wesFswSDd9&X1Gru=7&HAXRgqd>P$-TWrd_{zh>c>jmOHMD@DY0cY z)O0(8iAw+`u6?|trmC#XT)~0 zqwlp9+cAU$BJC2qb>>T1FQflL6m)rc9u{Mli6NR{^ap(cWgKTpfFc=!WSsg2v~0L8 zi^j_z1#;p=lss3d2tl(sOU;h=K|{vWk=Iycyv^Bs8&VrTM_;t*QGVc2#r)#}RwssE zi!PocnX4lDe;U56iSUWna@tQaj<$co+iO2N=*daUEbNQX=wYq4ga)f>ETQ1O10w} z8$$isCm3D;Kx~$^!0e{l=ZMk*FmFOi^}rucr?(R@7PLJvx@5!maM};SWbp2*(G{UC zxGvTTSP%>q%k~L)+uldo*MzpAy3^^vVl|1Zi~eh``Z_$W1~2#!7afz|c9p3!wdVwr z0HncX!lya*7wIA4Y0j!j#hZ9`wQu)ZQ8BpmH|Raw{9>unZ`((JOkwc;xrNo(Y^r)v z5EMJob?M@XiSsYrw;ZMW8@Lt3JjFhwmDzcIi2bSl;P4WM(i;0@%aEfe72l|3l*g3t zXaWcGr22~jgPPJ1yVEw%Nik-GWC}egHFHN{c5)tBPc^j*)935%%%7D(Jpu1M87GB` z&I$uYmhLO;gA6yCiOeHf^O*7o#%OK! z&qg`>1%9l^TZA1Ee2OBqU7ZSj!5J_01=AJy>agDL+(OK9-}Qd zDy*aLP4MgZ-Rz3YweCfbCSeql3lES(5cYCWckWFWzhGVoqYwS~BK~bQqs!eW5CM8(&Zj zxg=~lFlwE+$wJi8MzmJb=NYb@P4jInnsIGy<4OJ2*xusTj*}|em|{l)$zXzM%O3BA zZ%w^~0q(8Hy0g1X8!kBKPwI(0zIdSh5T#3Y@pGOYS$ed!9@)kB6}eKyI2NO?NGUo7 z!WtM#kV?j@{c8b-;aIZc?g>7~@PhOlPO5q783-N(xeNAs!OdcE;tu}e=tLDg-UBk{ zI5@Qg(P}d12!m$+8oiyKcmk=tJ2>)v_lPLHwby+gCc03JQ;WM-dF*e*x0zrQ6S{Ze zo9p8-bi!*mfVdfN_=c3IAG%+IwC|3idF|u)M%Tux{a75CME{NOZTx&`<7+!`Ea>j2!4}ZP zlt%a*35=!pk0h@>r?=2<*^r{@8OsMv=?PcwSEyA1gy`*fIf>DBB*V{-iX9 zPg!-H-RnV30eQQ97F^viW#E}A)xyx0F7ELxiybA;iq$`UXD+sF>kZW6FYOnG_ zfWim=M^6?Xp_ca8Q)x`&+m&l?e|VP7b~P}*5QtMhss3|lhRPsV_uX5-mG&q<_ak5V zOzV=Jy~O0GH@#s77@x`2m9A1i`S4gY<;dM;Vd4vrsa{DsCC;RF7nXUl+qpUTkb)*7 zKTdq-Qt(#6!uV-!jLr{d62?4(m8O|+E4B#p3qudh6;#Z6G*`>rz2C<+jyK<5^b@NY ztzr1ZzUcyx?Bly>%HWB*Z806YB~q2&HZ9t2Nf#ipwV~trE!Uyw>ZmUa>$BUWI#Mz- z`h^t*u}-8Y!iY(CZ;uPk|ZX(5ZB^t`IQfO-e)uXQ+0C|ztXd8hYu=Z z{bXBWYX|#Z#$E`Z;`a)tSqM!Z-aMoUdxLu!fZuQv}SUI!Pyc%^@K!ES@c~@-~fT&+GK3MR#{`ZMxJe za0)Iq6gxFz+gB9M+au=-MMfLA-)y+lTTM5xv+Pb_+pW8tIja1(7X8F?Rl8CBk8}?v z!^+z$$zE`o+3LuM$v;aoY}R)7l8(fK*Wql_sLA9+;mP zGgs;m|9DZLqWXh9Xtpx(;Z$xE24y~}WmeH%6-5{16sZ|x>M2Igwl?%lrZz0k;69Gd zgr1_kl+wuPHh!e^(oILs{h?AvpGME6Crkyyk z?O7B0&V4b;FxRE3a_M(lhFBP#@RtB1MVA-1#r=$okm)#NX=8I^iBR(n&uj zIhw_cxr9?@#db`v?h#shxK8?lC#~9*Lj1@%p+D1rN2Pji-+#hAhivOqtI4_k(@+QK zRw>iV#zU7}Sab~WQZc2f?G`>IfGiupBzSlBK0cvwDyu|3gKUfGE#k^Amr4!)5#VuR}%HzxIn)&=tSj*{!GC77J9w%G1?x9}J`2UhRs3 z0{zJ|?BbM9JAMP|rF(vMJ$|ezguidRfa>$S3D$1aG^$fYHGOp;%#*G8PT9Gj>5!fJ zD3`@8ok*3LOO{dQ$jNxzOTp36l>D{iClB{p{G0CApGahSTFE~#j$sfU>^Br{uZ$_qsv*vtZZJxC+_{ zsS34kSPtmFKEyNJ6b5k)N#^CL4*_QO(lcl>HwNLUjTR2!qXh{%THEjLc z^?^I+M5_8}#rZEoeLL}Q$xL#Kx=_m`F2mu+u%@sds72m;mknKDg>nk@o6LpH39nUHP!sCv1Tu_@k z%dD)njLcUtIgNdvve}Tt~%S~&z2ldUoj2ACMql5qgn#V{O zKXdZ_lYJ4mzhZhrxX-;zy+3AGw4s@o{8bshtC*ESA$&x5zyG5vDsbj_?$-Ldd}hN3 zCO!oj+nl~*uX4jTfoMvOBRT^1Ahen@@2a=C>SU1fD0{KF*%YyLul(?Dxq!AYikI5A zQ!2rLJC>W)p0BouFKcF<#`0_PeBn@d0&gDwVjA08xW9<><3lzvE4PWqDg|_<{TkZ2+u8gD!dVu7akbNQ+2itVA%5pH;ocR5OtTz5bYBo# zRuEoLTbZS?ch?$Wr=Xn6Ubka3tJLqyp|dX)p8BHfd`16My1}L`WDgPJ-}tEpkp`e~ z2hdTtq~OQ_m9*A!&#H;@@RA_YaC+Bxp4<5K;m3$4;7?zv(pS0^m#<=D_&JxLl1JmE z5YapS=RFUH@u(D!M0ZaQ(dV=UPAu=M zS+a5Wmt}}dl>RAwC+X>iR54RfNn7YbjZb1KFK?V^rwxcV5%UCm;qi|lcQHV5`eIIdyWcuEX|NxMzk5b@IgYakiJr5bGBPu%dt zm6r}GPa1#|BDe&k*mvZosws42DrK! zM*BJzH!Z3klBOQL+SFK8C3jo%LECDTyT8hw$LhvNSfo(|>n;r$yMp9cuiNAwWY{aP zg1zOJtJtOS@zcUfn|y-#W@c`~T8Dl=hf!06=s+#a2VA-jahL30C)zbq$1D+p98~8$ zOFIQ=q9g{0|L!=v{0NRqqjWE@@d-uOsa=#%Q?(zB#`bLByKESn@fVVxhAPQ-{R^9N zTkpF`spJBg`E~qFg>GelrqYop4+ZI{O{d%^5mB}C-x>X9MNp_W=6Tb0uj7BVv+mKP zT(PNV5UgO>Gm_~^!*QH@yo;v zYfIyaWv?o8cuUW5a(H+d=bq))%*NqlEF!f2u)&#Zs`L_?Jc9#C_^RU7ZIz=H#}e)9 zAh|`6Q7NE$QQPdI1$5R4K0b|0A|Le0I$nMg+Xc^}Ym!noE!UMhVD)lV>sbq3C2t?0 z7F+i1F0mPUJbJKct}?VL9EfON&Yrm0YZe$X`qa%|#XN?Jp)wbTTO)5!n6Cxw^kjd# z95jO&3!cPYv?och%QqXD&!(Dxu(`S>V7zp(#xVQ?&e+VsUy)gRlMn<*oopnn=N-^H zdXV3JceP;snrVB1a)Qt?sUY{E#Z%YMN?YZ4zryE(T@xB|abb|$d>5LY#izmucSwlf zmf=C{!Z;?5PlfkSD%)O}>1Vz0`SX1J-h;8baggmI1D zq`*{VlbB})JHOqW#`Xs?;6T^Dv7UZ;qs|Vm1J8;b6t;l}<#eAQ3mJw2@&w!}xu^-l zfdnHa|6NR=o@K^&+ezhM`U7NO?A>N3_U+H}lPOISlUs33QkYdTe?D~v7LHWv z@=%qjy%giJ+V^Vx=2GBfuvQ&9)(n|*Er;oY;h_}~YNQ!xj_UhH_+h%!$WElU90_nx zp6?^|HgWnjHyd0$<7XMaUGvLfkdeM}`;Jre_ z@RwC~HT%CYEP|^IEq(U1eP3F%FsAWXx;Oi6G*=s2#Okfg;v2M8krrMe1z{fk!2NIX zrGLM=m!-UQ-kT8$vd6(h_+npscuAb;-6tp?Z|*P9Z3z!m=GZ&T^5F@O2i&LiZ6v@C z?LqHk+|M)0!#|On;lp%k<*oYbaoI)9S)!^9O0DKzqV?Jl6>1}N3F_0sr=3?{r%OUU9P-p z(lgc*X?xv^CS5WB@I`Z)+Acqlb?N?LG;>?ls>7bWzMOBC=$Lo_)#a)~{xAR^(5SU^UdBP%kEhDthlQ&|rJ$UP)WyN|L zhBc?|7@4Nz%?^c^jyVZaEI1v#Y12T6P*LT1=uL{fU#7LJ_fJ)|bKx)w(P8b5AUOc`~cnUA*?OAp5iI=;!P&v|g~g3Vf(dNKn@=jdpn%yZ@47a9djS?dEsJp~c;$T?w~}V8bCa=8ww>T@D-g zm;8zoo`&^b#)qU-a%cSSnD?Gu2%Q1!Xijrhng6O7CjSk|c`sbX-JO-oTHjZZ_4Iif zq%qv+sJ8EMo84ED^OXwMaA#_kSq>doD2w~7X&dYeLn9RL*DHMHKr46D?YT|hFo{9GSbOCU$c_3fl#;h6Wu{k)LaQ(;qusA>QMOvLn zKhdRc*#?wz;l?6cV)nviBFOV@`@FRV-K!pX>bO-!suumoC;q|9pdrM+U3N|-r#1Mv zxjN9Wn2r02k3v+&!nl~=a!sinq502tOKDHuMsgZSNyWWv5dl5Hi z6{pspRvk(Hqv|!ub*F>fCkNUY3+h+g%*;2m#PZn;#|4&~#U}H(p-g8mHbzbVu*K%} zCDm8N*$lvppuzf~2y{Ma#2F3>Kei z<}Yg!u9u4MG+}VpB5f|HS{RS0NsT7zMv-a8-=8REJwqGzmQSIcvG%rf`oXhyZlx19 zQ_s+Ld9bnUO^jN4KENvf8qj_U3oXG%;-k{9_lHljgQ06jD`=;rHdBt5En``I0q!)P zbxHgGJx2+klL=IKN~mxduQxF1Dbrky6GeSqw2Z_* z_aM~>A3V7cz1$mIJ~%pQ$ye9F$n9~op`Lc`+a_F=y4|>vIaqNDq@=tGTF<%lLKzd@ z`}oo#@oW3vk1aMzk`+{C!+4p@`&mj9{QeJ}BY0t{CK8q)5Pg^~p1<{hj3G`<852Pl zep*mk{YT&~d$Z7vBfHY1e=vXJh%j$fcTza-=3lH+so$$y*wUPvzqz=8>?cFs z<*U2QLFbF3a;}KIEcqJi;daXABYrZU^q=QS{KE&R`C&eN$q$>F?7_9?GMT7k z-V>?Cb>OX6EbTV=sGJ}?qSs>5unV(Ry-z-Xb?#%o^J-_wDPcW-Prp3iCE1#EE~ll+ zH5_}C<50trknp<#wUCyr56<)Tz>PdJw#OsZqEh!wP}I34Q2UwK&Nv4(6>fxSz3Sn;E80Tt;Hm>z|-y9W`7JoXh5Si9Q<>3-Fj0SGl-0GQq6&CLhNvxW- z=ih95pjG-+B@Ry=s38Spyie05ONXv@FOiwf^vu^QE62I*B|f(iXlhT-yj0zfmoj

)bNtXB<>| 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 From 33a97bbf0971db5376648a16f2bee107aa4205e9 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Tue, 9 Apr 2024 00:27:09 +0200 Subject: [PATCH 098/175] Some tweaks to text strings --- nf_core/pipelines/create/create.py | 4 ++-- nf_core/pipelines/create/githubexit.py | 2 +- nf_core/pipelines/create/githubrepo.py | 24 +++++++++++------------- nf_core/pipelines/create/welcome.py | 23 +++++++++++------------ 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index 1fd4601ee7..801c203d20 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -267,7 +267,7 @@ def init_pipeline(self): def render_template(self): """Runs Jinja to create a new nf-core pipeline.""" - log.info(f"Creating new nf-core pipeline: '{self.name}'") + log.info(f"Creating new pipeline: '{self.name}'") # Check if the output directory exists if self.outdir.exists(): @@ -536,7 +536,7 @@ def git_init_pipeline(self): "Pipeline git repository will not be initialised." ) - log.info("Initialising pipeline git repository") + log.info("Initialising local pipeline git repository") repo = git.Repo.init(self.outdir) repo.git.add(A=True) repo.index.commit(f"initial template build from nf-core/tools, version {nf_core.__version__}") diff --git a/nf_core/pipelines/create/githubexit.py b/nf_core/pipelines/create/githubexit.py index 79421813f3..3dac88cc5f 100644 --- a/nf_core/pipelines/create/githubexit.py +++ b/nf_core/pipelines/create/githubexit.py @@ -20,7 +20,7 @@ ```bash git push --all origin ``` - * Note the `--all` flag: this is needed to push all branches to the remote. + > 💡 Note the `--all` flag: this is needed to push all branches to the remote. """ diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 656f8c51ea..ec762e181f 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -17,11 +17,6 @@ log = logging.getLogger(__name__) -github_text_markdown = """ -Now that we have created a new pipeline locally, we can create a new -GitHub repository using the GitHub API and push the code to it. -""" - class GithubRepo(Screen): """Create a GitHub repository and push all branches.""" @@ -29,16 +24,19 @@ class GithubRepo(Screen): def compose(self) -> ComposeResult: yield Header() yield Footer() - yield Markdown( - dedent( - """ - # Create GitHub repository - """ - ) + gh_user, gh_token = self._get_github_credentials() + github_text_markdown = dedent( + """ + # Create GitHub repository + + You can optionally create a new GitHub repository and push your + newly created pipeline to it. + """ ) - yield Markdown(dedent(github_text_markdown)) + if gh_user: + github_text_markdown += f">\n> 💡 _Found GitHub username {'and token ' if gh_token else ''}in local [GitHub CLI](https://cli.github.com/) config_\n>\n" + yield Markdown(github_text_markdown) with Horizontal(classes="ghrepo-cols"): - gh_user, gh_token = self._get_github_credentials() yield TextInput( "gh_username", "GitHub username", diff --git a/nf_core/pipelines/create/welcome.py b/nf_core/pipelines/create/welcome.py index 38f29b0411..1da0a3c01d 100644 --- a/nf_core/pipelines/create/welcome.py +++ b/nf_core/pipelines/create/welcome.py @@ -9,18 +9,17 @@ # Welcome to the nf-core pipeline creation wizard This app will help you create a new Nextflow pipeline -from the nf-core pipeline template, part of the -[nf-core/tools repository](https://github.com/nf-core/tools). - -The template _must_ be used for nf-core pipelines, but hopefully -helps all Nextflow developers benefit from nf-core best practices. - -If you want to add a pipeline to nf-core, please -[join on Slack](https://nf-co.re/join) and discuss your plans with the -community as early as possible; _**ideally before you start on your pipeline!**_ -See the [nf-core guidelines](https://nf-co.re/docs/contributing/guidelines) -and the [#new-pipelines](https://nfcore.slack.com/channels/new-pipelines) -Slack channel for more information. +from the [nf-core/tools pipeline template](https://github.com/nf-core/tools). + +The template helps anyone benefit from nf-core best practices, +and is a requirement for nf-core pipelines. + +> 💡 If you want to add a pipeline to nf-core, please +> [join on Slack](https://nf-co.re/join) and discuss your plans with the +> community as early as possible; _**ideally before you start on your pipeline!**_ +> See the [nf-core guidelines](https://nf-co.re/docs/contributing/guidelines) +> and the [#new-pipelines](https://nfcore.slack.com/channels/new-pipelines) +> Slack channel for more information. """ From 1503b12bb447826478416c8910879b01e5753ea6 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Tue, 9 Apr 2024 00:58:20 +0200 Subject: [PATCH 099/175] Whitespace etc --- nf_core/pipelines/create/githubrepo.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 29c008d4da..cbe1891bdf 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -19,14 +19,15 @@ log = logging.getLogger(__name__) github_org_help = """ -> ⚠️ **You can't create a repository directly in the nf-core organisation.** +> ⚠️ **You can't create a repository directly in the nf-core organisation.** > > Please create the pipeline repo to an organisation where you have access or use your user account. > A core-team member will be able to transfer the repo to nf-core once the development has started. -> 💡 Your GitHub user account will be used by default if 'nf-core' is given as the org name. +> 💡 Your GitHub user account will be used by default if `nf-core` is given as the org name. """ + class GithubRepo(Screen): """Create a GitHub repository and push all branches.""" From 0acb2e2d639ffa55ae8d66b42b3c529b03a07839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Thu, 11 Apr 2024 09:09:09 +0000 Subject: [PATCH 100/175] push s allcreens, not switch --- nf_core/pipelines/create/__init__.py | 3 +-- nf_core/pipelines/create/finaldetails.py | 2 +- nf_core/pipelines/create/githubrepo.py | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index 96f027e9fc..c7a4014962 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -87,8 +87,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: elif event.button.id == "github_repo": self.push_screen("github_repo") elif event.button.id == "close_screen": - # Switch screen (not push) to allow viewing old logging messages - self.switch_screen("github_repo_question") + self.push_screen("github_repo_question") elif event.button.id == "exit": self.push_screen("github_exit") if event.button.id == "close_app": diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 86b93423fd..3ea75f419a 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -84,7 +84,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: # Create the new pipeline self._create_pipeline() self.parent.LOGGING_STATE = "pipeline created" - self.parent.switch_screen(LoggingScreen()) + self.parent.push_screen(LoggingScreen()) class PipelineExists(Message): """Custom message to indicate that the pipeline already exists.""" diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index cbe1891bdf..3e3144b4e9 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -185,10 +185,10 @@ def on_button_pressed(self, event: Button.Pressed) -> None: ) except UserWarning as e: log.error(f"There was an error with message: {e}") - self.parent.switch_screen("github_exit") + self.parent.push_screen("github_exit") self.parent.LOGGING_STATE = "repo created" - self.parent.switch_screen(LoggingScreen()) + self.parent.push_screen(LoggingScreen()) class RepoExists(Message): """Custom message to indicate that the GitHub repo already exists.""" From 5fcedccfa26aa4d6d6ea070ba7a92abb2eb5b5bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Thu, 11 Apr 2024 09:12:48 +0000 Subject: [PATCH 101/175] always push files to the remote repo --- nf_core/pipelines/create/githubrepo.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index 3e3144b4e9..fafb66a4ef 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -86,14 +86,6 @@ def compose(self) -> ComposeResult: with Vertical(): yield Static("Private", classes="") yield Static("Select to make the new GitHub repo private.", classes="feature_subtitle") - with Horizontal(classes="ghrepo-cols"): - yield Switch(value=True, id="push") - with Vertical(): - yield Static("Push files", classes="custom_grid") - yield Static( - "Select to push pipeline files and branches to your GitHub repo.", - classes="feature_subtitle", - ) yield Center( Button("Back", id="back", variant="default"), Button("Create GitHub repo", id="create_github", variant="success"), @@ -169,7 +161,6 @@ def on_button_pressed(self, event: Button.Pressed) -> None: github_variables["repo_name"], pipeline_repo, github_variables["private"], - github_variables["push"], ) else: # Create the repo in the user's account @@ -181,7 +172,6 @@ def on_button_pressed(self, event: Button.Pressed) -> None: github_variables["repo_name"], pipeline_repo, github_variables["private"], - github_variables["push"], ) except UserWarning as e: log.error(f"There was an error with message: {e}") @@ -201,7 +191,7 @@ def show_github_info_button(self) -> None: add_hide_class(self.parent, "close_app") @work(thread=True, exclusive=True) - def _create_repo_and_push(self, org, repo_name, pipeline_repo, private, push): + def _create_repo_and_push(self, org, repo_name, pipeline_repo, private): """Create a GitHub repository and push all branches.""" self.post_message(ShowLogs()) # Check if repo already exists @@ -230,14 +220,14 @@ def _create_repo_and_push(self, org, repo_name, pipeline_repo, private, push): self.parent.call_from_thread(change_select_disabled, self.parent, "close_app", False) add_hide_class(self.parent, "exit") - # Add the remote and push + # Add the remote try: pipeline_repo.create_remote("origin", repo.clone_url) except git.exc.GitCommandError: # Remote already exists pass - if push: - pipeline_repo.remotes.origin.push(all=True).raise_if_error() + # Push all branches + pipeline_repo.remotes.origin.push(all=True).raise_if_error() def _github_authentication(self, gh_username, gh_token): """Authenticate to GitHub""" From c2381ae6b10b8faf09fe87b221b11c4c4da377e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Thu, 11 Apr 2024 10:22:52 +0000 Subject: [PATCH 102/175] fix going back from nf-core to custom pipeline --- nf_core/pipelines/create/basicdetails.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py index 3f319b58f6..deb22b48b3 100644 --- a/nf_core/pipelines/create/basicdetails.py +++ b/nf_core/pipelines/create/basicdetails.py @@ -77,3 +77,9 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.parent.push_screen("type_custom") except ValueError: pass + + def on_screen_resume(self): + """Update displayed value on screen resume""" + for text_input in self.query("TextInput"): + if text_input.field_id == "org": + text_input.disabled = self.parent.PIPELINE_TYPE == "nfcore" From 30f6c5a2f0d9261a72e54de2ad2ee3c2537f79bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Thu, 11 Apr 2024 12:20:59 +0000 Subject: [PATCH 103/175] fix logging screen by using a class to hide buttons --- nf_core/pipelines/create/__init__.py | 1 + nf_core/pipelines/create/finaldetails.py | 11 +++---- nf_core/pipelines/create/githubrepo.py | 12 ++++---- nf_core/pipelines/create/loggingscreen.py | 35 ++++++++++++----------- nf_core/pipelines/create/utils.py | 10 +++---- 5 files changed, 33 insertions(+), 36 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index c7a4014962..da6a693220 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -53,6 +53,7 @@ class PipelineCreateApp(App[CreateConfig]): "type_custom": CustomPipeline(), "type_nfcore": NfcorePipeline(), "final_details": FinalDetails(), + "logging": LoggingScreen(), "github_repo_question": GithubRepoQuestion(), "github_repo": GithubRepo(), "github_exit": GithubExit(), diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index 3ea75f419a..d894d9a5f5 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -10,8 +10,7 @@ from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch from nf_core.pipelines.create.create import PipelineCreate -from nf_core.pipelines.create.loggingscreen import LoggingScreen -from nf_core.pipelines.create.utils import ShowLogs, TextInput, add_hide_class, change_select_disabled +from nf_core.pipelines.create.utils import ShowLogs, TextInput, remove_hide_class class FinalDetails(Screen): @@ -84,7 +83,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: # Create the new pipeline self._create_pipeline() self.parent.LOGGING_STATE = "pipeline created" - self.parent.push_screen(LoggingScreen()) + self.parent.push_screen("logging") class PipelineExists(Message): """Custom message to indicate that the pipeline already exists.""" @@ -93,8 +92,7 @@ class PipelineExists(Message): @on(PipelineExists) def show_back_button(self) -> None: - change_select_disabled(self.parent, "back", False) - add_hide_class(self.parent, "close_screen") + remove_hide_class(self.parent, "back") @work(thread=True, exclusive=True) def _create_pipeline(self) -> None: @@ -106,7 +104,6 @@ def _create_pipeline(self) -> None: ) try: create_obj.init_pipeline() - self.parent.call_from_thread(change_select_disabled, self.parent, "close_screen", False) - add_hide_class(self.parent, "back") + remove_hide_class(self.parent, "close_screen") except UserWarning: self.post_message(self.PipelineExists()) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index fafb66a4ef..bac63c1f4e 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -13,8 +13,7 @@ from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch -from nf_core.pipelines.create.loggingscreen import LoggingScreen -from nf_core.pipelines.create.utils import ShowLogs, TextInput, add_hide_class, change_select_disabled +from nf_core.pipelines.create.utils import ShowLogs, TextInput, remove_hide_class log = logging.getLogger(__name__) @@ -178,7 +177,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.parent.push_screen("github_exit") self.parent.LOGGING_STATE = "repo created" - self.parent.push_screen(LoggingScreen()) + self.parent.push_screen("logging") class RepoExists(Message): """Custom message to indicate that the GitHub repo already exists.""" @@ -187,8 +186,8 @@ class RepoExists(Message): @on(RepoExists) def show_github_info_button(self) -> None: - change_select_disabled(self.parent, "exit", False) - add_hide_class(self.parent, "close_app") + remove_hide_class(self.parent, "exit") + remove_hide_class(self.parent, "back") @work(thread=True, exclusive=True) def _create_repo_and_push(self, org, repo_name, pipeline_repo, private): @@ -217,8 +216,7 @@ def _create_repo_and_push(self, org, repo_name, pipeline_repo, private): if not repo_exists: repo = org.create_repo(repo_name, description=self.parent.TEMPLATE_CONFIG.description, private=private) log.info(f"GitHub repository '{repo_name}' created successfully") - self.parent.call_from_thread(change_select_disabled, self.parent, "close_app", False) - add_hide_class(self.parent, "exit") + remove_hide_class(self.parent, "close_app") # Add the remote try: diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index a862852d75..ae9b5244f9 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -5,6 +5,7 @@ from textual.screen import Screen from textual.widgets import Button, Footer, Header, Markdown, Static +from nf_core.pipelines.create.utils import add_hide_class from nf_core.utils import nfcore_logo @@ -25,21 +26,21 @@ def compose(self) -> ComposeResult: "\n" + "\n".join(nfcore_logo) + "\n", id="logo", ) - if self.parent.LOGGING_STATE == "repo created": - yield Markdown("Creating GitHub repository..") - else: - yield Markdown("Creating pipeline..") - self.parent.LOG_HANDLER.console.clear() + yield Markdown("Creating...") yield Center(self.parent.LOG_HANDLER.console) - if self.parent.LOGGING_STATE == "repo created": - yield Center( - Button("Continue", id="exit", variant="success", disabled=True), - Button("Close App", id="close_app", variant="success", disabled=True), - classes="cta", - ) - else: - yield Center( - Button("Back", id="back", variant="default", disabled=True), - Button("Continue", id="close_screen", variant="success", disabled=True), - classes="cta", - ) + yield Center( + Button("Back", id="back", variant="default", classes="hide"), + Button("Continue", id="close_screen", variant="success", classes="hide"), + Button("Continue", id="exit", variant="success", classes="hide"), + Button("Close App", id="close_app", variant="success", classes="hide"), + classes="cta", + ) + + def on_screen_resume(self): + """Clear console on screen resume. + Hide all buttons as disabled on screen resume.""" + self.parent.LOG_HANDLER.console.clear() + button_ids = ["back", "close_screen", "exit", "close_app"] + for button in self.query("Button"): + if button.id in button_ids: + add_hide_class(self.parent, button.id) diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 7b332615fa..670aa585f5 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -201,16 +201,16 @@ class ShowLogs(Message): ## Functions -def change_select_disabled(app, widget_id: str, disabled: bool) -> None: - """Change the disabled state of a widget.""" - app.get_widget_by_id(widget_id).disabled = disabled - - def add_hide_class(app, widget_id: str) -> None: """Add class 'hide' to a widget. Not display widget.""" app.get_widget_by_id(widget_id).add_class("hide") +def remove_hide_class(app, widget_id: str) -> None: + """Remove class 'hide' to a widget. Display widget.""" + app.get_widget_by_id(widget_id).remove_class("hide") + + ## Markdown text to reuse in different screens markdown_genomes = """ Nf-core pipelines are configured to use a copy of the most common reference genome files. From bf14b4e1bd181b2cbdf24cfab0d84dbb99a201c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Fri, 12 Apr 2024 11:51:07 +0000 Subject: [PATCH 104/175] remove force switch and always force, show warning --- nf_core/pipelines/create/basicdetails.py | 39 ++++++++++++--- nf_core/pipelines/create/finaldetails.py | 61 ++++++++++++----------- nf_core/pipelines/create/loggingscreen.py | 8 +-- nf_core/pipelines/create/utils.py | 2 +- 4 files changed, 69 insertions(+), 41 deletions(-) diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py index deb22b48b3..b88ede10d0 100644 --- a/nf_core/pipelines/create/basicdetails.py +++ b/nf_core/pipelines/create/basicdetails.py @@ -1,5 +1,6 @@ """A Textual app to create a pipeline.""" +from pathlib import Path from textwrap import dedent from textual import on @@ -8,7 +9,14 @@ from textual.screen import Screen from textual.widgets import Button, Footer, Header, Input, Markdown -from nf_core.pipelines.create.utils import CreateConfig, TextInput +from nf_core.pipelines.create.utils import CreateConfig, TextInput, add_hide_class, remove_hide_class + +pipeline_exists_warn = """ +> ⚠️ **The pipeline you are trying to create already exists.** +> +> If you continue, you will **override** the existing pipeline. +> Please change the pipeline or organisation name to create a different pipeline. +""" class BasicDetails(Screen): @@ -50,12 +58,35 @@ def compose(self) -> ComposeResult: "Author(s)", "Name of the main author / authors", ) + yield Markdown(dedent(pipeline_exists_warn), id="exist_warn", classes="hide") yield Center( Button("Back", id="back", variant="default"), Button("Next", id="next", variant="success"), classes="cta", ) + @on(Input.Changed) + @on(Input.Submitted) + def show_exists_warn(self): + """Check if the pipeline exists on every input change or submitted. + If the pipeline exists, show warning message saying that it will be overriden.""" + config = {} + for text_input in self.query("TextInput"): + this_input = text_input.query_one(Input) + config[text_input.field_id] = this_input.value + if Path(config["org"] + "-" + config["name"]).is_dir(): + remove_hide_class(self.parent, "exist_warn") + else: + add_hide_class(self.parent, "exist_warn") + + def on_screen_resume(self): + """Hide warn message on screen resume. + Update displayed value on screen resume.""" + add_hide_class(self.parent, "exist_warn") + for text_input in self.query("TextInput"): + if text_input.field_id == "org": + text_input.disabled = self.parent.PIPELINE_TYPE == "nfcore" + @on(Button.Pressed) def on_button_pressed(self, event: Button.Pressed) -> None: """Save fields to the config.""" @@ -77,9 +108,3 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.parent.push_screen("type_custom") except ValueError: pass - - def on_screen_resume(self): - """Update displayed value on screen resume""" - for text_input in self.query("TextInput"): - if text_input.field_id == "org": - text_input.disabled = self.parent.PIPELINE_TYPE == "nfcore" diff --git a/nf_core/pipelines/create/finaldetails.py b/nf_core/pipelines/create/finaldetails.py index d894d9a5f5..bd15cf9ddd 100644 --- a/nf_core/pipelines/create/finaldetails.py +++ b/nf_core/pipelines/create/finaldetails.py @@ -1,16 +1,24 @@ """A Textual app to create a pipeline.""" +from pathlib import Path from textwrap import dedent from textual import on, work from textual.app import ComposeResult -from textual.containers import Center, Horizontal, Vertical -from textual.message import Message +from textual.containers import Center, Horizontal from textual.screen import Screen -from textual.widgets import Button, Footer, Header, Input, Markdown, Static, Switch +from textual.widgets import Button, Footer, Header, Input, Markdown from nf_core.pipelines.create.create import PipelineCreate -from nf_core.pipelines.create.utils import ShowLogs, TextInput, remove_hide_class +from nf_core.pipelines.create.utils import ShowLogs, TextInput, add_hide_class, remove_hide_class + +pipeline_exists_warn = """ +> ⚠️ **The pipeline you are trying to create already exists.** +> +> If you continue, you will **override** the existing pipeline. +> Please change the pipeline or organisation name to create a different pipeline. +> Alternatively, provide a different output directory. +""" class FinalDetails(Screen): @@ -42,14 +50,8 @@ def compose(self) -> ComposeResult: ".", classes="column", ) - with Horizontal(): - yield Switch(value=False, id="force") - with Vertical(): - yield Static("Force creation", classes="custom_grid") - yield Static( - "Overwrite any existing pipeline output directories.", - classes="feature_subtitle", - ) + + yield Markdown(dedent(pipeline_exists_warn), id="exist_warn", classes="hide") yield Center( Button("Back", id="back", variant="default"), @@ -74,25 +76,27 @@ def on_button_pressed(self, event: Button.Pressed) -> None: except ValueError: pass - this_switch = self.query_one(Switch) - try: - self.parent.TEMPLATE_CONFIG.__dict__.update({"force": this_switch.value}) - except ValueError: - pass - # Create the new pipeline self._create_pipeline() self.parent.LOGGING_STATE = "pipeline created" self.parent.push_screen("logging") - class PipelineExists(Message): - """Custom message to indicate that the pipeline already exists.""" - - pass + @on(Input.Changed) + @on(Input.Submitted) + def show_exists_warn(self): + """Check if the pipeline exists on every input change or submitted. + If the pipeline exists, show warning message saying that it will be overriden.""" + outdir = "" + for text_input in self.query("TextInput"): + this_input = text_input.query_one(Input) + if text_input.field_id == "outdir": + outdir = this_input.value + if Path(outdir, self.parent.TEMPLATE_CONFIG.org + "-" + self.parent.TEMPLATE_CONFIG.name).is_dir(): + remove_hide_class(self.parent, "exist_warn") - @on(PipelineExists) - def show_back_button(self) -> None: - remove_hide_class(self.parent, "back") + def on_screen_resume(self): + """Hide warn message on screen resume.""" + add_hide_class(self.parent, "exist_warn") @work(thread=True, exclusive=True) def _create_pipeline(self) -> None: @@ -102,8 +106,5 @@ def _create_pipeline(self) -> None: template_config=self.parent.TEMPLATE_CONFIG, is_interactive=True, ) - try: - create_obj.init_pipeline() - remove_hide_class(self.parent, "close_screen") - except UserWarning: - self.post_message(self.PipelineExists()) + create_obj.init_pipeline() + remove_hide_class(self.parent, "close_screen") diff --git a/nf_core/pipelines/create/loggingscreen.py b/nf_core/pipelines/create/loggingscreen.py index ae9b5244f9..f862dccea1 100644 --- a/nf_core/pipelines/create/loggingscreen.py +++ b/nf_core/pipelines/create/loggingscreen.py @@ -37,10 +37,12 @@ def compose(self) -> ComposeResult: ) def on_screen_resume(self): - """Clear console on screen resume. - Hide all buttons as disabled on screen resume.""" - self.parent.LOG_HANDLER.console.clear() + """Hide all buttons as disabled on screen resume.""" button_ids = ["back", "close_screen", "exit", "close_app"] for button in self.query("Button"): if button.id in button_ids: add_hide_class(self.parent, button.id) + + def on_screen_suspend(self): + """Clear console on screen suspend.""" + self.parent.LOG_HANDLER.console.clear() diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 670aa585f5..6006452baf 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -23,7 +23,7 @@ class CreateConfig(BaseModel): description: Optional[str] = None author: Optional[str] = None version: Optional[str] = None - force: Optional[bool] = None + force: Optional[bool] = True outdir: Optional[str] = None skip_features: Optional[list] = None is_nfcore: Optional[bool] = None From b1412cf39af03f52e8302d95c805db121433c6a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Fri, 12 Apr 2024 11:59:13 +0000 Subject: [PATCH 105/175] add warning if github org not found --- nf_core/pipelines/create/githubrepo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index bac63c1f4e..ddf7bf90f4 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -150,7 +150,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: f"Repo will be created in the GitHub organisation account '{github_variables['repo_org']}'" ) except UnknownObjectException: - pass + log.warn(f"Provided organisation '{github_variables['repo_org']}' not found. ") # Create the repo try: From 7cc3757198974574834df992ebd747251443ecca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Fri, 12 Apr 2024 14:46:46 +0000 Subject: [PATCH 106/175] update snapshots --- tests/__snapshots__/test_create_app.ambr | 1181 ++++------------------ 1 file changed, 209 insertions(+), 972 deletions(-) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index 3477a381a4..ecf8cd0336 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1133,809 +1133,252 @@ font-weight: 700; } - .terminal-3970307065-matrix { + .terminal-596440806-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3970307065-title { + .terminal-596440806-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3970307065-r1 { fill: #c5c8c6 } - .terminal-3970307065-r2 { fill: #e3e3e3 } - .terminal-3970307065-r3 { fill: #989898 } - .terminal-3970307065-r4 { fill: #e1e1e1 } - .terminal-3970307065-r5 { fill: #121212 } - .terminal-3970307065-r6 { fill: #0053aa } - .terminal-3970307065-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3970307065-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-3970307065-r9 { fill: #1e1e1e } - .terminal-3970307065-r10 { fill: #008139 } - .terminal-3970307065-r11 { fill: #e2e2e2 } - .terminal-3970307065-r12 { fill: #b93c5b } - .terminal-3970307065-r13 { fill: #808080 } - .terminal-3970307065-r14 { fill: #454a50 } - .terminal-3970307065-r15 { fill: #7ae998 } - .terminal-3970307065-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-3970307065-r17 { fill: #0a180e;font-weight: bold } - .terminal-3970307065-r18 { fill: #000000 } - .terminal-3970307065-r19 { fill: #ddedf9 } + .terminal-596440806-r1 { fill: #c5c8c6 } + .terminal-596440806-r2 { fill: #e3e3e3 } + .terminal-596440806-r3 { fill: #989898 } + .terminal-596440806-r4 { fill: #e1e1e1 } + .terminal-596440806-r5 { fill: #121212 } + .terminal-596440806-r6 { fill: #0053aa } + .terminal-596440806-r7 { fill: #dde8f3;font-weight: bold } + .terminal-596440806-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-596440806-r9 { fill: #1e1e1e } + .terminal-596440806-r10 { fill: #008139 } + .terminal-596440806-r11 { fill: #e2e2e2 } + .terminal-596440806-r12 { fill: #b93c5b } + .terminal-596440806-r13 { fill: #454a50 } + .terminal-596440806-r14 { fill: #7ae998 } + .terminal-596440806-r15 { fill: #e2e3e3;font-weight: bold } + .terminal-596440806-r16 { fill: #0a180e;font-weight: bold } + .terminal-596440806-r17 { fill: #000000 } + .terminal-596440806-r18 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Final details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - First version of the pipelinePath to the output directory where the pipeline  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created - 1.0.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔Force creation - Overwrite any existing pipeline output directories. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackFinish - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  - - - - - ''' -# --- -# name: test_github_details - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - nf-core create - - - - - - - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - Now that we have created a new pipeline locally, we can create a new GitHub repository using - the GitHub API and push the code to it. - - - - Your GitHub usernameYour GitHub personal access token - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - The name of the organisation where the The name of the new GitHub repository - GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline - nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - You can't create a repository to the nf-core organisation. Please create the pipeline repo  - to an organisation where you have access or use your user account. A core-team member will  - be able to transfer the repo to nf-core once the development has started. You user account  - will be used by default if 'nf-core' is provided. - - - ▔▔▔▔▔▔▔▔Private - Select to make the new GitHub repo private. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔Push files - Select to push pipeline files and branches to your GitHub repo. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackCreate GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - -  D  Toggle dark mode  Q  Quit  - - - - - ''' -# --- -# name: test_github_exit_message - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - nf-core create - - - - - - - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - HowTo create a GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - -                                           ,--./,-. -           ___     __   __   __   ___     /,-._.--~\  -     |\ | |__  __ /  ` /  \ |__) |__         }  { -     | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                           `._,._,' - - If you would like to create the GitHub repository later, you can do it manually by following - these steps: - -  1. Create a new GitHub repository -  2. Add the remote to your local repository: - - - cd<pipeline_directory> - gitremoteaddorigingit@github.com:<username>/<repo_name>.git - - -  3. Push the code to the remote: - - - gitpush--allorigin - - - ● Note the --all flag: this is needed to push all branches to the remote. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Final details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + First version of the pipelinePath to the output directory where the pipeline  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created + 1.0.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackFinish + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -1944,7 +1387,7 @@ # --- # name: test_github_question ''' - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - After creating the pipeline template locally, we can create a GitHub repository and push the - code to it. - - Do you want to create a GitHub repository? - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Create GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + @@ -3069,147 +2304,149 @@ font-weight: 700; } - .terminal-2790734285-matrix { + .terminal-3553059683-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2790734285-title { + .terminal-3553059683-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2790734285-r1 { fill: #c5c8c6 } - .terminal-2790734285-r2 { fill: #e3e3e3 } - .terminal-2790734285-r3 { fill: #989898 } - .terminal-2790734285-r4 { fill: #1e1e1e } - .terminal-2790734285-r5 { fill: #98e024 } - .terminal-2790734285-r6 { fill: #626262 } - .terminal-2790734285-r7 { fill: #9d65ff } - .terminal-2790734285-r8 { fill: #fd971f } - .terminal-2790734285-r9 { fill: #e1e1e1 } - .terminal-2790734285-r10 { fill: #121212 } - .terminal-2790734285-r11 { fill: #0053aa } - .terminal-2790734285-r12 { fill: #dde8f3;font-weight: bold } - .terminal-2790734285-r13 { fill: #e1e1e1;text-decoration: underline; } - .terminal-2790734285-r14 { fill: #e1e1e1;font-style: italic; } - .terminal-2790734285-r15 { fill: #14191f } - .terminal-2790734285-r16 { fill: #e1e1e1;font-weight: bold;font-style: italic; } - .terminal-2790734285-r17 { fill: #ddedf9 } + .terminal-3553059683-r1 { fill: #c5c8c6 } + .terminal-3553059683-r2 { fill: #e3e3e3 } + .terminal-3553059683-r3 { fill: #989898 } + .terminal-3553059683-r4 { fill: #1e1e1e } + .terminal-3553059683-r5 { fill: #98e024 } + .terminal-3553059683-r6 { fill: #626262 } + .terminal-3553059683-r7 { fill: #9d65ff } + .terminal-3553059683-r8 { fill: #fd971f } + .terminal-3553059683-r9 { fill: #e1e1e1 } + .terminal-3553059683-r10 { fill: #121212 } + .terminal-3553059683-r11 { fill: #0053aa } + .terminal-3553059683-r12 { fill: #dde8f3;font-weight: bold } + .terminal-3553059683-r13 { fill: #e1e1e1;text-decoration: underline; } + .terminal-3553059683-r14 { fill: #14191f } + .terminal-3553059683-r15 { fill: #4ebf71 } + .terminal-3553059683-r16 { fill: #e2e2e2 } + .terminal-3553059683-r17 { fill: #e2e2e2;text-decoration: underline; } + .terminal-3553059683-r18 { fill: #e2e2e2;font-weight: bold;font-style: italic; } + .terminal-3553059683-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pip… - -                                           ,--./,-. -           ___     __   __   __   ___     /,-._.--~\  -     |\ | |__  __ /  ` /  \ |__) |__         }  { -     | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                           `._,._,' - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Welcome to the nf-core pipeline creation wizard - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - This app will help you create a new Nextflow pipeline from the nf-core - pipeline template, part of the nf-core/tools repository. - - The template must be used for nf-core pipelines, but hopefully helps  - all Nextflow developers benefit from nf-core best practices. - - If you want to add a pipeline to nf-core, please join on Slack and ▆▆ - discuss your plans with the community as early as possible; ideally  - before you start on your pipeline! See the nf-core guidelines and the  - #new-pipelines Slack channel for more information. -  D Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pip… + +                                           ,--./,-. +           ___     __   __   __   ___     /,-._.--~\  +     |\ | |__  __ /  ` /  \ |__) |__         }  { +     | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                           `._,._,' + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Welcome to the nf-core pipeline creation wizard + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This app will help you create a new Nextflow pipeline from the  + nf-core/tools pipeline template. + + The template helps anyone benefit from nf-core best practices, and is  + a requirement for nf-core pipelines. + ▃▃ + 💡 If you want to add a pipeline to nf-core, please join on Slack + and discuss your plans with the community as early as possible;  + ideally before you start on your pipeline! See the nf-core  + guidelines and the #new-pipelines Slack channel for more  +  D Toggle dark mode  Q  Quit  From 0bd18070be88542b735b5ef719512a7682037d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Mon, 15 Apr 2024 17:36:21 +0000 Subject: [PATCH 107/175] fix providing outdir --- nf_core/pipelines/create/create.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index 801c203d20..3fb86e88f0 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -105,9 +105,9 @@ def __init__( self.default_branch = default_branch self.is_interactive = is_interactive self.force = self.config.force - if outdir is None: - outdir = os.path.join(os.getcwd(), self.jinja_params["name_noslash"]) - self.outdir = Path(outdir) + if self.config.outdir is None: + self.config.outdir = os.getcwd() + self.outdir = Path(self.config.outdir, self.jinja_params["name_noslash"]).absolute() def check_template_yaml_info(self, template_yaml, name, description, author): """Ensure that the provided template yaml file contains the necessary information. @@ -367,7 +367,7 @@ def render_template(self): if self.config: config_fn, config_yml = nf_core.utils.load_tools_config(self.outdir) - with open(self.outdir / config_fn, "w") as fh: + with open(config_fn, "w") as fh: config_yml.update(template=self.config.model_dump()) yaml.safe_dump(config_yml, fh) log.debug(f"Dumping pipeline template yml to pipeline config file '{config_fn.name}'") From 9976440e6d8b5f4a49b1673a7347e3ab663d173a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Mon, 15 Apr 2024 18:08:28 +0000 Subject: [PATCH 108/175] try fixing pytests by using tmpdir instead of mock --- tests/__snapshots__/test_create_app.ambr | 792 ++++++++++++++++++++++- tests/test_create_app.py | 26 +- 2 files changed, 798 insertions(+), 20 deletions(-) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index ecf8cd0336..b2af13b11b 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1385,9 +1385,569 @@ ''' # --- +# name: test_github_details + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Now that we have created a new pipeline locally, we can create a new GitHub repository and  + push the code to it. + + + + Your GitHub usernameYour GitHub personal access token + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁••••••••••••▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + The name of the organisation where the The name of the new GitHub repository + GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline + nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + ⚠️ You can't create a repository directly in the nf-core organisation. + Please create the pipeline repo to an organisation where you have access or use your user + account. A core-team member will be able to transfer the repo to nf-core once the  + development has started. + + 💡 Your GitHub user account will be used by default if nf-core is given as the org name. + + + ▔▔▔▔▔▔▔▔Private + Select to make the new GitHub repo private. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackCreate GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_github_exit_message + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + HowTo create a GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + +                                           ,--./,-. +           ___     __   __   __   ___     /,-._.--~\  +     |\ | |__  __ /  ` /  \ |__) |__         }  { +     | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                           `._,._,' + + If you would like to create the GitHub repository later, you can do it manually by following + these steps: + +  1. Create a new GitHub repository +  2. Add the remote to your local repository: + + + cd<pipeline_directory> + gitremoteaddorigingit@github.com:<username>/<repo_name>.git + + +  3. Push the code to the remote: + + + gitpush--allorigin + + + 💡 Note the --all flag: this is needed to push all branches to the remote. + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- # name: test_github_question ''' - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - nf-core create + nf-core create - - - - + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + After creating the pipeline template locally, we can create a GitHub repository and push the + code to it. + + Do you want to create a GitHub repository? + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Create GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  diff --git a/tests/test_create_app.py b/tests/test_create_app.py index 124078cec1..92fb52e43f 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -1,7 +1,5 @@ """Test Pipeline Create App""" -from unittest import mock - import pytest from nf_core.pipelines.create import PipelineCreateApp @@ -189,8 +187,7 @@ async def run_before(pilot) -> None: assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) -@mock.patch("nf_core.pipelines.create.create.PipelineCreate.init_pipeline", return_value=None) -def test_github_question(mock_init_pipeline, snap_compare): +def test_github_question(tmpdir, snap_compare): """Test snapshot for the github_repo_question screen. Steps to get to this screen: screen welcome > press start > @@ -212,14 +209,18 @@ async def run_before(pilot) -> None: await pilot.press("M", "e") await pilot.click("#next") await pilot.click("#continue") + await pilot.press("backspace") + await pilot.press("tab") + await pilot.press(*str(tmpdir)) await pilot.click("#finish") + pilot.app.get_widget_by_id("close_screen").remove_class("hide") + await pilot.pause() await pilot.click("#close_screen") assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) -@mock.patch("nf_core.pipelines.create.create.PipelineCreate.init_pipeline", return_value=None) -def test_github_details(mock_init_pipeline, snap_compare): +def test_github_details(tmpdir, snap_compare): """Test snapshot for the github_repo screen. Steps to get to this screen: screen welcome > press start > @@ -243,7 +244,12 @@ async def run_before(pilot) -> None: await pilot.press("M", "e") await pilot.click("#next") await pilot.click("#continue") + await pilot.press("backspace") + await pilot.press("tab") + await pilot.press(*str(tmpdir)) await pilot.click("#finish") + pilot.app.get_widget_by_id("close_screen").remove_class("hide") + await pilot.pause() await pilot.click("#close_screen") await pilot.click("#github_repo") await pilot.click("#gh_username") @@ -254,8 +260,7 @@ async def run_before(pilot) -> None: assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) -@mock.patch("nf_core.pipelines.create.create.PipelineCreate.init_pipeline", return_value=None) -def test_github_exit_message(mock_init_pipeline, snap_compare): +def test_github_exit_message(tmpdir, snap_compare): """Test snapshot for the github_exit screen. Steps to get to this screen: screen welcome > press start > @@ -279,7 +284,12 @@ async def run_before(pilot) -> None: await pilot.press("M", "e") await pilot.click("#next") await pilot.click("#continue") + await pilot.press("backspace") + await pilot.press("tab") + await pilot.press(*str(tmpdir)) await pilot.click("#finish") + pilot.app.get_widget_by_id("close_screen").remove_class("hide") + await pilot.pause() await pilot.click("#close_screen") await pilot.click("#github_repo") await pilot.click("#exit") From 777f68c7c9060b9ddaa405695fa8314a5cf65092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Tue, 16 Apr 2024 10:42:16 +0000 Subject: [PATCH 109/175] fix outdir again to fix tests --- nf_core/pipelines/create/create.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index 3fb86e88f0..cd86c9a361 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -107,7 +107,7 @@ def __init__( self.force = self.config.force if self.config.outdir is None: self.config.outdir = os.getcwd() - self.outdir = Path(self.config.outdir, self.jinja_params["name_noslash"]).absolute() + self.outdir = Path(self.config.outdir).absolute() def check_template_yaml_info(self, template_yaml, name, description, author): """Ensure that the provided template yaml file contains the necessary information. From e7d38867611490042f6b220f7f17202c5fcb2df5 Mon Sep 17 00:00:00 2001 From: mashehu Date: Wed, 17 Apr 2024 12:42:38 +0200 Subject: [PATCH 110/175] debugging ci tests --- .github/workflows/create-test-wf.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index 3aa2e3eb47..f2c25a2be3 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -71,6 +71,10 @@ jobs: mkdir create-test-wf && cd create-test-wf export NXF_WORK=$(pwd) nf-core --log-file log.txt pipelines create -n testpipeline -d "This pipeline is for testing" -a "Testing McTestface" + # echo current directory + pwd + # echo content of current directory + ls -la nextflow run nf-core-testpipeline -profile test,self_hosted_runner --outdir ./results - name: Upload log file artifact From 6b83de8c53b0362ca070c72681bc91090ea65f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 17 Apr 2024 15:35:55 +0000 Subject: [PATCH 111/175] try fixing outdir, again --- nf_core/pipelines/create/create.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nf_core/pipelines/create/create.py b/nf_core/pipelines/create/create.py index cd86c9a361..151ad83ff2 100644 --- a/nf_core/pipelines/create/create.py +++ b/nf_core/pipelines/create/create.py @@ -107,7 +107,10 @@ def __init__( self.force = self.config.force if self.config.outdir is None: self.config.outdir = os.getcwd() - self.outdir = Path(self.config.outdir).absolute() + if self.config.outdir == ".": + self.outdir = Path(self.config.outdir, self.jinja_params["name_noslash"]).absolute() + else: + self.outdir = Path(self.config.outdir).absolute() def check_template_yaml_info(self, template_yaml, name, description, author): """Ensure that the provided template yaml file contains the necessary information. From 20b824d3f65fa95a9385b903bbe187ae190a8255 Mon Sep 17 00:00:00 2001 From: Niklas Schandry Date: Fri, 26 Apr 2024 12:04:24 +0200 Subject: [PATCH 112/175] Add charliecloud.registry --- nf_core/pipeline-template/nextflow.config | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nf_core/pipeline-template/nextflow.config b/nf_core/pipeline-template/nextflow.config index 17e75f18a4..f097cc2ff6 100644 --- a/nf_core/pipeline-template/nextflow.config +++ b/nf_core/pipeline-template/nextflow.config @@ -184,11 +184,11 @@ profiles { // Set default registry for Apptainer, Docker, Podman and Singularity independent of -profile // Will not be used unless Apptainer / Docker / Podman / Singularity are enabled // Set to your registry if you have a mirror of containers -apptainer.registry = 'quay.io' -docker.registry = 'quay.io' -podman.registry = 'quay.io' -singularity.registry = 'quay.io' - +apptainer.registry = 'quay.io' +docker.registry = 'quay.io' +podman.registry = 'quay.io' +singularity.registry = 'quay.io' +charliecloud.registry = 'quay.io' // Nextflow plugins plugins { id 'nf-validation@1.1.3' // Validation of pipeline parameters and creation of an input channel from a sample sheet From 97bfc217fa02fef86c36100331fa8b27a6042c5b Mon Sep 17 00:00:00 2001 From: Niklas Schandry Date: Fri, 26 Apr 2024 13:17:06 +0200 Subject: [PATCH 113/175] Update comment, add newline --- nf_core/pipeline-template/nextflow.config | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nf_core/pipeline-template/nextflow.config b/nf_core/pipeline-template/nextflow.config index f90fc546f6..cbc98cb022 100644 --- a/nf_core/pipeline-template/nextflow.config +++ b/nf_core/pipeline-template/nextflow.config @@ -180,14 +180,15 @@ profiles { test_full { includeConfig 'conf/test_full.config' } } -// Set default registry for Apptainer, Docker, Podman and Singularity independent of -profile -// Will not be used unless Apptainer / Docker / Podman / Singularity are enabled +// Set default registry for Apptainer, Docker, Podman, Charliecloud and Singularity independent of -profile +// Will not be used unless Apptainer / Docker / Podman / Charliecloud / Singularity are enabled // Set to your registry if you have a mirror of containers apptainer.registry = 'quay.io' docker.registry = 'quay.io' podman.registry = 'quay.io' singularity.registry = 'quay.io' charliecloud.registry = 'quay.io' + // Nextflow plugins plugins { id 'nf-validation@1.1.3' // Validation of pipeline parameters and creation of an input channel from a sample sheet From dcc7757b0062b100b656fd44d208914e9aa6d605 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 9 May 2024 10:36:14 +0200 Subject: [PATCH 114/175] update snapshots --- tests/__snapshots__/test_create_app.ambr | 2979 +++++++++------------- tests/test_create_app.py | 2 +- 2 files changed, 1263 insertions(+), 1718 deletions(-) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index b2af13b11b..d2c239acba 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -22,253 +22,253 @@ font-weight: 700; } - .terminal-3000245001-matrix { + .terminal-1527309810-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3000245001-title { + .terminal-1527309810-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3000245001-r1 { fill: #c5c8c6 } - .terminal-3000245001-r2 { fill: #e3e3e3 } - .terminal-3000245001-r3 { fill: #989898 } - .terminal-3000245001-r4 { fill: #e1e1e1 } - .terminal-3000245001-r5 { fill: #121212 } - .terminal-3000245001-r6 { fill: #0053aa } - .terminal-3000245001-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3000245001-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-3000245001-r9 { fill: #1e1e1e } - .terminal-3000245001-r10 { fill: #008139 } - .terminal-3000245001-r11 { fill: #e2e2e2 } - .terminal-3000245001-r12 { fill: #787878 } - .terminal-3000245001-r13 { fill: #b93c5b } - .terminal-3000245001-r14 { fill: #454a50 } - .terminal-3000245001-r15 { fill: #7ae998 } - .terminal-3000245001-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-3000245001-r17 { fill: #0a180e;font-weight: bold } - .terminal-3000245001-r18 { fill: #000000 } - .terminal-3000245001-r19 { fill: #ddedf9 } + .terminal-1527309810-r1 { fill: #c5c8c6 } + .terminal-1527309810-r2 { fill: #e3e3e3 } + .terminal-1527309810-r3 { fill: #989898 } + .terminal-1527309810-r4 { fill: #e1e1e1 } + .terminal-1527309810-r5 { fill: #121212 } + .terminal-1527309810-r6 { fill: #0053aa } + .terminal-1527309810-r7 { fill: #dde8f3;font-weight: bold } + .terminal-1527309810-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-1527309810-r9 { fill: #1e1e1e } + .terminal-1527309810-r10 { fill: #008139 } + .terminal-1527309810-r11 { fill: #e2e2e2 } + .terminal-1527309810-r12 { fill: #787878 } + .terminal-1527309810-r13 { fill: #b93c5b } + .terminal-1527309810-r14 { fill: #454a50 } + .terminal-1527309810-r15 { fill: #7ae998 } + .terminal-1527309810-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-1527309810-r17 { fill: #0a180e;font-weight: bold } + .terminal-1527309810-r18 { fill: #000000 } + .terminal-1527309810-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackNext - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -298,256 +298,256 @@ font-weight: 700; } - .terminal-2776506879-matrix { + .terminal-2230840552-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2776506879-title { + .terminal-2230840552-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2776506879-r1 { fill: #c5c8c6 } - .terminal-2776506879-r2 { fill: #e3e3e3 } - .terminal-2776506879-r3 { fill: #989898 } - .terminal-2776506879-r4 { fill: #e1e1e1 } - .terminal-2776506879-r5 { fill: #121212 } - .terminal-2776506879-r6 { fill: #0053aa } - .terminal-2776506879-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2776506879-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-2776506879-r9 { fill: #1e1e1e } - .terminal-2776506879-r10 { fill: #0f4e2a } - .terminal-2776506879-r11 { fill: #0178d4 } - .terminal-2776506879-r12 { fill: #a7a7a7 } - .terminal-2776506879-r13 { fill: #787878 } - .terminal-2776506879-r14 { fill: #e2e2e2 } - .terminal-2776506879-r15 { fill: #b93c5b } - .terminal-2776506879-r16 { fill: #454a50 } - .terminal-2776506879-r17 { fill: #7ae998 } - .terminal-2776506879-r18 { fill: #e2e3e3;font-weight: bold } - .terminal-2776506879-r19 { fill: #0a180e;font-weight: bold } - .terminal-2776506879-r20 { fill: #000000 } - .terminal-2776506879-r21 { fill: #008139 } - .terminal-2776506879-r22 { fill: #ddedf9 } + .terminal-2230840552-r1 { fill: #c5c8c6 } + .terminal-2230840552-r2 { fill: #e3e3e3 } + .terminal-2230840552-r3 { fill: #989898 } + .terminal-2230840552-r4 { fill: #e1e1e1 } + .terminal-2230840552-r5 { fill: #121212 } + .terminal-2230840552-r6 { fill: #0053aa } + .terminal-2230840552-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2230840552-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-2230840552-r9 { fill: #1e1e1e } + .terminal-2230840552-r10 { fill: #0f4e2a } + .terminal-2230840552-r11 { fill: #0178d4 } + .terminal-2230840552-r12 { fill: #a7a7a7 } + .terminal-2230840552-r13 { fill: #787878 } + .terminal-2230840552-r14 { fill: #e2e2e2 } + .terminal-2230840552-r15 { fill: #b93c5b } + .terminal-2230840552-r16 { fill: #454a50 } + .terminal-2230840552-r17 { fill: #7ae998 } + .terminal-2230840552-r18 { fill: #e2e3e3;font-weight: bold } + .terminal-2230840552-r19 { fill: #0a180e;font-weight: bold } + .terminal-2230840552-r20 { fill: #000000 } + .terminal-2230840552-r21 { fill: #008139 } + .terminal-2230840552-r22 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackNext - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -577,253 +577,253 @@ font-weight: 700; } - .terminal-1170633481-matrix { + .terminal-3444045345-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1170633481-title { + .terminal-3444045345-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1170633481-r1 { fill: #c5c8c6 } - .terminal-1170633481-r2 { fill: #e3e3e3 } - .terminal-1170633481-r3 { fill: #989898 } - .terminal-1170633481-r4 { fill: #e1e1e1 } - .terminal-1170633481-r5 { fill: #121212 } - .terminal-1170633481-r6 { fill: #0053aa } - .terminal-1170633481-r7 { fill: #dde8f3;font-weight: bold } - .terminal-1170633481-r8 { fill: #24292f } - .terminal-1170633481-r9 { fill: #e2e3e3;font-weight: bold } - .terminal-1170633481-r10 { fill: #e2e3e3;font-weight: bold;font-style: italic; } - .terminal-1170633481-r11 { fill: #4ebf71;font-weight: bold } - .terminal-1170633481-r12 { fill: #e1e1e1;font-style: italic; } - .terminal-1170633481-r13 { fill: #7ae998 } - .terminal-1170633481-r14 { fill: #008139 } - .terminal-1170633481-r15 { fill: #507bb3 } - .terminal-1170633481-r16 { fill: #dde6ed;font-weight: bold } - .terminal-1170633481-r17 { fill: #001541 } - .terminal-1170633481-r18 { fill: #e1e1e1;text-decoration: underline; } - .terminal-1170633481-r19 { fill: #ddedf9 } + .terminal-3444045345-r1 { fill: #c5c8c6 } + .terminal-3444045345-r2 { fill: #e3e3e3 } + .terminal-3444045345-r3 { fill: #989898 } + .terminal-3444045345-r4 { fill: #e1e1e1 } + .terminal-3444045345-r5 { fill: #121212 } + .terminal-3444045345-r6 { fill: #0053aa } + .terminal-3444045345-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3444045345-r8 { fill: #24292f } + .terminal-3444045345-r9 { fill: #e2e3e3;font-weight: bold } + .terminal-3444045345-r10 { fill: #e2e3e3;font-weight: bold;font-style: italic; } + .terminal-3444045345-r11 { fill: #4ebf71;font-weight: bold } + .terminal-3444045345-r12 { fill: #e1e1e1;font-style: italic; } + .terminal-3444045345-r13 { fill: #7ae998 } + .terminal-3444045345-r14 { fill: #507bb3 } + .terminal-3444045345-r15 { fill: #008139 } + .terminal-3444045345-r16 { fill: #dde6ed;font-weight: bold } + .terminal-3444045345-r17 { fill: #001541 } + .terminal-3444045345-r18 { fill: #e1e1e1;text-decoration: underline; } + .terminal-3444045345-r19 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Choose pipeline type - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -          Choose "nf-core" if:                  Choose "Custom" if:           - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ● You want your pipeline to be part of the● Your pipeline will never be part of  - nf-core communitynf-core - ● You think that there's an outside chance● You want full control over all features  - that it ever could be part of nf-corethat are included from the template  - (including those that are mandatory for  - nf-core). - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-core - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Custom - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -                                  What's the difference?                                  - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Choosing "nf-core" effectively pre-selects the following template features: - - ● GitHub Actions continuous-integration configuration files: - ▪ Pipeline test runs: Small-scale (GitHub) and large-scale (AWS) - ▪ Code formatting checks with Prettier - ▪ Auto-fix linting functionality using @nf-core-bot - ▪ Marking old issues as stale - ● Inclusion of shared nf-core configuration profiles - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Choose pipeline type + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +        Choose "nf-core" if:              Choose "Custom" if:         + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ● You want your pipeline to be part of● Your pipeline will never be part of  + the nf-core communitynf-core + ● You think that there's an outside ● You want full control over all + chance that it ever could be part offeatures that are included from the  + nf-coretemplate (including those that are  + mandatory for nf-core). + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-core▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Custom + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +                                  What's the difference?                                  + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Choosing "nf-core" effectively pre-selects the following template features: + + ● GitHub Actions continuous-integration configuration files: + ▪ Pipeline test runs: Small-scale (GitHub) and large-scale (AWS) + ▪ Code formatting checks with Prettier + ▪ Auto-fix linting functionality using @nf-core-bot + ▪ Marking old issues as stale + ● Inclusion of shared nf-core configuration profiles + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  @@ -853,257 +853,257 @@ font-weight: 700; } - .terminal-3272111277-matrix { + .terminal-3071202289-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3272111277-title { + .terminal-3071202289-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3272111277-r1 { fill: #c5c8c6 } - .terminal-3272111277-r2 { fill: #e3e3e3 } - .terminal-3272111277-r3 { fill: #989898 } - .terminal-3272111277-r4 { fill: #e1e1e1 } - .terminal-3272111277-r5 { fill: #121212 } - .terminal-3272111277-r6 { fill: #0053aa } - .terminal-3272111277-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3272111277-r8 { fill: #1e1e1e } - .terminal-3272111277-r9 { fill: #0178d4 } - .terminal-3272111277-r10 { fill: #454a50 } - .terminal-3272111277-r11 { fill: #e2e2e2 } - .terminal-3272111277-r12 { fill: #808080 } - .terminal-3272111277-r13 { fill: #e2e3e3;font-weight: bold } - .terminal-3272111277-r14 { fill: #000000 } - .terminal-3272111277-r15 { fill: #e4e4e4 } - .terminal-3272111277-r16 { fill: #14191f } - .terminal-3272111277-r17 { fill: #507bb3 } - .terminal-3272111277-r18 { fill: #dde6ed;font-weight: bold } - .terminal-3272111277-r19 { fill: #001541 } - .terminal-3272111277-r20 { fill: #7ae998 } - .terminal-3272111277-r21 { fill: #0a180e;font-weight: bold } - .terminal-3272111277-r22 { fill: #008139 } - .terminal-3272111277-r23 { fill: #ddedf9 } + .terminal-3071202289-r1 { fill: #c5c8c6 } + .terminal-3071202289-r2 { fill: #e3e3e3 } + .terminal-3071202289-r3 { fill: #989898 } + .terminal-3071202289-r4 { fill: #e1e1e1 } + .terminal-3071202289-r5 { fill: #121212 } + .terminal-3071202289-r6 { fill: #0053aa } + .terminal-3071202289-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3071202289-r8 { fill: #1e1e1e } + .terminal-3071202289-r9 { fill: #0178d4 } + .terminal-3071202289-r10 { fill: #454a50 } + .terminal-3071202289-r11 { fill: #e2e2e2 } + .terminal-3071202289-r12 { fill: #808080 } + .terminal-3071202289-r13 { fill: #e2e3e3;font-weight: bold } + .terminal-3071202289-r14 { fill: #000000 } + .terminal-3071202289-r15 { fill: #e4e4e4 } + .terminal-3071202289-r16 { fill: #14191f } + .terminal-3071202289-r17 { fill: #507bb3 } + .terminal-3071202289-r18 { fill: #dde6ed;font-weight: bold } + .terminal-3071202289-r19 { fill: #001541 } + .terminal-3071202289-r20 { fill: #7ae998 } + .terminal-3071202289-r21 { fill: #0a180e;font-weight: bold } + .terminal-3071202289-r22 { fill: #008139 } + .terminal-3071202289-r23 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Template features - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference The pipeline will beHide help - ▁▁▁▁▁▁▁▁genomesconfigured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - copy of the most  - common reference  - genome files from  - iGenomes - - - Nf-core pipelines are configured to use a copy of the most common  - reference genome files. - - By selecting this option, your pipeline will include a configuration  - file specifying the paths to these files. - - The required code to use these files will also be included in the  - template. When the pipeline user provides an appropriate genome key, the - pipeline will automatically download the required reference files. - ▅▅ - For more information about reference genomes in nf-core pipelines, see  - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github CI testsThe pipeline will Show help - ▁▁▁▁▁▁▁▁include several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - GitHub actions for  - Continuous  - Integration (CI)  - testing - ▆▆ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github badgesThe README.md file Show help - ▁▁▁▁▁▁▁▁of the pipeline will▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - include GitHub  - badges - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackContinue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Template features + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference The pipeline Hide help + ▁▁▁▁▁▁▁▁genomeswill be ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + configured to  + use a copy of  + the most common  + reference genome + files from  + iGenomes + + + Nf-core pipelines are configured to use a copy of the most  + common reference genome files. + + By selecting this option, your pipeline will include a  + configuration file specifying the paths to these files. + + The required code to use these files will also be included in  + the template. When the pipeline user provides an appropriate  + genome key, the pipeline will automatically download the ▂▂ + required reference files. + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github CI The pipeline Show help▅▅ + ▁▁▁▁▁▁▁▁testswill include ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + several GitHub  + actions for  + Continuous  + Integration (CI) + testing + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github The README.md Show help + ▁▁▁▁▁▁▁▁badgesfile of the ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + pipeline will  + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  @@ -1133,541 +1133,259 @@ font-weight: 700; } - .terminal-596440806-matrix { + .terminal-1456849374-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-596440806-title { + .terminal-1456849374-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-596440806-r1 { fill: #c5c8c6 } - .terminal-596440806-r2 { fill: #e3e3e3 } - .terminal-596440806-r3 { fill: #989898 } - .terminal-596440806-r4 { fill: #e1e1e1 } - .terminal-596440806-r5 { fill: #121212 } - .terminal-596440806-r6 { fill: #0053aa } - .terminal-596440806-r7 { fill: #dde8f3;font-weight: bold } - .terminal-596440806-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-596440806-r9 { fill: #1e1e1e } - .terminal-596440806-r10 { fill: #008139 } - .terminal-596440806-r11 { fill: #e2e2e2 } - .terminal-596440806-r12 { fill: #b93c5b } - .terminal-596440806-r13 { fill: #454a50 } - .terminal-596440806-r14 { fill: #7ae998 } - .terminal-596440806-r15 { fill: #e2e3e3;font-weight: bold } - .terminal-596440806-r16 { fill: #0a180e;font-weight: bold } - .terminal-596440806-r17 { fill: #000000 } - .terminal-596440806-r18 { fill: #ddedf9 } + .terminal-1456849374-r1 { fill: #c5c8c6 } + .terminal-1456849374-r2 { fill: #e3e3e3 } + .terminal-1456849374-r3 { fill: #989898 } + .terminal-1456849374-r4 { fill: #e1e1e1 } + .terminal-1456849374-r5 { fill: #121212 } + .terminal-1456849374-r6 { fill: #0053aa } + .terminal-1456849374-r7 { fill: #dde8f3;font-weight: bold } + .terminal-1456849374-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-1456849374-r9 { fill: #1e1e1e } + .terminal-1456849374-r10 { fill: #008139 } + .terminal-1456849374-r11 { fill: #e2e2e2 } + .terminal-1456849374-r12 { fill: #b93c5b } + .terminal-1456849374-r13 { fill: #454a50 } + .terminal-1456849374-r14 { fill: #7ae998 } + .terminal-1456849374-r15 { fill: #e2e3e3;font-weight: bold } + .terminal-1456849374-r16 { fill: #0a180e;font-weight: bold } + .terminal-1456849374-r17 { fill: #000000 } + .terminal-1456849374-r18 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Final details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - First version of the pipelinePath to the output directory where the pipeline  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created - 1.0.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackFinish - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Final details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + First version of the pipelinePath to the output directory where the pipeline  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created + 1.0.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackFinish + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  ''' # --- -# name: test_github_details - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - nf-core create - - - - - - - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Now that we have created a new pipeline locally, we can create a new GitHub repository and  - push the code to it. - - - - Your GitHub usernameYour GitHub personal access token - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁••••••••••••▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - The name of the organisation where the The name of the new GitHub repository - GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline - nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - ⚠️ You can't create a repository directly in the nf-core organisation. - Please create the pipeline repo to an organisation where you have access or use your user - account. A core-team member will be able to transfer the repo to nf-core once the  - development has started. - - 💡 Your GitHub user account will be used by default if nf-core is given as the org name. - - - ▔▔▔▔▔▔▔▔Private - Select to make the new GitHub repo private. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackCreate GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  - - - - - ''' -# --- -# name: test_github_exit_message +# name: test_github_question ''' @@ -1690,262 +1408,255 @@ font-weight: 700; } - .terminal-1291666581-matrix { + .terminal-4165331380-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1291666581-title { + .terminal-4165331380-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1291666581-r1 { fill: #c5c8c6 } - .terminal-1291666581-r2 { fill: #e3e3e3 } - .terminal-1291666581-r3 { fill: #989898 } - .terminal-1291666581-r4 { fill: #e1e1e1 } - .terminal-1291666581-r5 { fill: #121212 } - .terminal-1291666581-r6 { fill: #0053aa } - .terminal-1291666581-r7 { fill: #dde8f3;font-weight: bold } - .terminal-1291666581-r8 { fill: #98e024 } - .terminal-1291666581-r9 { fill: #626262 } - .terminal-1291666581-r10 { fill: #9d65ff } - .terminal-1291666581-r11 { fill: #fd971f } - .terminal-1291666581-r12 { fill: #4ebf71;font-weight: bold } - .terminal-1291666581-r13 { fill: #d2d2d2 } - .terminal-1291666581-r14 { fill: #82aaff } - .terminal-1291666581-r15 { fill: #eeffff } - .terminal-1291666581-r16 { fill: #4ebf71 } - .terminal-1291666581-r17 { fill: #e2e2e2 } - .terminal-1291666581-r18 { fill: #969696;font-weight: bold } - .terminal-1291666581-r19 { fill: #7ae998 } - .terminal-1291666581-r20 { fill: #008139 } - .terminal-1291666581-r21 { fill: #ddedf9 } + .terminal-4165331380-r1 { fill: #c5c8c6 } + .terminal-4165331380-r2 { fill: #e3e3e3 } + .terminal-4165331380-r3 { fill: #989898 } + .terminal-4165331380-r4 { fill: #e1e1e1 } + .terminal-4165331380-r5 { fill: #121212 } + .terminal-4165331380-r6 { fill: #0053aa } + .terminal-4165331380-r7 { fill: #dde8f3;font-weight: bold } + .terminal-4165331380-r8 { fill: #7ae998 } + .terminal-4165331380-r9 { fill: #507bb3 } + .terminal-4165331380-r10 { fill: #4ebf71;font-weight: bold } + .terminal-4165331380-r11 { fill: #dde6ed;font-weight: bold } + .terminal-4165331380-r12 { fill: #008139 } + .terminal-4165331380-r13 { fill: #001541 } + .terminal-4165331380-r14 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - HowTo create a GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - -                                           ,--./,-. -           ___     __   __   __   ___     /,-._.--~\  -     |\ | |__  __ /  ` /  \ |__) |__         }  { -     | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                           `._,._,' - - If you would like to create the GitHub repository later, you can do it manually by following - these steps: - -  1. Create a new GitHub repository -  2. Add the remote to your local repository: - - - cd<pipeline_directory> - gitremoteaddorigingit@github.com:<username>/<repo_name>.git - - -  3. Push the code to the remote: - - - gitpush--allorigin - - - 💡 Note the --all flag: this is needed to push all branches to the remote. - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + After creating the pipeline template locally, we can create a GitHub repository and push the + code to it. + + Do you want to create a GitHub repository? + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Create GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  ''' # --- -# name: test_github_question +# name: test_type_custom ''' @@ -1968,255 +1679,261 @@ font-weight: 700; } - .terminal-3308461771-matrix { + .terminal-3459022791-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3308461771-title { + .terminal-3459022791-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3308461771-r1 { fill: #c5c8c6 } - .terminal-3308461771-r2 { fill: #e3e3e3 } - .terminal-3308461771-r3 { fill: #989898 } - .terminal-3308461771-r4 { fill: #e1e1e1 } - .terminal-3308461771-r5 { fill: #121212 } - .terminal-3308461771-r6 { fill: #0053aa } - .terminal-3308461771-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3308461771-r8 { fill: #7ae998 } - .terminal-3308461771-r9 { fill: #507bb3 } - .terminal-3308461771-r10 { fill: #4ebf71;font-weight: bold } - .terminal-3308461771-r11 { fill: #dde6ed;font-weight: bold } - .terminal-3308461771-r12 { fill: #008139 } - .terminal-3308461771-r13 { fill: #001541 } - .terminal-3308461771-r14 { fill: #ddedf9 } + .terminal-3459022791-r1 { fill: #c5c8c6 } + .terminal-3459022791-r2 { fill: #e3e3e3 } + .terminal-3459022791-r3 { fill: #989898 } + .terminal-3459022791-r4 { fill: #e1e1e1 } + .terminal-3459022791-r5 { fill: #121212 } + .terminal-3459022791-r6 { fill: #0053aa } + .terminal-3459022791-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3459022791-r8 { fill: #1e1e1e } + .terminal-3459022791-r9 { fill: #507bb3 } + .terminal-3459022791-r10 { fill: #e2e2e2 } + .terminal-3459022791-r11 { fill: #808080 } + .terminal-3459022791-r12 { fill: #dde6ed;font-weight: bold } + .terminal-3459022791-r13 { fill: #001541 } + .terminal-3459022791-r14 { fill: #454a50 } + .terminal-3459022791-r15 { fill: #7ae998 } + .terminal-3459022791-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-3459022791-r17 { fill: #0a180e;font-weight: bold } + .terminal-3459022791-r18 { fill: #000000 } + .terminal-3459022791-r19 { fill: #008139 } + .terminal-3459022791-r20 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - After creating the pipeline template locally, we can create a GitHub repository and push the - code to it. - - Do you want to create a GitHub repository? - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Create GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Template features + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference The pipeline willShow help + ▁▁▁▁▁▁▁▁genomesbe configured to ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + use a copy of the + most common  + reference genome  + files from  + iGenomes + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github CI The pipeline willShow help + ▁▁▁▁▁▁▁▁testsinclude several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + GitHub actions  + for Continuous  + Integration (CI)  + testing + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github badgesThe README.md Show help + ▁▁▁▁▁▁▁▁file of the ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + pipeline will  + include GitHub  + badges + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add configurationThe pipeline willShow help + ▁▁▁▁▁▁▁▁filesinclude ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + configuration  + profiles  + containing custom + parameters  + requried to run  + nf-core pipelines + at different  + institutions + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  ''' # --- -# name: test_type_custom +# name: test_type_nfcore ''' @@ -2239,261 +1956,261 @@ font-weight: 700; } - .terminal-1734914007-matrix { + .terminal-461754173-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1734914007-title { + .terminal-461754173-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1734914007-r1 { fill: #c5c8c6 } - .terminal-1734914007-r2 { fill: #e3e3e3 } - .terminal-1734914007-r3 { fill: #989898 } - .terminal-1734914007-r4 { fill: #e1e1e1 } - .terminal-1734914007-r5 { fill: #121212 } - .terminal-1734914007-r6 { fill: #0053aa } - .terminal-1734914007-r7 { fill: #dde8f3;font-weight: bold } - .terminal-1734914007-r8 { fill: #1e1e1e } - .terminal-1734914007-r9 { fill: #507bb3 } - .terminal-1734914007-r10 { fill: #e2e2e2 } - .terminal-1734914007-r11 { fill: #808080 } - .terminal-1734914007-r12 { fill: #dde6ed;font-weight: bold } - .terminal-1734914007-r13 { fill: #001541 } - .terminal-1734914007-r14 { fill: #454a50 } - .terminal-1734914007-r15 { fill: #7ae998 } - .terminal-1734914007-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-1734914007-r17 { fill: #0a180e;font-weight: bold } - .terminal-1734914007-r18 { fill: #000000 } - .terminal-1734914007-r19 { fill: #008139 } - .terminal-1734914007-r20 { fill: #ddedf9 } + .terminal-461754173-r1 { fill: #c5c8c6 } + .terminal-461754173-r2 { fill: #e3e3e3 } + .terminal-461754173-r3 { fill: #989898 } + .terminal-461754173-r4 { fill: #e1e1e1 } + .terminal-461754173-r5 { fill: #121212 } + .terminal-461754173-r6 { fill: #0053aa } + .terminal-461754173-r7 { fill: #dde8f3;font-weight: bold } + .terminal-461754173-r8 { fill: #1e1e1e } + .terminal-461754173-r9 { fill: #507bb3 } + .terminal-461754173-r10 { fill: #e2e2e2 } + .terminal-461754173-r11 { fill: #808080 } + .terminal-461754173-r12 { fill: #dde6ed;font-weight: bold } + .terminal-461754173-r13 { fill: #001541 } + .terminal-461754173-r14 { fill: #454a50 } + .terminal-461754173-r15 { fill: #7ae998 } + .terminal-461754173-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-461754173-r17 { fill: #0a180e;font-weight: bold } + .terminal-461754173-r18 { fill: #000000 } + .terminal-461754173-r19 { fill: #008139 } + .terminal-461754173-r20 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Template features - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference genomesThe pipeline will be Show help - ▁▁▁▁▁▁▁▁configured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - copy of the most  - common reference  - genome files from  - iGenomes - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github CI testsThe pipeline will Show help - ▁▁▁▁▁▁▁▁include several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - GitHub actions for  - Continuous  - Integration (CI)  - testing - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github badgesThe README.md file ofShow help - ▁▁▁▁▁▁▁▁the pipeline will ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - include GitHub badges - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add configuration The pipeline will Show help - ▁▁▁▁▁▁▁▁filesinclude configuration▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - profiles containing  - custom parameters  - requried to run  - nf-core pipelines at  - different  - institutions - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackContinue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Template features + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference The pipeline willShow help + ▁▁▁▁▁▁▁▁genomesbe configured to ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + use a copy of the + most common  + reference genome  + files from  + iGenomes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  D  Toggle dark mode  Q  Quit  ''' # --- -# name: test_type_nfcore +# name: test_type_nfcore_validation ''' @@ -2516,261 +2233,263 @@ font-weight: 700; } - .terminal-182709094-matrix { + .terminal-2179958535-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-182709094-title { + .terminal-2179958535-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-182709094-r1 { fill: #c5c8c6 } - .terminal-182709094-r2 { fill: #e3e3e3 } - .terminal-182709094-r3 { fill: #989898 } - .terminal-182709094-r4 { fill: #e1e1e1 } - .terminal-182709094-r5 { fill: #121212 } - .terminal-182709094-r6 { fill: #0053aa } - .terminal-182709094-r7 { fill: #dde8f3;font-weight: bold } - .terminal-182709094-r8 { fill: #1e1e1e } - .terminal-182709094-r9 { fill: #507bb3 } - .terminal-182709094-r10 { fill: #e2e2e2 } - .terminal-182709094-r11 { fill: #808080 } - .terminal-182709094-r12 { fill: #dde6ed;font-weight: bold } - .terminal-182709094-r13 { fill: #001541 } - .terminal-182709094-r14 { fill: #454a50 } - .terminal-182709094-r15 { fill: #7ae998 } - .terminal-182709094-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-182709094-r17 { fill: #0a180e;font-weight: bold } - .terminal-182709094-r18 { fill: #000000 } - .terminal-182709094-r19 { fill: #008139 } - .terminal-182709094-r20 { fill: #ddedf9 } + .terminal-2179958535-r1 { fill: #c5c8c6 } + .terminal-2179958535-r2 { fill: #e3e3e3 } + .terminal-2179958535-r3 { fill: #989898 } + .terminal-2179958535-r4 { fill: #e1e1e1 } + .terminal-2179958535-r5 { fill: #121212 } + .terminal-2179958535-r6 { fill: #0053aa } + .terminal-2179958535-r7 { fill: #dde8f3;font-weight: bold } + .terminal-2179958535-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-2179958535-r9 { fill: #1e1e1e } + .terminal-2179958535-r10 { fill: #0f4e2a } + .terminal-2179958535-r11 { fill: #7b3042 } + .terminal-2179958535-r12 { fill: #a7a7a7 } + .terminal-2179958535-r13 { fill: #787878 } + .terminal-2179958535-r14 { fill: #e2e2e2 } + .terminal-2179958535-r15 { fill: #b93c5b } + .terminal-2179958535-r16 { fill: #454a50 } + .terminal-2179958535-r17 { fill: #166d39 } + .terminal-2179958535-r18 { fill: #e2e3e3;font-weight: bold } + .terminal-2179958535-r19 { fill: #3c8b54;font-weight: bold } + .terminal-2179958535-r20 { fill: #000000 } + .terminal-2179958535-r21 { fill: #5aa86f } + .terminal-2179958535-r22 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Template features - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference genomesThe pipeline will be Show help - ▁▁▁▁▁▁▁▁configured to use a ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - copy of the most  - common reference  - genome files from  - iGenomes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackContinue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Basic details + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Must be lowercase without  + punctuation. + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  ''' # --- -# name: test_type_nfcore_validation +# name: test_welcome ''' @@ -2793,428 +2512,254 @@ font-weight: 700; } - .terminal-2320153615-matrix { + .terminal-1144763792-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2320153615-title { + .terminal-1144763792-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2320153615-r1 { fill: #c5c8c6 } - .terminal-2320153615-r2 { fill: #e3e3e3 } - .terminal-2320153615-r3 { fill: #989898 } - .terminal-2320153615-r4 { fill: #e1e1e1 } - .terminal-2320153615-r5 { fill: #121212 } - .terminal-2320153615-r6 { fill: #0053aa } - .terminal-2320153615-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2320153615-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-2320153615-r9 { fill: #1e1e1e } - .terminal-2320153615-r10 { fill: #0f4e2a } - .terminal-2320153615-r11 { fill: #7b3042 } - .terminal-2320153615-r12 { fill: #a7a7a7 } - .terminal-2320153615-r13 { fill: #787878 } - .terminal-2320153615-r14 { fill: #e2e2e2 } - .terminal-2320153615-r15 { fill: #b93c5b } - .terminal-2320153615-r16 { fill: #454a50 } - .terminal-2320153615-r17 { fill: #166d39 } - .terminal-2320153615-r18 { fill: #e2e3e3;font-weight: bold } - .terminal-2320153615-r19 { fill: #3c8b54;font-weight: bold } - .terminal-2320153615-r20 { fill: #000000 } - .terminal-2320153615-r21 { fill: #5aa86f } - .terminal-2320153615-r22 { fill: #ddedf9 } + .terminal-1144763792-r1 { fill: #c5c8c6 } + .terminal-1144763792-r2 { fill: #e3e3e3 } + .terminal-1144763792-r3 { fill: #989898 } + .terminal-1144763792-r4 { fill: #98e024 } + .terminal-1144763792-r5 { fill: #626262 } + .terminal-1144763792-r6 { fill: #9d65ff } + .terminal-1144763792-r7 { fill: #fd971f } + .terminal-1144763792-r8 { fill: #e1e1e1 } + .terminal-1144763792-r9 { fill: #121212 } + .terminal-1144763792-r10 { fill: #0053aa } + .terminal-1144763792-r11 { fill: #dde8f3;font-weight: bold } + .terminal-1144763792-r12 { fill: #e1e1e1;text-decoration: underline; } + .terminal-1144763792-r13 { fill: #4ebf71 } + .terminal-1144763792-r14 { fill: #e2e2e2 } + .terminal-1144763792-r15 { fill: #e2e2e2;text-decoration: underline; } + .terminal-1144763792-r16 { fill: #e2e2e2;font-weight: bold;font-style: italic; } + .terminal-1144763792-r17 { fill: #7ae998 } + .terminal-1144763792-r18 { fill: #4ebf71;font-weight: bold } + .terminal-1144763792-r19 { fill: #008139 } + .terminal-1144763792-r20 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create - - - - - - - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Must be lowercase without  - punctuation. - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Cannot be left empty. - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Cannot be left empty. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackNext - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  - - - - - ''' -# --- -# name: test_welcome - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pip… - -                                           ,--./,-. -           ___     __   __   __   ___     /,-._.--~\  -     |\ | |__  __ /  ` /  \ |__) |__         }  { -     | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                           `._,._,' - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Welcome to the nf-core pipeline creation wizard - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - This app will help you create a new Nextflow pipeline from the  - nf-core/tools pipeline template. - - The template helps anyone benefit from nf-core best practices, and is  - a requirement for nf-core pipelines. - ▃▃ - 💡 If you want to add a pipeline to nf-core, please join on Slack - and discuss your plans with the community as early as possible;  - ideally before you start on your pipeline! See the nf-core  - guidelines and the #new-pipelines Slack channel for more  -  D Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + +                                           ,--./,-. +           ___     __   __   __   ___     /,-._.--~\  +     |\ | |__  __ /  ` /  \ |__) |__         }  { +     | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                           `._,._,' + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Welcome to the nf-core pipeline creation wizard + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This app will help you create a new Nextflow pipeline from the nf-core/tools pipeline  + template. + + The template helps anyone benefit from nf-core best practices, and is a requirement for  + nf-core pipelines. + + 💡 If you want to add a pipeline to nf-core, please join on Slack and discuss your plans  + with the community as early as possible; ideally before you start on your pipeline! See  + the nf-core guidelines and the #new-pipelines Slack channel for more information. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Let's go! + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  diff --git a/tests/test_create_app.py b/tests/test_create_app.py index 92fb52e43f..ee010c251e 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -24,7 +24,7 @@ async def test_app_bindings(): def test_welcome(snap_compare): """Test snapshot for the first screen in the app. The welcome screen.""" - assert snap_compare("../nf_core/pipelines/create/__init__.py") + assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50)) def test_choose_type(snap_compare): From 8aceeb3ac84922f985ec8645c3fe5f06ce86ddd1 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 9 May 2024 11:05:15 +0200 Subject: [PATCH 115/175] handle token not configured with gh --- nf_core/pipelines/create/githubrepo.py | 11 +- tests/__snapshots__/test_create_app.ambr | 562 +++++++++++++++++++++++ 2 files changed, 569 insertions(+), 4 deletions(-) diff --git a/nf_core/pipelines/create/githubrepo.py b/nf_core/pipelines/create/githubrepo.py index ddf7bf90f4..99e7b09ab8 100644 --- a/nf_core/pipelines/create/githubrepo.py +++ b/nf_core/pipelines/create/githubrepo.py @@ -240,10 +240,13 @@ def _get_github_credentials(self): # Use gh CLI config if installed gh_cli_config_fn = os.path.expanduser("~/.config/gh/hosts.yml") if os.path.exists(gh_cli_config_fn): - with open(gh_cli_config_fn) as fh: - gh_cli_config = yaml.safe_load(fh) - gh_user = (gh_cli_config["github.com"]["user"],) - gh_token = gh_cli_config["github.com"]["oauth_token"] + try: + with open(gh_cli_config_fn) as fh: + gh_cli_config = yaml.safe_load(fh) + gh_user = (gh_cli_config["github.com"]["user"],) + gh_token = gh_cli_config["github.com"]["oauth_token"] + except KeyError: + pass # If gh CLI not installed, try to get credentials from environment variables elif os.environ.get("GITHUB_TOKEN") is not None: gh_token = self.auth = os.environ["GITHUB_TOKEN"] diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index d2c239acba..d3cf69a2d1 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1385,6 +1385,568 @@ ''' # --- +# name: test_github_details + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Now that we have created a new pipeline locally, we can create a new GitHub repository and  + push the code to it. + + 💡 Found GitHub username in local GitHub CLI config + + + + Your GitHub usernameYour GitHub personal access token + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + mirpedr▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁••••••••••••▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + The name of the organisation where the The name of the new GitHub repository + GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline + nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + ⚠️ You can't create a repository directly in the nf-core organisation. + Please create the pipeline repo to an organisation where you have access or use your user + account. A core-team member will be able to transfer the repo to nf-core once the  + development has started. + + 💡 Your GitHub user account will be used by default if nf-core is given as the org name. + + + ▔▔▔▔▔▔▔▔Private + Select to make the new GitHub repo private. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackCreate GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- +# name: test_github_exit_message + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nf-core create + + + + + + + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + HowTo create a GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + +                                           ,--./,-. +           ___     __   __   __   ___     /,-._.--~\  +     |\ | |__  __ /  ` /  \ |__) |__         }  { +     | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                           `._,._,' + + If you would like to create the GitHub repository later, you can do it manually by following + these steps: + +  1. Create a new GitHub repository +  2. Add the remote to your local repository: + + + cd<pipeline_directory> + gitremoteaddorigingit@github.com:<username>/<repo_name>.git + + +  3. Push the code to the remote: + + + gitpush--allorigin + + + 💡 Note the --all flag: this is needed to push all branches to the remote. + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  + + + + + ''' +# --- # name: test_github_question ''' From 2d4aefa53ea6c7e414bf5629cc9a934b0702cebf Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 9 May 2024 13:56:44 +0200 Subject: [PATCH 116/175] bump to 2.14.2dev --- .gitpod.yml | 2 +- CHANGELOG.md | 12 ++++++++++++ setup.py | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index 445cb35706..b2fbb73133 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,4 +1,4 @@ -image: nfcore/gitpod:latest +image: nfcore/gitpod:dev tasks: - name: install current state of nf-core/tools and setup pre-commit command: | diff --git a/CHANGELOG.md b/CHANGELOG.md index e130d3c37b..b71c64fe26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # nf-core/tools: Changelog +## v2.14.2dev + +### Template + +### Linting + +### Download + +### Components + +### General + ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] ### Template diff --git a/setup.py b/setup.py index 47137cde70..013c863b9a 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import find_packages, setup -version = "2.14.1" +version = "2.14.2dev" with open("README.md") as f: readme = f.read() From 43545440d9d1338d01cdfe28d471963fbc5a4e26 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 17:46:22 +0000 Subject: [PATCH 117/175] Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.4 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 887cbe027c..4b1941d81e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.3 + rev: v0.4.4 hooks: - id: ruff # linter args: [--fix, --exit-non-zero-on-fix] # sort imports and fix From 37a4bfc4d7dea4ae329cfb8aceefcc1ec804af67 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Thu, 9 May 2024 17:47:18 +0000 Subject: [PATCH 118/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b71c64fe26..3f46a265cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ ### General +- Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.4 ([#2974](https://github.com/nf-core/tools/pull/2974)) + ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] ### Template From 9572b237f89a864e728d3384e5dc841a33758fa1 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 10 May 2024 12:03:27 +0200 Subject: [PATCH 119/175] add asyncio to pytest.ini and upload snapshot report on fail on CI --- .github/workflows/pytest.yml | 7 +++++++ pytest.ini | 3 +++ tests/test_create_app.py | 3 --- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 70b9cfd0a8..587f8166d5 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -148,6 +148,13 @@ jobs: name: coverage_${{ matrix.test }} path: .coverage + - name: Store snapshot report on failure + uses: actions/upload-artifact@v4 + if: ${{matrix.test}} == "test_create_app.py" && failure() + with: + name: Snapshot Report ${{ matrix.test }} + path: ./snapshot_report.html + coverage: needs: test # use the runner given by the input if it is dispatched manually, run on github if it is a rerun or on self-hosted by default diff --git a/pytest.ini b/pytest.ini index cf37159478..fcbd03fa45 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,3 +2,6 @@ testpaths = tests python_files = test_*.py + +# automatically run coroutine tests with asyncio +asyncio_mode = auto diff --git a/tests/test_create_app.py b/tests/test_create_app.py index ee010c251e..2682fff6b4 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -1,11 +1,8 @@ """Test Pipeline Create App""" -import pytest - from nf_core.pipelines.create import PipelineCreateApp -@pytest.mark.asyncio async def test_app_bindings(): """Test that the app bindings work.""" app = PipelineCreateApp() From bc1096f89bb1c082afac338e90b819ce4cfdab03 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 10 May 2024 12:27:44 +0200 Subject: [PATCH 120/175] wait for workers to complete --- tests/__snapshots__/test_create_app.ambr | 267 ++++++++++++----------- tests/test_create_app.py | 9 +- 2 files changed, 137 insertions(+), 139 deletions(-) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index d3cf69a2d1..698e21b70a 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1408,261 +1408,262 @@ font-weight: 700; } - .terminal-2377938861-matrix { + .terminal-3947539839-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2377938861-title { + .terminal-3947539839-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2377938861-r1 { fill: #c5c8c6 } - .terminal-2377938861-r2 { fill: #e3e3e3 } - .terminal-2377938861-r3 { fill: #989898 } - .terminal-2377938861-r4 { fill: #e1e1e1 } - .terminal-2377938861-r5 { fill: #121212 } - .terminal-2377938861-r6 { fill: #0053aa } - .terminal-2377938861-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2377938861-r8 { fill: #4ebf71 } - .terminal-2377938861-r9 { fill: #e2e2e2 } - .terminal-2377938861-r10 { fill: #e2e2e2;font-style: italic; } - .terminal-2377938861-r11 { fill: #e2e2e2;font-style: italic;;text-decoration: underline; } - .terminal-2377938861-r12 { fill: #a5a5a5;font-style: italic; } - .terminal-2377938861-r13 { fill: #1e1e1e } - .terminal-2377938861-r14 { fill: #008139 } - .terminal-2377938861-r15 { fill: #454a50 } - .terminal-2377938861-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-2377938861-r17 { fill: #000000 } - .terminal-2377938861-r18 { fill: #b93c5b } - .terminal-2377938861-r19 { fill: #e2e2e2;font-weight: bold } - .terminal-2377938861-r20 { fill: #969696;font-weight: bold } - .terminal-2377938861-r21 { fill: #808080 } - .terminal-2377938861-r22 { fill: #7ae998 } - .terminal-2377938861-r23 { fill: #507bb3 } - .terminal-2377938861-r24 { fill: #0a180e;font-weight: bold } - .terminal-2377938861-r25 { fill: #dde6ed;font-weight: bold } - .terminal-2377938861-r26 { fill: #001541 } - .terminal-2377938861-r27 { fill: #ddedf9 } + .terminal-3947539839-r1 { fill: #c5c8c6 } + .terminal-3947539839-r2 { fill: #e3e3e3 } + .terminal-3947539839-r3 { fill: #989898 } + .terminal-3947539839-r4 { fill: #e1e1e1 } + .terminal-3947539839-r5 { fill: #121212 } + .terminal-3947539839-r6 { fill: #0053aa } + .terminal-3947539839-r7 { fill: #dde8f3;font-weight: bold } + .terminal-3947539839-r8 { fill: #4ebf71 } + .terminal-3947539839-r9 { fill: #e2e2e2 } + .terminal-3947539839-r10 { fill: #e2e2e2;font-style: italic; } + .terminal-3947539839-r11 { fill: #e2e2e2;font-style: italic;;text-decoration: underline; } + .terminal-3947539839-r12 { fill: #a5a5a5;font-style: italic; } + .terminal-3947539839-r13 { fill: #1e1e1e } + .terminal-3947539839-r14 { fill: #008139 } + .terminal-3947539839-r15 { fill: #454a50 } + .terminal-3947539839-r16 { fill: #787878 } + .terminal-3947539839-r17 { fill: #e2e3e3;font-weight: bold } + .terminal-3947539839-r18 { fill: #000000 } + .terminal-3947539839-r19 { fill: #b93c5b } + .terminal-3947539839-r20 { fill: #e2e2e2;font-weight: bold } + .terminal-3947539839-r21 { fill: #969696;font-weight: bold } + .terminal-3947539839-r22 { fill: #808080 } + .terminal-3947539839-r23 { fill: #7ae998 } + .terminal-3947539839-r24 { fill: #507bb3 } + .terminal-3947539839-r25 { fill: #0a180e;font-weight: bold } + .terminal-3947539839-r26 { fill: #dde6ed;font-weight: bold } + .terminal-3947539839-r27 { fill: #001541 } + .terminal-3947539839-r28 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Now that we have created a new pipeline locally, we can create a new GitHub repository and  - push the code to it. - - 💡 Found GitHub username in local GitHub CLI config - - - - Your GitHub usernameYour GitHub personal access token - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - mirpedr▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁••••••••••••▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - The name of the organisation where the The name of the new GitHub repository - GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline - nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - ⚠️ You can't create a repository directly in the nf-core organisation. - Please create the pipeline repo to an organisation where you have access or use your user - account. A core-team member will be able to transfer the repo to nf-core once the  - development has started. - - 💡 Your GitHub user account will be used by default if nf-core is given as the org name. - - - ▔▔▔▔▔▔▔▔Private - Select to make the new GitHub repo private. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackCreate GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Now that we have created a new pipeline locally, we can create a new GitHub repository and  + push the code to it. + + 💡 Found GitHub username in local GitHub CLI config + + + + Your GitHub usernameYour GitHub personal access token + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + The name of the organisation where the The name of the new GitHub repository + GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline + nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + ⚠️ You can't create a repository directly in the nf-core organisation. + Please create the pipeline repo to an organisation where you have access or use your user + account. A core-team member will be able to transfer the repo to nf-core once the  + development has started. + + 💡 Your GitHub user account will be used by default if nf-core is given as the org name. + + + ▔▔▔▔▔▔▔▔Private + Select to make the new GitHub repo private. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackCreate GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + +  D  Toggle dark mode  Q  Quit  diff --git a/tests/test_create_app.py b/tests/test_create_app.py index 2682fff6b4..f01ea5b6bd 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -210,8 +210,7 @@ async def run_before(pilot) -> None: await pilot.press("tab") await pilot.press(*str(tmpdir)) await pilot.click("#finish") - pilot.app.get_widget_by_id("close_screen").remove_class("hide") - await pilot.pause() + await pilot.app.workers.wait_for_complete() await pilot.click("#close_screen") assert snap_compare("../nf_core/pipelines/create/__init__.py", terminal_size=(100, 50), run_before=run_before) @@ -245,8 +244,7 @@ async def run_before(pilot) -> None: await pilot.press("tab") await pilot.press(*str(tmpdir)) await pilot.click("#finish") - pilot.app.get_widget_by_id("close_screen").remove_class("hide") - await pilot.pause() + await pilot.app.workers.wait_for_complete() await pilot.click("#close_screen") await pilot.click("#github_repo") await pilot.click("#gh_username") @@ -285,8 +283,7 @@ async def run_before(pilot) -> None: await pilot.press("tab") await pilot.press(*str(tmpdir)) await pilot.click("#finish") - pilot.app.get_widget_by_id("close_screen").remove_class("hide") - await pilot.pause() + await pilot.app.workers.wait_for_complete() await pilot.click("#close_screen") await pilot.click("#github_repo") await pilot.click("#exit") From af584d3d3f6563d855ae5d156767c628a80b57e0 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 10 May 2024 12:45:19 +0200 Subject: [PATCH 121/175] upload snapshot report always --- .github/workflows/pytest.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 587f8166d5..1edebb0b5c 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -149,8 +149,8 @@ jobs: path: .coverage - name: Store snapshot report on failure - uses: actions/upload-artifact@v4 - if: ${{matrix.test}} == "test_create_app.py" && failure() + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4 + if: ${{matrix.test}} == "test_create_app.py" && always() with: name: Snapshot Report ${{ matrix.test }} path: ./snapshot_report.html From 0de5b690ce65fa0c5f73ca16c04bec27c8243285 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 10 May 2024 12:48:54 +0200 Subject: [PATCH 122/175] upload snapshot report first --- .github/workflows/pytest.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 1edebb0b5c..4e873385e8 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -142,18 +142,18 @@ jobs: exit 1 fi - - name: Upload coverage + - name: Store snapshot report uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4 + if: always() with: - name: coverage_${{ matrix.test }} - path: .coverage + name: Snapshot Report ${{ matrix.test }} + path: ./snapshot_report.html - - name: Store snapshot report on failure + - name: Upload coverage uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4 - if: ${{matrix.test}} == "test_create_app.py" && always() with: - name: Snapshot Report ${{ matrix.test }} - path: ./snapshot_report.html + name: coverage_${{ matrix.test }} + path: .coverage coverage: needs: test From 9d6838c0a94d7bd8755fc4a8c9e38c542bf9adf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Fri, 10 May 2024 11:00:16 +0000 Subject: [PATCH 123/175] update snapshot from gitpod --- tests/__snapshots__/test_create_app.ambr | 266 +++++++++++------------ 1 file changed, 132 insertions(+), 134 deletions(-) diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index 698e21b70a..c486ec4f8f 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1408,262 +1408,260 @@ font-weight: 700; } - .terminal-3947539839-matrix { + .terminal-436990287-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3947539839-title { + .terminal-436990287-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3947539839-r1 { fill: #c5c8c6 } - .terminal-3947539839-r2 { fill: #e3e3e3 } - .terminal-3947539839-r3 { fill: #989898 } - .terminal-3947539839-r4 { fill: #e1e1e1 } - .terminal-3947539839-r5 { fill: #121212 } - .terminal-3947539839-r6 { fill: #0053aa } - .terminal-3947539839-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3947539839-r8 { fill: #4ebf71 } - .terminal-3947539839-r9 { fill: #e2e2e2 } - .terminal-3947539839-r10 { fill: #e2e2e2;font-style: italic; } - .terminal-3947539839-r11 { fill: #e2e2e2;font-style: italic;;text-decoration: underline; } - .terminal-3947539839-r12 { fill: #a5a5a5;font-style: italic; } - .terminal-3947539839-r13 { fill: #1e1e1e } - .terminal-3947539839-r14 { fill: #008139 } - .terminal-3947539839-r15 { fill: #454a50 } - .terminal-3947539839-r16 { fill: #787878 } - .terminal-3947539839-r17 { fill: #e2e3e3;font-weight: bold } - .terminal-3947539839-r18 { fill: #000000 } - .terminal-3947539839-r19 { fill: #b93c5b } - .terminal-3947539839-r20 { fill: #e2e2e2;font-weight: bold } - .terminal-3947539839-r21 { fill: #969696;font-weight: bold } - .terminal-3947539839-r22 { fill: #808080 } - .terminal-3947539839-r23 { fill: #7ae998 } - .terminal-3947539839-r24 { fill: #507bb3 } - .terminal-3947539839-r25 { fill: #0a180e;font-weight: bold } - .terminal-3947539839-r26 { fill: #dde6ed;font-weight: bold } - .terminal-3947539839-r27 { fill: #001541 } - .terminal-3947539839-r28 { fill: #ddedf9 } + .terminal-436990287-r1 { fill: #c5c8c6 } + .terminal-436990287-r2 { fill: #e3e3e3 } + .terminal-436990287-r3 { fill: #989898 } + .terminal-436990287-r4 { fill: #e1e1e1 } + .terminal-436990287-r5 { fill: #121212 } + .terminal-436990287-r6 { fill: #0053aa } + .terminal-436990287-r7 { fill: #dde8f3;font-weight: bold } + .terminal-436990287-r8 { fill: #a5a5a5;font-style: italic; } + .terminal-436990287-r9 { fill: #1e1e1e } + .terminal-436990287-r10 { fill: #008139 } + .terminal-436990287-r11 { fill: #454a50 } + .terminal-436990287-r12 { fill: #787878 } + .terminal-436990287-r13 { fill: #e2e2e2 } + .terminal-436990287-r14 { fill: #e2e3e3;font-weight: bold } + .terminal-436990287-r15 { fill: #000000 } + .terminal-436990287-r16 { fill: #b93c5b } + .terminal-436990287-r17 { fill: #4ebf71 } + .terminal-436990287-r18 { fill: #e2e2e2;font-weight: bold } + .terminal-436990287-r19 { fill: #969696;font-weight: bold } + .terminal-436990287-r20 { fill: #808080 } + .terminal-436990287-r21 { fill: #7ae998 } + .terminal-436990287-r22 { fill: #507bb3 } + .terminal-436990287-r23 { fill: #0a180e;font-weight: bold } + .terminal-436990287-r24 { fill: #dde6ed;font-weight: bold } + .terminal-436990287-r25 { fill: #001541 } + .terminal-436990287-r26 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Now that we have created a new pipeline locally, we can create a new GitHub repository and  - push the code to it. - - 💡 Found GitHub username in local GitHub CLI config - - - - Your GitHub usernameYour GitHub personal access token - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - The name of the organisation where the The name of the new GitHub repository - GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline - nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - ⚠️ You can't create a repository directly in the nf-core organisation. - Please create the pipeline repo to an organisation where you have access or use your user - account. A core-team member will be able to transfer the repo to nf-core once the  - development has started. - - 💡 Your GitHub user account will be used by default if nf-core is given as the org name. - - - ▔▔▔▔▔▔▔▔Private - Select to make the new GitHub repo private. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackCreate GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Create GitHub repository + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Now that we have created a new pipeline locally, we can create a new GitHub repository and  + push the code to it. + + + + Your GitHub usernameYour GitHub personal access token + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + The name of the organisation where the The name of the new GitHub repository + GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline + nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + ⚠️ You can't create a repository directly in the nf-core organisation. + Please create the pipeline repo to an organisation where you have access or use your user + account. A core-team member will be able to transfer the repo to nf-core once the  + development has started. + + 💡 Your GitHub user account will be used by default if nf-core is given as the org name. + + + ▔▔▔▔▔▔▔▔Private + Select to make the new GitHub repo private. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackCreate GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + +  D  Toggle dark mode  Q  Quit  From 3cf57a85d3b0104679ecda719ea8227a7883045c Mon Sep 17 00:00:00 2001 From: itrujnara Date: Fri, 10 May 2024 15:52:42 +0200 Subject: [PATCH 124/175] Added nf-schema as condition to exclude Java deps file --- nf_core/lint/files_exist.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/nf_core/lint/files_exist.py b/nf_core/lint/files_exist.py index d801caf704..0c87100622 100644 --- a/nf_core/lint/files_exist.py +++ b/nf_core/lint/files_exist.py @@ -200,8 +200,8 @@ def files_exist(self) -> Dict[str, Union[List[str], bool]]: Path("Singularity"), ] files_warn_ifexists = [Path(".travis.yml")] - files_fail_ifinconfig: List[Tuple[Path, Dict[str, str]]] = [ - (Path("lib", "nfcore_external_java_deps.jar"), {"plugins": "nf-validation"}), + files_fail_ifinconfig: List[Tuple[Path, List[Dict[str, str]]]] = [ + (Path("lib", "nfcore_external_java_deps.jar"), [{"plugins": "nf-validation"}, {"plugins": "nf-schema"}]), ] # Remove files that should be ignored according to the linting config @@ -246,10 +246,11 @@ def pf(file_path: Union[str, Path]) -> Path: if str(file_cond[0]) in ignore_files: continue in_config = False - config_key, config_value = list(file_cond[1].items())[0] - if config_key in self.nf_config and config_value in self.nf_config[config_key]: - log.debug(f"Found {config_key} in nextflow.config with value {config_value}") - in_config = True + for condition in file_cond[1]: + config_key, config_value = list(condition.items())[0] + if config_key in self.nf_config and config_value in self.nf_config[config_key]: + log.debug(f"Found {config_key} in nextflow.config with value {config_value}") + in_config = True if pf(file_cond[0]).is_file() and in_config: failed.append(f"File must be removed: {self._wrap_quotes(file_cond[0])}") elif pf(file_cond[0]).is_file() and not in_config: From 0bdd4dd99bd0f0da6375c57c0fafa27e1d03bfc6 Mon Sep 17 00:00:00 2001 From: mashehu Date: Fri, 10 May 2024 16:47:07 +0200 Subject: [PATCH 125/175] add explicit test for nf-schema --- tests/lint/files_exist.py | 17 +++++++++++++++++ tests/test_lint.py | 1 + 2 files changed, 18 insertions(+) diff --git a/tests/lint/files_exist.py b/tests/lint/files_exist.py index 5081522899..08da7f14db 100644 --- a/tests/lint/files_exist.py +++ b/tests/lint/files_exist.py @@ -79,3 +79,20 @@ def test_files_exist_fail_conditional(self): results = lint_obj.files_exist() assert results["failed"] == ["File must be removed: `lib/nfcore_external_java_deps.jar`"] assert results["ignored"] == [] + + +def test_files_exist_pass_conditional_nfschema(self): + new_pipeline = self._make_pipeline_copy() + # replace nf-validation with nf-schema in nextflow.config + with open(Path(new_pipeline, "nextflow.config")) as f: + config = f.read() + config = config.replace("nf-validation", "nf-schema") + with open(Path(new_pipeline, "nextflow.config"), "w") as f: + f.write(config) + + lint_obj = nf_core.lint.PipelineLint(new_pipeline) + lint_obj._load() + lint_obj.nf_config["manifest.schema"] = "nf-core" + results = lint_obj.files_exist() + assert results["failed"] == [] + assert results["ignored"] == [] diff --git a/tests/test_lint.py b/tests/test_lint.py index b72a6bfdfa..15c1550e72 100644 --- a/tests/test_lint.py +++ b/tests/test_lint.py @@ -212,6 +212,7 @@ def test_sphinx_md_files(self): test_files_exist_missing_main, test_files_exist_pass, test_files_exist_pass_conditional, + test_files_exist_pass_conditional_nfschema, ) from .lint.files_unchanged import ( # type: ignore[misc] test_files_unchanged_fail, From c3e2844b77fddd43c812fa3ea1c734f1b72cc0ae Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Fri, 10 May 2024 14:49:13 +0000 Subject: [PATCH 126/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f46a265cc..6dd09482b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ ### Linting +- Fix linting fail on nfcore_external_java_deps if nf_schema is used ([#2976](https://github.com/nf-core/tools/pull/2976)) + ### Download ### Components From 5e611c8ff68824836b487a9bfd4153e6c2db78fd Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 13 May 2024 10:42:19 +0200 Subject: [PATCH 127/175] add GHA to post comment about outdated template version --- .../.github/workflows/linting.yml | 8 +++- .../workflows/template_version_comment.yml | 42 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 nf_core/pipeline-template/.github/workflows/template_version_comment.yml diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index b2cde075fe..229aa9f652 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -41,10 +41,16 @@ jobs: python-version: "3.12" architecture: "x64" + - name: read .nf-core.yml + uses: pietrobolcato/action-read-yaml@1.0.0 + id: read_yml + with: + config: ${{ github.workspace }}/.nf-core.yaml + - name: Install dependencies run: | python -m pip install --upgrade pip - pip install nf-core + pip install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} - name: Run nf-core lint env: diff --git a/nf_core/pipeline-template/.github/workflows/template_version_comment.yml b/nf_core/pipeline-template/.github/workflows/template_version_comment.yml new file mode 100644 index 0000000000..2f49ab1269 --- /dev/null +++ b/nf_core/pipeline-template/.github/workflows/template_version_comment.yml @@ -0,0 +1,42 @@ +name: nf-core template version comment +# This workflow is triggered on PRs to check if the pipeline template version matches the latest nf-core version. +# It posts a comment to the PR, even if it comes from a fork. + +on: pull_request_target + +jobs: + template_version: + runs-on: ubuntu-latest + steps: + - name: Check out pipeline code + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 + + - name: Read template version from .nf-core.yml + uses: pietrobolcato/action-read-yaml@1.0.0 + id: read_yml + with: + config: ${{ github.workspace }}/.nf-core.yml + + - name: Install nf-core + run: | + python -m pip install --upgrade pip + pip install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} + + - name: Check nf-core outdated + id: nf_core_outdated + run: pip list --outdated | grep nf-core + + - name: Post nf-core template version comment + uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2 + if: | + ${{ steps.nf_core_outdated.outputs.stdout }} =~ 'nf-core' + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + allow-repeats: false + message: | + ## :warning: New nf-core template version available + + Your pipeline is using an old version of the nf-core template: ${{ steps.read_yml.outputs['nf_core_version'] }}. + Please update your pipeline to the latest version. + + For more documentation on how to update your pipeline, please see the [nf-core documentation](https://github.com/nf-core/tools?tab=readme-ov-file#sync-a-pipeline-with-the-template) and [Synchronisation documentation](https://nf-co.re/docs/contributing/sync). From 7c1bb8a17ebe4b6e3a8afe27e4c78bdc42df01fb Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Mon, 13 May 2024 08:45:47 +0000 Subject: [PATCH 128/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f46a265cc..ba1d7da108 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ ### Linting +- Template: Lint pipelines with the nf-core template version and post comment if it is outdated ([#2978](https://github.com/nf-core/tools/pull/2978)) + ### Download ### Components From 940b3841e94b8368b5827aa356010e8700f3ead7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Mon, 13 May 2024 11:33:16 +0200 Subject: [PATCH 129/175] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- .../.github/workflows/template_version_comment.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nf_core/pipeline-template/.github/workflows/template_version_comment.yml b/nf_core/pipeline-template/.github/workflows/template_version_comment.yml index 2f49ab1269..e21283309d 100644 --- a/nf_core/pipeline-template/.github/workflows/template_version_comment.yml +++ b/nf_core/pipeline-template/.github/workflows/template_version_comment.yml @@ -31,10 +31,10 @@ jobs: if: | ${{ steps.nf_core_outdated.outputs.stdout }} =~ 'nf-core' with: - repo-token: ${{ secrets.GITHUB_TOKEN }} + repo-token: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} allow-repeats: false message: | - ## :warning: New nf-core template version available + ## :warning: Newer version of the nf-core template is available. Your pipeline is using an old version of the nf-core template: ${{ steps.read_yml.outputs['nf_core_version'] }}. Please update your pipeline to the latest version. From 961a17b1fc223bdd3a07cca42f6bbfdb0c147636 Mon Sep 17 00:00:00 2001 From: mashehu Date: Mon, 13 May 2024 11:44:35 +0200 Subject: [PATCH 130/175] fix links in api_ref index page --- docs/api/_src/index.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/api/_src/index.md b/docs/api/_src/index.md index 17bf2407f5..af3813bc51 100644 --- a/docs/api/_src/index.md +++ b/docs/api/_src/index.md @@ -16,7 +16,6 @@ This documentation is for the `nf-core/tools` package. ## Contents -- [Pipeline code lint tests](pipeline_lint_tests/index.md) (run by `nf-core lint`) -- [Module code lint tests](module_lint_tests/index.md) (run by `nf-core modules lint`) -- [Subworkflow code lint tests](subworkflow_lint_tests/index.md) (run by `nf-core subworkflows lint`) -- [nf-core/tools Python package API reference](api/index.md) +- [Pipeline code lint tests](pipeline_lint_tests/) (run by `nf-core lint`) +- [Module code lint tests](module_lint_tests/) (run by `nf-core modules lint`) +- [Subworkflow code lint tests](subworkflow_lint_tests/) (run by `nf-core subworkflows lint`) From 25c6ff47e000a18d2e59f343a26f183a7789c583 Mon Sep 17 00:00:00 2001 From: mashehu Date: Mon, 13 May 2024 15:01:38 +0200 Subject: [PATCH 131/175] update getting started link --- nf_core/create.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nf_core/create.py b/nf_core/create.py index b420b1c86d..59db7fa4af 100644 --- a/nf_core/create.py +++ b/nf_core/create.py @@ -259,8 +259,8 @@ def init_pipeline(self): "[green bold]!!!!!! IMPORTANT !!!!!!\n\n" "[green not bold]If you are interested in adding your pipeline to the nf-core community,\n" "PLEASE COME AND TALK TO US IN THE NF-CORE SLACK BEFORE WRITING ANY CODE!\n\n" - "[default]Please read: [link=https://nf-co.re/developers/adding_pipelines#join-the-community]" - "https://nf-co.re/developers/adding_pipelines#join-the-community[/link]" + "[default]Please read: [link=https://nf-co.re/docs/tutorials/adding_a_pipeline/overview#join-the-community]" + "https://nf-co.re/docs/tutorials/adding_a_pipeline/overview#join-the-community[/link]" ) def render_template(self): From c36741f7aef8a575e980390afb070c79eb744013 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 20:29:04 +0000 Subject: [PATCH 132/175] Update gitpod/workspace-base Docker digest to 92dd1bc --- nf_core/gitpod/gitpod.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/gitpod/gitpod.Dockerfile b/nf_core/gitpod/gitpod.Dockerfile index 6afca0e479..628421607f 100644 --- a/nf_core/gitpod/gitpod.Dockerfile +++ b/nf_core/gitpod/gitpod.Dockerfile @@ -1,7 +1,7 @@ # Test build locally before making a PR # docker build -t gitpod:test -f nf_core/gitpod/gitpod.Dockerfile . -FROM gitpod/workspace-base@sha256:124f2b8cbefe9b4abbb6a14538da8846770dde20b93f038d9551b6230aec1d1c +FROM gitpod/workspace-base@sha256:92dd1bcbd5a2fb466c81b1e4c21fc2495575546a9e6c53b3f7d4ba0b0c29c5be USER root From c8fc54bab9a67a3a0e95c60b639f80d8a5cb6a82 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Wed, 15 May 2024 04:39:25 +0000 Subject: [PATCH 133/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dd09482b1..70b606932b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ ### General - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.4 ([#2974](https://github.com/nf-core/tools/pull/2974)) +- Update gitpod/workspace-base Docker digest to 92dd1bc ([#2982](https://github.com/nf-core/tools/pull/2982)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From c448406b5e8ddae9d2c618db0ca464dbc97e7cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Famke=20Ba=CC=88uerle?= Date: Wed, 15 May 2024 14:21:04 +0200 Subject: [PATCH 134/175] update template according to PR 5281 in modules --- nf_core/module-template/tests/main.nf.test.j2 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nf_core/module-template/tests/main.nf.test.j2 b/nf_core/module-template/tests/main.nf.test.j2 index f31e92d659..1f70df64b0 100644 --- a/nf_core/module-template/tests/main.nf.test.j2 +++ b/nf_core/module-template/tests/main.nf.test.j2 @@ -28,10 +28,10 @@ nextflow_process { {% if has_meta %} input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.test_data['sarscov2']['illumina']['test_paired_end_bam'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) ] {%- else %} - input[0] = file(params.test_data['sarscov2']['illumina']['test_single_end_bam'], checkIfExists: true) + input[0] = file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true) {%- endif %} """ } @@ -60,10 +60,10 @@ nextflow_process { {% if has_meta %} input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.test_data['sarscov2']['illumina']['test_paired_end_bam'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) ] {%- else %} - input[0] = file(params.test_data['sarscov2']['illumina']['test_single_end_bam'], checkIfExists: true) + input[0] = file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true) {%- endif %} """ } From 4ca14b448471dd365c13b41dbe13c46254d24b2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Famke=20Ba=CC=88uerle?= Date: Wed, 15 May 2024 14:27:11 +0200 Subject: [PATCH 135/175] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e130d3c37b..02dc68cae2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # nf-core/tools: Changelog +### Template + +- Change paths to test data ([#2985](https://github.com/nf-core/tools/pull/2985)) + ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] ### Template From 51447b27afc787075048b0deb51d2737dcc43062 Mon Sep 17 00:00:00 2001 From: Maxime U Garcia Date: Wed, 15 May 2024 14:29:08 +0200 Subject: [PATCH 136/175] Apply suggestions from code review --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0338ec0bae..52b4d57350 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,5 @@ # nf-core/tools: Changelog - ## v2.14.2dev ### Template From 515ef02739a2da37701964c96798e2c2c1e15e8a Mon Sep 17 00:00:00 2001 From: Stephen Watts Date: Mon, 20 May 2024 14:24:55 +1000 Subject: [PATCH 137/175] Fix README.md admonition --- nf_core/pipeline-template/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nf_core/pipeline-template/README.md b/nf_core/pipeline-template/README.md index e6351b0c6f..ad0914f98d 100644 --- a/nf_core/pipeline-template/README.md +++ b/nf_core/pipeline-template/README.md @@ -80,8 +80,7 @@ nextflow run {{ name }} \ ``` > [!WARNING] -> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; -> see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). +> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). {% if is_nfcore -%} From 0fa391d2e8c846514d430776afdb8a1739708900 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 20 May 2024 16:32:48 +0200 Subject: [PATCH 138/175] fix contributing sentence --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4ed5e63734..85b608bf77 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ pip install --upgrade -r requirements-dev.txt -e . ## Contributions and Support -If you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md). +If you would like to contribute to this package, please see the [contributing guidelines](.github/CONTRIBUTING.md). For further information or help, don't hesitate to get in touch on the [Slack `#tools` channel](https://nfcore.slack.com/channels/tools) (you can join with [this invite](https://nf-co.re/join/slack)). From a70f8a80316bf580c408fef925ef01652191b912 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Mon, 20 May 2024 17:02:32 +0200 Subject: [PATCH 139/175] Update website docs link --- nf_core/pipeline-template/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/pipeline-template/README.md b/nf_core/pipeline-template/README.md index ad0914f98d..feece399b5 100644 --- a/nf_core/pipeline-template/README.md +++ b/nf_core/pipeline-template/README.md @@ -80,7 +80,7 @@ nextflow run {{ name }} \ ``` > [!WARNING] -> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). +> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files). {% if is_nfcore -%} From cfc06fe702a837f50487951e222997e9a6d4fb58 Mon Sep 17 00:00:00 2001 From: mashehu Date: Tue, 21 May 2024 07:40:26 +0200 Subject: [PATCH 140/175] update output of generation script for api docs to new structure --- docs/api/generate-api-docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/generate-api-docs.sh b/docs/api/generate-api-docs.sh index 6b3c3abfa3..f2b905c0c3 100644 --- a/docs/api/generate-api-docs.sh +++ b/docs/api/generate-api-docs.sh @@ -28,7 +28,7 @@ done # Set the output directory if not set if [[ -z "$output_dir" ]]; then - output_dir="../src/content/tools/docs" + output_dir="../src/content/api_reference" fi # if no release is specified, use all releases From db6f0d38ab665e229cfa24393528415e68fdeac2 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Tue, 21 May 2024 05:42:04 +0000 Subject: [PATCH 141/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70b606932b..16573a91e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.4 ([#2974](https://github.com/nf-core/tools/pull/2974)) - Update gitpod/workspace-base Docker digest to 92dd1bc ([#2982](https://github.com/nf-core/tools/pull/2982)) +- Update output of generation script for API docs to new structure ([#2988](https://github.com/nf-core/tools/pull/2988)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From 1d0d69135454ea080abee18a32636eb50bd8d2fb Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 21 May 2024 12:33:10 +0200 Subject: [PATCH 142/175] update test after updating bwa/mem module --- tests/components/generate_snapshot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/components/generate_snapshot.py b/tests/components/generate_snapshot.py index 3176569ec8..a5a8eaba39 100644 --- a/tests/components/generate_snapshot.py +++ b/tests/components/generate_snapshot.py @@ -91,7 +91,7 @@ def test_update_snapshot_module(self): snap_content = json.load(fh) original_timestamp = snap_content["Single-End"]["timestamp"] # delete the timestamp in json - snap_content["Single-End"]["content"][0]["0"][0][1] = "" + snap_content["Single-End"]["timestamp"] = "" with open(snap_path, "w") as fh: json.dump(snap_content, fh) snap_generator = ComponentsTest( From 49896ff1f42ab44b97f64f22c63455256473d214 Mon Sep 17 00:00:00 2001 From: Mahesh Binzer-Panchal Date: Tue, 21 May 2024 13:20:12 +0000 Subject: [PATCH 143/175] Add no clobber and put bash options on their own line --- nf_core/pipeline-template/nextflow.config | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/nf_core/pipeline-template/nextflow.config b/nf_core/pipeline-template/nextflow.config index 7648a5ebc3..4d1701bf76 100644 --- a/nf_core/pipeline-template/nextflow.config +++ b/nf_core/pipeline-template/nextflow.config @@ -220,8 +220,15 @@ env { JULIA_DEPOT_PATH = "/usr/local/share/julia" } -// Capture exit codes from upstream processes when piping -process.shell = ['/bin/bash', '-euo', 'pipefail'] +// Set bash options +process.shell = """\ +bash + +set -e # Exit if a tool returns a non-zero status/exit code +set -u # Treat unset variables and parameters as an error +set -o pipefail # Returns the status of the last command to exit with a non-zero status or zero if all successfully execute +set -C # No clobber - prevent output redirection from overwriting files. +""" // Disable process selector warnings by default. Use debug profile to enable warnings. nextflow.enable.configProcessNamesValidation = false From 589265e68164bf024654f83255e36509d425dc60 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Tue, 21 May 2024 13:23:11 +0000 Subject: [PATCH 144/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16573a91e2..06d8e1b5c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.4 ([#2974](https://github.com/nf-core/tools/pull/2974)) - Update gitpod/workspace-base Docker digest to 92dd1bc ([#2982](https://github.com/nf-core/tools/pull/2982)) - Update output of generation script for API docs to new structure ([#2988](https://github.com/nf-core/tools/pull/2988)) +- Add no clobber and put bash options on their own line ([#2991](https://github.com/nf-core/tools/pull/2991)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From e6b089b6e14ea2d8a1dd86a1b8454aec02e46b99 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 22:40:15 +0000 Subject: [PATCH 145/175] Update python:3.12-slim Docker digest to afc139a --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ae3a4e1a3d..fe4162b4fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.12-slim@sha256:2be8daddbb82756f7d1f2c7ece706aadcb284bf6ab6d769ea695cc3ed6016743 +FROM python:3.12-slim@sha256:afc139a0a640942491ec481ad8dda10f2c5b753f5c969393b12480155fe15a63 LABEL authors="phil.ewels@seqera.io,erik.danielsson@scilifelab.se" \ description="Docker image containing requirements for nf-core/tools" From 2220a743aafea764f97b8a7b186888e689b7b7b3 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 23 May 2024 12:30:23 +0200 Subject: [PATCH 146/175] update minimal textual version and snapshots accordingly --- requirements.txt | 2 +- tests/__snapshots__/test_create_app.ambr | 3031 +++++++++++----------- 2 files changed, 1516 insertions(+), 1517 deletions(-) diff --git a/requirements.txt b/requirements.txt index acf30f491d..44241e0d95 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,6 +21,6 @@ requests_cache rich-click>=1.6.1 rich>=13.3.1 tabulate -textual>=0.47.1 +textual>=0.63.1 trogon pdiff diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index c486ec4f8f..f5a519b133 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -22,253 +22,254 @@ font-weight: 700; } - .terminal-1527309810-matrix { + .terminal-3833894853-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1527309810-title { + .terminal-3833894853-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1527309810-r1 { fill: #c5c8c6 } - .terminal-1527309810-r2 { fill: #e3e3e3 } - .terminal-1527309810-r3 { fill: #989898 } - .terminal-1527309810-r4 { fill: #e1e1e1 } - .terminal-1527309810-r5 { fill: #121212 } - .terminal-1527309810-r6 { fill: #0053aa } - .terminal-1527309810-r7 { fill: #dde8f3;font-weight: bold } - .terminal-1527309810-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-1527309810-r9 { fill: #1e1e1e } - .terminal-1527309810-r10 { fill: #008139 } - .terminal-1527309810-r11 { fill: #e2e2e2 } - .terminal-1527309810-r12 { fill: #787878 } - .terminal-1527309810-r13 { fill: #b93c5b } - .terminal-1527309810-r14 { fill: #454a50 } - .terminal-1527309810-r15 { fill: #7ae998 } - .terminal-1527309810-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-1527309810-r17 { fill: #0a180e;font-weight: bold } - .terminal-1527309810-r18 { fill: #000000 } - .terminal-1527309810-r19 { fill: #ddedf9 } + .terminal-3833894853-r1 { fill: #c5c8c6 } + .terminal-3833894853-r2 { fill: #e3e3e3 } + .terminal-3833894853-r3 { fill: #989898 } + .terminal-3833894853-r4 { fill: #e1e1e1 } + .terminal-3833894853-r5 { fill: #4ebf71;font-weight: bold } + .terminal-3833894853-r6 { fill: #a5a5a5;font-style: italic; } + .terminal-3833894853-r7 { fill: #1e1e1e } + .terminal-3833894853-r8 { fill: #008139 } + .terminal-3833894853-r9 { fill: #121212 } + .terminal-3833894853-r10 { fill: #e2e2e2 } + .terminal-3833894853-r11 { fill: #787878 } + .terminal-3833894853-r12 { fill: #b93c5b } + .terminal-3833894853-r13 { fill: #454a50 } + .terminal-3833894853-r14 { fill: #7ae998 } + .terminal-3833894853-r15 { fill: #e2e3e3;font-weight: bold } + .terminal-3833894853-r16 { fill: #0a180e;font-weight: bold } + .terminal-3833894853-r17 { fill: #000000 } + .terminal-3833894853-r18 { fill: #fea62b;font-weight: bold } + .terminal-3833894853-r19 { fill: #a7a9ab } + .terminal-3833894853-r20 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackNext - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + Basic details + + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + +  d Toggle dark mode q Quit @@ -298,256 +299,257 @@ font-weight: 700; } - .terminal-2230840552-matrix { + .terminal-170499771-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2230840552-title { + .terminal-170499771-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2230840552-r1 { fill: #c5c8c6 } - .terminal-2230840552-r2 { fill: #e3e3e3 } - .terminal-2230840552-r3 { fill: #989898 } - .terminal-2230840552-r4 { fill: #e1e1e1 } - .terminal-2230840552-r5 { fill: #121212 } - .terminal-2230840552-r6 { fill: #0053aa } - .terminal-2230840552-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2230840552-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-2230840552-r9 { fill: #1e1e1e } - .terminal-2230840552-r10 { fill: #0f4e2a } - .terminal-2230840552-r11 { fill: #0178d4 } - .terminal-2230840552-r12 { fill: #a7a7a7 } - .terminal-2230840552-r13 { fill: #787878 } - .terminal-2230840552-r14 { fill: #e2e2e2 } - .terminal-2230840552-r15 { fill: #b93c5b } - .terminal-2230840552-r16 { fill: #454a50 } - .terminal-2230840552-r17 { fill: #7ae998 } - .terminal-2230840552-r18 { fill: #e2e3e3;font-weight: bold } - .terminal-2230840552-r19 { fill: #0a180e;font-weight: bold } - .terminal-2230840552-r20 { fill: #000000 } - .terminal-2230840552-r21 { fill: #008139 } - .terminal-2230840552-r22 { fill: #ddedf9 } + .terminal-170499771-r1 { fill: #c5c8c6 } + .terminal-170499771-r2 { fill: #e3e3e3 } + .terminal-170499771-r3 { fill: #989898 } + .terminal-170499771-r4 { fill: #e1e1e1 } + .terminal-170499771-r5 { fill: #4ebf71;font-weight: bold } + .terminal-170499771-r6 { fill: #a5a5a5;font-style: italic; } + .terminal-170499771-r7 { fill: #1e1e1e } + .terminal-170499771-r8 { fill: #0f4e2a } + .terminal-170499771-r9 { fill: #0178d4 } + .terminal-170499771-r10 { fill: #a7a7a7 } + .terminal-170499771-r11 { fill: #787878 } + .terminal-170499771-r12 { fill: #e2e2e2 } + .terminal-170499771-r13 { fill: #b93c5b } + .terminal-170499771-r14 { fill: #121212 } + .terminal-170499771-r15 { fill: #454a50 } + .terminal-170499771-r16 { fill: #7ae998 } + .terminal-170499771-r17 { fill: #e2e3e3;font-weight: bold } + .terminal-170499771-r18 { fill: #0a180e;font-weight: bold } + .terminal-170499771-r19 { fill: #000000 } + .terminal-170499771-r20 { fill: #008139 } + .terminal-170499771-r21 { fill: #fea62b;font-weight: bold } + .terminal-170499771-r22 { fill: #a7a9ab } + .terminal-170499771-r23 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackNext - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + Basic details + + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + +  d Toggle dark mode q Quit @@ -577,253 +579,251 @@ font-weight: 700; } - .terminal-3444045345-matrix { + .terminal-2364166316-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3444045345-title { + .terminal-2364166316-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3444045345-r1 { fill: #c5c8c6 } - .terminal-3444045345-r2 { fill: #e3e3e3 } - .terminal-3444045345-r3 { fill: #989898 } - .terminal-3444045345-r4 { fill: #e1e1e1 } - .terminal-3444045345-r5 { fill: #121212 } - .terminal-3444045345-r6 { fill: #0053aa } - .terminal-3444045345-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3444045345-r8 { fill: #24292f } - .terminal-3444045345-r9 { fill: #e2e3e3;font-weight: bold } - .terminal-3444045345-r10 { fill: #e2e3e3;font-weight: bold;font-style: italic; } - .terminal-3444045345-r11 { fill: #4ebf71;font-weight: bold } - .terminal-3444045345-r12 { fill: #e1e1e1;font-style: italic; } - .terminal-3444045345-r13 { fill: #7ae998 } - .terminal-3444045345-r14 { fill: #507bb3 } - .terminal-3444045345-r15 { fill: #008139 } - .terminal-3444045345-r16 { fill: #dde6ed;font-weight: bold } - .terminal-3444045345-r17 { fill: #001541 } - .terminal-3444045345-r18 { fill: #e1e1e1;text-decoration: underline; } - .terminal-3444045345-r19 { fill: #ddedf9 } + .terminal-2364166316-r1 { fill: #c5c8c6 } + .terminal-2364166316-r2 { fill: #e3e3e3 } + .terminal-2364166316-r3 { fill: #989898 } + .terminal-2364166316-r4 { fill: #e1e1e1 } + .terminal-2364166316-r5 { fill: #4ebf71;font-weight: bold } + .terminal-2364166316-r6 { fill: #4ebf71;text-decoration: underline; } + .terminal-2364166316-r7 { fill: #4ebf71;font-style: italic;;text-decoration: underline; } + .terminal-2364166316-r8 { fill: #e1e1e1;font-style: italic; } + .terminal-2364166316-r9 { fill: #7ae998 } + .terminal-2364166316-r10 { fill: #008139 } + .terminal-2364166316-r11 { fill: #507bb3 } + .terminal-2364166316-r12 { fill: #dde6ed;font-weight: bold } + .terminal-2364166316-r13 { fill: #001541 } + .terminal-2364166316-r14 { fill: #e1e1e1;text-decoration: underline; } + .terminal-2364166316-r15 { fill: #fea62b;font-weight: bold } + .terminal-2364166316-r16 { fill: #a7a9ab } + .terminal-2364166316-r17 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Choose pipeline type - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -        Choose "nf-core" if:              Choose "Custom" if:         - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ● You want your pipeline to be part of● Your pipeline will never be part of  - the nf-core communitynf-core - ● You think that there's an outside ● You want full control over all - chance that it ever could be part offeatures that are included from the  - nf-coretemplate (including those that are  - mandatory for nf-core). - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-core▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Custom - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -                                  What's the difference?                                  - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Choosing "nf-core" effectively pre-selects the following template features: - - ● GitHub Actions continuous-integration configuration files: - ▪ Pipeline test runs: Small-scale (GitHub) and large-scale (AWS) - ▪ Code formatting checks with Prettier - ▪ Auto-fix linting functionality using @nf-core-bot - ▪ Marking old issues as stale - ● Inclusion of shared nf-core configuration profiles - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + Choose pipeline type + + + + + Choose "nf-core" if:Choose "Custom" if: + + ● You want your pipeline to be part of the ● Your pipeline will never be part of  + nf-core communitynf-core + ● You think that there's an outside chance ● You want full control over all features  + that it ever could be part of nf-corethat are included from the template  + (including those that are mandatory for  + nf-core). + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-core + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Custom + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + What's the difference? + + Choosing "nf-core" effectively pre-selects the following template features: + + ● GitHub Actions continuous-integration configuration files: + ▪ Pipeline test runs: Small-scale (GitHub) and large-scale (AWS) + ▪ Code formatting checks with Prettier + ▪ Auto-fix linting functionality using @nf-core-bot + ▪ Marking old issues as stale + ● Inclusion of shared nf-core configuration profiles + + + + + + + + + + + + + + +  d Toggle dark mode q Quit @@ -853,257 +853,257 @@ font-weight: 700; } - .terminal-3071202289-matrix { + .terminal-3598234483-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3071202289-title { + .terminal-3598234483-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3071202289-r1 { fill: #c5c8c6 } - .terminal-3071202289-r2 { fill: #e3e3e3 } - .terminal-3071202289-r3 { fill: #989898 } - .terminal-3071202289-r4 { fill: #e1e1e1 } - .terminal-3071202289-r5 { fill: #121212 } - .terminal-3071202289-r6 { fill: #0053aa } - .terminal-3071202289-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3071202289-r8 { fill: #1e1e1e } - .terminal-3071202289-r9 { fill: #0178d4 } - .terminal-3071202289-r10 { fill: #454a50 } - .terminal-3071202289-r11 { fill: #e2e2e2 } - .terminal-3071202289-r12 { fill: #808080 } - .terminal-3071202289-r13 { fill: #e2e3e3;font-weight: bold } - .terminal-3071202289-r14 { fill: #000000 } - .terminal-3071202289-r15 { fill: #e4e4e4 } - .terminal-3071202289-r16 { fill: #14191f } - .terminal-3071202289-r17 { fill: #507bb3 } - .terminal-3071202289-r18 { fill: #dde6ed;font-weight: bold } - .terminal-3071202289-r19 { fill: #001541 } - .terminal-3071202289-r20 { fill: #7ae998 } - .terminal-3071202289-r21 { fill: #0a180e;font-weight: bold } - .terminal-3071202289-r22 { fill: #008139 } - .terminal-3071202289-r23 { fill: #ddedf9 } + .terminal-3598234483-r1 { fill: #c5c8c6 } + .terminal-3598234483-r2 { fill: #e3e3e3 } + .terminal-3598234483-r3 { fill: #989898 } + .terminal-3598234483-r4 { fill: #e1e1e1 } + .terminal-3598234483-r5 { fill: #4ebf71;font-weight: bold } + .terminal-3598234483-r6 { fill: #1e1e1e } + .terminal-3598234483-r7 { fill: #0178d4 } + .terminal-3598234483-r8 { fill: #454a50 } + .terminal-3598234483-r9 { fill: #e2e2e2 } + .terminal-3598234483-r10 { fill: #808080 } + .terminal-3598234483-r11 { fill: #e2e3e3;font-weight: bold } + .terminal-3598234483-r12 { fill: #000000 } + .terminal-3598234483-r13 { fill: #e4e4e4 } + .terminal-3598234483-r14 { fill: #14191f } + .terminal-3598234483-r15 { fill: #507bb3 } + .terminal-3598234483-r16 { fill: #dde6ed;font-weight: bold } + .terminal-3598234483-r17 { fill: #001541 } + .terminal-3598234483-r18 { fill: #7ae998 } + .terminal-3598234483-r19 { fill: #0a180e;font-weight: bold } + .terminal-3598234483-r20 { fill: #008139 } + .terminal-3598234483-r21 { fill: #fea62b;font-weight: bold } + .terminal-3598234483-r22 { fill: #a7a9ab } + .terminal-3598234483-r23 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Template features - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference The pipeline Hide help - ▁▁▁▁▁▁▁▁genomeswill be ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - configured to  - use a copy of  - the most common  - reference genome - files from  - iGenomes - - - Nf-core pipelines are configured to use a copy of the most  - common reference genome files. - - By selecting this option, your pipeline will include a  - configuration file specifying the paths to these files. - - The required code to use these files will also be included in  - the template. When the pipeline user provides an appropriate  - genome key, the pipeline will automatically download the ▂▂ - required reference files. - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github CI The pipeline Show help▅▅ - ▁▁▁▁▁▁▁▁testswill include ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - several GitHub  - actions for  - Continuous  - Integration (CI) - testing - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github The README.md Show help - ▁▁▁▁▁▁▁▁badgesfile of the ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - pipeline will  - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackContinue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + Template features + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference The pipeline will Hide help + ▁▁▁▁▁▁▁▁genomesbe configured to ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + use a copy of the  + most common  + reference genome  + files from  + iGenomes + + + Nf-core pipelines are configured to use a copy of the most common  + reference genome files. + + By selecting this option, your pipeline will include a configuration + file specifying the paths to these files. + + The required code to use these files will also be included in the  + template. When the pipeline user provides an appropriate genome key, + the pipeline will automatically download the required reference ▂▂ + files. + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github CI The pipeline will Show help + ▁▁▁▁▁▁▁▁testsinclude several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + GitHub actions for + Continuous  + Integration (CI)  + testing▄▄ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github badgesThe README.md fileShow help + ▁▁▁▁▁▁▁▁of the pipeline ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + will include  + GitHub badges + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  d Toggle dark mode q Quit @@ -1133,252 +1133,252 @@ font-weight: 700; } - .terminal-1456849374-matrix { + .terminal-1869771697-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1456849374-title { + .terminal-1869771697-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1456849374-r1 { fill: #c5c8c6 } - .terminal-1456849374-r2 { fill: #e3e3e3 } - .terminal-1456849374-r3 { fill: #989898 } - .terminal-1456849374-r4 { fill: #e1e1e1 } - .terminal-1456849374-r5 { fill: #121212 } - .terminal-1456849374-r6 { fill: #0053aa } - .terminal-1456849374-r7 { fill: #dde8f3;font-weight: bold } - .terminal-1456849374-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-1456849374-r9 { fill: #1e1e1e } - .terminal-1456849374-r10 { fill: #008139 } - .terminal-1456849374-r11 { fill: #e2e2e2 } - .terminal-1456849374-r12 { fill: #b93c5b } - .terminal-1456849374-r13 { fill: #454a50 } - .terminal-1456849374-r14 { fill: #7ae998 } - .terminal-1456849374-r15 { fill: #e2e3e3;font-weight: bold } - .terminal-1456849374-r16 { fill: #0a180e;font-weight: bold } - .terminal-1456849374-r17 { fill: #000000 } - .terminal-1456849374-r18 { fill: #ddedf9 } + .terminal-1869771697-r1 { fill: #c5c8c6 } + .terminal-1869771697-r2 { fill: #e3e3e3 } + .terminal-1869771697-r3 { fill: #989898 } + .terminal-1869771697-r4 { fill: #e1e1e1 } + .terminal-1869771697-r5 { fill: #4ebf71;font-weight: bold } + .terminal-1869771697-r6 { fill: #a5a5a5;font-style: italic; } + .terminal-1869771697-r7 { fill: #1e1e1e } + .terminal-1869771697-r8 { fill: #008139 } + .terminal-1869771697-r9 { fill: #e2e2e2 } + .terminal-1869771697-r10 { fill: #b93c5b } + .terminal-1869771697-r11 { fill: #454a50 } + .terminal-1869771697-r12 { fill: #7ae998 } + .terminal-1869771697-r13 { fill: #e2e3e3;font-weight: bold } + .terminal-1869771697-r14 { fill: #0a180e;font-weight: bold } + .terminal-1869771697-r15 { fill: #000000 } + .terminal-1869771697-r16 { fill: #fea62b;font-weight: bold } + .terminal-1869771697-r17 { fill: #a7a9ab } + .terminal-1869771697-r18 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Final details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - First version of the pipelinePath to the output directory where the pipeline  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created - 1.0.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackFinish - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + Final details + + + + First version of the pipelinePath to the output directory where the pipeline  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔will be created + 1.0.0dev▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackFinish + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  d Toggle dark mode q Quit @@ -1408,260 +1408,262 @@ font-weight: 700; } - .terminal-436990287-matrix { + .terminal-1242773313-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-436990287-title { + .terminal-1242773313-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-436990287-r1 { fill: #c5c8c6 } - .terminal-436990287-r2 { fill: #e3e3e3 } - .terminal-436990287-r3 { fill: #989898 } - .terminal-436990287-r4 { fill: #e1e1e1 } - .terminal-436990287-r5 { fill: #121212 } - .terminal-436990287-r6 { fill: #0053aa } - .terminal-436990287-r7 { fill: #dde8f3;font-weight: bold } - .terminal-436990287-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-436990287-r9 { fill: #1e1e1e } - .terminal-436990287-r10 { fill: #008139 } - .terminal-436990287-r11 { fill: #454a50 } - .terminal-436990287-r12 { fill: #787878 } - .terminal-436990287-r13 { fill: #e2e2e2 } - .terminal-436990287-r14 { fill: #e2e3e3;font-weight: bold } - .terminal-436990287-r15 { fill: #000000 } - .terminal-436990287-r16 { fill: #b93c5b } - .terminal-436990287-r17 { fill: #4ebf71 } - .terminal-436990287-r18 { fill: #e2e2e2;font-weight: bold } - .terminal-436990287-r19 { fill: #969696;font-weight: bold } - .terminal-436990287-r20 { fill: #808080 } - .terminal-436990287-r21 { fill: #7ae998 } - .terminal-436990287-r22 { fill: #507bb3 } - .terminal-436990287-r23 { fill: #0a180e;font-weight: bold } - .terminal-436990287-r24 { fill: #dde6ed;font-weight: bold } - .terminal-436990287-r25 { fill: #001541 } - .terminal-436990287-r26 { fill: #ddedf9 } + .terminal-1242773313-r1 { fill: #c5c8c6 } + .terminal-1242773313-r2 { fill: #e3e3e3 } + .terminal-1242773313-r3 { fill: #989898 } + .terminal-1242773313-r4 { fill: #e1e1e1 } + .terminal-1242773313-r5 { fill: #4ebf71;font-weight: bold } + .terminal-1242773313-r6 { fill: #18954b } + .terminal-1242773313-r7 { fill: #e2e2e2 } + .terminal-1242773313-r8 { fill: #e2e2e2;font-style: italic; } + .terminal-1242773313-r9 { fill: #e2e2e2;font-style: italic;;text-decoration: underline; } + .terminal-1242773313-r10 { fill: #a5a5a5;font-style: italic; } + .terminal-1242773313-r11 { fill: #1e1e1e } + .terminal-1242773313-r12 { fill: #008139 } + .terminal-1242773313-r13 { fill: #454a50 } + .terminal-1242773313-r14 { fill: #787878 } + .terminal-1242773313-r15 { fill: #e2e3e3;font-weight: bold } + .terminal-1242773313-r16 { fill: #000000 } + .terminal-1242773313-r17 { fill: #b93c5b } + .terminal-1242773313-r18 { fill: #e2e2e2;font-weight: bold } + .terminal-1242773313-r19 { fill: #969696;font-weight: bold } + .terminal-1242773313-r20 { fill: #808080 } + .terminal-1242773313-r21 { fill: #7ae998 } + .terminal-1242773313-r22 { fill: #507bb3 } + .terminal-1242773313-r23 { fill: #0a180e;font-weight: bold } + .terminal-1242773313-r24 { fill: #dde6ed;font-weight: bold } + .terminal-1242773313-r25 { fill: #001541 } + .terminal-1242773313-r26 { fill: #fea62b;font-weight: bold } + .terminal-1242773313-r27 { fill: #a7a9ab } + .terminal-1242773313-r28 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Now that we have created a new pipeline locally, we can create a new GitHub repository and  - push the code to it. - - - - Your GitHub usernameYour GitHub personal access token - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - The name of the organisation where the The name of the new GitHub repository - GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline - nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - ⚠️ You can't create a repository directly in the nf-core organisation. - Please create the pipeline repo to an organisation where you have access or use your user - account. A core-team member will be able to transfer the repo to nf-core once the  - development has started. - - 💡 Your GitHub user account will be used by default if nf-core is given as the org name. - - - ▔▔▔▔▔▔▔▔Private - Select to make the new GitHub repo private. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackCreate GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + Create GitHub repository + + Now that we have created a new pipeline locally, we can create a new GitHub repository and push  + the code to it. + + 💡 Found GitHub username in local GitHub CLI config + + + + Your GitHub usernameYour GitHub personal access token + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + The name of the organisation where the The name of the new GitHub repository + GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline + nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + ⚠️ You can't create a repository directly in the nf-core organisation. + Please create the pipeline repo to an organisation where you have access or use your user  + account. A core-team member will be able to transfer the repo to nf-core once the development + has started. + + 💡 Your GitHub user account will be used by default if nf-core is given as the org name. + + + ▔▔▔▔▔▔▔▔Private + Select to make the new GitHub repo private. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackCreate GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + +  d Toggle dark mode q Quit @@ -1691,255 +1693,254 @@ font-weight: 700; } - .terminal-2484211597-matrix { + .terminal-396289429-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2484211597-title { + .terminal-396289429-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2484211597-r1 { fill: #c5c8c6 } - .terminal-2484211597-r2 { fill: #e3e3e3 } - .terminal-2484211597-r3 { fill: #989898 } - .terminal-2484211597-r4 { fill: #e1e1e1 } - .terminal-2484211597-r5 { fill: #121212 } - .terminal-2484211597-r6 { fill: #0053aa } - .terminal-2484211597-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2484211597-r8 { fill: #98e024 } - .terminal-2484211597-r9 { fill: #626262 } - .terminal-2484211597-r10 { fill: #9d65ff } - .terminal-2484211597-r11 { fill: #fd971f } - .terminal-2484211597-r12 { fill: #4ebf71;font-weight: bold } - .terminal-2484211597-r13 { fill: #d2d2d2 } - .terminal-2484211597-r14 { fill: #82aaff } - .terminal-2484211597-r15 { fill: #eeffff } - .terminal-2484211597-r16 { fill: #4ebf71 } - .terminal-2484211597-r17 { fill: #e2e2e2 } - .terminal-2484211597-r18 { fill: #969696;font-weight: bold } - .terminal-2484211597-r19 { fill: #7ae998 } - .terminal-2484211597-r20 { fill: #008139 } - .terminal-2484211597-r21 { fill: #ddedf9 } + .terminal-396289429-r1 { fill: #c5c8c6 } + .terminal-396289429-r2 { fill: #e3e3e3 } + .terminal-396289429-r3 { fill: #989898 } + .terminal-396289429-r4 { fill: #e1e1e1 } + .terminal-396289429-r5 { fill: #4ebf71;font-weight: bold } + .terminal-396289429-r6 { fill: #98e024 } + .terminal-396289429-r7 { fill: #626262 } + .terminal-396289429-r8 { fill: #9d65ff } + .terminal-396289429-r9 { fill: #fd971f } + .terminal-396289429-r10 { fill: #d2d2d2 } + .terminal-396289429-r11 { fill: #82aaff } + .terminal-396289429-r12 { fill: #eeffff } + .terminal-396289429-r13 { fill: #18954b } + .terminal-396289429-r14 { fill: #e2e2e2 } + .terminal-396289429-r15 { fill: #969696;font-weight: bold } + .terminal-396289429-r16 { fill: #7ae998 } + .terminal-396289429-r17 { fill: #008139 } + .terminal-396289429-r18 { fill: #fea62b;font-weight: bold } + .terminal-396289429-r19 { fill: #a7a9ab } + .terminal-396289429-r20 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - HowTo create a GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - -                                           ,--./,-. -           ___     __   __   __   ___     /,-._.--~\  -     |\ | |__  __ /  ` /  \ |__) |__         }  { -     | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                           `._,._,' - - If you would like to create the GitHub repository later, you can do it manually by following - these steps: - -  1. Create a new GitHub repository -  2. Add the remote to your local repository: - - - cd<pipeline_directory> - gitremoteaddorigingit@github.com:<username>/<repo_name>.git - - -  3. Push the code to the remote: - - - gitpush--allorigin - - - 💡 Note the --all flag: this is needed to push all branches to the remote. - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + HowTo create a GitHub repository + + + +                                           ,--./,-. +           ___     __   __   __   ___     /,-._.--~\  +     |\ | |__  __ /  ` /  \ |__) |__         }  { +     | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                           `._,._,' + + If you would like to create the GitHub repository later, you can do it manually by following  + these steps: + +  1. Create a new GitHub repository +  2. Add the remote to your local repository: + + + cd<pipeline_directory> + gitremoteaddorigingit@github.com:<username>/<repo_name>.git + + +  3. Push the code to the remote: + + + gitpush--allorigin + + + 💡 Note the --all flag: this is needed to push all branches to the remote. + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + +  d Toggle dark mode q Quit @@ -1969,248 +1970,247 @@ font-weight: 700; } - .terminal-4165331380-matrix { + .terminal-3492397142-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4165331380-title { + .terminal-3492397142-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4165331380-r1 { fill: #c5c8c6 } - .terminal-4165331380-r2 { fill: #e3e3e3 } - .terminal-4165331380-r3 { fill: #989898 } - .terminal-4165331380-r4 { fill: #e1e1e1 } - .terminal-4165331380-r5 { fill: #121212 } - .terminal-4165331380-r6 { fill: #0053aa } - .terminal-4165331380-r7 { fill: #dde8f3;font-weight: bold } - .terminal-4165331380-r8 { fill: #7ae998 } - .terminal-4165331380-r9 { fill: #507bb3 } - .terminal-4165331380-r10 { fill: #4ebf71;font-weight: bold } - .terminal-4165331380-r11 { fill: #dde6ed;font-weight: bold } - .terminal-4165331380-r12 { fill: #008139 } - .terminal-4165331380-r13 { fill: #001541 } - .terminal-4165331380-r14 { fill: #ddedf9 } + .terminal-3492397142-r1 { fill: #c5c8c6 } + .terminal-3492397142-r2 { fill: #e3e3e3 } + .terminal-3492397142-r3 { fill: #989898 } + .terminal-3492397142-r4 { fill: #e1e1e1 } + .terminal-3492397142-r5 { fill: #4ebf71;font-weight: bold } + .terminal-3492397142-r6 { fill: #7ae998 } + .terminal-3492397142-r7 { fill: #507bb3 } + .terminal-3492397142-r8 { fill: #dde6ed;font-weight: bold } + .terminal-3492397142-r9 { fill: #008139 } + .terminal-3492397142-r10 { fill: #001541 } + .terminal-3492397142-r11 { fill: #fea62b;font-weight: bold } + .terminal-3492397142-r12 { fill: #a7a9ab } + .terminal-3492397142-r13 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Create GitHub repository - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - After creating the pipeline template locally, we can create a GitHub repository and push the - code to it. - - Do you want to create a GitHub repository? - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Create GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + Create GitHub repository + + + After creating the pipeline template locally, we can create a GitHub repository and push the  + code to it. + + Do you want to create a GitHub repository? + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Create GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  d Toggle dark mode q Quit @@ -2240,254 +2240,254 @@ font-weight: 700; } - .terminal-3459022791-matrix { + .terminal-4082092032-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3459022791-title { + .terminal-4082092032-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3459022791-r1 { fill: #c5c8c6 } - .terminal-3459022791-r2 { fill: #e3e3e3 } - .terminal-3459022791-r3 { fill: #989898 } - .terminal-3459022791-r4 { fill: #e1e1e1 } - .terminal-3459022791-r5 { fill: #121212 } - .terminal-3459022791-r6 { fill: #0053aa } - .terminal-3459022791-r7 { fill: #dde8f3;font-weight: bold } - .terminal-3459022791-r8 { fill: #1e1e1e } - .terminal-3459022791-r9 { fill: #507bb3 } - .terminal-3459022791-r10 { fill: #e2e2e2 } - .terminal-3459022791-r11 { fill: #808080 } - .terminal-3459022791-r12 { fill: #dde6ed;font-weight: bold } - .terminal-3459022791-r13 { fill: #001541 } - .terminal-3459022791-r14 { fill: #454a50 } - .terminal-3459022791-r15 { fill: #7ae998 } - .terminal-3459022791-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-3459022791-r17 { fill: #0a180e;font-weight: bold } - .terminal-3459022791-r18 { fill: #000000 } - .terminal-3459022791-r19 { fill: #008139 } - .terminal-3459022791-r20 { fill: #ddedf9 } + .terminal-4082092032-r1 { fill: #c5c8c6 } + .terminal-4082092032-r2 { fill: #e3e3e3 } + .terminal-4082092032-r3 { fill: #989898 } + .terminal-4082092032-r4 { fill: #e1e1e1 } + .terminal-4082092032-r5 { fill: #4ebf71;font-weight: bold } + .terminal-4082092032-r6 { fill: #1e1e1e } + .terminal-4082092032-r7 { fill: #507bb3 } + .terminal-4082092032-r8 { fill: #e2e2e2 } + .terminal-4082092032-r9 { fill: #808080 } + .terminal-4082092032-r10 { fill: #dde6ed;font-weight: bold } + .terminal-4082092032-r11 { fill: #001541 } + .terminal-4082092032-r12 { fill: #454a50 } + .terminal-4082092032-r13 { fill: #7ae998 } + .terminal-4082092032-r14 { fill: #e2e3e3;font-weight: bold } + .terminal-4082092032-r15 { fill: #0a180e;font-weight: bold } + .terminal-4082092032-r16 { fill: #000000 } + .terminal-4082092032-r17 { fill: #008139 } + .terminal-4082092032-r18 { fill: #fea62b;font-weight: bold } + .terminal-4082092032-r19 { fill: #a7a9ab } + .terminal-4082092032-r20 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Template features - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference The pipeline willShow help - ▁▁▁▁▁▁▁▁genomesbe configured to ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - use a copy of the - most common  - reference genome  - files from  - iGenomes - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github CI The pipeline willShow help - ▁▁▁▁▁▁▁▁testsinclude several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - GitHub actions  - for Continuous  - Integration (CI)  - testing - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add Github badgesThe README.md Show help - ▁▁▁▁▁▁▁▁file of the ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - pipeline will  - include GitHub  - badges - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Add configurationThe pipeline willShow help - ▁▁▁▁▁▁▁▁filesinclude ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - configuration  - profiles  - containing custom - parameters  - requried to run  - nf-core pipelines - at different  - institutions - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackContinue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + Template features + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference The pipeline will Show help + ▁▁▁▁▁▁▁▁genomesbe configured to ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + use a copy of the  + most common  + reference genome  + files from iGenomes + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github CI testsThe pipeline will Show help + ▁▁▁▁▁▁▁▁include several ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + GitHub actions for  + Continuous  + Integration (CI)  + testing + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add Github badgesThe README.md file Show help + ▁▁▁▁▁▁▁▁of the pipeline ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + will include GitHub + badges + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Add configuration The pipeline will Show help + ▁▁▁▁▁▁▁▁filesinclude ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + configuration  + profiles containing + custom parameters  + requried to run  + nf-core pipelines  + at different  + institutions + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  d Toggle dark mode q Quit @@ -2517,254 +2517,254 @@ font-weight: 700; } - .terminal-461754173-matrix { + .terminal-1639960877-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-461754173-title { + .terminal-1639960877-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-461754173-r1 { fill: #c5c8c6 } - .terminal-461754173-r2 { fill: #e3e3e3 } - .terminal-461754173-r3 { fill: #989898 } - .terminal-461754173-r4 { fill: #e1e1e1 } - .terminal-461754173-r5 { fill: #121212 } - .terminal-461754173-r6 { fill: #0053aa } - .terminal-461754173-r7 { fill: #dde8f3;font-weight: bold } - .terminal-461754173-r8 { fill: #1e1e1e } - .terminal-461754173-r9 { fill: #507bb3 } - .terminal-461754173-r10 { fill: #e2e2e2 } - .terminal-461754173-r11 { fill: #808080 } - .terminal-461754173-r12 { fill: #dde6ed;font-weight: bold } - .terminal-461754173-r13 { fill: #001541 } - .terminal-461754173-r14 { fill: #454a50 } - .terminal-461754173-r15 { fill: #7ae998 } - .terminal-461754173-r16 { fill: #e2e3e3;font-weight: bold } - .terminal-461754173-r17 { fill: #0a180e;font-weight: bold } - .terminal-461754173-r18 { fill: #000000 } - .terminal-461754173-r19 { fill: #008139 } - .terminal-461754173-r20 { fill: #ddedf9 } + .terminal-1639960877-r1 { fill: #c5c8c6 } + .terminal-1639960877-r2 { fill: #e3e3e3 } + .terminal-1639960877-r3 { fill: #989898 } + .terminal-1639960877-r4 { fill: #e1e1e1 } + .terminal-1639960877-r5 { fill: #4ebf71;font-weight: bold } + .terminal-1639960877-r6 { fill: #1e1e1e } + .terminal-1639960877-r7 { fill: #507bb3 } + .terminal-1639960877-r8 { fill: #e2e2e2 } + .terminal-1639960877-r9 { fill: #808080 } + .terminal-1639960877-r10 { fill: #dde6ed;font-weight: bold } + .terminal-1639960877-r11 { fill: #001541 } + .terminal-1639960877-r12 { fill: #454a50 } + .terminal-1639960877-r13 { fill: #7ae998 } + .terminal-1639960877-r14 { fill: #e2e3e3;font-weight: bold } + .terminal-1639960877-r15 { fill: #0a180e;font-weight: bold } + .terminal-1639960877-r16 { fill: #000000 } + .terminal-1639960877-r17 { fill: #008139 } + .terminal-1639960877-r18 { fill: #fea62b;font-weight: bold } + .terminal-1639960877-r19 { fill: #a7a9ab } + .terminal-1639960877-r20 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Template features - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Use reference The pipeline willShow help - ▁▁▁▁▁▁▁▁genomesbe configured to ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - use a copy of the - most common  - reference genome  - files from  - iGenomes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackContinue - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + Template features + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Use reference The pipeline will Show help + ▁▁▁▁▁▁▁▁genomesbe configured to ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + use a copy of the  + most common  + reference genome  + files from iGenomes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackContinue + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  d Toggle dark mode q Quit @@ -2794,256 +2794,256 @@ font-weight: 700; } - .terminal-2179958535-matrix { + .terminal-2625911002-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2179958535-title { + .terminal-2625911002-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2179958535-r1 { fill: #c5c8c6 } - .terminal-2179958535-r2 { fill: #e3e3e3 } - .terminal-2179958535-r3 { fill: #989898 } - .terminal-2179958535-r4 { fill: #e1e1e1 } - .terminal-2179958535-r5 { fill: #121212 } - .terminal-2179958535-r6 { fill: #0053aa } - .terminal-2179958535-r7 { fill: #dde8f3;font-weight: bold } - .terminal-2179958535-r8 { fill: #a5a5a5;font-style: italic; } - .terminal-2179958535-r9 { fill: #1e1e1e } - .terminal-2179958535-r10 { fill: #0f4e2a } - .terminal-2179958535-r11 { fill: #7b3042 } - .terminal-2179958535-r12 { fill: #a7a7a7 } - .terminal-2179958535-r13 { fill: #787878 } - .terminal-2179958535-r14 { fill: #e2e2e2 } - .terminal-2179958535-r15 { fill: #b93c5b } - .terminal-2179958535-r16 { fill: #454a50 } - .terminal-2179958535-r17 { fill: #166d39 } - .terminal-2179958535-r18 { fill: #e2e3e3;font-weight: bold } - .terminal-2179958535-r19 { fill: #3c8b54;font-weight: bold } - .terminal-2179958535-r20 { fill: #000000 } - .terminal-2179958535-r21 { fill: #5aa86f } - .terminal-2179958535-r22 { fill: #ddedf9 } + .terminal-2625911002-r1 { fill: #c5c8c6 } + .terminal-2625911002-r2 { fill: #e3e3e3 } + .terminal-2625911002-r3 { fill: #989898 } + .terminal-2625911002-r4 { fill: #e1e1e1 } + .terminal-2625911002-r5 { fill: #4ebf71;font-weight: bold } + .terminal-2625911002-r6 { fill: #a5a5a5;font-style: italic; } + .terminal-2625911002-r7 { fill: #1e1e1e } + .terminal-2625911002-r8 { fill: #0f4e2a } + .terminal-2625911002-r9 { fill: #7b3042 } + .terminal-2625911002-r10 { fill: #a7a7a7 } + .terminal-2625911002-r11 { fill: #787878 } + .terminal-2625911002-r12 { fill: #e2e2e2 } + .terminal-2625911002-r13 { fill: #b93c5b } + .terminal-2625911002-r14 { fill: #454a50 } + .terminal-2625911002-r15 { fill: #166d39 } + .terminal-2625911002-r16 { fill: #e2e3e3;font-weight: bold } + .terminal-2625911002-r17 { fill: #3c8b54;font-weight: bold } + .terminal-2625911002-r18 { fill: #000000 } + .terminal-2625911002-r19 { fill: #5aa86f } + .terminal-2625911002-r20 { fill: #fea62b;font-weight: bold } + .terminal-2625911002-r21 { fill: #a7a9ab } + .terminal-2625911002-r22 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Basic details - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - GitHub organisationWorkflow name - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - nf-corePipeline Name - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Must be lowercase without  - punctuation. - - A short description of your pipeline. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Description - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Cannot be left empty. - - Name of the main author / authors - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Author(s) - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Value error, Cannot be left empty. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackNext - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + Basic details + + + + GitHub organisationWorkflow name + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + nf-corePipeline Name + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Must be lowercase without  + punctuation. + + A short description of your pipeline. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Description + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + + Name of the main author / authors + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Author(s) + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Value error, Cannot be left empty. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackNext + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + +  d Toggle dark mode q Quit @@ -3073,254 +3073,253 @@ font-weight: 700; } - .terminal-1144763792-matrix { + .terminal-3787732750-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1144763792-title { + .terminal-3787732750-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1144763792-r1 { fill: #c5c8c6 } - .terminal-1144763792-r2 { fill: #e3e3e3 } - .terminal-1144763792-r3 { fill: #989898 } - .terminal-1144763792-r4 { fill: #98e024 } - .terminal-1144763792-r5 { fill: #626262 } - .terminal-1144763792-r6 { fill: #9d65ff } - .terminal-1144763792-r7 { fill: #fd971f } - .terminal-1144763792-r8 { fill: #e1e1e1 } - .terminal-1144763792-r9 { fill: #121212 } - .terminal-1144763792-r10 { fill: #0053aa } - .terminal-1144763792-r11 { fill: #dde8f3;font-weight: bold } - .terminal-1144763792-r12 { fill: #e1e1e1;text-decoration: underline; } - .terminal-1144763792-r13 { fill: #4ebf71 } - .terminal-1144763792-r14 { fill: #e2e2e2 } - .terminal-1144763792-r15 { fill: #e2e2e2;text-decoration: underline; } - .terminal-1144763792-r16 { fill: #e2e2e2;font-weight: bold;font-style: italic; } - .terminal-1144763792-r17 { fill: #7ae998 } - .terminal-1144763792-r18 { fill: #4ebf71;font-weight: bold } - .terminal-1144763792-r19 { fill: #008139 } - .terminal-1144763792-r20 { fill: #ddedf9 } + .terminal-3787732750-r1 { fill: #c5c8c6 } + .terminal-3787732750-r2 { fill: #e3e3e3 } + .terminal-3787732750-r3 { fill: #989898 } + .terminal-3787732750-r4 { fill: #98e024 } + .terminal-3787732750-r5 { fill: #626262 } + .terminal-3787732750-r6 { fill: #9d65ff } + .terminal-3787732750-r7 { fill: #fd971f } + .terminal-3787732750-r8 { fill: #e1e1e1 } + .terminal-3787732750-r9 { fill: #4ebf71;font-weight: bold } + .terminal-3787732750-r10 { fill: #e1e1e1;text-decoration: underline; } + .terminal-3787732750-r11 { fill: #18954b } + .terminal-3787732750-r12 { fill: #e2e2e2 } + .terminal-3787732750-r13 { fill: #e2e2e2;text-decoration: underline; } + .terminal-3787732750-r14 { fill: #e2e2e2;font-weight: bold;font-style: italic; } + .terminal-3787732750-r15 { fill: #7ae998 } + .terminal-3787732750-r16 { fill: #008139 } + .terminal-3787732750-r17 { fill: #fea62b;font-weight: bold } + .terminal-3787732750-r18 { fill: #a7a9ab } + .terminal-3787732750-r19 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - -                                           ,--./,-. -           ___     __   __   __   ___     /,-._.--~\  -     |\ | |__  __ /  ` /  \ |__) |__         }  { -     | \| |       \__, \__/ |  \ |___     \`-._,-`-, -                                           `._,._,' - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Welcome to the nf-core pipeline creation wizard - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - This app will help you create a new Nextflow pipeline from the nf-core/tools pipeline  - template. - - The template helps anyone benefit from nf-core best practices, and is a requirement for  - nf-core pipelines. - - 💡 If you want to add a pipeline to nf-core, please join on Slack and discuss your plans  - with the community as early as possible; ideally before you start on your pipeline! See  - the nf-core guidelines and the #new-pipelines Slack channel for more information. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Let's go! - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - -  D  Toggle dark mode  Q  Quit  + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + +                                           ,--./,-. +           ___     __   __   __   ___     /,-._.--~\  +     |\ | |__  __ /  ` /  \ |__) |__         }  { +     | \| |       \__, \__/ |  \ |___     \`-._,-`-, +                                           `._,._,' + + + + Welcome to the nf-core pipeline creation wizard + + This app will help you create a new Nextflow pipeline from the nf-core/tools pipeline template. + + The template helps anyone benefit from nf-core best practices, and is a requirement for nf-core  + pipelines. + + 💡 If you want to add a pipeline to nf-core, please join on Slack and discuss your plans with + the community as early as possible; ideally before you start on your pipeline! See the  + nf-core guidelines and the #new-pipelines Slack channel for more information. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Let's go! + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + +  d Toggle dark mode q Quit From d77af41897561d70b99efbda87a223c7c05cf816 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Thu, 23 May 2024 11:07:10 +0000 Subject: [PATCH 147/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1b3a97663..16262bd1c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Update gitpod/workspace-base Docker digest to 92dd1bc ([#2982](https://github.com/nf-core/tools/pull/2982)) - Update output of generation script for API docs to new structure ([#2988](https://github.com/nf-core/tools/pull/2988)) - Add no clobber and put bash options on their own line ([#2991](https://github.com/nf-core/tools/pull/2991)) +- update minimal textual version and snapshots ([#2998](https://github.com/nf-core/tools/pull/2998)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From 8f6c8fb5ff34eecf2f9b0c502753de77123641b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Thu, 23 May 2024 11:21:49 +0000 Subject: [PATCH 148/175] update snapshots fom gitpod --- tests/__snapshots__/test_create_app.ambr | 266 +++++++++--------- .../pytest-0/test_github_details0 | 1 + .../pytest-0/test_github_exit_message0 | 1 + .../pytest-0/test_github_question0 | 1 + 4 files changed, 135 insertions(+), 134 deletions(-) create mode 160000 tmp/pytest-of-gitpod/pytest-0/test_github_details0 create mode 160000 tmp/pytest-of-gitpod/pytest-0/test_github_exit_message0 create mode 160000 tmp/pytest-of-gitpod/pytest-0/test_github_question0 diff --git a/tests/__snapshots__/test_create_app.ambr b/tests/__snapshots__/test_create_app.ambr index f5a519b133..ed7bf8b256 100644 --- a/tests/__snapshots__/test_create_app.ambr +++ b/tests/__snapshots__/test_create_app.ambr @@ -1408,262 +1408,260 @@ font-weight: 700; } - .terminal-1242773313-matrix { + .terminal-3893066652-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1242773313-title { + .terminal-3893066652-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1242773313-r1 { fill: #c5c8c6 } - .terminal-1242773313-r2 { fill: #e3e3e3 } - .terminal-1242773313-r3 { fill: #989898 } - .terminal-1242773313-r4 { fill: #e1e1e1 } - .terminal-1242773313-r5 { fill: #4ebf71;font-weight: bold } - .terminal-1242773313-r6 { fill: #18954b } - .terminal-1242773313-r7 { fill: #e2e2e2 } - .terminal-1242773313-r8 { fill: #e2e2e2;font-style: italic; } - .terminal-1242773313-r9 { fill: #e2e2e2;font-style: italic;;text-decoration: underline; } - .terminal-1242773313-r10 { fill: #a5a5a5;font-style: italic; } - .terminal-1242773313-r11 { fill: #1e1e1e } - .terminal-1242773313-r12 { fill: #008139 } - .terminal-1242773313-r13 { fill: #454a50 } - .terminal-1242773313-r14 { fill: #787878 } - .terminal-1242773313-r15 { fill: #e2e3e3;font-weight: bold } - .terminal-1242773313-r16 { fill: #000000 } - .terminal-1242773313-r17 { fill: #b93c5b } - .terminal-1242773313-r18 { fill: #e2e2e2;font-weight: bold } - .terminal-1242773313-r19 { fill: #969696;font-weight: bold } - .terminal-1242773313-r20 { fill: #808080 } - .terminal-1242773313-r21 { fill: #7ae998 } - .terminal-1242773313-r22 { fill: #507bb3 } - .terminal-1242773313-r23 { fill: #0a180e;font-weight: bold } - .terminal-1242773313-r24 { fill: #dde6ed;font-weight: bold } - .terminal-1242773313-r25 { fill: #001541 } - .terminal-1242773313-r26 { fill: #fea62b;font-weight: bold } - .terminal-1242773313-r27 { fill: #a7a9ab } - .terminal-1242773313-r28 { fill: #e2e3e3 } + .terminal-3893066652-r1 { fill: #c5c8c6 } + .terminal-3893066652-r2 { fill: #e3e3e3 } + .terminal-3893066652-r3 { fill: #989898 } + .terminal-3893066652-r4 { fill: #e1e1e1 } + .terminal-3893066652-r5 { fill: #4ebf71;font-weight: bold } + .terminal-3893066652-r6 { fill: #a5a5a5;font-style: italic; } + .terminal-3893066652-r7 { fill: #1e1e1e } + .terminal-3893066652-r8 { fill: #008139 } + .terminal-3893066652-r9 { fill: #454a50 } + .terminal-3893066652-r10 { fill: #787878 } + .terminal-3893066652-r11 { fill: #e2e2e2 } + .terminal-3893066652-r12 { fill: #e2e3e3;font-weight: bold } + .terminal-3893066652-r13 { fill: #000000 } + .terminal-3893066652-r14 { fill: #b93c5b } + .terminal-3893066652-r15 { fill: #18954b } + .terminal-3893066652-r16 { fill: #e2e2e2;font-weight: bold } + .terminal-3893066652-r17 { fill: #969696;font-weight: bold } + .terminal-3893066652-r18 { fill: #808080 } + .terminal-3893066652-r19 { fill: #7ae998 } + .terminal-3893066652-r20 { fill: #507bb3 } + .terminal-3893066652-r21 { fill: #0a180e;font-weight: bold } + .terminal-3893066652-r22 { fill: #dde6ed;font-weight: bold } + .terminal-3893066652-r23 { fill: #001541 } + .terminal-3893066652-r24 { fill: #fea62b;font-weight: bold } + .terminal-3893066652-r25 { fill: #a7a9ab } + .terminal-3893066652-r26 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - nf-core create + nf-core create - - - - nf-core create — Create a new pipeline with the nf-core pipeline template - - - Create GitHub repository - - Now that we have created a new pipeline locally, we can create a new GitHub repository and push  - the code to it. - - 💡 Found GitHub username in local GitHub CLI config - - - - Your GitHub usernameYour GitHub personal access token - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - The name of the organisation where the The name of the new GitHub repository - GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline - nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - ⚠️ You can't create a repository directly in the nf-core organisation. - Please create the pipeline repo to an organisation where you have access or use your user  - account. A core-team member will be able to transfer the repo to nf-core once the development - has started. - - 💡 Your GitHub user account will be used by default if nf-core is given as the org name. - - - ▔▔▔▔▔▔▔▔Private - Select to make the new GitHub repo private. - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - BackCreate GitHub repoFinish without creating a repo - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - -  d Toggle dark mode q Quit + + + + nf-core create — Create a new pipeline with the nf-core pipeline template + + + Create GitHub repository + + Now that we have created a new pipeline locally, we can create a new GitHub repository and push  + the code to it. + + + + Your GitHub usernameYour GitHub personal access token + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔for login.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + GitHub username▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Show + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁GitHub token▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + The name of the organisation where the The name of the new GitHub repository + GitHub repo will be cretaed▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mypipeline + nf-core▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + ⚠️ You can't create a repository directly in the nf-core organisation. + Please create the pipeline repo to an organisation where you have access or use your user  + account. A core-team member will be able to transfer the repo to nf-core once the development + has started. + + 💡 Your GitHub user account will be used by default if nf-core is given as the org name. + + + ▔▔▔▔▔▔▔▔Private + Select to make the new GitHub repo private. + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + BackCreate GitHub repoFinish without creating a repo + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + +  d Toggle dark mode q Quit diff --git a/tmp/pytest-of-gitpod/pytest-0/test_github_details0 b/tmp/pytest-of-gitpod/pytest-0/test_github_details0 new file mode 160000 index 0000000000..19fc648c4a --- /dev/null +++ b/tmp/pytest-of-gitpod/pytest-0/test_github_details0 @@ -0,0 +1 @@ +Subproject commit 19fc648c4a1fc31b474b13cbfebd322ce9538b95 diff --git a/tmp/pytest-of-gitpod/pytest-0/test_github_exit_message0 b/tmp/pytest-of-gitpod/pytest-0/test_github_exit_message0 new file mode 160000 index 0000000000..75465e6bd7 --- /dev/null +++ b/tmp/pytest-of-gitpod/pytest-0/test_github_exit_message0 @@ -0,0 +1 @@ +Subproject commit 75465e6bd715b1bf9075c7efbce1f2dd38c4df37 diff --git a/tmp/pytest-of-gitpod/pytest-0/test_github_question0 b/tmp/pytest-of-gitpod/pytest-0/test_github_question0 new file mode 160000 index 0000000000..07281e3aa6 --- /dev/null +++ b/tmp/pytest-of-gitpod/pytest-0/test_github_question0 @@ -0,0 +1 @@ +Subproject commit 07281e3aa6aef6d8a282c1cafaf7defaef745565 From e9740b6454df2b238fd2c7a1ab407eee9b193029 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 May 2024 12:03:25 +0000 Subject: [PATCH 149/175] Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.5 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4b1941d81e..01bd13a9e9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.4 + rev: v0.4.5 hooks: - id: ruff # linter args: [--fix, --exit-non-zero-on-fix] # sort imports and fix From e7136379bbadd7d3c883a9c80be3d37ce68a307c Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 27 May 2024 13:06:23 +0200 Subject: [PATCH 150/175] return directory if base_dir is the root directory --- nf_core/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/utils.py b/nf_core/utils.py index 8c50f0a49f..1a1e8a2a99 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -1069,7 +1069,7 @@ def determine_base_dir(directory="."): config_fn = get_first_available_path(base_dir, CONFIG_PATHS) if config_fn: break - return directory if base_dir == start_dir else base_dir + return directory if (base_dir == start_dir or str(base_dir) == base_dir.root) else base_dir def get_first_available_path(directory, paths): From ae47db3608feaa95cb9165a876740fcee96534ac Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Mon, 27 May 2024 11:07:57 +0000 Subject: [PATCH 151/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16262bd1c3..a5795245a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Update output of generation script for API docs to new structure ([#2988](https://github.com/nf-core/tools/pull/2988)) - Add no clobber and put bash options on their own line ([#2991](https://github.com/nf-core/tools/pull/2991)) - update minimal textual version and snapshots ([#2998](https://github.com/nf-core/tools/pull/2998)) +- return directory if base_dir is the root directory ([#3003](https://github.com/nf-core/tools/pull/3003)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From efd397d94ee223f8dd60f1c3a88a04211bc4b27e Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke Date: Mon, 27 May 2024 14:39:17 +0200 Subject: [PATCH 152/175] add org to main.nf.test tag --- nf_core/components/create.py | 4 ++++ nf_core/module-template/tests/main.nf.test.j2 | 2 +- nf_core/subworkflow-template/tests/main.nf.test.j2 | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/nf_core/components/create.py b/nf_core/components/create.py index 6c9c01b496..e603db3857 100644 --- a/nf_core/components/create.py +++ b/nf_core/components/create.py @@ -157,6 +157,10 @@ def create(self): if self.component_type == "modules": self._get_module_structure_components() + # Add a valid organization name for nf-test tags + not_alphabet = re.compile(r'[^a-zA-Z]') + self.org_alphabet = not_alphabet.sub('', self.org) + # Create component template with jinja2 self._render_template() log.info(f"Created component template: '{self.component_name}'") diff --git a/nf_core/module-template/tests/main.nf.test.j2 b/nf_core/module-template/tests/main.nf.test.j2 index 1f70df64b0..456c989f85 100644 --- a/nf_core/module-template/tests/main.nf.test.j2 +++ b/nf_core/module-template/tests/main.nf.test.j2 @@ -7,7 +7,7 @@ nextflow_process { process "{{ component_name_underscore|upper }}" tag "modules" - tag "modules_nfcore" + tag "modules_{{ org_alphabet }}" {%- if subtool %} tag "{{ component }}" {%- endif %} diff --git a/nf_core/subworkflow-template/tests/main.nf.test.j2 b/nf_core/subworkflow-template/tests/main.nf.test.j2 index c44e19a4e4..8aaf6e0c7c 100644 --- a/nf_core/subworkflow-template/tests/main.nf.test.j2 +++ b/nf_core/subworkflow-template/tests/main.nf.test.j2 @@ -7,7 +7,7 @@ nextflow_workflow { workflow "{{ component_name_underscore|upper }}" tag "subworkflows" - tag "subworkflows_nfcore" + tag "subworkflows_{{ org_alphabet }}" tag "subworkflows/{{ component_name }}" // TODO nf-core: Add tags for all modules used within this subworkflow. Example: tag "samtools" From a446f29d01470e05870552d6bb496236460d46b6 Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke Date: Mon, 27 May 2024 15:19:50 +0200 Subject: [PATCH 153/175] make sure linting passes this new feature --- nf_core/modules/lint/module_tests.py | 6 +++++- nf_core/subworkflows/lint/subworkflow_tests.py | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/nf_core/modules/lint/module_tests.py b/nf_core/modules/lint/module_tests.py index b2b6c2221f..080fc2bdc8 100644 --- a/nf_core/modules/lint/module_tests.py +++ b/nf_core/modules/lint/module_tests.py @@ -4,6 +4,7 @@ import json import logging +import re from pathlib import Path import yaml @@ -137,7 +138,10 @@ def module_tests(_, module: NFCoreComponent): ) # Verify that tags are correct. main_nf_tags = module._get_main_nf_tags(module.nftest_main_nf) - required_tags = ["modules", "modules_nfcore", module.component_name] + not_alphabet = re.compile(r'[^a-zA-Z]') + org_alp = not_alphabet.sub('', module.org) + org_alphabet = org_alp if org_alp != "" else "nfcore" + required_tags = ["modules", f"modules_{org_alphabet}", module.component_name] if module.component_name.count("/") == 1: required_tags.append(module.component_name.split("/")[0]) chained_components_tags = module._get_included_components_in_chained_tests(module.nftest_main_nf) diff --git a/nf_core/subworkflows/lint/subworkflow_tests.py b/nf_core/subworkflows/lint/subworkflow_tests.py index cfae2d553c..87e850e8fb 100644 --- a/nf_core/subworkflows/lint/subworkflow_tests.py +++ b/nf_core/subworkflows/lint/subworkflow_tests.py @@ -4,6 +4,7 @@ import json import logging +import re from pathlib import Path import yaml @@ -144,10 +145,13 @@ def subworkflow_tests(_, subworkflow: NFCoreComponent): ) # Verify that tags are correct. main_nf_tags = subworkflow._get_main_nf_tags(subworkflow.nftest_main_nf) + not_alphabet = re.compile(r'[^a-zA-Z]') + org_alp = not_alphabet.sub('', subworkflow.org) + org_alphabet = org_alp if org_alp != "" else "nfcore" required_tags = [ "subworkflows", f"subworkflows/{subworkflow.component_name}", - "subworkflows_nfcore", + f"subworkflows_{org_alphabet}", ] included_components = [] if subworkflow.main_nf.is_file(): From 7bae122e1da8fb54511ebdfe02894a602621dbce Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke Date: Mon, 27 May 2024 15:27:20 +0200 Subject: [PATCH 154/175] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16262bd1c3..259982e39f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ ### Components +- The `modules_nfcore` tag in the `main.nf.test` file of modules/subworkflows now displays the organization name in custom modules repositories ([#3005](https://github.com/nf-core/tools/pull/3005)) + ### General - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.4 ([#2974](https://github.com/nf-core/tools/pull/2974)) From a4ecb70909da3b6986c25d8986ba956391bcd0fc Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke Date: Mon, 27 May 2024 15:32:45 +0200 Subject: [PATCH 155/175] ruff! --- nf_core/components/create.py | 4 ++-- nf_core/modules/lint/module_tests.py | 4 ++-- nf_core/subworkflows/lint/subworkflow_tests.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/nf_core/components/create.py b/nf_core/components/create.py index e603db3857..78c30b5179 100644 --- a/nf_core/components/create.py +++ b/nf_core/components/create.py @@ -158,8 +158,8 @@ def create(self): self._get_module_structure_components() # Add a valid organization name for nf-test tags - not_alphabet = re.compile(r'[^a-zA-Z]') - self.org_alphabet = not_alphabet.sub('', self.org) + not_alphabet = re.compile(r"[^a-zA-Z]") + self.org_alphabet = not_alphabet.sub("", self.org) # Create component template with jinja2 self._render_template() diff --git a/nf_core/modules/lint/module_tests.py b/nf_core/modules/lint/module_tests.py index 080fc2bdc8..4bf4ea7745 100644 --- a/nf_core/modules/lint/module_tests.py +++ b/nf_core/modules/lint/module_tests.py @@ -138,8 +138,8 @@ def module_tests(_, module: NFCoreComponent): ) # Verify that tags are correct. main_nf_tags = module._get_main_nf_tags(module.nftest_main_nf) - not_alphabet = re.compile(r'[^a-zA-Z]') - org_alp = not_alphabet.sub('', module.org) + not_alphabet = re.compile(r"[^a-zA-Z]") + org_alp = not_alphabet.sub("", module.org) org_alphabet = org_alp if org_alp != "" else "nfcore" required_tags = ["modules", f"modules_{org_alphabet}", module.component_name] if module.component_name.count("/") == 1: diff --git a/nf_core/subworkflows/lint/subworkflow_tests.py b/nf_core/subworkflows/lint/subworkflow_tests.py index 87e850e8fb..fe7b40407a 100644 --- a/nf_core/subworkflows/lint/subworkflow_tests.py +++ b/nf_core/subworkflows/lint/subworkflow_tests.py @@ -145,8 +145,8 @@ def subworkflow_tests(_, subworkflow: NFCoreComponent): ) # Verify that tags are correct. main_nf_tags = subworkflow._get_main_nf_tags(subworkflow.nftest_main_nf) - not_alphabet = re.compile(r'[^a-zA-Z]') - org_alp = not_alphabet.sub('', subworkflow.org) + not_alphabet = re.compile(r"[^a-zA-Z]") + org_alp = not_alphabet.sub("", subworkflow.org) org_alphabet = org_alp if org_alp != "" else "nfcore" required_tags = [ "subworkflows", From 6d9feb3a900db74980bce66523e65f2470cdb507 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 22:45:25 +0000 Subject: [PATCH 156/175] Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.6 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 01bd13a9e9..8521c44100 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.5 + rev: v0.4.6 hooks: - id: ruff # linter args: [--fix, --exit-non-zero-on-fix] # sort imports and fix From f94ec87ccd246eba4db29609e1b0f5ed44b2fb80 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Tue, 28 May 2024 22:46:12 +0000 Subject: [PATCH 157/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae43fd4e7b..63bef50b84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - Add no clobber and put bash options on their own line ([#2991](https://github.com/nf-core/tools/pull/2991)) - update minimal textual version and snapshots ([#2998](https://github.com/nf-core/tools/pull/2998)) - return directory if base_dir is the root directory ([#3003](https://github.com/nf-core/tools/pull/3003)) +- Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.6 ([#3006](https://github.com/nf-core/tools/pull/3006)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From 60b79b156ccd77f369ad174997fdb0284db62682 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 29 May 2024 15:35:19 +0200 Subject: [PATCH 158/175] use pydantic validation context on module initialization. use global variable for pipeline type --- nf_core/pipelines/create/__init__.py | 16 +++++----- nf_core/pipelines/create/utils.py | 46 +++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index da6a693220..c118d8520d 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -5,6 +5,7 @@ from textual.app import App from textual.widgets import Button +from nf_core.pipelines.create import utils from nf_core.pipelines.create.basicdetails import BasicDetails from nf_core.pipelines.create.custompipeline import CustomPipeline from nf_core.pipelines.create.finaldetails import FinalDetails @@ -14,15 +15,10 @@ from nf_core.pipelines.create.loggingscreen import LoggingScreen from nf_core.pipelines.create.nfcorepipeline import NfcorePipeline from nf_core.pipelines.create.pipelinetype import ChoosePipelineType -from nf_core.pipelines.create.utils import ( - CreateConfig, - CustomLogHandler, - LoggingConsole, -) from nf_core.pipelines.create.welcome import WelcomeScreen -log_handler = CustomLogHandler( - console=LoggingConsole(classes="log_console"), +log_handler = utils.CustomLogHandler( + console=utils.LoggingConsole(classes="log_console"), rich_tracebacks=True, show_time=False, show_path=False, @@ -36,7 +32,7 @@ log_handler.setLevel("INFO") -class PipelineCreateApp(App[CreateConfig]): +class PipelineCreateApp(App[utils.CreateConfig]): """A Textual app to manage stopwatches.""" CSS_PATH = "create.tcss" @@ -60,7 +56,7 @@ class PipelineCreateApp(App[CreateConfig]): } # Initialise config as empty - TEMPLATE_CONFIG = CreateConfig() + TEMPLATE_CONFIG = utils.CreateConfig() # Initialise pipeline type PIPELINE_TYPE = None @@ -79,9 +75,11 @@ def on_button_pressed(self, event: Button.Pressed) -> None: self.push_screen("choose_type") elif event.button.id == "type_nfcore": self.PIPELINE_TYPE = "nfcore" + utils.PIPELINE_TYPE_GLOBAL = "nfcore" self.push_screen("basic_details") elif event.button.id == "type_custom": self.PIPELINE_TYPE = "custom" + utils.PIPELINE_TYPE_GLOBAL = "custom" self.push_screen("basic_details") elif event.button.id == "continue": self.push_screen("final_details") diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 6006452baf..0754c54b54 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -1,9 +1,11 @@ import re +from contextlib import contextmanager +from contextvars import ContextVar from logging import LogRecord from pathlib import Path -from typing import Optional, Union +from typing import Any, Dict, Iterator, Optional, Union -from pydantic import BaseModel, ConfigDict, ValidationError, field_validator +from pydantic import BaseModel, ConfigDict, ValidationError, ValidationInfo, field_validator from rich.logging import RichHandler from textual import on from textual._context import active_app @@ -14,6 +16,22 @@ from textual.widget import Widget from textual.widgets import Button, Input, Markdown, RichLog, Static, Switch +# Use ContextVar to define a context on the model initialization +_init_context_var: ContextVar = ContextVar("_init_context_var", default={}) + + +@contextmanager +def init_context(value: Dict[str, Any]) -> Iterator[None]: + token = _init_context_var.set(value) + try: + yield + finally: + _init_context_var.reset(token) + + +# Define a global variable to store the pipeline type +PIPELINE_TYPE_GLOBAL: str | None = None + class CreateConfig(BaseModel): """Pydantic model for the nf-core create config.""" @@ -30,12 +48,25 @@ class CreateConfig(BaseModel): model_config = ConfigDict(extra="allow") + def __init__(self, /, **data: Any) -> None: + """Custom init method to allow using a context on the model initialization.""" + self.__pydantic_validator__.validate_python( + data, + self_instance=self, + context=_init_context_var.get(), + ) + @field_validator("name") @classmethod - def name_nospecialchars(cls, v: str) -> str: + def name_nospecialchars(cls, v: str, info: ValidationInfo) -> str: """Check that the pipeline name is simple.""" - if not re.match(r"^[a-z]+$", v): - raise ValueError("Must be lowercase without punctuation.") + context = info.context + if context and context["is_nfcore"]: + if not re.match(r"^[a-z]+$", v): + raise ValueError("Must be lowercase without punctuation.") + else: + if not re.match(r"^[a-zA-Z-_]+$", v): + raise ValueError("Must not contain special characters. Only '-' or '_' are allowed.") return v @field_validator("org", "description", "author", "version", "outdir") @@ -117,8 +148,9 @@ def validate(self, value: str) -> ValidationResult: If it fails, return the error messages.""" try: - CreateConfig(**{f"{self.key}": value}) - return self.success() + with init_context({"is_nfcore": PIPELINE_TYPE_GLOBAL == "nfcore"}): + CreateConfig(**{f"{self.key}": value}) + return self.success() except ValidationError as e: return self.failure(", ".join([err["msg"] for err in e.errors()])) From 0186535fe3e6a7c8f79fdd379ebc0d2d20f423d1 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Wed, 29 May 2024 13:40:21 +0000 Subject: [PATCH 159/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63bef50b84..af62a6ed55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - update minimal textual version and snapshots ([#2998](https://github.com/nf-core/tools/pull/2998)) - return directory if base_dir is the root directory ([#3003](https://github.com/nf-core/tools/pull/3003)) - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.6 ([#3006](https://github.com/nf-core/tools/pull/3006)) +- Create: allow more special characters on the pipeline name for non-nf-core pipelines ([#3008](https://github.com/nf-core/tools/pull/3008)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From 6275553f13f948ad76a6ebd0ec6ad2b73fa07cd1 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 29 May 2024 15:51:36 +0200 Subject: [PATCH 160/175] use union for typing --- nf_core/pipelines/create/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 0754c54b54..d70fea1403 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -30,7 +30,7 @@ def init_context(value: Dict[str, Any]) -> Iterator[None]: # Define a global variable to store the pipeline type -PIPELINE_TYPE_GLOBAL: str | None = None +PIPELINE_TYPE_GLOBAL: Union[str, None] = None class CreateConfig(BaseModel): From 2b724e0e7f98d8f6b5956eda6b776041728885bd Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 30 May 2024 13:46:53 +0200 Subject: [PATCH 161/175] use NFCORE_PIPELINE as a boolean instead of a PIPELINE_TYPE string --- nf_core/pipelines/create/__init__.py | 10 +++++----- nf_core/pipelines/create/basicdetails.py | 8 ++++---- nf_core/pipelines/create/utils.py | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/nf_core/pipelines/create/__init__.py b/nf_core/pipelines/create/__init__.py index c118d8520d..56e25bf1d5 100644 --- a/nf_core/pipelines/create/__init__.py +++ b/nf_core/pipelines/create/__init__.py @@ -59,7 +59,7 @@ class PipelineCreateApp(App[utils.CreateConfig]): TEMPLATE_CONFIG = utils.CreateConfig() # Initialise pipeline type - PIPELINE_TYPE = None + NFCORE_PIPELINE = True # Log handler LOG_HANDLER = log_handler @@ -74,12 +74,12 @@ def on_button_pressed(self, event: Button.Pressed) -> None: if event.button.id == "start": self.push_screen("choose_type") elif event.button.id == "type_nfcore": - self.PIPELINE_TYPE = "nfcore" - utils.PIPELINE_TYPE_GLOBAL = "nfcore" + self.NFCORE_PIPELINE = True + utils.NFCORE_PIPELINE_GLOBAL = True self.push_screen("basic_details") elif event.button.id == "type_custom": - self.PIPELINE_TYPE = "custom" - utils.PIPELINE_TYPE_GLOBAL = "custom" + self.NFCORE_PIPELINE = False + utils.NFCORE_PIPELINE_GLOBAL = False self.push_screen("basic_details") elif event.button.id == "continue": self.push_screen("final_details") diff --git a/nf_core/pipelines/create/basicdetails.py b/nf_core/pipelines/create/basicdetails.py index b88ede10d0..09484fa2ea 100644 --- a/nf_core/pipelines/create/basicdetails.py +++ b/nf_core/pipelines/create/basicdetails.py @@ -39,7 +39,7 @@ def compose(self) -> ComposeResult: "GitHub organisation", "nf-core", classes="column", - disabled=self.parent.PIPELINE_TYPE == "nfcore", + disabled=self.parent.NFCORE_PIPELINE, ) yield TextInput( "name", @@ -85,7 +85,7 @@ def on_screen_resume(self): add_hide_class(self.parent, "exist_warn") for text_input in self.query("TextInput"): if text_input.field_id == "org": - text_input.disabled = self.parent.PIPELINE_TYPE == "nfcore" + text_input.disabled = self.parent.NFCORE_PIPELINE @on(Button.Pressed) def on_button_pressed(self, event: Button.Pressed) -> None: @@ -102,9 +102,9 @@ def on_button_pressed(self, event: Button.Pressed) -> None: try: self.parent.TEMPLATE_CONFIG = CreateConfig(**config) if event.button.id == "next": - if self.parent.PIPELINE_TYPE == "nfcore": + if self.parent.NFCORE_PIPELINE: self.parent.push_screen("type_nfcore") - elif self.parent.PIPELINE_TYPE == "custom": + else: self.parent.push_screen("type_custom") except ValueError: pass diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index d70fea1403..f1e0bae3ce 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -30,7 +30,7 @@ def init_context(value: Dict[str, Any]) -> Iterator[None]: # Define a global variable to store the pipeline type -PIPELINE_TYPE_GLOBAL: Union[str, None] = None +NFCORE_PIPELINE_GLOBAL: bool = True class CreateConfig(BaseModel): @@ -148,7 +148,7 @@ def validate(self, value: str) -> ValidationResult: If it fails, return the error messages.""" try: - with init_context({"is_nfcore": PIPELINE_TYPE_GLOBAL == "nfcore"}): + with init_context({"is_nfcore": NFCORE_PIPELINE_GLOBAL}): CreateConfig(**{f"{self.key}": value}) return self.success() except ValidationError as e: From 02017aac324b790d7afedfbaa2edc9ca8fb7fb9f Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Fri, 31 May 2024 23:13:04 +0200 Subject: [PATCH 162/175] README - absolute image paths Make the logo render on PyPI --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 85b608bf77..58fb708a0d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

- - nf-core/tools + + nf-core/tools

From 089264292c7f1430c2e17f0978c1169dfc369ff7 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Fri, 31 May 2024 21:13:59 +0000 Subject: [PATCH 163/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1d7678c45..e8a8d1fbf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - return directory if base_dir is the root directory ([#3003](https://github.com/nf-core/tools/pull/3003)) - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.6 ([#3006](https://github.com/nf-core/tools/pull/3006)) - Create: allow more special characters on the pipeline name for non-nf-core pipelines ([#3008](https://github.com/nf-core/tools/pull/3008)) +- README - absolute image paths ([#3013](https://github.com/nf-core/tools/pull/3013)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From b96f56b15d24431fb97382bed7715bccfafd21df Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Fri, 31 May 2024 23:35:39 +0200 Subject: [PATCH 164/175] Conda module linting: Include package name in log file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tried to do this with GitHub Copilot Workspaces but it failed 😅 As I was looking at the code anyway I could see the fix so figured I would put it manually. Closes https://github.com/nf-core/tools/issues/3009 Untested, done in web browser only. --- nf_core/modules/lint/main_nf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index fd4d81f7f2..81308ba5c5 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -367,14 +367,14 @@ def check_process_section(self, lines, registry, fix_version, progress_bar): # response = _bioconda_package(bp) response = nf_core.utils.anaconda_package(bp) except LookupError: - self.warned.append(("bioconda_version", "Conda version not specified correctly", self.main_nf)) + self.warned.append(("bioconda_version", f"Conda version not specified correctly: {bp}", self.main_nf)) except ValueError: - self.failed.append(("bioconda_version", "Conda version not specified correctly", self.main_nf)) + self.failed.append(("bioconda_version", f"Conda version not specified correctly: {bp}", self.main_nf)) else: # Check that required version is available at all if bioconda_version not in response.get("versions"): self.failed.append( - ("bioconda_version", f"Conda package had unknown version: `{bioconda_version}`", self.main_nf) + ("bioconda_version", f"Conda package {bp} had unknown version: `{bioconda_version}`", self.main_nf) ) continue # No need to test for latest version, continue linting # Check version is latest available From 93acb91abe8c418ac9a8b9f06b237e2ec2d980e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 31 May 2024 22:20:54 +0000 Subject: [PATCH 165/175] Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.7 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8521c44100..0bfe44f870 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.6 + rev: v0.4.7 hooks: - id: ruff # linter args: [--fix, --exit-non-zero-on-fix] # sort imports and fix From d4a91832343df619927ed1fdcc776c0daffb5e5a Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Fri, 31 May 2024 22:21:50 +0000 Subject: [PATCH 166/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1d7678c45..515189e300 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - return directory if base_dir is the root directory ([#3003](https://github.com/nf-core/tools/pull/3003)) - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.6 ([#3006](https://github.com/nf-core/tools/pull/3006)) - Create: allow more special characters on the pipeline name for non-nf-core pipelines ([#3008](https://github.com/nf-core/tools/pull/3008)) +- Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.7 ([#3015](https://github.com/nf-core/tools/pull/3015)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From 847a3763d1b67a9e75432bf0c74a0c531891d687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Mon, 3 Jun 2024 08:40:07 +0000 Subject: [PATCH 167/175] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1d7678c45..6b421ba4de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Linting - Fix linting fail on nfcore_external_java_deps if nf_schema is used ([#2976](https://github.com/nf-core/tools/pull/2976)) +- Conda module linting: Include package name in log file ([#3014](https://github.com/nf-core/tools/pull/3014)) ### Download From 005972e33d0d5808791fbcc18a6af914b249babc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 19:58:25 +0000 Subject: [PATCH 168/175] Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.8 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0bfe44f870..2e1373904f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.7 + rev: v0.4.8 hooks: - id: ruff # linter args: [--fix, --exit-non-zero-on-fix] # sort imports and fix From ee5a22b263ffe926fc4e437adcc45831d13ab4e8 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Wed, 5 Jun 2024 19:59:12 +0000 Subject: [PATCH 169/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 996650e00a..1d82830b71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ - Create: allow more special characters on the pipeline name for non-nf-core pipelines ([#3008](https://github.com/nf-core/tools/pull/3008)) - README - absolute image paths ([#3013](https://github.com/nf-core/tools/pull/3013)) - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.7 ([#3015](https://github.com/nf-core/tools/pull/3015)) +- Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.8 ([#3017](https://github.com/nf-core/tools/pull/3017)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From 8ee2040007c222825dc8356a731a024424cc1397 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 8 Jun 2024 01:11:09 +0000 Subject: [PATCH 170/175] Update python:3.12-slim Docker digest to e3ae8cf --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index fe4162b4fe..6fe79d2eba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.12-slim@sha256:afc139a0a640942491ec481ad8dda10f2c5b753f5c969393b12480155fe15a63 +FROM python:3.12-slim@sha256:e3ae8cf03c4f0abbfef13a8147478a7cd92798a94fa729a36a185d9106cbae32 LABEL authors="phil.ewels@seqera.io,erik.danielsson@scilifelab.se" \ description="Docker image containing requirements for nf-core/tools" From a63a653ab230e6b576d3e1cd952a51433a852ea4 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Sun, 9 Jun 2024 03:35:11 +0000 Subject: [PATCH 171/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d82830b71..715bc2dc12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ - README - absolute image paths ([#3013](https://github.com/nf-core/tools/pull/3013)) - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.7 ([#3015](https://github.com/nf-core/tools/pull/3015)) - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.8 ([#3017](https://github.com/nf-core/tools/pull/3017)) +- Update python:3.12-slim Docker digest to e3ae8cf ([#3020](https://github.com/nf-core/tools/pull/3020)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From 05f60b440aa3a2b5125ed3cc65ae8b86dc979ef2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 13:30:29 +0000 Subject: [PATCH 172/175] Update dawidd6/action-download-artifact action to v6 --- nf_core/pipeline-template/.github/workflows/linting_comment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/pipeline-template/.github/workflows/linting_comment.yml b/nf_core/pipeline-template/.github/workflows/linting_comment.yml index ea408fd6f8..908dcea159 100644 --- a/nf_core/pipeline-template/.github/workflows/linting_comment.yml +++ b/nf_core/pipeline-template/.github/workflows/linting_comment.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download lint results - uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe # v3 + uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 # v6 with: workflow: linting.yml workflow_conclusion: completed From 90f7e344d7e8d07060701bca0cedd36ce7866bf9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 18:31:15 +0000 Subject: [PATCH 173/175] Update python:3.12-slim Docker digest to 2fba8e7 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 6fe79d2eba..9ebc7e9853 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.12-slim@sha256:e3ae8cf03c4f0abbfef13a8147478a7cd92798a94fa729a36a185d9106cbae32 +FROM python:3.12-slim@sha256:2fba8e70a87bcc9f6edd20dda0a1d4adb32046d2acbca7361bc61da5a106a914 LABEL authors="phil.ewels@seqera.io,erik.danielsson@scilifelab.se" \ description="Docker image containing requirements for nf-core/tools" From 6f444c96d3292dd3fd9fd4863ec7716de6ed4c1d Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Fri, 14 Jun 2024 23:01:49 +0000 Subject: [PATCH 174/175] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 715bc2dc12..9da8c1ab24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.7 ([#3015](https://github.com/nf-core/tools/pull/3015)) - Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.8 ([#3017](https://github.com/nf-core/tools/pull/3017)) - Update python:3.12-slim Docker digest to e3ae8cf ([#3020](https://github.com/nf-core/tools/pull/3020)) +- Update python:3.12-slim Docker digest to 2fba8e7 ([#3023](https://github.com/nf-core/tools/pull/3023)) ## [v2.14.1 - Tantalum Toad - Patch](https://github.com/nf-core/tools/releases/tag/2.14.1) - [2024-05-09] From a15a6f0e7f94a6d57e4d35a349b96bd29e7f886e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 15 Jun 2024 04:47:47 +0000 Subject: [PATCH 175/175] Update pre-commit hook astral-sh/ruff-pre-commit to v0.4.9 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2e1373904f..6d8e34e0b4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.8 + rev: v0.4.9 hooks: - id: ruff # linter args: [--fix, --exit-non-zero-on-fix] # sort imports and fix