From 527b4b2e40799eafa80da1f29ff54f8c5d709c1b Mon Sep 17 00:00:00 2001 From: DavHau Date: Wed, 20 Aug 2025 15:39:17 +0700 Subject: [PATCH] vars: ensure shared generators don't depend on machine specific generators A dependency relation like this would not make sense as it would not be clear which machines generator the shared generator would depend on --- pkgs/clan-cli/clan_cli/tests/test_vars.py | 33 +++++++++++++++++++++++ pkgs/clan-cli/clan_cli/vars/generator.py | 5 ++++ 2 files changed, 38 insertions(+) diff --git a/pkgs/clan-cli/clan_cli/tests/test_vars.py b/pkgs/clan-cli/clan_cli/tests/test_vars.py index bc0e7574c..d0a592aae 100644 --- a/pkgs/clan-cli/clan_cli/tests/test_vars.py +++ b/pkgs/clan-cli/clan_cli/tests/test_vars.py @@ -681,6 +681,39 @@ def test_prompt( assert sops_store.get(my_generator, "prompt_persist").decode() == "prompt_persist" +@pytest.mark.with_core +def test_shared_vars_must_never_depend_on_machine_specific_vars( + monkeypatch: pytest.MonkeyPatch, + flake_with_sops: ClanFlake, +) -> None: + """ + Ensure that shared vars never depend on machine specific vars. + """ + flake = flake_with_sops + + config = flake.machines["my_machine"] + config["nixpkgs"]["hostPlatform"] = "x86_64-linux" + my_generator = config["clan"]["core"]["vars"]["generators"]["my_generator"] + my_generator["share"] = True + my_generator["files"]["my_value"]["secret"] = False + my_generator["script"] = 'echo "$RANDOM" > "$out"/my_value' + my_generator["dependencies"] = ["machine_specific_generator"] + machine_specific_generator = config["clan"]["core"]["vars"]["generators"][ + "machine_specific_generator" + ] + machine_specific_generator["share"] = False + machine_specific_generator["files"]["my_value"]["secret"] = False + machine_specific_generator["script"] = 'echo "$RANDOM" > "$out"/my_value' + flake.refresh() + monkeypatch.chdir(flake.path) + # make sure an Exception is raised when trying to generate vars + with pytest.raises( + ClanError, + match="Shared generators must not depend on machine specific generators", + ): + cli.run(["vars", "generate", "--flake", str(flake.path), "my_machine"]) + + @pytest.mark.with_core def test_multi_machine_shared_vars( monkeypatch: pytest.MonkeyPatch, diff --git a/pkgs/clan-cli/clan_cli/vars/generator.py b/pkgs/clan-cli/clan_cli/vars/generator.py index 1a7c88407..d5e73bfdb 100644 --- a/pkgs/clan-cli/clan_cli/vars/generator.py +++ b/pkgs/clan-cli/clan_cli/vars/generator.py @@ -228,6 +228,11 @@ class Generator: msg = f"Generator {dep_key.name} not found in machine {machine.name}" raise ClanError(msg) + # Check that shared generators don't depend on machine-specific generators + if self.share and not dep_generator.share: + msg = f"Shared generators must not depend on machine specific generators. Generator '{self.name}' (shared) depends on '{dep_generator.name}' (machine-specific)" + raise ClanError(msg) + dep_files = dep_generator.files for file in dep_files: if file.secret: