From 62c4f735ed824865423d5cc0afaa28dae8742ca4 Mon Sep 17 00:00:00 2001 From: a-kenji Date: Wed, 30 Jul 2025 15:07:05 +0200 Subject: [PATCH] pkgs/clan/lib: Move `get_clan_directories` to dirs --- pkgs/clan-cli/clan_lib/api/directory.py | 52 +------------------ pkgs/clan-cli/clan_lib/api/directory_test.py | 47 +---------------- pkgs/clan-cli/clan_lib/dirs/__init__.py | 48 +++++++++++++++++ pkgs/clan-cli/clan_lib/dirs/dirs_test.py | 54 ++++++++++++++++++++ 4 files changed, 105 insertions(+), 96 deletions(-) create mode 100644 pkgs/clan-cli/clan_lib/dirs/dirs_test.py diff --git a/pkgs/clan-cli/clan_lib/api/directory.py b/pkgs/clan-cli/clan_lib/api/directory.py index 27a63bb2c..f871862ab 100644 --- a/pkgs/clan-cli/clan_lib/api/directory.py +++ b/pkgs/clan-cli/clan_lib/api/directory.py @@ -52,56 +52,6 @@ def get_clan_folder() -> Flake: raise NotImplementedError(msg) -@API.register -def get_clan_directories(flake: Flake) -> tuple[str, str]: - """ - Get the clan source directory and computed clan directory paths. - - Args: - flake: The clan flake to get directories from - - Returns: - A tuple of (source_directory, computed_clan_directory) where: - - source_directory: Path to the clan source in the nixpkgs store - - computed_clan_directory: Computed clan directory path (source + relative directory) - - Raises: - ClanError: If the flake evaluation fails or directories cannot be found - """ - import json - from pathlib import Path - - from clan_lib.cmd import run - from clan_lib.errors import ClanError - from clan_lib.nix import nix_eval - - # Get the source directory from nix store - root_directory = flake.select("sourceInfo") - - # Get the configured directory using nix eval instead of flake.select - # to avoid the select bug with clanInternals.inventoryClass.directory - directory_result = run( - nix_eval( - flags=[ - f"{flake.identifier}#clanInternals.inventoryClass.directory", - ] - ) - ) - directory = json.loads(directory_result.stdout.strip()) - - # Both directories are in the nix store, but we need to calculate the relative path - # to get the actual configured value (e.g., "./direct-config") - root_path = Path(root_directory) - directory_path = Path(directory) - - try: - relative_path = directory_path.relative_to(root_path) - return (root_directory, str(relative_path)) - except ValueError as e: - msg = f"Directory path '{directory}' is not relative to root directory '{root_directory}'. This indicates a configuration issue with the clan directory setting." - raise ClanError(msg) from e - - @dataclass class BlkInfo: name: str @@ -175,5 +125,7 @@ def get_clan_directory_relative(flake: Flake) -> str: Raises: ClanError: If the flake evaluation fails or directories cannot be found """ + from clan_lib.dirs import get_clan_directories + _, relative_dir = get_clan_directories(flake) return relative_dir diff --git a/pkgs/clan-cli/clan_lib/api/directory_test.py b/pkgs/clan-cli/clan_lib/api/directory_test.py index ee9a97f32..ac9421540 100644 --- a/pkgs/clan-cli/clan_lib/api/directory_test.py +++ b/pkgs/clan-cli/clan_lib/api/directory_test.py @@ -4,56 +4,11 @@ from pathlib import Path import pytest from clan_cli.tests.fixtures_flakes import FlakeForTest -from clan_lib.api.directory import get_clan_directories, get_clan_directory_relative +from clan_lib.api.directory import get_clan_directory_relative from clan_lib.errors import ClanError from clan_lib.flake import Flake -@pytest.mark.with_core -def test_get_clan_directories_default(test_flake_with_core: FlakeForTest) -> None: - flake = Flake(str(test_flake_with_core.path)) - source_dir, computed_dir = get_clan_directories(flake) - - assert source_dir.startswith("/nix/store/") - assert "source" in source_dir - - computed_path = Path(computed_dir) - - assert computed_path == Path() - - -@pytest.mark.with_core -def test_get_clan_directories_invalid_flake() -> None: - invalid_flake = Flake("/non/existent/path") - - with pytest.raises(ClanError): - get_clan_directories(invalid_flake) - - -@pytest.mark.with_core -def test_get_clan_directories_with_direct_directory_config( - clan_flake: Callable[..., Flake], -) -> None: - """Test get_clan_directories with clan.directory set directly in Nix configuration""" - flake = clan_flake( - raw=""" -{ - directory = ./direct-config; -} -""" - ) - - test_subdir = Path(flake.path) / "direct-config" - test_subdir.mkdir(exist_ok=True) - - source_dir, computed_dir = get_clan_directories(flake) - - assert source_dir.startswith("/nix/store/") - assert "source" in source_dir - - assert computed_dir == "direct-config" - - @pytest.mark.with_core def test_get_relative_clan_directory_default( test_flake_with_core: FlakeForTest, diff --git a/pkgs/clan-cli/clan_lib/dirs/__init__.py b/pkgs/clan-cli/clan_lib/dirs/__init__.py index 53ee4b990..b32cce0de 100644 --- a/pkgs/clan-cli/clan_lib/dirs/__init__.py +++ b/pkgs/clan-cli/clan_lib/dirs/__init__.py @@ -170,3 +170,51 @@ def nixpkgs_source() -> Path: def select_source() -> Path: return (module_root() / "select").resolve() + + +def get_clan_directories(flake: "Flake") -> tuple[str, str]: + """ + Get the clan source directory and computed clan directory paths. + + Args: + flake: The clan flake to get directories from + + Returns: + A tuple of (source_directory, computed_clan_directory) where: + - source_directory: Path to the clan source in the nixpkgs store + - computed_clan_directory: Computed clan directory path (source + relative directory) + + Raises: + ClanError: If the flake evaluation fails or directories cannot be found + """ + import json + from pathlib import Path + + from clan_lib.cmd import run + from clan_lib.nix import nix_eval + + # Get the source directory from nix store + root_directory = flake.select("sourceInfo") + + # Get the configured directory using nix eval instead of flake.select + # to avoid the select bug with clanInternals.inventoryClass.directory + directory_result = run( + nix_eval( + flags=[ + f"{flake.identifier}#clanInternals.inventoryClass.directory", + ] + ) + ) + directory = json.loads(directory_result.stdout.strip()) + + # Both directories are in the nix store, but we need to calculate the relative path + # to get the actual configured value (e.g., "./direct-config") + root_path = Path(root_directory) + directory_path = Path(directory) + + try: + relative_path = directory_path.relative_to(root_path) + return (root_directory, str(relative_path)) + except ValueError as e: + msg = f"Directory path '{directory}' is not relative to root directory '{root_directory}'. This indicates a configuration issue with the clan directory setting." + raise ClanError(msg) from e diff --git a/pkgs/clan-cli/clan_lib/dirs/dirs_test.py b/pkgs/clan-cli/clan_lib/dirs/dirs_test.py new file mode 100644 index 000000000..422a37656 --- /dev/null +++ b/pkgs/clan-cli/clan_lib/dirs/dirs_test.py @@ -0,0 +1,54 @@ +from collections.abc import Callable +from pathlib import Path + +import pytest +from clan_cli.tests.fixtures_flakes import FlakeForTest + +from clan_lib.dirs import get_clan_directories +from clan_lib.errors import ClanError +from clan_lib.flake import Flake + + +@pytest.mark.with_core +def test_get_clan_directories_default(test_flake_with_core: FlakeForTest) -> None: + flake = Flake(str(test_flake_with_core.path)) + source_dir, computed_dir = get_clan_directories(flake) + + assert source_dir.startswith("/nix/store/") + assert "source" in source_dir + + computed_path = Path(computed_dir) + + assert computed_path == Path() + + +@pytest.mark.with_core +def test_get_clan_directories_invalid_flake() -> None: + invalid_flake = Flake("/non/existent/path") + + with pytest.raises(ClanError): + get_clan_directories(invalid_flake) + + +@pytest.mark.with_core +def test_get_clan_directories_with_direct_directory_config( + clan_flake: Callable[..., Flake], +) -> None: + """Test get_clan_directories with clan.directory set directly in Nix configuration""" + flake = clan_flake( + raw=""" +{ + directory = ./direct-config; +} +""" + ) + + test_subdir = Path(flake.path) / "direct-config" + test_subdir.mkdir(exist_ok=True) + + source_dir, computed_dir = get_clan_directories(flake) + + assert source_dir.startswith("/nix/store/") + assert "source" in source_dir + + assert computed_dir == "direct-config"