From b10631005907b90b4ebeffed19b4a6c341989e1a Mon Sep 17 00:00:00 2001 From: Victor Lin Date: Tue, 8 Sep 2026 15:42:59 -0700 Subject: [PATCH] Add dump_and_validate() config helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copied from rsv repo which was copied from measles repo.¹ Adding it here to manage the function in a central location. I've included a comment to note the loosely coupled handling of "custom_rules". Given that "custom_rules" is implemented the same way in most (all?) downstream workflows, I think fine to add this for the sake of avoiding duplicate code. ¹ https://github.com/nextstrain/rsv/blob/148dad4c7369a223a33a47f60687f6a213d8937d/workflow/snakemake_rules/config.smk#L19-L40 --- snakemake/config.smk | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/snakemake/config.smk b/snakemake/config.smk index 5e96b98..2a75920 100644 --- a/snakemake/config.smk +++ b/snakemake/config.smk @@ -3,12 +3,13 @@ Shared functions to be used within a Snakemake workflow for handling workflow configs. """ from dependencies import set_min_augur_version -set_min_augur_version("34.1.0") +set_min_augur_version("34.1.2") import os import sys import yaml from augur.config import resolve_filepath +from augur.validate import load_json_schema_locally, validate_json, ValidateError from collections.abc import Callable from typing import Optional from textwrap import dedent, indent @@ -68,6 +69,29 @@ class InvalidConfigError(Exception): pass +def dump_and_validate(dump_path, schema_path): + """ + Write Snakemake's 'config' variable to a file, then validate it against the + schema. Do both in the same function so that the validation output can + easily reference the path of the dumped config for inspection. + """ + global config + + write_config(dump_path) + + if "custom_rules" in config: + # Assumes the workflow invoking this function accepts "custom_rules" to + # define arbitrary Snakemake rules and supporting config. + print("WARNING: Skipping config schema validation because custom rules are defined.", file=sys.stderr) + return + + try: + validator = load_json_schema_locally(schema_path) + validate_json(config, validator, dump_path) + except ValidateError as e: + raise InvalidConfigError(str(e)) from e + + def resolve_config_path(path: str) -> Callable: """ Resolve a relative *path* given in a configuration value. Will always try to