From c5c190164ee72ea28c516b5861c5a0ab1abb6956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Tue, 19 Apr 2022 17:04:40 +0200 Subject: [PATCH 01/58] don't updatate sha if the module is not updated --- nf_core/modules/update.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/nf_core/modules/update.py b/nf_core/modules/update.py index 1967ac55a4..f2011f0d66 100644 --- a/nf_core/modules/update.py +++ b/nf_core/modules/update.py @@ -428,12 +428,6 @@ class DiffEnum(enum.Enum): if not dry_run: self.update_modules_json(modules_json, modules_repo.name, module, version) - # Don't save to a file, just iteratively update the variable - else: - modules_json = self.update_modules_json( - modules_json, modules_repo.name, module, version, write_file=False - ) - if self.save_diff_fn: # Compare the new modules.json and build a diff modules_json_diff = difflib.unified_diff( From f26c2d4fd3cf42a4fed86d1711ab2ba1f88b79b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 20 Apr 2022 10:16:30 +0200 Subject: [PATCH 02/58] modify changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fc9e1067d..2396490ff6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Bumped the minimum version of `rich` from `v10` to `v10.7.0` - Add an empty line to `modules.json`, `params.json` and `nextflow-schema.json` when dumping them to avoid prettier errors. +- Fix bug in modules.json when a module is not updated ([#1518](https://github.com/nf-core/tools/pull/1518)) ### Modules From 237475634eab661bc33cf9bbf7c840de63349c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Tue, 19 Apr 2022 17:04:40 +0200 Subject: [PATCH 03/58] don't updatate sha if the module is not updated --- nf_core/modules/update.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/nf_core/modules/update.py b/nf_core/modules/update.py index 1967ac55a4..f2011f0d66 100644 --- a/nf_core/modules/update.py +++ b/nf_core/modules/update.py @@ -428,12 +428,6 @@ class DiffEnum(enum.Enum): if not dry_run: self.update_modules_json(modules_json, modules_repo.name, module, version) - # Don't save to a file, just iteratively update the variable - else: - modules_json = self.update_modules_json( - modules_json, modules_repo.name, module, version, write_file=False - ) - if self.save_diff_fn: # Compare the new modules.json and build a diff modules_json_diff = difflib.unified_diff( From 5b04b2b54191b256ac561f5c6e65add39816b289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 20 Apr 2022 10:16:30 +0200 Subject: [PATCH 04/58] resolve conflicts in changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 259bd35e28..5298f0a411 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ - Add an empty line to `modules.json`, `params.json` and `nextflow-schema.json` when dumping them to avoid prettier errors. - Remove empty JSON schema definition groups to avoid usage errors ([#1419](https://github.com/nf-core/tools/issues/1419)) - Bumped the minimum version of `rich` from `v10` to `v10.7.0` +- Fix bug in modules.json when a module is not updated ([#1518](https://github.com/nf-core/tools/pull/1518)) ### Modules From e6b1af5d151831c158a74a58589806dfb9101b66 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 16 May 2022 15:25:50 +0200 Subject: [PATCH 05/58] resolve conflicts in main_nf.py --- nf_core/__main__.py | 7 +++-- nf_core/modules/lint/__init__.py | 30 ++++++++++++++------ nf_core/modules/lint/main_nf.py | 48 ++++++++++++++++++++++++++++---- 3 files changed, 69 insertions(+), 16 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 0c010ae9ab..bd8f9a19c4 100755 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -594,7 +594,8 @@ def create_test_yml(ctx, tool, run_tests, output, force, no_prompts): @click.option("-a", "--all", is_flag=True, help="Run on all modules") @click.option("--local", is_flag=True, help="Run additional lint tests for local modules") @click.option("--passed", is_flag=True, help="Show passed tests") -def lint(ctx, tool, dir, key, all, local, passed): +@click.option("--fix", is_flag=True, help="Fix the module version if a newer version is available") +def lint(ctx, tool, dir, key, all, local, passed, fix): """ Lint one or more modules in a directory. @@ -607,7 +608,9 @@ def lint(ctx, tool, dir, key, all, local, passed): try: module_lint = nf_core.modules.ModuleLint(dir=dir) module_lint.modules_repo = ctx.obj["modules_repo_obj"] - module_lint.lint(module=tool, key=key, all_modules=all, print_results=True, local=local, show_passed=passed) + module_lint.lint( + module=tool, key=key, all_modules=all, print_results=True, local=local, show_passed=passed, fix_version=fix + ) if len(module_lint.failed) > 0: sys.exit(1) except nf_core.modules.lint.ModuleLintException as e: diff --git a/nf_core/modules/lint/__init__.py b/nf_core/modules/lint/__init__.py index 6bea05cb27..91a9455899 100644 --- a/nf_core/modules/lint/__init__.py +++ b/nf_core/modules/lint/__init__.py @@ -100,7 +100,16 @@ def __init__(self, dir): def _get_all_lint_tests(): return ["main_nf", "meta_yml", "module_todos", "module_deprecations"] - def lint(self, module=None, key=(), all_modules=False, print_results=True, show_passed=False, local=False): + def lint( + self, + module=None, + key=(), + all_modules=False, + print_results=True, + show_passed=False, + local=False, + fix_version=False, + ): """ Lint all or one specific module @@ -117,6 +126,7 @@ def lint(self, module=None, key=(), all_modules=False, print_results=True, show_ :param module: A specific module to lint :param print_results: Whether to print the linting results :param show_passed: Whether passed tests should be shown as well + :param fix_version: Update the module version if a newer version is available :returns: A ModuleLint object containing information of the passed, warned and failed tests @@ -173,11 +183,11 @@ def lint(self, module=None, key=(), all_modules=False, print_results=True, show_ # Lint local modules if local and len(local_modules) > 0: - self.lint_modules(local_modules, local=True) + self.lint_modules(local_modules, local=True, fix_version=fix_version) # Lint nf-core modules if len(nfcore_modules) > 0: - self.lint_modules(nfcore_modules, local=False) + self.lint_modules(nfcore_modules, local=False, fix_version=fix_version) if print_results: self._print_results(show_passed=show_passed) @@ -280,13 +290,14 @@ def get_installed_modules(self): return local_modules, nfcore_modules - def lint_modules(self, modules, local=False): + def lint_modules(self, modules, local=False, fix_version=False): """ Lint a list of modules Args: modules ([NFCoreModule]): A list of module objects local (boolean): Whether the list consist of local or nf-core modules + fix_version (boolean): Fix the module version if a newer version is available """ progress_bar = rich.progress.Progress( "[bold blue]{task.description}", @@ -303,9 +314,9 @@ def lint_modules(self, modules, local=False): for mod in modules: progress_bar.update(lint_progress, advance=1, test_name=mod.module_name) - self.lint_module(mod, local=local) + self.lint_module(mod, local=local, fix_version=fix_version) - def lint_module(self, mod, local=False): + def lint_module(self, mod, local=False, fix_version=False): """ Perform linting on one module @@ -324,14 +335,17 @@ def lint_module(self, mod, local=False): # Only check the main script in case of a local module if local: - self.main_nf(mod) + self.main_nf(mod, fix_version) self.passed += [LintResult(mod, *m) for m in mod.passed] self.warned += [LintResult(mod, *m) for m in (mod.warned + mod.failed)] # Otherwise run all the lint tests else: for test_name in self.lint_tests: - getattr(self, test_name)(mod) + if test_name == "main_nf": + getattr(self, test_name)(mod, fix_version) + else: + getattr(self, test_name)(mod) self.passed += [LintResult(mod, *m) for m in mod.passed] self.warned += [LintResult(mod, *m) for m in mod.warned] diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 31dc6d5495..0d30629b77 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -6,8 +6,10 @@ import re import nf_core +from galaxy.tool_util.deps.mulled.util import build_target -def main_nf(module_lint_object, module): + +def main_nf(module_lint_object, module, fix_version): """ Lint a ``main.nf`` module file @@ -99,7 +101,7 @@ def main_nf(module_lint_object, module): module.passed.append(("main_nf_script_outputs", "Process 'output' block found", module.main_nf)) # Check the process definitions - if check_process_section(module, process_lines): + if check_process_section(module, process_lines, fix_version): module.passed.append(("main_nf_container", "Container versions match", module.main_nf)) else: module.warned.append(("main_nf_container", "Container versions do not match", module.main_nf)) @@ -189,7 +191,7 @@ def check_when_section(self, lines): self.passed.append(("when_condition", "when: condition is unchanged", self.main_nf)) -def check_process_section(self, lines): +def check_process_section(self, lines, fix_version): """ Lint the section of a module between the process definition and the 'input:' definition @@ -208,6 +210,7 @@ def check_process_section(self, lines): singularity_tag = "singularity" docker_tag = "docker" bioconda_packages = [] + update = False # Process name should be all capital letters self.process_name = lines[0].split()[1] @@ -235,14 +238,14 @@ def check_process_section(self, lines): self.warned.append(("process_standard_label", "Process label unspecified", self.main_nf)) for l in lines: - if re.search("bioconda::", l): + if _container_type(l) == "bioconda": bioconda_packages = [b for b in l.split() if "bioconda::" in b] l = l.strip(" '\"") - if l.startswith("https://containers") or l.startswith("https://depot"): + if _container_type(l) == "singularity": # e.g. "https://containers.biocontainers.pro/s3/SingImgsRepo/biocontainers/v1.2.0_cv1/biocontainers_v1.2.0_cv1.img' :" -> v1.2.0_cv1 # e.g. "https://depot.galaxyproject.org/singularity/fastqc:0.11.9--0' :" -> 0.11.9--0 singularity_tag = re.search("(?:\/)?(?:biocontainers_)?(?::)?([A-Za-z\d\-_\.]+)(?:\.img)?['\"]", l).group(1) - if l.startswith("biocontainers/") or l.startswith("quay.io/"): + if _container_type(l) == "docker": # e.g. "quay.io/biocontainers/krona:2.7.1--pl526_5' }" -> 2.7.1--pl526_5 # e.g. "biocontainers/biocontainers:v1.2.0_cv1' }" -> v1.2.0_cv1 docker_tag = re.search("(?:[\/])?(?::)?([A-Za-z\d\-_\.]+)['\"]", l).group(1) @@ -274,10 +277,15 @@ def check_process_section(self, lines): self.warned.append( ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) ) + update = True else: self.passed.append(("bioconda_latest", f"Conda package is the latest available: `{bp}`", self.main_nf)) + print(docker_tag, singularity_tag) if docker_tag == singularity_tag: + # If linting was successful and a new version is available and fix is True + if fix_version and update: + _fix_module_version(self, bioconda_version, last_ver, singularity_tag) return True else: return False @@ -340,3 +348,31 @@ def _is_empty(self, line): if line.strip().replace(" ", "") == "": empty = True return empty + + +def _fix_module_version(self, current_version, latest_version, singularity_tag): + """Updates the module version""" + # Get target object from the latest version + target = build_target(self.module_name, latest_version) + + with open(module.main_nf, "r") as source: + lines = source.readlines() + # Replace outdated versions by the latest one + with open(module.main_nf, "w") as source: + for line in lines: + line = line.strip(" '\"") + build_type = _container_type(line) + if build_type == "bioconda": + source.write(re.sub(rf"{current_version}", f"{latest_version}", line)) + elif build_type == "singularity" or build_type == "docker": + source.write(re.sub(rf"{singularity_tag}", f"{target.build}", line)) + + +def _container_type(line): + """Returns the container type of a build.""" + if re.search("bioconda::", line): + return "bioconda" + if line.startswith("https://containers") or line.startswith("https://depot"): + return "singularity" + if line.startswith("biocontainers/") or line.startswith("quay.io/"): + return "docker" From cee29f03ad549792f0389100ceb5507fd6420309 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 08:56:13 +0200 Subject: [PATCH 06/58] fix conflicts --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5298f0a411..259bd35e28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,6 @@ - Add an empty line to `modules.json`, `params.json` and `nextflow-schema.json` when dumping them to avoid prettier errors. - Remove empty JSON schema definition groups to avoid usage errors ([#1419](https://github.com/nf-core/tools/issues/1419)) - Bumped the minimum version of `rich` from `v10` to `v10.7.0` -- Fix bug in modules.json when a module is not updated ([#1518](https://github.com/nf-core/tools/pull/1518)) ### Modules From 21d9a546b7beaf47e324eb1d770c785d220e797f Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 08:51:12 +0200 Subject: [PATCH 07/58] get version and build --- nf_core/modules/lint/main_nf.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 0d30629b77..c4924cea0c 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -7,6 +7,7 @@ import nf_core from galaxy.tool_util.deps.mulled.util import build_target +import nf_core.modules.module_utils def main_nf(module_lint_object, module, fix_version): @@ -281,11 +282,10 @@ def check_process_section(self, lines, fix_version): else: self.passed.append(("bioconda_latest", f"Conda package is the latest available: `{bp}`", self.main_nf)) - print(docker_tag, singularity_tag) if docker_tag == singularity_tag: # If linting was successful and a new version is available and fix is True if fix_version and update: - _fix_module_version(self, bioconda_version, last_ver, singularity_tag) + _fix_module_version(self, bioconda_version, last_ver, singularity_tag, response) return True else: return False @@ -350,22 +350,37 @@ def _is_empty(self, line): return empty -def _fix_module_version(self, current_version, latest_version, singularity_tag): +def _fix_module_version(self, current_version, latest_version, singularity_tag, response): """Updates the module version""" # Get target object from the latest version - target = build_target(self.module_name, latest_version) + build = _get_build(response) - with open(module.main_nf, "r") as source: + with open(self.main_nf, "r") as source: lines = source.readlines() # Replace outdated versions by the latest one - with open(module.main_nf, "w") as source: + with open(self.main_nf, "w") as source: for line in lines: - line = line.strip(" '\"") - build_type = _container_type(line) + l = line.strip(" '\"") + build_type = _container_type(l) if build_type == "bioconda": source.write(re.sub(rf"{current_version}", f"{latest_version}", line)) elif build_type == "singularity" or build_type == "docker": - source.write(re.sub(rf"{singularity_tag}", f"{target.build}", line)) + source.write(re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line)) + else: + source.write(line) + ### CHECK URLS BEFORE WRITING + ### MOVE FUNCTION CALL UPPER TO WRITE LOG & DEBUG MESSAGES + + +def _get_build(response): + """Get the build of the container version""" + build_times = [] + latest_v = response.get("latest_version") + files = response.get("files") + for f in files: + if f.get("version") == latest_v: + build_times.append((f.get("upload_time"), f.get("attrs").get("build"))) + return sorted(build_times, key=lambda tup: tup[0], reverse=True)[0][1] def _container_type(line): From db7fac1e3b05d1b5adac7ac5501c13604edc6519 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 09:57:05 +0200 Subject: [PATCH 08/58] check that url exist & add log info --- nf_core/modules/lint/main_nf.py | 70 ++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index c4924cea0c..9fe6cfc12a 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -5,10 +5,14 @@ import re import nf_core +import logging +import requests from galaxy.tool_util.deps.mulled.util import build_target import nf_core.modules.module_utils +log = logging.getLogger(__name__) + def main_nf(module_lint_object, module, fix_version): """ @@ -211,7 +215,6 @@ def check_process_section(self, lines, fix_version): singularity_tag = "singularity" docker_tag = "docker" bioconda_packages = [] - update = False # Process name should be all capital letters self.process_name = lines[0].split()[1] @@ -275,17 +278,31 @@ def check_process_section(self, lines, fix_version): last_ver = response.get("latest_version") if last_ver is not None and last_ver != bioconda_version: package, ver = bp.split("=", 1) - self.warned.append( - ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) - ) - update = True + # If a new version is available and fix is True, update the version + if fix_version: + if _fix_module_version(self, bioconda_version, last_ver, singularity_tag, response): + log.info(f"Updating package {package} `{ver}` -> `{last_ver}`") + log.debug(f"Updating package {package} `{ver}` -> `{last_ver}`") + self.passed.append( + ( + "bioconda_latest", + f"Conda package has been updated to the latest available: `{bp}`", + self.main_nf, + ) + ) + else: + log.debug(f"Unable to updating package {package} `{ver}` -> `{last_ver}`") + self.warned.append( + ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) + ) + else: + self.warned.append( + ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) + ) else: self.passed.append(("bioconda_latest", f"Conda package is the latest available: `{bp}`", self.main_nf)) if docker_tag == singularity_tag: - # If linting was successful and a new version is available and fix is True - if fix_version and update: - _fix_module_version(self, bioconda_version, last_ver, singularity_tag, response) return True else: return False @@ -357,19 +374,34 @@ def _fix_module_version(self, current_version, latest_version, singularity_tag, with open(self.main_nf, "r") as source: lines = source.readlines() + + # Check if the new version + build exist and replace + new_lines = [] + for line in lines: + l = line.strip(" '\"") + build_type = _container_type(l) + if build_type == "bioconda": + new_lines.append(re.sub(rf"{current_version}", f"{latest_version}", line)) + elif build_type == "singularity" or build_type == "docker": + # Check that the new url is valid + new_url = re.search( + "(?:')(.+)(?:')", re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line) + ).group(1) + response_new_container = requests.get( + "https://" + new_url if not new_url.startswith("https://") else new_url, stream=True + ) + if response_new_container.status_code != 200: + return False + new_lines.append(re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line)) + else: + new_lines.append(line) + # Replace outdated versions by the latest one with open(self.main_nf, "w") as source: - for line in lines: - l = line.strip(" '\"") - build_type = _container_type(l) - if build_type == "bioconda": - source.write(re.sub(rf"{current_version}", f"{latest_version}", line)) - elif build_type == "singularity" or build_type == "docker": - source.write(re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line)) - else: - source.write(line) - ### CHECK URLS BEFORE WRITING - ### MOVE FUNCTION CALL UPPER TO WRITE LOG & DEBUG MESSAGES + for line in new_lines: + source.write(line) + + return True def _get_build(response): From 72c49c917503c482f106e5bc686e260aa2f212d2 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 11:33:53 +0200 Subject: [PATCH 09/58] improve logging --- nf_core/modules/lint/__init__.py | 9 +++++---- nf_core/modules/lint/main_nf.py | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/nf_core/modules/lint/__init__.py b/nf_core/modules/lint/__init__.py index 91a9455899..a588f49255 100644 --- a/nf_core/modules/lint/__init__.py +++ b/nf_core/modules/lint/__init__.py @@ -304,6 +304,7 @@ def lint_modules(self, modules, local=False, fix_version=False): rich.progress.BarColumn(bar_width=None), "[magenta]{task.completed} of {task.total}[reset] » [bold yellow]{task.fields[test_name]}", transient=True, + console=console, ) with progress_bar: lint_progress = progress_bar.add_task( @@ -314,9 +315,9 @@ def lint_modules(self, modules, local=False, fix_version=False): for mod in modules: progress_bar.update(lint_progress, advance=1, test_name=mod.module_name) - self.lint_module(mod, local=local, fix_version=fix_version) + self.lint_module(mod, progress_bar, local=local, fix_version=fix_version) - def lint_module(self, mod, local=False, fix_version=False): + def lint_module(self, mod, progress_bar, local=False, fix_version=False): """ Perform linting on one module @@ -335,7 +336,7 @@ def lint_module(self, mod, local=False, fix_version=False): # Only check the main script in case of a local module if local: - self.main_nf(mod, fix_version) + self.main_nf(mod, fix_version, progress_bar) self.passed += [LintResult(mod, *m) for m in mod.passed] self.warned += [LintResult(mod, *m) for m in (mod.warned + mod.failed)] @@ -343,7 +344,7 @@ def lint_module(self, mod, local=False, fix_version=False): else: for test_name in self.lint_tests: if test_name == "main_nf": - getattr(self, test_name)(mod, fix_version) + getattr(self, test_name)(mod, fix_version, progress_bar) else: getattr(self, test_name)(mod) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 9fe6cfc12a..bc30718f8c 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -14,7 +14,7 @@ log = logging.getLogger(__name__) -def main_nf(module_lint_object, module, fix_version): +def main_nf(module_lint_object, module, fix_version, progress_bar): """ Lint a ``main.nf`` module file @@ -106,7 +106,7 @@ def main_nf(module_lint_object, module, fix_version): module.passed.append(("main_nf_script_outputs", "Process 'output' block found", module.main_nf)) # Check the process definitions - if check_process_section(module, process_lines, fix_version): + if check_process_section(module, process_lines, fix_version, progress_bar): module.passed.append(("main_nf_container", "Container versions match", module.main_nf)) else: module.warned.append(("main_nf_container", "Container versions do not match", module.main_nf)) @@ -196,7 +196,7 @@ def check_when_section(self, lines): self.passed.append(("when_condition", "when: condition is unchanged", self.main_nf)) -def check_process_section(self, lines, fix_version): +def check_process_section(self, lines, fix_version, progress_bar): """ Lint the section of a module between the process definition and the 'input:' definition @@ -281,7 +281,7 @@ def check_process_section(self, lines, fix_version): # If a new version is available and fix is True, update the version if fix_version: if _fix_module_version(self, bioconda_version, last_ver, singularity_tag, response): - log.info(f"Updating package {package} `{ver}` -> `{last_ver}`") + progress_bar.print(f"[blue]INFO[/blue]\t Updating package '{package}' {ver} -> {last_ver}") log.debug(f"Updating package {package} `{ver}` -> `{last_ver}`") self.passed.append( ( @@ -291,7 +291,7 @@ def check_process_section(self, lines, fix_version): ) ) else: - log.debug(f"Unable to updating package {package} `{ver}` -> `{last_ver}`") + log.debug(f"Unable to update package {package} `{ver}` -> `{last_ver}`") self.warned.append( ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) ) From 008350ededcc7c565b709e8a51d563e1b6eae6ee Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 11:42:04 +0200 Subject: [PATCH 10/58] improve comments --- nf_core/modules/lint/main_nf.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index bc30718f8c..b170a3b6cd 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -368,8 +368,14 @@ def _is_empty(self, line): def _fix_module_version(self, current_version, latest_version, singularity_tag, response): - """Updates the module version""" - # Get target object from the latest version + """Updates the module version + + Changes the bioconda current version by the latest version. + Obtains the latest build from bioconda response + Checks that the new URLs for docker and singularity with the tag [version]--[build] are valid + Changes the docker and singularity URLs + """ + # Get latest build build = _get_build(response) with open(self.main_nf, "r") as source: @@ -405,7 +411,7 @@ def _fix_module_version(self, current_version, latest_version, singularity_tag, def _get_build(response): - """Get the build of the container version""" + """Get the latest build of the container version""" build_times = [] latest_v = response.get("latest_version") files = response.get("files") From e152b7be98e63634874f4dc2a060fd5596aa8bb4 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 12:49:12 +0200 Subject: [PATCH 11/58] remove changes made by error --- nf_core/modules/update.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nf_core/modules/update.py b/nf_core/modules/update.py index f2011f0d66..1967ac55a4 100644 --- a/nf_core/modules/update.py +++ b/nf_core/modules/update.py @@ -428,6 +428,12 @@ class DiffEnum(enum.Enum): if not dry_run: self.update_modules_json(modules_json, modules_repo.name, module, version) + # Don't save to a file, just iteratively update the variable + else: + modules_json = self.update_modules_json( + modules_json, modules_repo.name, module, version, write_file=False + ) + if self.save_diff_fn: # Compare the new modules.json and build a diff modules_json_diff = difflib.unified_diff( From 106b60e7534f186b8847b18f02e35f1966a6e885 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 14:24:03 +0200 Subject: [PATCH 12/58] update changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6084931ff2..ecee8b46ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # nf-core/tools: Changelog +## v2.4.2dev + +- Add `fix` flag to `nf-core modules lint` command to update modules to the latest version ([#1588](https://github.com/nf-core/tools/pull/1588)) + ## [v2.4.1 - Cobolt Koala Patch](https://github.com/nf-core/tools/releases/tag/2.4) - [2022-05-16] - Patch release to try to fix the template sync ([#1585](https://github.com/nf-core/tools/pull/1585)) @@ -30,7 +34,6 @@ - Remove empty JSON schema definition groups to avoid usage errors ([#1419](https://github.com/nf-core/tools/issues/1419)) - Bumped the minimum version of `rich` from `v10` to `v10.7.0` - ### Modules - Add a new command `nf-core modules mulled` which can generate the name for a multi-tool container image. From c1c4541058a7795d2518d5fa41ebdde8e88bf89e Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 14:44:26 +0200 Subject: [PATCH 13/58] small changelog change --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe78f9993e..d6699bf2e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,5 @@ # nf-core/tools: Changelog - ## v2.5dev ### Template From 9f6f5bb65f2c415d8b01fd7ebb257923f80cba82 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 18 May 2022 09:38:38 +0200 Subject: [PATCH 14/58] add --fail-warned to pipeline linting --- .github/workflows/create-lint-wf.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index ab9b3f19b3..87dffebb0a 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -82,7 +82,7 @@ jobs: # Run nf-core linting - name: nf-core lint - run: nf-core --log-file log.txt lint --dir nf-core-testpipeline --fail-ignored + run: nf-core --log-file log.txt lint --dir nf-core-testpipeline --fail-ignored --fail-warned # Run the other nf-core commands - name: nf-core list From 36c04806bfd22565d8316afe8b27dbf78d4d76ab Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 18 May 2022 10:15:35 +0200 Subject: [PATCH 15/58] remove TODO statements from template pipeline --- .github/workflows/create-lint-wf.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index 87dffebb0a..a389628e29 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -61,6 +61,10 @@ jobs: - name: nf-core create run: nf-core --log-file log.txt create -n testpipeline -d "This pipeline is for testing" -a "Testing McTestface" + # Remove TODO statements + - name: remove TODO + run: find nf-core-testpipeline -type f -exec sed -i '/^\s*\/\/ TODO nf-core:/d' {} \; + # Try syncing it before we change anything - name: nf-core sync run: nf-core --log-file log.txt sync --dir nf-core-testpipeline/ From ed6f62a72af7d370d0d1843c8e76c08cabc8b69d Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 18 May 2022 10:41:36 +0200 Subject: [PATCH 16/58] commit changes after removing TODO --- .github/workflows/create-lint-wf.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index a389628e29..c9f498107b 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -63,7 +63,7 @@ jobs: # Remove TODO statements - name: remove TODO - run: find nf-core-testpipeline -type f -exec sed -i '/^\s*\/\/ TODO nf-core:/d' {} \; + run: find nf-core-testpipeline -type f -exec sed -i '/^\s*\/\/ TODO nf-core:/d' {} \; && git add . && git commit -a -m "remove todo statements" # Try syncing it before we change anything - name: nf-core sync From 6c14116908d4e5705cd38b641103449305f314b4 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 18 May 2022 10:56:25 +0200 Subject: [PATCH 17/58] remove todos after sync --- .github/workflows/create-lint-wf.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index c9f498107b..a96e0fcab0 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -61,10 +61,6 @@ jobs: - name: nf-core create run: nf-core --log-file log.txt create -n testpipeline -d "This pipeline is for testing" -a "Testing McTestface" - # Remove TODO statements - - name: remove TODO - run: find nf-core-testpipeline -type f -exec sed -i '/^\s*\/\/ TODO nf-core:/d' {} \; && git add . && git commit -a -m "remove todo statements" - # Try syncing it before we change anything - name: nf-core sync run: nf-core --log-file log.txt sync --dir nf-core-testpipeline/ @@ -84,6 +80,10 @@ jobs: - name: nf-core modules update run: nf-core --log-file log.txt modules update --dir nf-core-testpipeline --all --no-preview + # Remove TODO statements + - name: remove TODO + run: find nf-core-testpipeline -type f -exec sed -i '/^\s*\/\/ TODO nf-core:/d' {} \; + # Run nf-core linting - name: nf-core lint run: nf-core --log-file log.txt lint --dir nf-core-testpipeline --fail-ignored --fail-warned From ba36c528523a2c4095105e74dcbc2869f281a009 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 18 May 2022 11:10:20 +0200 Subject: [PATCH 18/58] add fail-warned flag --- nf_core/__main__.py | 5 +++-- nf_core/lint/__init__.py | 20 ++++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 0c010ae9ab..51df8cfd85 100755 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -300,9 +300,10 @@ def create(name, description, author, version, no_git, force, outdir): @click.option("-k", "--key", type=str, metavar="", multiple=True, help="Run only these lint tests") @click.option("-p", "--show-passed", is_flag=True, help="Show passing tests on the command line") @click.option("-i", "--fail-ignored", is_flag=True, help="Convert ignored tests to failures") +@click.option("-w", "--fail-warned", is_flag=True, help="Convert warn tests to failures") @click.option("--markdown", type=str, metavar="", help="File to write linting results to (Markdown)") @click.option("--json", type=str, metavar="", help="File to write linting results to (JSON)") -def lint(dir, release, fix, key, show_passed, fail_ignored, markdown, json): +def lint(dir, release, fix, key, show_passed, fail_ignored, fail_warned, markdown, json): """ Check pipeline code against nf-core guidelines. @@ -324,7 +325,7 @@ def lint(dir, release, fix, key, show_passed, fail_ignored, markdown, json): # Run the lint tests! try: lint_obj, module_lint_obj = nf_core.lint.run_linting( - dir, release, fix, key, show_passed, fail_ignored, markdown, json + dir, release, fix, key, show_passed, fail_ignored, fail_warned, markdown, json ) if len(lint_obj.failed) + len(module_lint_obj.failed) > 0: sys.exit(1) diff --git a/nf_core/lint/__init__.py b/nf_core/lint/__init__.py index 97293d2a2d..145731c546 100644 --- a/nf_core/lint/__init__.py +++ b/nf_core/lint/__init__.py @@ -27,7 +27,15 @@ def run_linting( - pipeline_dir, release_mode=False, fix=(), key=(), show_passed=False, fail_ignored=False, md_fn=None, json_fn=None + pipeline_dir, + release_mode=False, + fix=(), + key=(), + show_passed=False, + fail_ignored=False, + fail_warned=False, + md_fn=None, + json_fn=None, ): """Runs all nf-core linting checks on a given Nextflow pipeline project in either `release` mode or `normal` mode (default). Returns an object @@ -60,7 +68,7 @@ def run_linting( # Create the lint object pipeline_keys = list(set(key).intersection(set(PipelineLint._get_all_lint_tests(release_mode)))) if key else [] - lint_obj = PipelineLint(pipeline_dir, release_mode, fix, pipeline_keys, fail_ignored) + lint_obj = PipelineLint(pipeline_dir, release_mode, fix, pipeline_keys, fail_ignored, fail_warned) # Load the various pipeline configs lint_obj._load_lint_config() @@ -165,7 +173,7 @@ class PipelineLint(nf_core.utils.Pipeline): from .template_strings import template_strings from .version_consistency import version_consistency - def __init__(self, wf_path, release_mode=False, fix=(), key=(), fail_ignored=False): + def __init__(self, wf_path, release_mode=False, fix=(), key=(), fail_ignored=False, fail_warned=False): """Initialise linting object""" # Initialise the parent object @@ -177,6 +185,7 @@ def __init__(self, wf_path, release_mode=False, fix=(), key=(), fail_ignored=Fal self.lint_config = {} self.release_mode = release_mode self.fail_ignored = fail_ignored + self.fail_warned = fail_warned self.failed = [] self.ignored = [] self.fixed = [] @@ -311,7 +320,10 @@ def _lint_pipeline(self): for test in test_results.get("fixed", []): self.fixed.append((test_name, test)) for test in test_results.get("warned", []): - self.warned.append((test_name, test)) + if self.fail_warned: + self.failed.append((test_name, test)) + else: + self.warned.append((test_name, test)) for test in test_results.get("failed", []): self.failed.append((test_name, test)) if test_results.get("could_fix", False): From b833b4a1371f22999b9065c3b63e5be167c63dbf Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 18 May 2022 11:12:48 +0200 Subject: [PATCH 19/58] add fail-warned to linting in release mode --- .github/workflows/create-lint-wf.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index a96e0fcab0..0cd3a6e4df 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -102,7 +102,7 @@ jobs: run: nf-core --log-file log.txt bump-version --dir nf-core-testpipeline/ 1.1 - name: nf-core lint in release mode - run: nf-core --log-file log.txt lint --dir nf-core-testpipeline --fail-ignored --release + run: nf-core --log-file log.txt lint --dir nf-core-testpipeline --fail-ignored --fail-warned --release - name: nf-core modules install run: nf-core --log-file log.txt modules install fastqc --dir nf-core-testpipeline/ --force From 51cb1cc6df14a3f673253d4773a96ae46b431118 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 18 May 2022 11:19:53 +0200 Subject: [PATCH 20/58] fix bug in sed regex --- .github/workflows/create-lint-wf.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index 0cd3a6e4df..e3876c71c6 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -82,7 +82,7 @@ jobs: # Remove TODO statements - name: remove TODO - run: find nf-core-testpipeline -type f -exec sed -i '/^\s*\/\/ TODO nf-core:/d' {} \; + run: find nf-core-testpipeline -type f -exec sed -i '/TODO nf-core:/d' {} \; # Run nf-core linting - name: nf-core lint From 38661dd691db19e75fc1854c07af9e2717733668 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 18 May 2022 11:28:41 +0200 Subject: [PATCH 21/58] update CHANGELOG --- .github/workflows/create-lint-wf.yml | 2 +- CHANGELOG.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index e3876c71c6..3cc541caae 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -80,7 +80,7 @@ jobs: - name: nf-core modules update run: nf-core --log-file log.txt modules update --dir nf-core-testpipeline --all --no-preview - # Remove TODO statements + # Remove TODO statements - name: remove TODO run: find nf-core-testpipeline -type f -exec sed -i '/TODO nf-core:/d' {} \; diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e5584a365..fb5ebc7432 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ### General +- Add `--fix-warning` flag to `nf-core lint` to make warnings fail. +- Add `--fix-warning` flag to pipeline linting workflow + ### Modules ## [v2.4.1 - Cobolt Koala Patch](https://github.com/nf-core/tools/releases/tag/2.4) - [2022-05-16] From 83e0754c727252c5f0e4e4fa38adc15757e6838a Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Wed, 18 May 2022 11:30:06 +0200 Subject: [PATCH 22/58] update CHANGELOG 2 --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb5ebc7432..257962bf3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,8 @@ ### General -- Add `--fix-warning` flag to `nf-core lint` to make warnings fail. -- Add `--fix-warning` flag to pipeline linting workflow +- Add `--fix-warning` flag to `nf-core lint` to make warnings fail [#1593](https://github.com/nf-core/tools/pull/1593) +- Add `--fix-warning` flag to pipeline linting workflow [#1593](https://github.com/nf-core/tools/pull/1593) ### Modules From e6525ef3ff30b7cf59bfdb6816ac241c457f6c65 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 19 May 2022 14:22:34 +0200 Subject: [PATCH 23/58] improve debug messages --- nf_core/modules/lint/main_nf.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index b170a3b6cd..d1c568f4f1 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -282,7 +282,7 @@ def check_process_section(self, lines, fix_version, progress_bar): if fix_version: if _fix_module_version(self, bioconda_version, last_ver, singularity_tag, response): progress_bar.print(f"[blue]INFO[/blue]\t Updating package '{package}' {ver} -> {last_ver}") - log.debug(f"Updating package {package} `{ver}` -> `{last_ver}`") + log.debug(f"Updating package {package} {ver} -> {last_ver}") self.passed.append( ( "bioconda_latest", @@ -291,7 +291,10 @@ def check_process_section(self, lines, fix_version, progress_bar): ) ) else: - log.debug(f"Unable to update package {package} `{ver}` -> `{last_ver}`") + progress_bar.print( + f"[blue]INFO[/blue]\t Tried to update package. Unable to update package '{package}' {ver} -> {last_ver}" + ) + log.debug(f"Unable to update package {package} {ver} -> {last_ver}") self.warned.append( ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) ) @@ -396,6 +399,9 @@ def _fix_module_version(self, current_version, latest_version, singularity_tag, response_new_container = requests.get( "https://" + new_url if not new_url.startswith("https://") else new_url, stream=True ) + log.debug( + f"Connected to URL: {'https://' + new_url if not new_url.startswith('https://') else new_url}, status_code: {response_new_container.status_code}" + ) if response_new_container.status_code != 200: return False new_lines.append(re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line)) From a0b6e31fe06201f1e09e81cf9ddbf0e4469b77db Mon Sep 17 00:00:00 2001 From: fabianegli Date: Tue, 24 May 2022 20:00:34 +0200 Subject: [PATCH 24/58] use pytest.raises to test for raised exception --- tests/test_download.py | 8 ++++---- tests/test_list.py | 4 ++-- tests/test_schema.py | 45 +++++++++++++++++++++--------------------- tests/test_utils.py | 8 ++++---- 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/tests/test_download.py b/tests/test_download.py index 2dcc7b8cc5..02a0b13aa6 100644 --- a/tests/test_download.py +++ b/tests/test_download.py @@ -59,7 +59,6 @@ def test_get_release_hash_branch(self): == "https://github.com/nf-core/exoseq/archive/819cbac792b76cf66c840b567ed0ee9a2f620db7.zip" ) - @pytest.mark.xfail(raises=AssertionError, strict=True) def test_get_release_hash_non_existent_release(self): wfs = nf_core.list.Workflows() wfs.get_remote_workflows() @@ -70,7 +69,8 @@ def test_get_release_hash_non_existent_release(self): download_obj.wf_revisions, download_obj.wf_branches, ) = nf_core.utils.get_repo_releases_branches(pipeline, wfs) - download_obj.get_revision_hash() + with pytest.raises(AssertionError): + download_obj.get_revision_hash() # # Tests for 'download_wf_files' @@ -149,7 +149,6 @@ def test_matching_md5sums(self, tmpfile): download_obj.validate_md5(tmpfile.name, val_hash) @with_temporary_file - @pytest.mark.xfail(raises=IOError, strict=True) def test_mismatching_md5sums(self, tmpfile): download_obj = DownloadWorkflow(pipeline="dummy") test_hash = hashlib.md5() @@ -159,7 +158,8 @@ def test_mismatching_md5sums(self, tmpfile): with open(tmpfile.name, "w") as f: f.write("test") - download_obj.validate_md5(tmpfile.name, val_hash) + with pytest.raises(IOError): + download_obj.validate_md5(tmpfile.name, val_hash) # # Tests for 'singularity_pull_image' diff --git a/tests/test_list.py b/tests/test_list.py index f1c74da90d..e51b8969be 100644 --- a/tests/test_list.py +++ b/tests/test_list.py @@ -62,12 +62,12 @@ def test_pretty_datetime(self): now_ts = time.mktime(now.timetuple()) nf_core.list.pretty_date(now_ts) - @pytest.mark.xfail(raises=AssertionError, strict=True) def test_local_workflows_and_fail(self): """Test the local workflow class and try to get local Nextflow workflow information""" loc_wf = nf_core.list.LocalWorkflow("myWF") - loc_wf.get_local_nf_workflow_details() + with pytest.raises(AssertionError): + loc_wf.get_local_nf_workflow_details() def test_local_workflows_compare_and_fail_silently(self): """Test the workflow class and try to compare local diff --git a/tests/test_schema.py b/tests/test_schema.py index acda087690..cd1e05757f 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -41,20 +41,18 @@ def test_load_lint_schema(self): self.schema_obj.get_schema_path(self.template_dir) self.schema_obj.load_lint_schema() - @pytest.mark.xfail(raises=AssertionError, strict=True) def test_load_lint_schema_nofile(self): """Check that linting raises properly if a non-existant file is given""" - self.schema_obj.get_schema_path("fake_file") - self.schema_obj.load_lint_schema() + with pytest.raises(AssertionError): + self.schema_obj.get_schema_path("fake_file") - @pytest.mark.xfail(raises=AssertionError, strict=True) def test_load_lint_schema_notjson(self): """Check that linting raises properly if a non-JSON file is given""" self.schema_obj.get_schema_path(os.path.join(self.template_dir, "nextflow.config")) - self.schema_obj.load_lint_schema() + with pytest.raises(AssertionError): + self.schema_obj.load_lint_schema() @with_temporary_file - @pytest.mark.xfail(raises=AssertionError, strict=True) def test_load_lint_schema_noparams(self, tmp_file): """ Check that linting raises properly if a JSON file is given without any params @@ -63,7 +61,8 @@ def test_load_lint_schema_noparams(self, tmp_file): with open(tmp_file.name, "w") as fh: json.dump({"type": "fubar"}, fh) self.schema_obj.get_schema_path(tmp_file.name) - self.schema_obj.load_lint_schema() + with pytest.raises(AssertionError): + self.schema_obj.load_lint_schema() def test_get_schema_path_dir(self): """Get schema file from directory""" @@ -73,22 +72,22 @@ def test_get_schema_path_path(self): """Get schema file from a path""" self.schema_obj.get_schema_path(self.template_schema) - @pytest.mark.xfail(raises=AssertionError, strict=True) def test_get_schema_path_path_notexist(self): """Get schema file from a path""" - self.schema_obj.get_schema_path("fubar", local_only=True) + with pytest.raises(AssertionError): + self.schema_obj.get_schema_path("fubar", local_only=True) def test_get_schema_path_name(self): """Get schema file from the name of a remote pipeline""" self.schema_obj.get_schema_path("atacseq") - @pytest.mark.xfail(raises=AssertionError, strict=True) def test_get_schema_path_name_notexist(self): """ Get schema file from the name of a remote pipeline that doesn't have a schema file """ - self.schema_obj.get_schema_path("exoseq") + with pytest.raises(AssertionError): + self.schema_obj.get_schema_path("exoseq") def test_load_schema(self): """Try to load a schema from a file""" @@ -134,10 +133,10 @@ def test_load_input_params_yaml(self, tmp_file): yaml.dump({"input": "fubar"}, fh) self.schema_obj.load_input_params(tmp_file.name) - @pytest.mark.xfail(raises=AssertionError, strict=True) def test_load_input_params_invalid(self): """Check failure when a non-existent file params file is loaded""" - self.schema_obj.load_input_params("fubar") + with pytest.raises(AssertionError): + self.schema_obj.load_input_params("fubar") def test_validate_params_pass(self): """Try validating a set of parameters against a schema""" @@ -162,11 +161,11 @@ def test_validate_schema_pass(self): self.schema_obj.load_schema() self.schema_obj.validate_schema(self.schema_obj.schema) - @pytest.mark.xfail(raises=AssertionError, strict=True) def test_validate_schema_fail_noparams(self): """Check that the schema validation fails when no params described""" self.schema_obj.schema = {"type": "invalidthing"} - self.schema_obj.validate_schema(self.schema_obj.schema) + with pytest.raises(AssertionError): + self.schema_obj.validate_schema(self.schema_obj.schema) def test_validate_schema_fail_duplicate_ids(self): """ @@ -326,37 +325,37 @@ def test_build_schema_from_scratch(self, tmp_dir): param = self.schema_obj.build_schema(test_pipeline_dir, True, False, None) - @pytest.mark.xfail(raises=AssertionError, strict=True) @mock.patch("requests.post") def test_launch_web_builder_timeout(self, mock_post): """Mock launching the web builder, but timeout on the request""" # Define the behaviour of the request get mock mock_post.side_effect = requests.exceptions.Timeout() - self.schema_obj.launch_web_builder() + with pytest.raises(AssertionError): + self.schema_obj.launch_web_builder() - @pytest.mark.xfail(raises=AssertionError, strict=True) @mock.patch("requests.post") def test_launch_web_builder_connection_error(self, mock_post): """Mock launching the web builder, but get a connection error""" # Define the behaviour of the request get mock mock_post.side_effect = requests.exceptions.ConnectionError() - self.schema_obj.launch_web_builder() + with pytest.raises(AssertionError): + self.schema_obj.launch_web_builder() - @pytest.mark.xfail(raises=AssertionError, strict=True) @mock.patch("requests.post") def test_get_web_builder_response_timeout(self, mock_post): """Mock checking for a web builder response, but timeout on the request""" # Define the behaviour of the request get mock mock_post.side_effect = requests.exceptions.Timeout() - self.schema_obj.launch_web_builder() + with pytest.raises(AssertionError): + self.schema_obj.launch_web_builder() - @pytest.mark.xfail(raises=AssertionError, strict=True) @mock.patch("requests.post") def test_get_web_builder_response_connection_error(self, mock_post): """Mock checking for a web builder response, but get a connection error""" # Define the behaviour of the request get mock mock_post.side_effect = requests.exceptions.ConnectionError() - self.schema_obj.launch_web_builder() + with pytest.raises(AssertionError): + self.schema_obj.launch_web_builder() def mocked_requests_post(**kwargs): """Helper function to emulate POST requests responses from the web""" diff --git a/tests/test_utils.py b/tests/test_utils.py index b62a8c979b..4313dcaf94 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -166,14 +166,14 @@ def test_get_repo_releases_branches_not_nf_core(self): raise AssertionError("MultiQC release v1.10 not found") assert "master" in wf_branches.keys() - @pytest.mark.xfail(raises=AssertionError, strict=True) def test_get_repo_releases_branches_not_exists(self): wfs = nf_core.list.Workflows() wfs.get_remote_workflows() - pipeline, wf_releases, wf_branches = nf_core.utils.get_repo_releases_branches("made_up_pipeline", wfs) + with pytest.raises(AssertionError): + nf_core.utils.get_repo_releases_branches("made_up_pipeline", wfs) - @pytest.mark.xfail(raises=AssertionError, strict=True) def test_get_repo_releases_branches_not_exists_slash(self): wfs = nf_core.list.Workflows() wfs.get_remote_workflows() - pipeline, wf_releases, wf_branches = nf_core.utils.get_repo_releases_branches("made-up/pipeline", wfs) + with pytest.raises(AssertionError): + nf_core.utils.get_repo_releases_branches("made-up/pipeline", wfs) From dd6d0a1136d36cf1c450085693b974e5e9330668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Tue, 31 May 2022 15:21:14 +0200 Subject: [PATCH 25/58] Apply correction from code review Co-authored-by: Gisela Gabernet --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 257962bf3d..5005440df0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,8 @@ ### General -- Add `--fix-warning` flag to `nf-core lint` to make warnings fail [#1593](https://github.com/nf-core/tools/pull/1593) -- Add `--fix-warning` flag to pipeline linting workflow [#1593](https://github.com/nf-core/tools/pull/1593) +- Add `--fail-warned` flag to `nf-core lint` to make warnings fail [#1593](https://github.com/nf-core/tools/pull/1593) +- Add `--fail-warned` flag to pipeline linting workflow [#1593](https://github.com/nf-core/tools/pull/1593) ### Modules From b907c30c4c63eeacf154187c060d1441d0d86307 Mon Sep 17 00:00:00 2001 From: fabianegli Date: Wed, 1 Jun 2022 12:00:25 +0200 Subject: [PATCH 26/58] black and isort pre-commit hooks --- .pre-commit-config.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..3b042970e9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,9 @@ +repos: +- repo: https://github.com/psf/black + rev: 22.3.0 + hooks: + - id: black +- repo: https://github.com/pycqa/isort + rev: 5.10.1 + hooks: + - id: isort From 7dae9f92c49e4f1190196fa494e50bf1e3b5f444 Mon Sep 17 00:00:00 2001 From: fabianegli Date: Wed, 1 Jun 2022 12:05:42 +0200 Subject: [PATCH 27/58] add pre-commit requirement --- requirements-dev.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-dev.txt b/requirements-dev.txt index 7a38e2e51b..7cd475870e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,3 +6,4 @@ black Sphinx sphinx_rtd_theme isort +pre-commit From 3a1606cb1f750d372068562ecdc0b307bdb2a9ad Mon Sep 17 00:00:00 2001 From: fabianegli Date: Wed, 1 Jun 2022 12:27:10 +0200 Subject: [PATCH 28/58] add pre-commit documentation --- .github/CONTRIBUTING.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index c4927d8a07..282fecdc78 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -71,6 +71,27 @@ Or [version control integration](https://pycqa.github.io/isort/docs/configuratio There is an automated CI check that runs when you open a pull-request to nf-core/tools that will fail if any code does not adhere to isort formatting. + +### pre-commit hooks + +This repository comes with [pre-commit](https://pre-commit.com/) hooks for black and isort. pre-commit automatically runs code before a commit is checked into the git history. In this case black and isort. If all checks pass, the commit is made, if black or isort changed files, the user is informed and has to stage the changes and attempt the commit again. + +You can use the pre-commit hooks if you like, but you don't have to. The CI on Github will run the same checks as the tools installed with pre-commit. If the pre-commit for black and isort pass, then the CI for black and isort will pass, too. + +You can install the pre-commit hooks into the development environment by running the following command in the root directory of the repository. + +```bash +pre-commit install --install-hooks +``` + + +You can also run all pre-commit hooks without making a commit: + +```bash +pre-commit run --all +``` + + ## API Documentation We aim to write function docstrings according to the [Google Python style-guide](https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings). These are used to automatically generate package documentation on the nf-core website using Sphinx. From efe083af7e19b290d4112f9efe0003d91937570a Mon Sep 17 00:00:00 2001 From: fabianegli Date: Wed, 1 Jun 2022 12:42:08 +0200 Subject: [PATCH 29/58] prevent redefinition of version --- nf_core/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nf_core/utils.py b/nf_core/utils.py index aab00cfcdf..886e4226d1 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -15,7 +15,7 @@ import subprocess import sys import time -from distutils import version +from distutils.version import StrictVersion import git import prompt_toolkit @@ -75,7 +75,7 @@ def check_if_outdated(current_version=None, remote_version=None, source_url="htt response = requests.get(source_url, timeout=3) remote_version = re.sub(r"[^0-9\.]", "", response.text) # Check if we have an available update - is_outdated = version.StrictVersion(remote_version) > version.StrictVersion(current_version) + is_outdated = StrictVersion(remote_version) > StrictVersion(current_version) return (is_outdated, current_version, remote_version) From dd3bc0413c68692e1e3ce224ad2b0fe056e43d8f Mon Sep 17 00:00:00 2001 From: fabianegli Date: Wed, 1 Jun 2022 13:12:52 +0200 Subject: [PATCH 30/58] add Prettier pre-commit hook --- .github/CONTRIBUTING.md | 7 ++----- .pre-commit-config.yaml | 10 +++++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 282fecdc78..800ba7ab10 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -71,12 +71,11 @@ Or [version control integration](https://pycqa.github.io/isort/docs/configuratio There is an automated CI check that runs when you open a pull-request to nf-core/tools that will fail if any code does not adhere to isort formatting. - ### pre-commit hooks -This repository comes with [pre-commit](https://pre-commit.com/) hooks for black and isort. pre-commit automatically runs code before a commit is checked into the git history. In this case black and isort. If all checks pass, the commit is made, if black or isort changed files, the user is informed and has to stage the changes and attempt the commit again. +This repository comes with [pre-commit](https://pre-commit.com/) hooks for black, isort and Prettier. pre-commit automatically runs checks before a commit is committed into the git history. If all checks pass, the commit is made, if files are changed by the pre-commit hooks, the user is informed and has to stage the changes and attempt the commit again. -You can use the pre-commit hooks if you like, but you don't have to. The CI on Github will run the same checks as the tools installed with pre-commit. If the pre-commit for black and isort pass, then the CI for black and isort will pass, too. +You can use the pre-commit hooks if you like, but you don't have to. The CI on Github will run the same checks as the tools installed with pre-commit. If the pre-commit checks pass, then the same checks in the CI will pass, too. You can install the pre-commit hooks into the development environment by running the following command in the root directory of the repository. @@ -84,14 +83,12 @@ You can install the pre-commit hooks into the development environment by running pre-commit install --install-hooks ``` - You can also run all pre-commit hooks without making a commit: ```bash pre-commit run --all ``` - ## API Documentation We aim to write function docstrings according to the [Google Python style-guide](https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings). These are used to automatically generate package documentation on the nf-core website using Sphinx. diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3b042970e9..b425a9329b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,9 +1,13 @@ repos: -- repo: https://github.com/psf/black + - repo: https://github.com/psf/black rev: 22.3.0 hooks: - - id: black -- repo: https://github.com/pycqa/isort + - id: black + - repo: https://github.com/pycqa/isort rev: 5.10.1 hooks: - id: isort + - repo: https://github.com/pre-commit/mirrors-prettier + rev: "" + hooks: + - id: prettier From 30f9550be7ae98da8d722df342703402fd8414e9 Mon Sep 17 00:00:00 2001 From: fabianegli Date: Wed, 1 Jun 2022 13:25:26 +0200 Subject: [PATCH 31/58] add Prettier version tag --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b425a9329b..c8159a35c6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,6 +8,6 @@ repos: hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-prettier - rev: "" + rev: "v2.6.2" hooks: - id: prettier From 1a7dc71fbd8b2d9fd56df48832c04793dbe08f02 Mon Sep 17 00:00:00 2001 From: fabianegli Date: Wed, 1 Jun 2022 16:42:04 +0200 Subject: [PATCH 32/58] pytest is a general requirement --- requirements-dev.txt | 1 - requirements.txt | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 7a38e2e51b..28c97723b7 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,3 @@ -pytest pytest-datafiles pytest-cov mock diff --git a/requirements.txt b/requirements.txt index 798ed3470b..d8ae663a71 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,7 @@ jsonschema>=3.0 markdown>=3.3 packaging prompt_toolkit>=3.0.3 +pytest pytest-workflow pyyaml questionary>=1.8.0 From 36419c0df87277f51d4051fc481f31de8b28f94e Mon Sep 17 00:00:00 2001 From: fabianegli Date: Wed, 1 Jun 2022 16:45:11 +0200 Subject: [PATCH 33/58] specify pytest minimal version requirement --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d8ae663a71..2fe309fe7a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ jsonschema>=3.0 markdown>=3.3 packaging prompt_toolkit>=3.0.3 -pytest +pytest>=7.0.0 pytest-workflow pyyaml questionary>=1.8.0 From f880e9daea3afeca03d0b85d4a6610ffdb17d3bf Mon Sep 17 00:00:00 2001 From: fabianegli Date: Wed, 1 Jun 2022 16:46:05 +0200 Subject: [PATCH 34/58] specify pytest-workflow minimal version --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2fe309fe7a..67ee9f79a3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ markdown>=3.3 packaging prompt_toolkit>=3.0.3 pytest>=7.0.0 -pytest-workflow +pytest-workflow>=1.6.0 pyyaml questionary>=1.8.0 requests From 57bde0f79cb5c7cc8d0bc3f4df5bde8b97911c89 Mon Sep 17 00:00:00 2001 From: fabianegli Date: Wed, 1 Jun 2022 16:54:15 +0200 Subject: [PATCH 35/58] mention pytest and pytest-workflow requirements update --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ebed5628f..be73100b9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ ### General +- Updated the package requirements to prevent defunct installations of nf-core [#1620](https://github.com/nf-core/tools/pull/1620) + ### Modules - Fix a bug in the regex extracting the version from biocontainers URLs [#1598](https://github.com/nf-core/tools/pull/1598) From 0122056fd7d2b365db9b66528ca6b4d3e146a08e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Tue, 19 Apr 2022 17:04:40 +0200 Subject: [PATCH 36/58] don't updatate sha if the module is not updated --- nf_core/modules/update.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/nf_core/modules/update.py b/nf_core/modules/update.py index 150e787a74..ad68cb6c28 100644 --- a/nf_core/modules/update.py +++ b/nf_core/modules/update.py @@ -433,12 +433,6 @@ class DiffEnum(enum.Enum): if not dry_run: self.update_modules_json(modules_json, modules_repo.name, module, version) - # Don't save to a file, just iteratively update the variable - else: - modules_json = self.update_modules_json( - modules_json, modules_repo.name, module, version, write_file=False - ) - if self.save_diff_fn: # Compare the new modules.json and build a diff modules_json_diff = difflib.unified_diff( From b288578a00f65a6b64f750a54d62675d4b3a63d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 20 Apr 2022 10:16:30 +0200 Subject: [PATCH 37/58] resolve conflicts in changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a287038b4..e6ae3b38b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ - Add an empty line to `modules.json`, `params.json` and `nextflow-schema.json` when dumping them to avoid prettier errors. - Remove empty JSON schema definition groups to avoid usage errors ([#1419](https://github.com/nf-core/tools/issues/1419)) - Bumped the minimum version of `rich` from `v10` to `v10.7.0` +- Fix bug in modules.json when a module is not updated ([#1518](https://github.com/nf-core/tools/pull/1518)) ### Modules From 7b1538ea947b7cfc3b19cbd226df83df0c62d52c Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Mon, 16 May 2022 15:25:50 +0200 Subject: [PATCH 38/58] resolve conflicts in main_nf.py --- nf_core/__main__.py | 7 +++-- nf_core/modules/lint/__init__.py | 30 ++++++++++++++------ nf_core/modules/lint/main_nf.py | 48 ++++++++++++++++++++++++++++---- 3 files changed, 69 insertions(+), 16 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 50a65f4778..38b70371b9 100755 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -596,7 +596,8 @@ def create_test_yml(ctx, tool, run_tests, output, force, no_prompts): @click.option("-a", "--all", is_flag=True, help="Run on all modules") @click.option("--local", is_flag=True, help="Run additional lint tests for local modules") @click.option("--passed", is_flag=True, help="Show passed tests") -def lint(ctx, tool, dir, key, all, local, passed): +@click.option("--fix", is_flag=True, help="Fix the module version if a newer version is available") +def lint(ctx, tool, dir, key, all, local, passed, fix): """ Lint one or more modules in a directory. @@ -609,7 +610,9 @@ def lint(ctx, tool, dir, key, all, local, passed): try: module_lint = nf_core.modules.ModuleLint(dir=dir) module_lint.modules_repo = ctx.obj["modules_repo_obj"] - module_lint.lint(module=tool, key=key, all_modules=all, print_results=True, local=local, show_passed=passed) + module_lint.lint( + module=tool, key=key, all_modules=all, print_results=True, local=local, show_passed=passed, fix_version=fix + ) if len(module_lint.failed) > 0: sys.exit(1) except nf_core.modules.lint.ModuleLintException as e: diff --git a/nf_core/modules/lint/__init__.py b/nf_core/modules/lint/__init__.py index ed9db99371..407eb73416 100644 --- a/nf_core/modules/lint/__init__.py +++ b/nf_core/modules/lint/__init__.py @@ -101,7 +101,16 @@ def __init__(self, dir): def _get_all_lint_tests(): return ["main_nf", "meta_yml", "module_todos", "module_deprecations"] - def lint(self, module=None, key=(), all_modules=False, print_results=True, show_passed=False, local=False): + def lint( + self, + module=None, + key=(), + all_modules=False, + print_results=True, + show_passed=False, + local=False, + fix_version=False, + ): """ Lint all or one specific module @@ -118,6 +127,7 @@ def lint(self, module=None, key=(), all_modules=False, print_results=True, show_ :param module: A specific module to lint :param print_results: Whether to print the linting results :param show_passed: Whether passed tests should be shown as well + :param fix_version: Update the module version if a newer version is available :returns: A ModuleLint object containing information of the passed, warned and failed tests @@ -174,11 +184,11 @@ def lint(self, module=None, key=(), all_modules=False, print_results=True, show_ # Lint local modules if local and len(local_modules) > 0: - self.lint_modules(local_modules, local=True) + self.lint_modules(local_modules, local=True, fix_version=fix_version) # Lint nf-core modules if len(nfcore_modules) > 0: - self.lint_modules(nfcore_modules, local=False) + self.lint_modules(nfcore_modules, local=False, fix_version=fix_version) if print_results: self._print_results(show_passed=show_passed) @@ -282,13 +292,14 @@ def get_installed_modules(self): return local_modules, nfcore_modules - def lint_modules(self, modules, local=False): + def lint_modules(self, modules, local=False, fix_version=False): """ Lint a list of modules Args: modules ([NFCoreModule]): A list of module objects local (boolean): Whether the list consist of local or nf-core modules + fix_version (boolean): Fix the module version if a newer version is available """ progress_bar = rich.progress.Progress( "[bold blue]{task.description}", @@ -305,9 +316,9 @@ def lint_modules(self, modules, local=False): for mod in modules: progress_bar.update(lint_progress, advance=1, test_name=mod.module_name) - self.lint_module(mod, local=local) + self.lint_module(mod, local=local, fix_version=fix_version) - def lint_module(self, mod, local=False): + def lint_module(self, mod, local=False, fix_version=False): """ Perform linting on one module @@ -326,14 +337,17 @@ def lint_module(self, mod, local=False): # Only check the main script in case of a local module if local: - self.main_nf(mod) + self.main_nf(mod, fix_version) self.passed += [LintResult(mod, *m) for m in mod.passed] self.warned += [LintResult(mod, *m) for m in (mod.warned + mod.failed)] # Otherwise run all the lint tests else: for test_name in self.lint_tests: - getattr(self, test_name)(mod) + if test_name == "main_nf": + getattr(self, test_name)(mod, fix_version) + else: + getattr(self, test_name)(mod) self.passed += [LintResult(mod, *m) for m in mod.passed] self.warned += [LintResult(mod, *m) for m in mod.warned] diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 8d745cd186..030918c79a 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -5,10 +5,12 @@ import re +from galaxy.tool_util.deps.mulled.util import build_target + import nf_core -def main_nf(module_lint_object, module): +def main_nf(module_lint_object, module, fix_version): """ Lint a ``main.nf`` module file @@ -100,7 +102,7 @@ def main_nf(module_lint_object, module): module.passed.append(("main_nf_script_outputs", "Process 'output' block found", module.main_nf)) # Check the process definitions - if check_process_section(module, process_lines): + if check_process_section(module, process_lines, fix_version): module.passed.append(("main_nf_container", "Container versions match", module.main_nf)) else: module.warned.append(("main_nf_container", "Container versions do not match", module.main_nf)) @@ -190,7 +192,7 @@ def check_when_section(self, lines): self.passed.append(("when_condition", "when: condition is unchanged", self.main_nf)) -def check_process_section(self, lines): +def check_process_section(self, lines, fix_version): """ Lint the section of a module between the process definition and the 'input:' definition @@ -209,6 +211,7 @@ def check_process_section(self, lines): singularity_tag = "singularity" docker_tag = "docker" bioconda_packages = [] + update = False # Process name should be all capital letters self.process_name = lines[0].split()[1] @@ -236,14 +239,14 @@ def check_process_section(self, lines): self.warned.append(("process_standard_label", "Process label unspecified", self.main_nf)) for l in lines: - if re.search("bioconda::", l): + if _container_type(l) == "bioconda": bioconda_packages = [b for b in l.split() if "bioconda::" in b] l = l.strip(" '\"") - if l.startswith("https://containers") or l.startswith("https://depot"): + if _container_type(l) == "singularity": # e.g. "https://containers.biocontainers.pro/s3/SingImgsRepo/biocontainers/v1.2.0_cv1/biocontainers_v1.2.0_cv1.img' :" -> v1.2.0_cv1 # e.g. "https://depot.galaxyproject.org/singularity/fastqc:0.11.9--0' :" -> 0.11.9--0 singularity_tag = re.search(r"(?:/)?(?:biocontainers_)?(?::)?([A-Za-z\d\-_.]+?)(?:\.img)?['\"]", l).group(1) - if l.startswith("biocontainers/") or l.startswith("quay.io/"): + if _container_type(l) == "docker": # e.g. "quay.io/biocontainers/krona:2.7.1--pl526_5' }" -> 2.7.1--pl526_5 # e.g. "biocontainers/biocontainers:v1.2.0_cv1' }" -> v1.2.0_cv1 docker_tag = re.search(r"(?:[/])?(?::)?([A-Za-z\d\-_.]+)['\"]", l).group(1) @@ -275,10 +278,15 @@ def check_process_section(self, lines): self.warned.append( ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) ) + update = True else: self.passed.append(("bioconda_latest", f"Conda package is the latest available: `{bp}`", self.main_nf)) + print(docker_tag, singularity_tag) if docker_tag == singularity_tag: + # If linting was successful and a new version is available and fix is True + if fix_version and update: + _fix_module_version(self, bioconda_version, last_ver, singularity_tag) return True else: return False @@ -341,3 +349,31 @@ def _is_empty(self, line): if line.strip().replace(" ", "") == "": empty = True return empty + + +def _fix_module_version(self, current_version, latest_version, singularity_tag): + """Updates the module version""" + # Get target object from the latest version + target = build_target(self.module_name, latest_version) + + with open(module.main_nf, "r") as source: + lines = source.readlines() + # Replace outdated versions by the latest one + with open(module.main_nf, "w") as source: + for line in lines: + line = line.strip(" '\"") + build_type = _container_type(line) + if build_type == "bioconda": + source.write(re.sub(rf"{current_version}", f"{latest_version}", line)) + elif build_type == "singularity" or build_type == "docker": + source.write(re.sub(rf"{singularity_tag}", f"{target.build}", line)) + + +def _container_type(line): + """Returns the container type of a build.""" + if re.search("bioconda::", line): + return "bioconda" + if line.startswith("https://containers") or line.startswith("https://depot"): + return "singularity" + if line.startswith("biocontainers/") or line.startswith("quay.io/"): + return "docker" From ef00edee5af8bf6750b376f853695b5b94429abe Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 08:56:13 +0200 Subject: [PATCH 39/58] fix conflicts --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6ae3b38b9..5a287038b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,7 +53,6 @@ - Add an empty line to `modules.json`, `params.json` and `nextflow-schema.json` when dumping them to avoid prettier errors. - Remove empty JSON schema definition groups to avoid usage errors ([#1419](https://github.com/nf-core/tools/issues/1419)) - Bumped the minimum version of `rich` from `v10` to `v10.7.0` -- Fix bug in modules.json when a module is not updated ([#1518](https://github.com/nf-core/tools/pull/1518)) ### Modules From f205b1527feb11a1f67b241aec6fd63f005635d1 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 08:51:12 +0200 Subject: [PATCH 40/58] get version and build --- nf_core/modules/lint/main_nf.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 030918c79a..d9ef144233 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -6,6 +6,7 @@ import re from galaxy.tool_util.deps.mulled.util import build_target +import nf_core.modules.module_utils import nf_core @@ -282,11 +283,10 @@ def check_process_section(self, lines, fix_version): else: self.passed.append(("bioconda_latest", f"Conda package is the latest available: `{bp}`", self.main_nf)) - print(docker_tag, singularity_tag) if docker_tag == singularity_tag: # If linting was successful and a new version is available and fix is True if fix_version and update: - _fix_module_version(self, bioconda_version, last_ver, singularity_tag) + _fix_module_version(self, bioconda_version, last_ver, singularity_tag, response) return True else: return False @@ -351,22 +351,37 @@ def _is_empty(self, line): return empty -def _fix_module_version(self, current_version, latest_version, singularity_tag): +def _fix_module_version(self, current_version, latest_version, singularity_tag, response): """Updates the module version""" # Get target object from the latest version - target = build_target(self.module_name, latest_version) + build = _get_build(response) - with open(module.main_nf, "r") as source: + with open(self.main_nf, "r") as source: lines = source.readlines() # Replace outdated versions by the latest one - with open(module.main_nf, "w") as source: + with open(self.main_nf, "w") as source: for line in lines: - line = line.strip(" '\"") - build_type = _container_type(line) + l = line.strip(" '\"") + build_type = _container_type(l) if build_type == "bioconda": source.write(re.sub(rf"{current_version}", f"{latest_version}", line)) elif build_type == "singularity" or build_type == "docker": - source.write(re.sub(rf"{singularity_tag}", f"{target.build}", line)) + source.write(re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line)) + else: + source.write(line) + ### CHECK URLS BEFORE WRITING + ### MOVE FUNCTION CALL UPPER TO WRITE LOG & DEBUG MESSAGES + + +def _get_build(response): + """Get the build of the container version""" + build_times = [] + latest_v = response.get("latest_version") + files = response.get("files") + for f in files: + if f.get("version") == latest_v: + build_times.append((f.get("upload_time"), f.get("attrs").get("build"))) + return sorted(build_times, key=lambda tup: tup[0], reverse=True)[0][1] def _container_type(line): From 877b6f69a2a27dd36242f63818b82769f664b7f7 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 2 Jun 2022 10:48:57 +0200 Subject: [PATCH 41/58] resolve rebase conflicts --- nf_core/modules/lint/main_nf.py | 76 ++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 19 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index d9ef144233..072df19239 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -4,11 +4,21 @@ """ import re +<<<<<<< HEAD +======= +import nf_core +import logging +import requests +>>>>>>> db7fac1e (check that url exist & add log info) from galaxy.tool_util.deps.mulled.util import build_target import nf_core.modules.module_utils +<<<<<<< HEAD import nf_core +======= +log = logging.getLogger(__name__) +>>>>>>> db7fac1e (check that url exist & add log info) def main_nf(module_lint_object, module, fix_version): @@ -212,7 +222,6 @@ def check_process_section(self, lines, fix_version): singularity_tag = "singularity" docker_tag = "docker" bioconda_packages = [] - update = False # Process name should be all capital letters self.process_name = lines[0].split()[1] @@ -276,17 +285,31 @@ def check_process_section(self, lines, fix_version): last_ver = response.get("latest_version") if last_ver is not None and last_ver != bioconda_version: package, ver = bp.split("=", 1) - self.warned.append( - ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) - ) - update = True + # If a new version is available and fix is True, update the version + if fix_version: + if _fix_module_version(self, bioconda_version, last_ver, singularity_tag, response): + log.info(f"Updating package {package} `{ver}` -> `{last_ver}`") + log.debug(f"Updating package {package} `{ver}` -> `{last_ver}`") + self.passed.append( + ( + "bioconda_latest", + f"Conda package has been updated to the latest available: `{bp}`", + self.main_nf, + ) + ) + else: + log.debug(f"Unable to updating package {package} `{ver}` -> `{last_ver}`") + self.warned.append( + ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) + ) + else: + self.warned.append( + ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) + ) else: self.passed.append(("bioconda_latest", f"Conda package is the latest available: `{bp}`", self.main_nf)) if docker_tag == singularity_tag: - # If linting was successful and a new version is available and fix is True - if fix_version and update: - _fix_module_version(self, bioconda_version, last_ver, singularity_tag, response) return True else: return False @@ -358,19 +381,34 @@ def _fix_module_version(self, current_version, latest_version, singularity_tag, with open(self.main_nf, "r") as source: lines = source.readlines() + + # Check if the new version + build exist and replace + new_lines = [] + for line in lines: + l = line.strip(" '\"") + build_type = _container_type(l) + if build_type == "bioconda": + new_lines.append(re.sub(rf"{current_version}", f"{latest_version}", line)) + elif build_type == "singularity" or build_type == "docker": + # Check that the new url is valid + new_url = re.search( + "(?:')(.+)(?:')", re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line) + ).group(1) + response_new_container = requests.get( + "https://" + new_url if not new_url.startswith("https://") else new_url, stream=True + ) + if response_new_container.status_code != 200: + return False + new_lines.append(re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line)) + else: + new_lines.append(line) + # Replace outdated versions by the latest one with open(self.main_nf, "w") as source: - for line in lines: - l = line.strip(" '\"") - build_type = _container_type(l) - if build_type == "bioconda": - source.write(re.sub(rf"{current_version}", f"{latest_version}", line)) - elif build_type == "singularity" or build_type == "docker": - source.write(re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line)) - else: - source.write(line) - ### CHECK URLS BEFORE WRITING - ### MOVE FUNCTION CALL UPPER TO WRITE LOG & DEBUG MESSAGES + for line in new_lines: + source.write(line) + + return True def _get_build(response): From 3886ad18d0c83c0c8b9949fbc284aaf95cb7304a Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 11:33:53 +0200 Subject: [PATCH 42/58] improve logging --- nf_core/modules/lint/__init__.py | 9 +++++---- nf_core/modules/lint/main_nf.py | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/nf_core/modules/lint/__init__.py b/nf_core/modules/lint/__init__.py index 407eb73416..9bbe173ef5 100644 --- a/nf_core/modules/lint/__init__.py +++ b/nf_core/modules/lint/__init__.py @@ -306,6 +306,7 @@ def lint_modules(self, modules, local=False, fix_version=False): rich.progress.BarColumn(bar_width=None), "[magenta]{task.completed} of {task.total}[reset] » [bold yellow]{task.fields[test_name]}", transient=True, + console=console, ) with progress_bar: lint_progress = progress_bar.add_task( @@ -316,9 +317,9 @@ def lint_modules(self, modules, local=False, fix_version=False): for mod in modules: progress_bar.update(lint_progress, advance=1, test_name=mod.module_name) - self.lint_module(mod, local=local, fix_version=fix_version) + self.lint_module(mod, progress_bar, local=local, fix_version=fix_version) - def lint_module(self, mod, local=False, fix_version=False): + def lint_module(self, mod, progress_bar, local=False, fix_version=False): """ Perform linting on one module @@ -337,7 +338,7 @@ def lint_module(self, mod, local=False, fix_version=False): # Only check the main script in case of a local module if local: - self.main_nf(mod, fix_version) + self.main_nf(mod, fix_version, progress_bar) self.passed += [LintResult(mod, *m) for m in mod.passed] self.warned += [LintResult(mod, *m) for m in (mod.warned + mod.failed)] @@ -345,7 +346,7 @@ def lint_module(self, mod, local=False, fix_version=False): else: for test_name in self.lint_tests: if test_name == "main_nf": - getattr(self, test_name)(mod, fix_version) + getattr(self, test_name)(mod, fix_version, progress_bar) else: getattr(self, test_name)(mod) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 072df19239..a28cdef8ca 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -21,7 +21,7 @@ >>>>>>> db7fac1e (check that url exist & add log info) -def main_nf(module_lint_object, module, fix_version): +def main_nf(module_lint_object, module, fix_version, progress_bar): """ Lint a ``main.nf`` module file @@ -113,7 +113,7 @@ def main_nf(module_lint_object, module, fix_version): module.passed.append(("main_nf_script_outputs", "Process 'output' block found", module.main_nf)) # Check the process definitions - if check_process_section(module, process_lines, fix_version): + if check_process_section(module, process_lines, fix_version, progress_bar): module.passed.append(("main_nf_container", "Container versions match", module.main_nf)) else: module.warned.append(("main_nf_container", "Container versions do not match", module.main_nf)) @@ -203,7 +203,7 @@ def check_when_section(self, lines): self.passed.append(("when_condition", "when: condition is unchanged", self.main_nf)) -def check_process_section(self, lines, fix_version): +def check_process_section(self, lines, fix_version, progress_bar): """ Lint the section of a module between the process definition and the 'input:' definition @@ -288,7 +288,7 @@ def check_process_section(self, lines, fix_version): # If a new version is available and fix is True, update the version if fix_version: if _fix_module_version(self, bioconda_version, last_ver, singularity_tag, response): - log.info(f"Updating package {package} `{ver}` -> `{last_ver}`") + progress_bar.print(f"[blue]INFO[/blue]\t Updating package '{package}' {ver} -> {last_ver}") log.debug(f"Updating package {package} `{ver}` -> `{last_ver}`") self.passed.append( ( @@ -298,7 +298,7 @@ def check_process_section(self, lines, fix_version): ) ) else: - log.debug(f"Unable to updating package {package} `{ver}` -> `{last_ver}`") + log.debug(f"Unable to update package {package} `{ver}` -> `{last_ver}`") self.warned.append( ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) ) From eac514d1368fb99f06ebc153bdf9372ffdb4dd92 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 11:42:04 +0200 Subject: [PATCH 43/58] improve comments --- nf_core/modules/lint/main_nf.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index a28cdef8ca..82c94810e3 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -375,8 +375,14 @@ def _is_empty(self, line): def _fix_module_version(self, current_version, latest_version, singularity_tag, response): - """Updates the module version""" - # Get target object from the latest version + """Updates the module version + + Changes the bioconda current version by the latest version. + Obtains the latest build from bioconda response + Checks that the new URLs for docker and singularity with the tag [version]--[build] are valid + Changes the docker and singularity URLs + """ + # Get latest build build = _get_build(response) with open(self.main_nf, "r") as source: @@ -412,7 +418,7 @@ def _fix_module_version(self, current_version, latest_version, singularity_tag, def _get_build(response): - """Get the build of the container version""" + """Get the latest build of the container version""" build_times = [] latest_v = response.get("latest_version") files = response.get("files") From a5ba61207158b54bda7678581abf2a239803745f Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Tue, 17 May 2022 12:49:12 +0200 Subject: [PATCH 44/58] remove changes made by error --- nf_core/modules/update.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nf_core/modules/update.py b/nf_core/modules/update.py index ad68cb6c28..150e787a74 100644 --- a/nf_core/modules/update.py +++ b/nf_core/modules/update.py @@ -433,6 +433,12 @@ class DiffEnum(enum.Enum): if not dry_run: self.update_modules_json(modules_json, modules_repo.name, module, version) + # Don't save to a file, just iteratively update the variable + else: + modules_json = self.update_modules_json( + modules_json, modules_repo.name, module, version, write_file=False + ) + if self.save_diff_fn: # Compare the new modules.json and build a diff modules_json_diff = difflib.unified_diff( From 08e1b945146f3dfdfff080e954aba6fced22bb13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Tue, 19 Apr 2022 17:04:40 +0200 Subject: [PATCH 45/58] don't updatate sha if the module is not updated --- nf_core/modules/update.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/nf_core/modules/update.py b/nf_core/modules/update.py index 150e787a74..ad68cb6c28 100644 --- a/nf_core/modules/update.py +++ b/nf_core/modules/update.py @@ -433,12 +433,6 @@ class DiffEnum(enum.Enum): if not dry_run: self.update_modules_json(modules_json, modules_repo.name, module, version) - # Don't save to a file, just iteratively update the variable - else: - modules_json = self.update_modules_json( - modules_json, modules_repo.name, module, version, write_file=False - ) - if self.save_diff_fn: # Compare the new modules.json and build a diff modules_json_diff = difflib.unified_diff( From 99bf43083ee073fd05a5b345907da68b7239526c Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 2 Jun 2022 10:56:05 +0200 Subject: [PATCH 46/58] resolve rebase conflicts --- CHANGELOG.md | 6 ++---- nf_core/modules/lint/main_nf.py | 14 ++++---------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a287038b4..2059c0477a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ ### Linting - Check that the `.prettierignore` file exists and that starts with the same content. +- Add isort configuration and GitHub workflow ([#1538](https://github.com/nf-core/tools/pull/1538)) +- Add `fix` flag to `nf-core modules lint` command to update modules to the latest version ([#1588](https://github.com/nf-core/tools/pull/1588)) ### General @@ -20,10 +22,6 @@ - Fix a bug in the regex extracting the version from biocontainers URLs [#1598](https://github.com/nf-core/tools/pull/1598) -### Linting - -- Add isort configuration and GitHub workflow ([#1538](https://github.com/nf-core/tools/pull/1538)) - ## [v2.4.1 - Cobolt Koala Patch](https://github.com/nf-core/tools/releases/tag/2.4) - [2022-05-16] - Patch release to try to fix the template sync ([#1585](https://github.com/nf-core/tools/pull/1585)) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 82c94810e3..f4adb8f2ee 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -3,22 +3,16 @@ Lint the main.nf file of a module """ -import re -<<<<<<< HEAD -======= -import nf_core import logging -import requests ->>>>>>> db7fac1e (check that url exist & add log info) +import re +import requests from galaxy.tool_util.deps.mulled.util import build_target -import nf_core.modules.module_utils -<<<<<<< HEAD import nf_core -======= +import nf_core.modules.module_utils + log = logging.getLogger(__name__) ->>>>>>> db7fac1e (check that url exist & add log info) def main_nf(module_lint_object, module, fix_version, progress_bar): From 550f6d2d72aff48bd1c22cb3218ff23055a7beaf Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 19 May 2022 14:22:34 +0200 Subject: [PATCH 47/58] improve debug messages --- nf_core/modules/lint/main_nf.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index f4adb8f2ee..44fd4e8353 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -283,7 +283,7 @@ def check_process_section(self, lines, fix_version, progress_bar): if fix_version: if _fix_module_version(self, bioconda_version, last_ver, singularity_tag, response): progress_bar.print(f"[blue]INFO[/blue]\t Updating package '{package}' {ver} -> {last_ver}") - log.debug(f"Updating package {package} `{ver}` -> `{last_ver}`") + log.debug(f"Updating package {package} {ver} -> {last_ver}") self.passed.append( ( "bioconda_latest", @@ -292,7 +292,10 @@ def check_process_section(self, lines, fix_version, progress_bar): ) ) else: - log.debug(f"Unable to update package {package} `{ver}` -> `{last_ver}`") + progress_bar.print( + f"[blue]INFO[/blue]\t Tried to update package. Unable to update package '{package}' {ver} -> {last_ver}" + ) + log.debug(f"Unable to update package {package} {ver} -> {last_ver}") self.warned.append( ("bioconda_latest", f"Conda update: {package} `{ver}` -> `{last_ver}`", self.main_nf) ) @@ -397,6 +400,9 @@ def _fix_module_version(self, current_version, latest_version, singularity_tag, response_new_container = requests.get( "https://" + new_url if not new_url.startswith("https://") else new_url, stream=True ) + log.debug( + f"Connected to URL: {'https://' + new_url if not new_url.startswith('https://') else new_url}, status_code: {response_new_container.status_code}" + ) if response_new_container.status_code != 200: return False new_lines.append(re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line)) From 3e9076c61718f0aeae74cff0691e3e7d4e9d2eb8 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 2 Jun 2022 14:16:36 +0200 Subject: [PATCH 48/58] refactor fix flag to fix-version --- nf_core/__main__.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 38b70371b9..f3f0701fba 100755 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -596,8 +596,8 @@ def create_test_yml(ctx, tool, run_tests, output, force, no_prompts): @click.option("-a", "--all", is_flag=True, help="Run on all modules") @click.option("--local", is_flag=True, help="Run additional lint tests for local modules") @click.option("--passed", is_flag=True, help="Show passed tests") -@click.option("--fix", is_flag=True, help="Fix the module version if a newer version is available") -def lint(ctx, tool, dir, key, all, local, passed, fix): +@click.option("--fix-version", is_flag=True, help="Fix the module version if a newer version is available") +def lint(ctx, tool, dir, key, all, local, passed, fix_version): """ Lint one or more modules in a directory. @@ -611,7 +611,13 @@ def lint(ctx, tool, dir, key, all, local, passed, fix): module_lint = nf_core.modules.ModuleLint(dir=dir) module_lint.modules_repo = ctx.obj["modules_repo_obj"] module_lint.lint( - module=tool, key=key, all_modules=all, print_results=True, local=local, show_passed=passed, fix_version=fix + module=tool, + key=key, + all_modules=all, + print_results=True, + local=local, + show_passed=passed, + fix_version=fix_version, ) if len(module_lint.failed) > 0: sys.exit(1) From 8e061f1bbc5ee922a7576746b720b92bb402e5a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Thu, 2 Jun 2022 14:59:42 +0200 Subject: [PATCH 49/58] fix typo in CHANGELOG.md Co-authored-by: Gisela Gabernet --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7421f50e05..842695e7ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ ### Modules -- Add `fix` flag to `nf-core modules lint` command to update modules to the latest version ([#1588](https://github.com/nf-core/tools/pull/1588)) +- Add `--fix-version` flag to `nf-core modules lint` command to update modules to the latest version ([#1588](https://github.com/nf-core/tools/pull/1588)) - Fix a bug in the regex extracting the version from biocontainers URLs [#1598](https://github.com/nf-core/tools/pull/1598) ## [v2.4.1 - Cobolt Koala Patch](https://github.com/nf-core/tools/releases/tag/2.4) - [2022-05-16] From 0037bf914cf5ea6050d6c651c295e678312c644f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Thu, 2 Jun 2022 15:08:03 +0200 Subject: [PATCH 50/58] Remove duplicate in CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 842695e7ec..575d2986e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,6 @@ - Check that the `.prettierignore` file exists and that starts with the same content. - Add isort configuration and GitHub workflow ([#1538](https://github.com/nf-core/tools/pull/1538)) -- Add `fix` flag to `nf-core modules lint` command to update modules to the latest version ([#1588](https://github.com/nf-core/tools/pull/1588)) ### General From cfcf3b6c3ea09a93c011f599712cdd38c3fbdb41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Thu, 2 Jun 2022 15:08:19 +0200 Subject: [PATCH 51/58] Remove changed made by mistake --- nf_core/modules/update.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nf_core/modules/update.py b/nf_core/modules/update.py index ad68cb6c28..2ad6afab2d 100644 --- a/nf_core/modules/update.py +++ b/nf_core/modules/update.py @@ -433,6 +433,12 @@ class DiffEnum(enum.Enum): if not dry_run: self.update_modules_json(modules_json, modules_repo.name, module, version) + # Don't save to a file, just iteratively update the variable + else: + modules_json = self.update_modules_json( + modules_json, modules_repo.name, module, version, write_file=False + ) + if self.save_diff_fn: # Compare the new modules.json and build a diff modules_json_diff = difflib.unified_diff( From 358bb0a4d56b28372d6394088d34ed41f45277a5 Mon Sep 17 00:00:00 2001 From: mirpedrol Date: Thu, 2 Jun 2022 15:13:11 +0200 Subject: [PATCH 52/58] fix black linting --- nf_core/modules/update.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/modules/update.py b/nf_core/modules/update.py index 2ad6afab2d..150e787a74 100644 --- a/nf_core/modules/update.py +++ b/nf_core/modules/update.py @@ -438,7 +438,7 @@ class DiffEnum(enum.Enum): modules_json = self.update_modules_json( modules_json, modules_repo.name, module, version, write_file=False ) - + if self.save_diff_fn: # Compare the new modules.json and build a diff modules_json_diff = difflib.unified_diff( From 932070f2d5cef808be6d67e6f5c0c5e50046dc9d Mon Sep 17 00:00:00 2001 From: fabianegli Date: Thu, 9 Jun 2022 13:41:58 +0200 Subject: [PATCH 53/58] black does multiprocessing internally --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c8159a35c6..18a6a27f1a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,6 +3,7 @@ repos: rev: 22.3.0 hooks: - id: black + require_serial: true - repo: https://github.com/pycqa/isort rev: 5.10.1 hooks: From 01c2870b3fbbfdb46a687044addc5dac1fac05e9 Mon Sep 17 00:00:00 2001 From: fabianegli Date: Thu, 9 Jun 2022 13:42:57 +0200 Subject: [PATCH 54/58] add tests for test-file names --- .pre-commit-config.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 18a6a27f1a..182b93a857 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,3 +12,8 @@ repos: rev: "v2.6.2" hooks: - id: prettier + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: "v4.3.0" + hooks: + - id: name-tests-test + args: [--pytest-test-first] From 170f5ee4b77eecdad40c9f94791519ca0cd89f22 Mon Sep 17 00:00:00 2001 From: fabianegli Date: Thu, 9 Jun 2022 13:53:23 +0200 Subject: [PATCH 55/58] require_serial is inherited form the hook repo --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 182b93a857..7d87c548a0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,6 @@ repos: rev: 22.3.0 hooks: - id: black - require_serial: true - repo: https://github.com/pycqa/isort rev: 5.10.1 hooks: From 695ea4379320cfeee9a6dd2fa695f891962db119 Mon Sep 17 00:00:00 2001 From: fabianegli Date: Thu, 9 Jun 2022 13:54:40 +0200 Subject: [PATCH 56/58] specify the latest supported Python version --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7d87c548a0..948eb523f1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,6 +3,7 @@ repos: rev: 22.3.0 hooks: - id: black + language_version: python3.10 - repo: https://github.com/pycqa/isort rev: 5.10.1 hooks: From ed883341d41b1cc35dd9f20ba2830542a70ffbfc Mon Sep 17 00:00:00 2001 From: fabianegli Date: Fri, 10 Jun 2022 08:22:18 +0200 Subject: [PATCH 57/58] Add Prettier badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 806561ed9b..00ce6ce5d1 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Python tests](https://github.com/nf-core/tools/workflows/Python%20tests/badge.svg?branch=master&event=push)](https://github.com/nf-core/tools/actions?query=workflow%3A%22Python+tests%22+branch%3Amaster) [![codecov](https://codecov.io/gh/nf-core/tools/branch/master/graph/badge.svg)](https://codecov.io/gh/nf-core/tools) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![code style: prettier](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) [![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/) [![install with Bioconda](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg)](https://bioconda.github.io/recipes/nf-core/README.html) From 7a7397347e4c4b0e9e0a1f8fce0de68266683688 Mon Sep 17 00:00:00 2001 From: fabianegli Date: Fri, 10 Jun 2022 08:23:17 +0200 Subject: [PATCH 58/58] consistent capitalization in codestyle badges --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 00ce6ce5d1..cfdef5df16 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Python tests](https://github.com/nf-core/tools/workflows/Python%20tests/badge.svg?branch=master&event=push)](https://github.com/nf-core/tools/actions?query=workflow%3A%22Python+tests%22+branch%3Amaster) [![codecov](https://codecov.io/gh/nf-core/tools/branch/master/graph/badge.svg)](https://codecov.io/gh/nf-core/tools) -[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![code style: prettier](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) [![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)