Merge pull request 'clan-lib: Make Flake throw more concrete errors if the flake path is invalid or non existend' (#4870) from Qubasa/clan-core:fix_ui_stuff2 into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/4870
This commit is contained in:
Luis Hebendanz
2025-08-21 22:08:28 +00:00
4 changed files with 67 additions and 5 deletions

View File

@@ -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()

View File

@@ -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"

View File

@@ -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",
]

View File

@@ -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"]