From 607f3f9f76edc119c16639a57b35adb416c29283 Mon Sep 17 00:00:00 2001 From: ahuston-0 Date: Wed, 26 Mar 2025 11:22:29 -0400 Subject: [PATCH 1/2] exit on failure, add per-class logging Signed-off-by: ahuston-0 --- flupdt/flake_build.py | 19 ++++++++++--------- flupdt/flake_diff.py | 8 +++++--- flupdt/flake_eval.py | 14 ++++++++------ flupdt/flake_show.py | 11 ++++++----- flupdt/main.py | 21 +++++++++++++-------- 5 files changed, 42 insertions(+), 31 deletions(-) diff --git a/flupdt/flake_build.py b/flupdt/flake_build.py index 3821396..1a57d55 100644 --- a/flupdt/flake_build.py +++ b/flupdt/flake_build.py @@ -11,6 +11,7 @@ from flupdt.common import bash_wrapper drv_re = re.compile(r".*(/nix/store/.*\.drv).*") OUTPUT_DIR = mkdtemp(prefix="flupdt-outputs-") +logger = logging.getLogger(__name__) def build_output(path: str, output: str) -> str | None: @@ -20,16 +21,16 @@ def build_output(path: str, output: str) -> str | None: :param output: flake output to be built :returns the .drv path on success or None on failure """ - logging.info(f"build {output}") - logging.debug(f"outputting to {OUTPUT_DIR}/{output}.nixoutput") + logger.info(f"build {output}") + logger.debug(f"outputting to {OUTPUT_DIR}/{output}.nixoutput") out = bash_wrapper(f"nix build {path}#{output} -o {OUTPUT_DIR}/{output}.nixoutput") - logging.debug("output") - logging.debug(out[0]) - logging.debug("error") - logging.debug(out[1]) - logging.debug("statuscode") - logging.debug(out[2]) + logger.debug("output") + logger.debug(out[0]) + logger.debug("error") + logger.debug(out[1]) + logger.debug("statuscode") + logger.debug(out[2]) if out[2] != 0: - logging.warning(f"output {output} did not build correctly") + logger.warning(f"output {output} did not build correctly") return None return "" diff --git a/flupdt/flake_diff.py b/flupdt/flake_diff.py index fa16c80..52d5de2 100644 --- a/flupdt/flake_diff.py +++ b/flupdt/flake_diff.py @@ -5,6 +5,8 @@ import shutil from flupdt.common import bash_wrapper +logger = logging.getLogger(__name__) + def compare_derivations( path_to_flake: str, path_to_pre_drv: str, path_to_post_drv: str, *, soft_failure: bool = True @@ -24,10 +26,10 @@ def compare_derivations( ) if returncode != 0: - log_func = logging.error + log_func = logger.error if soft_failure: - log_func = logging.warning - logging.warning(f"diff failed for {path_to_pre_drv} and {path_to_post_drv}") + log_func = logger.warning + logger.warning(f"diff failed for {path_to_pre_drv} and {path_to_post_drv}") log_func(stderr) return stdout diff --git a/flupdt/flake_eval.py b/flupdt/flake_eval.py index 99caba9..e88d03c 100644 --- a/flupdt/flake_eval.py +++ b/flupdt/flake_eval.py @@ -9,6 +9,8 @@ from flupdt.common import bash_wrapper drv_re = re.compile(r".*(/nix/store/.*\.drv).*") +logger = logging.getLogger(__name__) + def evaluate_output(path: str, output: str) -> str | None: """Evaluates a given output in a flake. @@ -18,19 +20,19 @@ def evaluate_output(path: str, output: str) -> str | None: :returns the .drv path on success or None on failure :raises RuntimeError: evaluation succeeds but no derivation is found """ - logging.info(f"evaluating {output}") + logger.info(f"evaluating {output}") out = bash_wrapper(f"nix eval {path}#{output}") - logging.debug(out[0]) - logging.debug(out[1]) - logging.debug(out[2]) + logger.debug(out[0]) + logger.debug(out[1]) + logger.debug(out[2]) if out[2] != 0: - logging.warning(f"output {output} did not evaluate correctly") + logger.warning(f"output {output} did not evaluate correctly") return None drv_match = drv_re.match(out[0]) if drv_match is None: out_msg = "derivation succeeded but output derivation does not contain a derivation" raise RuntimeError(out_msg) drv = drv_match.group(1) - logging.debug(f"derivation evaluated to {drv}") + logger.debug(f"derivation evaluated to {drv}") return drv diff --git a/flupdt/flake_show.py b/flupdt/flake_show.py index aea4170..9704f3c 100644 --- a/flupdt/flake_show.py +++ b/flupdt/flake_show.py @@ -12,6 +12,7 @@ output_regexes = [ re.compile(r"checking derivation (.*)..."), re.compile(r"checking NixOS configuration \'(nixosConfigurations.*)\'\.\.\."), ] +logger = logging.getLogger(__name__) def traverse_json_base(json_dict: dict[str, typing.Any], path: list[str]) -> list[str]: @@ -54,7 +55,7 @@ def get_derivations_from_check(nix_path: str, path_to_flake: str) -> list[str]: """ flake_check = bash_wrapper(f"{nix_path} flake check --verbose --keep-going", path=path_to_flake) if flake_check[2] != 0: - logging.warning( + logger.warning( "nix flake check returned non-zero exit code, collecting all available outputs" ) error_out = flake_check[1].split("\n") @@ -62,10 +63,10 @@ def get_derivations_from_check(nix_path: str, path_to_flake: str) -> list[str]: derivations = [] for output in possible_outputs: for r in output_regexes: - logging.debug(f"{output} {r.pattern}") + logger.debug(f"{output} {r.pattern}") match = r.match(output) if match is not None: - logging.debug(match.groups()) + logger.debug(match.groups()) derivations += [match.groups()[0]] return derivations @@ -84,8 +85,8 @@ def get_derivations(path_to_flake: str) -> list[str]: raise RuntimeError(status_msg) flake_show = bash_wrapper(f"{nix_path} flake show --json", path=path_to_flake) if flake_show[2] != 0: - logging.error("flake show returned non-zero exit code") - logging.warning("falling back to full evaluation via nix flake check") + logger.error("flake show returned non-zero exit code") + logger.warning("falling back to full evaluation via nix flake check") derivations = get_derivations_from_check(nix_path, path_to_flake) else: flake_show_json = json.loads(flake_show[0]) diff --git a/flupdt/main.py b/flupdt/main.py index edff707..07a7e00 100755 --- a/flupdt/main.py +++ b/flupdt/main.py @@ -4,6 +4,7 @@ import logging import os +import sys from argparse import Namespace from pathlib import Path @@ -14,6 +15,8 @@ from flupdt.flake_diff import compare_derivations from flupdt.flake_eval import evaluate_output from flupdt.flake_show import get_derivations +logger = logging.getLogger(__name__) + def batch_eval(args: Namespace, flake_path: str, derivations: list[str]) -> None: """Bulk run evaluations or builds on a derivation set. @@ -28,12 +31,14 @@ def batch_eval(args: Namespace, flake_path: str, derivations: list[str]) -> None if args.evaluate: drv_map[d] = evaluate_output(flake_path, d) if args.build: - build_output(flake_path, d) + drv_map[d] = build_output(flake_path, d) if args.json: with Path.open(args.json, "w+") as f: from json import dump dump(drv_map, f) + if any(x is None for x in drv_map.values()): + sys.exit(1) def compare_drvs(args: Namespace) -> None: @@ -52,8 +57,8 @@ def compare_drvs(args: Namespace) -> None: pre_json_dict = load(pre) post_json_dict = load(post) - logging.debug(f"pre-snapshot derivations: {pre_json_dict}") - logging.debug(f"post-snapshot derivations: {post_json_dict}") + logger.debug(f"pre-snapshot derivations: {pre_json_dict}") + logger.debug(f"post-snapshot derivations: {post_json_dict}") pre_json_keys = set(pre_json_dict.keys()) post_json_keys = set(post_json_dict.keys()) @@ -64,11 +69,11 @@ def compare_drvs(args: Namespace) -> None: missing_pre_keys = post_json_keys.difference(common_keys_to_eval) if missing_pre_keys: - logging.warning(f"Following outputs are missing from pre-snapshot: {missing_pre_keys}") + logger.warning(f"Following outputs are missing from pre-snapshot: {missing_pre_keys}") if missing_post_keys: - logging.warning(f"Following outputs are missing from post-snapshot: {missing_post_keys}") + logger.warning(f"Following outputs are missing from post-snapshot: {missing_post_keys}") - logging.info(f"Evaluating the following outputs for differences: {common_keys_to_eval}") + logger.info(f"Evaluating the following outputs for differences: {common_keys_to_eval}") out_file: str = os.devnull if args.compare_output_to_file: @@ -97,11 +102,11 @@ def build_or_eval(args: Namespace) -> None: lambda s: s.startswith("hydraJobs"), get_derivations(flake_path) ) derivations, hydra_jobs = list(derivations), list(hydra_jobs) - logging.info(f"derivations: {list(derivations)}") + logger.info(f"derivations: {list(derivations)}") batch_eval(args, flake_path, derivations) if not args.keep_hydra: - logging.info("--keep-hydra flag is not specified, removing Hydra jobs") + logger.info("--keep-hydra flag is not specified, removing Hydra jobs") else: batch_eval(args, flake_path, hydra_jobs) -- 2.48.1 From 9103ece19c6353edc6d1a23902b2d0eecc55a4d9 Mon Sep 17 00:00:00 2001 From: ahuston-0 Date: Wed, 26 Mar 2025 11:33:38 -0400 Subject: [PATCH 2/2] default logging is now INFO --- flupdt/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flupdt/main.py b/flupdt/main.py index 07a7e00..151f4de 100755 --- a/flupdt/main.py +++ b/flupdt/main.py @@ -117,7 +117,7 @@ def main() -> None: :returns: None """ - configure_logger("DEBUG") + configure_logger("INFO") args = parse_inputs() if args.compare_drvs: compare_drvs(args) -- 2.48.1