diff --git a/pkgs/clan-cli/clan_cli/clan_uri.py b/pkgs/clan-cli/clan_cli/clan_uri.py index 51b05cd0..d4c1be40 100644 --- a/pkgs/clan-cli/clan_cli/clan_uri.py +++ b/pkgs/clan-cli/clan_cli/clan_uri.py @@ -106,6 +106,10 @@ class ClanURI: @classmethod def from_str(cls, url: str, params: ClanParameters | None = None) -> Self: # noqa + prefix = "clan://" + if url.startswith(prefix): + url = url[len(prefix) :] + if params is None: return cls(f"clan://{url}") @@ -118,4 +122,4 @@ class ClanURI: return cls(f"clan://{new_url}") def __str__(self) -> str: - return f"ClanURI({self._components.geturl()})" + return self.get_full_uri() diff --git a/pkgs/clan-cli/clan_cli/flakes/inspect.py b/pkgs/clan-cli/clan_cli/flakes/inspect.py index 42f5ec91..cfdd0362 100644 --- a/pkgs/clan-cli/clan_cli/flakes/inspect.py +++ b/pkgs/clan-cli/clan_cli/flakes/inspect.py @@ -5,6 +5,7 @@ from dataclasses import dataclass from pathlib import Path from ..errors import ClanError +from ..machines.list import list_machines from ..nix import nix_config, nix_eval, nix_metadata @@ -24,6 +25,12 @@ def inspect_flake(flake_url: str | Path, flake_attr: str) -> FlakeConfig: config = nix_config() system = config["system"] + machines = list_machines(flake_url) + if flake_attr not in machines: + raise ClanError( + f"Machine {flake_attr} not found in {flake_url}. Available machines: {', '.join(machines)}" + ) + cmd = nix_eval( [ f'{flake_url}#clanInternals.machines."{system}"."{flake_attr}".config.clanCore.clanIcon' diff --git a/pkgs/clan-cli/clan_cli/history/add.py b/pkgs/clan-cli/clan_cli/history/add.py index 2e98406b..d8253b67 100644 --- a/pkgs/clan-cli/clan_cli/history/add.py +++ b/pkgs/clan-cli/clan_cli/history/add.py @@ -77,12 +77,12 @@ def add_history(uri: ClanURI) -> list[HistoryEntry]: def add_history_command(args: argparse.Namespace) -> None: - add_history(args.path) + add_history(args.uri) # takes a (sub)parser and configures it def register_add_parser(parser: argparse.ArgumentParser) -> None: parser.add_argument( - "uri", type=ClanURI, help="Path to the flake", default=ClanURI(".") + "uri", type=ClanURI.from_str, help="Path to the flake", default="." ) parser.set_defaults(func=add_history_command) diff --git a/pkgs/clan-cli/clan_cli/machines/list.py b/pkgs/clan-cli/clan_cli/machines/list.py index 8ee271a7..b16a3c64 100644 --- a/pkgs/clan-cli/clan_cli/machines/list.py +++ b/pkgs/clan-cli/clan_cli/machines/list.py @@ -11,12 +11,12 @@ from ..nix import nix_config, nix_eval log = logging.getLogger(__name__) -def list_machines(flake_dir: Path) -> list[str]: +def list_machines(flake_url: Path | str) -> list[str]: config = nix_config() system = config["system"] cmd = nix_eval( [ - f"{flake_dir}#clanInternals.machines.{system}", + f"{flake_url}#clanInternals.machines.{system}", "--apply", "builtins.attrNames", "--json", diff --git a/pkgs/clan-cli/tests/test_clan_uri.py b/pkgs/clan-cli/tests/test_clan_uri.py index db520cc8..8a0b9d04 100644 --- a/pkgs/clan-cli/tests/test_clan_uri.py +++ b/pkgs/clan-cli/tests/test_clan_uri.py @@ -125,6 +125,11 @@ def test_from_str() -> None: assert uri.params.flake_attr == "defaultVM" assert uri.get_internal() == "~/Downloads/democlan" + uri_str = "clan://~/Downloads/democlan" + uri = ClanURI.from_str(url=uri_str) + assert uri.params.flake_attr == "defaultVM" + assert uri.get_internal() == "~/Downloads/democlan" + def test_remote_with_all_params() -> None: # Create a ClanURI object from a remote URI with parameters diff --git a/pkgs/clan-cli/tests/test_history_cli.py b/pkgs/clan-cli/tests/test_history_cli.py index 604fbca4..5f2e8ed6 100644 --- a/pkgs/clan-cli/tests/test_history_cli.py +++ b/pkgs/clan-cli/tests/test_history_cli.py @@ -5,6 +5,7 @@ from cli import Cli from fixtures_flakes import FlakeForTest from pytest import CaptureFixture +from clan_cli.clan_uri import ClanParameters, ClanURI from clan_cli.dirs import user_history_file from clan_cli.history.add import HistoryEntry @@ -16,10 +17,12 @@ def test_history_add( test_flake_with_core: FlakeForTest, ) -> None: cli = Cli() + params = ClanParameters(flake_attr="vm1") + uri = ClanURI.from_path(test_flake_with_core.path, params=params) cmd = [ "history", "add", - str(test_flake_with_core.path), + str(uri), ] cli.run(cmd) @@ -35,6 +38,8 @@ def test_history_list( test_flake_with_core: FlakeForTest, ) -> None: cli = Cli() + params = ClanParameters(flake_attr="vm1") + uri = ClanURI.from_path(test_flake_with_core.path, params=params) cmd = [ "history", "list", @@ -43,6 +48,6 @@ def test_history_list( cli.run(cmd) assert str(test_flake_with_core.path) not in capsys.readouterr().out - cli.run(["history", "add", str(test_flake_with_core.path)]) + cli.run(["history", "add", str(uri)]) cli.run(cmd) assert str(test_flake_with_core.path) in capsys.readouterr().out diff --git a/pkgs/clan-vm-manager/clan_vm_manager/models.py b/pkgs/clan-vm-manager/clan_vm_manager/models.py index 15c11654..de8ff324 100644 --- a/pkgs/clan-vm-manager/clan_vm_manager/models.py +++ b/pkgs/clan-vm-manager/clan_vm_manager/models.py @@ -4,7 +4,7 @@ from pathlib import Path from typing import Any import gi -from clan_cli import flakes, vms +from clan_cli import flakes, vms, history gi.require_version("GdkPixbuf", "2.0") from gi.repository import GdkPixbuf @@ -77,7 +77,7 @@ def get_initial_vms(start: int = 0, end: int | None = None) -> list[VM]: # TODO: list_history() should return a list of dicts, not a list of paths # Execute `clan flakes add ` to democlan for this to work - for entry in flakes.history.list_history(): + for entry in history.list.list_history(): flake_config = flakes.inspect.inspect_flake(entry.path, "defaultVM") vm_config = vms.inspect.inspect_vm(entry.path, "defaultVM")