From c9d5bbaa2e8201ad5d67756f838722853ef31542 Mon Sep 17 00:00:00 2001 From: Arthur Gymer <24782660+awgymer@users.noreply.github.com> Date: Wed, 5 Feb 2025 13:44:42 +1030 Subject: [PATCH 1/2] fix(schema lint defaults): use a recursive function to strip all instances of "required" key from schema for linting --- nf_core/pipelines/schema.py | 46 +++++++++++++------------------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/nf_core/pipelines/schema.py b/nf_core/pipelines/schema.py index 47990b106..3a0077cc5 100644 --- a/nf_core/pipelines/schema.py +++ b/nf_core/pipelines/schema.py @@ -322,35 +322,7 @@ def validate_default_params(self): if self.schema is None: log.error("[red][✗] Pipeline schema not found") try: - # TODO add support for nested parameters - # Make copy of schema and remove required flags - schema_no_required = copy.deepcopy(self.schema) - if "required" in schema_no_required: - schema_no_required.pop("required") - for keyword in ["allOf", "anyOf", "oneOf"]: - if keyword in schema_no_required: - for i, kw_content in enumerate(schema_no_required[keyword]): - if "required" in kw_content: - schema_no_required[keyword][i].pop("required") - schema_no_required[keyword] = [ - kw_content for kw_content in schema_no_required[keyword] if kw_content - ] - if not schema_no_required[keyword]: - schema_no_required.pop(keyword) - for group_key, group in schema_no_required.get(self.defs_notation, {}).items(): - if "required" in group: - schema_no_required[self.defs_notation][group_key].pop("required") - for keyword in ["allOf", "anyOf", "oneOf"]: - if keyword in group: - for i, kw_content in enumerate(group[keyword]): - if "required" in kw_content: - schema_no_required[self.defs_notation][group_key][keyword][i].pop("required") - schema_no_required[self.defs_notation][group_key][keyword] = [ - kw_content for kw_content in group[keyword] if kw_content - ] - if not group[keyword]: - schema_no_required[self.defs_notation][group_key].pop(keyword) - jsonschema.validate(self.schema_defaults, schema_no_required) + jsonschema.validate(self.schema_defaults, strip_required(self.schema)) except jsonschema.exceptions.ValidationError as e: log.debug(f"Complete error message:\n{e}") raise AssertionError(f"Default parameters are invalid: {e.message}") @@ -366,7 +338,7 @@ def validate_default_params(self): self.get_wf_params() # Go over group keys - for group_key, group in schema_no_required.get(self.defs_notation, {}).items(): + for group_key, group in self.schema.get(self.defs_notation, {}).items(): group_properties = group.get("properties") for param in group_properties: if param in self.ignored_params: @@ -1042,3 +1014,17 @@ def get_web_builder_response(self): f"Pipeline schema builder returned unexpected status ({web_response['status']}): " f"{self.web_schema_build_api_url}\n See verbose log for full response" ) + + +def strip_required(node): + if isinstance(node, dict): + return { + k: y + for k, v in node.items() + for y in [strip_required(v)] + if k != "required" and (y or y is False or y == "") + } + elif isinstance(node, list): + return [y for v in node for y in [strip_required(v)] if y or y is False or y == ""] + else: + return node From fd8bd3894081b41a2e2dab6c50750ffd89a6b33a Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Wed, 5 Feb 2025 03:17:46 +0000 Subject: [PATCH 2/2] [automated] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c772e8c0..482660d87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Linting - Add linting for ifEmpty(null) ([#3411](https://github.com/nf-core/tools/pull/3411)) +- Fix arbitrarily nested params schema linting ([#3443](https://github.com/nf-core/tools/pull/3443)) ### Modules