From 513de9528235a5d90ed4c7f09427c9d399c384e5 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Mon, 21 Aug 2023 00:15:13 +0200 Subject: [PATCH 001/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] [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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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/117] 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 33a97bbf0971db5376648a16f2bee107aa4205e9 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Tue, 9 Apr 2024 00:27:09 +0200 Subject: [PATCH 097/117] 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 098/117] 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 099/117] 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 100/117] 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 101/117] 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 102/117] 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 103/117] 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 104/117] 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 105/117] 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 106/117] 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 107/117] 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 108/117] 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 109/117] 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 110/117] 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 dcc7757b0062b100b656fd44d208914e9aa6d605 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 9 May 2024 10:36:14 +0200 Subject: [PATCH 111/117] 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 112/117] 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 9572b237f89a864e728d3384e5dc841a33758fa1 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Fri, 10 May 2024 12:03:27 +0200 Subject: [PATCH 113/117] 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 114/117] 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 115/117] 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 116/117] 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 117/117] 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