From b82a3b6085a0b1f2084b2aa5ce84097d5d35fc45 Mon Sep 17 00:00:00 2001 From: Qubasa Date: Thu, 27 Feb 2025 01:01:50 +0100 Subject: [PATCH] clan-cli: Fix flake.py missing cache eviction if there is a garbage collected path --- pkgs/clan-cli/clan_cli/flake.py | 36 ++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/pkgs/clan-cli/clan_cli/flake.py b/pkgs/clan-cli/clan_cli/flake.py index 7a9aff8b6..3f3e40fdc 100644 --- a/pkgs/clan-cli/clan_cli/flake.py +++ b/pkgs/clan-cli/clan_cli/flake.py @@ -480,4 +480,38 @@ class Flake: if not self._cache.is_cached(selector): log.info(f"Cache miss for {selector}") self.get_from_nix([selector], nix_options) - return self._cache.select(selector) + value = self._cache.select(selector) + + num_loops = 0 + + # Check if all nix store paths exist + # FIXME: If the value is a highly nested structure, this will be slow + def recursive_path_exists_check(val: Any) -> Any: + nonlocal num_loops + if isinstance(val, str): + if val.startswith("/nix/store/"): + path = Path(val) + if not path.exists(): + msg = f"{path} does not exist" + raise ClanError(msg) + + elif isinstance(val, dict): + return {k: recursive_path_exists_check(v) for k, v in val.items()} + elif isinstance(val, list): + return [recursive_path_exists_check(v) for v in val] + if num_loops > 75: + msg = "Maximum recursion depth (75) exceeded while checking paths" + log.warning(msg) + raise ClanError(msg) + num_loops += 1 + return val + + # If there are any paths that don't exist, refresh from nix + try: + recursive_path_exists_check(value) + except ClanError as e: + log.info(f"Path {e} for {selector} does not exist, refreshing from nix") + self.get_from_nix([selector], nix_options) + value = self._cache.select(selector) + + return value