diff --git a/pkgs/clan-cli/clan_cli/flake.py b/pkgs/clan-cli/clan_cli/flake.py index 68b7e73bb..28658f926 100644 --- a/pkgs/clan-cli/clan_cli/flake.py +++ b/pkgs/clan-cli/clan_cli/flake.py @@ -62,6 +62,7 @@ class FlakeCacheEntry: self, value: str | float | dict[str, Any] | list[Any], selectors: list[Selector], + is_out_path: bool = False, ) -> None: self.value: str | float | int | dict[str | int, FlakeCacheEntry] self.selector: Selector @@ -75,14 +76,28 @@ class FlakeCacheEntry: else: self.selector = selectors[0] - if isinstance(value, dict): + if is_out_path: + if selectors != []: + msg = "Cannot index outPath" + raise ValueError(msg) + if not isinstance(value, str): + msg = "outPath must be a string" + raise ValueError(msg) + self.value = value + + elif isinstance(value, dict): if isinstance(self.selector, set): if not all(isinstance(v, str) for v in self.selector): msg = "Cannot index dict with non-str set" raise ValueError(msg) self.value = {} for key, value_ in value.items(): - self.value[key] = FlakeCacheEntry(value_, selectors[1:]) + if key == "outPath": + self.value[key] = FlakeCacheEntry( + value_, selectors[1:], is_out_path=True + ) + else: + self.value[key] = FlakeCacheEntry(value_, selectors[1:]) elif isinstance(value, list): if isinstance(self.selector, int): @@ -111,6 +126,12 @@ class FlakeCacheEntry: msg = f"expected integer selector or all for type list, but got {type(selectors[0])}" raise TypeError(msg) + elif isinstance(value, str) and value.startswith("/nix/store/"): + self.value = {} + self.value["outPath"] = FlakeCacheEntry( + value, selectors[1:], is_out_path=True + ) + elif isinstance(value, (str | float | int)): self.value = value @@ -214,6 +235,9 @@ class FlakeCacheEntry: else: selector = selectors[0] + if selectors == [] and isinstance(self.value, dict) and "outPath" in self.value: + return self.value["outPath"].value + if isinstance(self.value, str | float | int): return self.value if isinstance(self.value, dict): diff --git a/pkgs/clan-cli/tests/test_flake_caching.py b/pkgs/clan-cli/tests/test_flake_caching.py index 64b868c15..b04dfffac 100644 --- a/pkgs/clan-cli/tests/test_flake_caching.py +++ b/pkgs/clan-cli/tests/test_flake_caching.py @@ -3,8 +3,7 @@ from clan_cli.flake import Flake, FlakeCacheEntry from fixtures_flakes import ClanFlake -@pytest.mark.with_core -def test_flake_caching(flake: ClanFlake) -> None: +def test_select() -> None: testdict = {"x": {"y": [123, 345, 456], "z": "bla"}} test_cache = FlakeCacheEntry(testdict, []) assert test_cache["x"]["z"].value == "bla" @@ -12,6 +11,16 @@ def test_flake_caching(flake: ClanFlake) -> None: assert test_cache.select(["x", "y", 0]) == 123 assert not test_cache.is_cached(["x", "z", 1]) + +def test_out_path() -> None: + testdict = {"x": {"y": [123, 345, 456], "z": "/nix/store/bla"}} + test_cache = FlakeCacheEntry(testdict, []) + assert test_cache.select(["x", "z"]) == "/nix/store/bla" + assert test_cache.select(["x", "z", "outPath"]) == "/nix/store/bla" + + +@pytest.mark.with_core +def test_flake_caching(flake: ClanFlake) -> None: m1 = flake.machines["machine1"] m1["nixpkgs"]["hostPlatform"] = "x86_64-linux" flake.machines["machine2"] = m1.copy()