From 29c764773f79b939ce19e4c1c5949b8266db6f86 Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Wed, 23 Jul 2025 11:33:36 +0200 Subject: [PATCH] pytest: clan_flake allow usage of plain dicts --- .../clan_lib/fixtures/flakes/flakes.py | 29 +++++++++++--- .../fixtures/flakes/lib_clan/flake.nix | 2 + .../clan_lib/machines/actions_test.py | 38 ++++++++++++------- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/pkgs/clan-cli/clan_lib/fixtures/flakes/flakes.py b/pkgs/clan-cli/clan_lib/fixtures/flakes/flakes.py index 83c303bf9..da9ac306f 100644 --- a/pkgs/clan-cli/clan_lib/fixtures/flakes/flakes.py +++ b/pkgs/clan-cli/clan_lib/fixtures/flakes/flakes.py @@ -1,3 +1,4 @@ +import json import shutil from collections.abc import Callable, Iterator from contextlib import contextmanager @@ -7,6 +8,7 @@ from typing import Any import pytest from clan_lib.clan.create import CreateOptions, create_clan from clan_lib.flake.flake import Flake +from clan_lib.nix_models.clan import Clan @pytest.fixture(scope="session") @@ -18,8 +20,12 @@ def offline_template(tmp_path_factory: Any, offline_session_flake_hook: Any) -> shutil.copytree(template, dst_dir, dirs_exist_ok=True, symlinks=True) # Emtpy clan.nix file for evaluation of the template - clan_file = dst_dir / "clan.nix" - with (clan_file).open("w") as f: + clan_nix_file = dst_dir / "clan.nix" + with (clan_nix_file).open("w") as f: + f.write(r"""{ }""") + + clan_json_file = dst_dir / "clan.json" + with (clan_json_file).open("w") as f: f.write(r"""{ }""") # expensive call ~6 seconds @@ -46,9 +52,15 @@ def patch_clan_template(monkeypatch: Any, offline_template: Path) -> None: @pytest.fixture() -def clan_flake(tmp_path: Path, patch_clan_template: Any) -> Callable[[str], Flake]: - def factory(clan_expr: str) -> Flake: +def clan_flake( + tmp_path: Path, patch_clan_template: Any +) -> Callable[[Clan | None, str | None], Flake]: + def factory(clan: Clan | None = None, raw: str | None = None) -> Flake: # TODO: Make more options configurable + if clan is None and raw is None: + msg = "Either 'clan' or 'raw' must be provided to create a Flake." + raise ValueError(msg) + dest = tmp_path / "my-clan" opts = CreateOptions( dest, @@ -57,8 +69,13 @@ def clan_flake(tmp_path: Path, patch_clan_template: Any) -> Callable[[str], Flak ) create_clan(opts) - with (dest / "clan.nix").open("w") as f: - f.write(clan_expr) + if clan is not None: + with (dest / "clan.json").open("w") as f: + f.write(json.dumps(clan)) + + if raw is not None: + with (dest / "clan.nix").open("w") as f: + f.write(raw) return Flake(str(dest)) diff --git a/pkgs/clan-cli/clan_lib/fixtures/flakes/lib_clan/flake.nix b/pkgs/clan-cli/clan_lib/fixtures/flakes/lib_clan/flake.nix index 6253d1dc5..daf1caea9 100644 --- a/pkgs/clan-cli/clan_lib/fixtures/flakes/lib_clan/flake.nix +++ b/pkgs/clan-cli/clan_lib/fixtures/flakes/lib_clan/flake.nix @@ -10,6 +10,8 @@ imports = [ ./clan.nix + (builtins.fromJSON (builtins.readFile ./clan.json)) + ( { lib, ... }: { diff --git a/pkgs/clan-cli/clan_lib/machines/actions_test.py b/pkgs/clan-cli/clan_lib/machines/actions_test.py index 0fa7acda0..49e0057e5 100644 --- a/pkgs/clan-cli/clan_lib/machines/actions_test.py +++ b/pkgs/clan-cli/clan_lib/machines/actions_test.py @@ -1,22 +1,23 @@ from collections.abc import Callable +from typing import cast import pytest from clan_lib.flake import Flake +from clan_lib.nix_models.clan import Clan, Unknown from .actions import list_machines @pytest.mark.with_core def test_list_nixos_machines(clan_flake: Callable[..., Flake]) -> None: - flake = clan_flake(r""" - { - machines = { - jon = { }; - sara = { }; - }; + clan_config: Clan = { + "machines": { + "jon": cast(Unknown, {}), # Nixos Modules are not type checkable + "sara": cast(Unknown, {}), # Nixos Modules are not type checkable } - """) + } + flake = clan_flake(clan_config) machines = list_machines(flake) @@ -25,15 +26,26 @@ def test_list_nixos_machines(clan_flake: Callable[..., Flake]) -> None: @pytest.mark.with_core def test_list_inventory_machines(clan_flake: Callable[..., Flake]) -> None: - flake = clan_flake(r""" + flake = clan_flake( { - inventory.machines = { - jon = { }; - sara = { }; + "inventory": { + "machines": { + "jon": {}, + "sara": {}, + }, + } + }, + # Attention: This is a raw Nix expression, which is not type-checked in python + # Use with care! + raw=r""" + { + machines = { + vanessa = { pkgs, ...}: { environment.systemPackages = [ pkgs.firefox ]; }; # Raw NixosModule }; } - """) + """, + ) machines = list_machines(flake) - assert list(machines.keys()) == ["jon", "sara"] + assert list(machines.keys()) == ["jon", "sara", "vanessa"]