diff --git a/pkgs/clan-cli/clan_cli/tests/test_vars.py b/pkgs/clan-cli/clan_cli/tests/test_vars.py index 716da490b..76747193e 100644 --- a/pkgs/clan-cli/clan_cli/tests/test_vars.py +++ b/pkgs/clan-cli/clan_cli/tests/test_vars.py @@ -156,6 +156,12 @@ def test_generate_public_and_secret_vars( vars_text = stringify_all_vars(machine) flake_obj = Flake(str(flake.path)) my_generator = Generator("my_generator", machine="my_machine", _flake=flake_obj) + shared_generator = Generator( + "my_shared_generator", + share=True, + machine="my_machine", + _flake=flake_obj, + ) dependent_generator = Generator( "dependent_generator", machine="my_machine", @@ -262,6 +268,36 @@ def test_generate_public_and_secret_vars( "my_generator value should NOT change after regenerating only my_shared_generator" ) + # test that a dependent is generated on a clean slate even when no --regenerate is given + # remove all generated vars + in_repo_store.delete_store("my_machine") + sops_store.delete(shared_generator, "my_shared_value") + sops_store.delete_store("my_machine") + cli.run( + [ + "vars", + "generate", + "--flake", + str(flake.path), + "my_machine", + "--generator", + "my_shared_generator", + ] + ) + # check that both my_shared_generator and dependent_generator are generated + shared_value_clean = get_machine_var( + machine, + "my_shared_generator/my_shared_value", + ).printable_value + assert shared_value_clean.startswith("shared"), "Shared value should be generated" + assert sops_store.exists(dependent_generator, "my_secret"), ( + "Dependent generator's secret should be generated" + ) + secret_value_clean = sops_store.get(dependent_generator, "my_secret").decode() + assert secret_value_clean == shared_value_clean, ( + "Dependent generator's secret should match the shared value" + ) + # TODO: it doesn't actually test if the group has access @pytest.mark.with_core diff --git a/pkgs/clan-cli/clan_cli/vars/graph.py b/pkgs/clan-cli/clan_cli/vars/graph.py index 1c4f4cb9b..d119c7ced 100644 --- a/pkgs/clan-cli/clan_cli/vars/graph.py +++ b/pkgs/clan-cli/clan_cli/vars/graph.py @@ -123,6 +123,9 @@ def requested_closure( # just enough to ensure that the list of selected generators are in a consistent state. # empty if nothing is missing. +# Theoretically we could have a more minimal closure that does not include dependents of +# the requested generators, but this would introduce the potential for previously +# generated dependents being out of sync. def minimal_closure( requested_generators: list[GeneratorKey], generators: dict[GeneratorKey, Generator], @@ -133,4 +136,6 @@ def minimal_closure( for gen_key in closure: if not generators[gen_key].exists: final_closure.add(gen_key) + # add dependents of final_closure + final_closure = add_dependents(final_closure, generators) return toposort_closure(final_closure, generators)