diff --git a/pkgs/clan-cli/clan_lib/clan/get.py b/pkgs/clan-cli/clan_lib/clan/get.py index d1627b666..259088445 100644 --- a/pkgs/clan-cli/clan_lib/clan/get.py +++ b/pkgs/clan-cli/clan_lib/clan/get.py @@ -19,9 +19,6 @@ def get_clan_details(flake: Flake) -> InventoryMeta: Raises: ClanError: If the flake does not exist, or if the inventory is invalid (missing the meta attribute). """ - if flake.is_local and not flake.path.exists(): - msg = f"Path {flake} does not exist" - raise ClanError(msg, description="clan directory does not exist") inventory_store = InventoryStore(flake) inventory = inventory_store.read() diff --git a/pkgs/clan-cli/clan_lib/clan/get_test.py b/pkgs/clan-cli/clan_lib/clan/get_test.py new file mode 100644 index 000000000..aa3f5d009 --- /dev/null +++ b/pkgs/clan-cli/clan_lib/clan/get_test.py @@ -0,0 +1,24 @@ +import pytest +from clan_cli.tests.fixtures_flakes import FlakeForTest + +from clan_lib.clan.get import get_clan_details +from clan_lib.flake import Flake, FlakeDoesNotExistError, FlakeInvalidError + + +@pytest.mark.with_core +def test_get_clan_details_invalid_flake() -> None: + invalid_flake = Flake("/non/existent/path") + + with pytest.raises(FlakeDoesNotExistError): + get_clan_details(invalid_flake) + + with pytest.raises(FlakeInvalidError): + get_clan_details(Flake("/tmp")) + + +@pytest.mark.with_core +def test_get_clan_details(test_flake_with_core: FlakeForTest) -> None: + flake = Flake(str(test_flake_with_core.path)) + details = get_clan_details(flake) + + assert details["name"] == "test_flake_with_core" diff --git a/pkgs/clan-cli/clan_lib/flake/__init__.py b/pkgs/clan-cli/clan_lib/flake/__init__.py index ed265fee9..a2ff40013 100644 --- a/pkgs/clan-cli/clan_lib/flake/__init__.py +++ b/pkgs/clan-cli/clan_lib/flake/__init__.py @@ -1 +1,15 @@ -from .flake import Flake, require_flake, ClanSelectError # noqa +from .flake import ( + ClanSelectError, + Flake, + FlakeDoesNotExistError, + FlakeInvalidError, + require_flake, +) + +__all__ = [ + "ClanSelectError", + "Flake", + "FlakeDoesNotExistError", + "FlakeInvalidError", + "require_flake", +] diff --git a/pkgs/clan-cli/clan_lib/flake/flake.py b/pkgs/clan-cli/clan_lib/flake/flake.py index 6d01a6f9a..8507ec353 100644 --- a/pkgs/clan-cli/clan_lib/flake/flake.py +++ b/pkgs/clan-cli/clan_lib/flake/flake.py @@ -16,6 +16,22 @@ from clan_lib.errors import ClanCmdError, ClanError log = logging.getLogger(__name__) +class FlakeDoesNotExistError(ClanError): + """Raised when a flake does not exist""" + + def __init__(self, flake_identifier: str, description: str | None = None) -> None: + msg = f"Flake '{flake_identifier}' does not exist or is not a valid flake." + super().__init__(msg, description=description, location=flake_identifier) + + +class FlakeInvalidError(ClanError): + """Raised when a flake is invalid""" + + def __init__(self, flake_identifier: str, description: str | None = None) -> None: + msg = f"Flake is invalid. Could not find a flake.nix file in '{flake_identifier}'." + super().__init__(msg, description=description, location=flake_identifier) + + def get_nix_store_dir() -> str: """Get the Nix store directory path pattern for regex matching. @@ -773,7 +789,18 @@ class Flake: trace_prefetch = os.environ.get("CLAN_DEBUG_NIX_PREFETCH", False) == "1" if not trace_prefetch: log.debug(f"Prefetching flake {self.identifier}") - flake_prefetch = run(nix_command(cmd), RunOpts(trace=trace_prefetch)) + try: + flake_prefetch = run(nix_command(cmd), RunOpts(trace=trace_prefetch)) + except ClanCmdError as e: + if ( + f"error: getting status of '{self.identifier}': No such file or directory" + in str(e) + ): + raise FlakeDoesNotExistError(self.identifier) from e + if "error: could not find a flake.nix file": + raise FlakeInvalidError(self.identifier) from e + raise + flake_metadata = json.loads(flake_prefetch.stdout) self.store_path = flake_metadata["storePath"] self.hash = flake_metadata["hash"]