diff --git a/pkgs/clan-cli/clan_cli/clan_uri.py b/pkgs/clan-cli/clan_cli/clan_uri.py index 5b28c661..539a27ee 100644 --- a/pkgs/clan-cli/clan_cli/clan_uri.py +++ b/pkgs/clan-cli/clan_cli/clan_uri.py @@ -12,7 +12,9 @@ class FlakeId: _value: str | Path def __str__(self) -> str: - return f"{self._value}" # The __str__ method returns a custom string representation + return str( + self._value + ) # The __str__ method returns a custom string representation @property def path(self) -> Path: @@ -34,26 +36,13 @@ class FlakeId: return isinstance(self._value, str) -@dataclass -class MachineData: - flake_id: FlakeId - name: str = "defaultVM" - - def get_id(self) -> str: - return f"{self.flake_id}#{self.name}" - - # Define the ClanURI class class ClanURI: - _orig_uri: str - _components: urllib.parse.ParseResult flake_id: FlakeId - _machines: list[MachineData] + machine_name: str # Initialize the class with a clan:// URI def __init__(self, uri: str) -> None: - self._machines = [] - # users might copy whitespace along with the uri uri = uri.strip() self._orig_uri = uri @@ -67,21 +56,16 @@ class ClanURI: # Parse the URI into components # url://netloc/path;parameters?query#fragment - self._components = urllib.parse.urlparse(nested_uri) + components: urllib.parse.ParseResult = urllib.parse.urlparse(nested_uri) # Replace the query string in the components with the new query string - clean_comps = self._components._replace( - query=self._components.query, fragment="" - ) + clean_comps = components._replace(query=components.query, fragment="") # Parse the URL into a ClanUrl object self.flake_id = self._parse_url(clean_comps) - - if self._components.fragment == "": - self._machines.append(MachineData(flake_id=self.flake_id)) - return - - self._machines.append(self._parse_machine_query(self._components.fragment)) + self.machine_name = "defaultVM" + if components.fragment: + self.machine_name = components.fragment def _parse_url(self, comps: urllib.parse.ParseResult) -> FlakeId: comb = ( @@ -100,20 +84,6 @@ class ClanURI: return flake_id - def _parse_machine_query(self, machine_frag: str) -> MachineData: - comp = urllib.parse.urlparse(machine_frag) - machine_name = comp.path - - machine = MachineData(flake_id=self.flake_id, name=machine_name) - return machine - - @property - def machine(self) -> MachineData: - return self._machines[0] - - def get_orig_uri(self) -> str: - return self._orig_uri - def get_url(self) -> str: return str(self.flake_id) @@ -134,8 +104,5 @@ class ClanURI: return cls(clan_uri) - def __str__(self) -> str: - return self.get_orig_uri() - def __repr__(self) -> str: return f"ClanURI({self})" diff --git a/pkgs/clan-cli/clan_cli/history/add.py b/pkgs/clan-cli/clan_cli/history/add.py index c997bc27..b8c6dc01 100644 --- a/pkgs/clan-cli/clan_cli/history/add.py +++ b/pkgs/clan-cli/clan_cli/history/add.py @@ -82,7 +82,7 @@ def add_all_to_history(uri: ClanURI) -> list[HistoryEntry]: def add_history(uri: ClanURI) -> HistoryEntry: user_history_file().parent.mkdir(parents=True, exist_ok=True) history = list_history() - new_entry = _add_maschine_to_history_list(uri.get_url(), uri.machine.name, history) + new_entry = _add_maschine_to_history_list(uri.get_url(), uri.machine_name, history) write_history_file(history) return new_entry diff --git a/pkgs/clan-cli/clan_cli/history/update.py b/pkgs/clan-cli/clan_cli/history/update.py index 6eb23ac2..6c263f80 100644 --- a/pkgs/clan-cli/clan_cli/history/update.py +++ b/pkgs/clan-cli/clan_cli/history/update.py @@ -30,7 +30,7 @@ def update_history() -> list[HistoryEntry]: url=str(entry.flake.flake_url), machine_name=entry.flake.flake_attr, ) - flake = inspect_flake(uri.get_url(), uri.machine.name) + flake = inspect_flake(uri.get_url(), uri.machine_name) flake.flake_url = str(flake.flake_url) entry = HistoryEntry( flake=flake, last_used=datetime.datetime.now().isoformat() diff --git a/pkgs/clan-cli/clan_cli/machines/machines.py b/pkgs/clan-cli/clan_cli/machines/machines.py index 2d34c509..f116e539 100644 --- a/pkgs/clan-cli/clan_cli/machines/machines.py +++ b/pkgs/clan-cli/clan_cli/machines/machines.py @@ -4,7 +4,7 @@ from pathlib import Path from tempfile import NamedTemporaryFile from typing import Any -from clan_cli.clan_uri import ClanURI, MachineData +from clan_cli.clan_uri import ClanURI, FlakeId from ..cmd import run_no_stdout from ..errors import ClanError @@ -16,8 +16,7 @@ log = logging.getLogger(__name__) class Machine: name: str - flake: str | Path - data: MachineData + flake: FlakeId nix_options: list[str] eval_cache: dict[str, str] build_cache: dict[str, Path] @@ -30,7 +29,6 @@ class Machine: flake: Path | str, deployment_info: dict | None = None, nix_options: list[str] = [], - machine: MachineData | None = None, ) -> None: """ Creates a Machine @@ -38,14 +36,9 @@ class Machine: @clan_dir: the directory of the clan, optional, if not set it will be determined from the current working directory @machine_json: can be optionally used to skip evaluation of the machine, location of the json file with machine data """ - if machine is None: - uri = ClanURI.from_str(str(flake), name) - machine = uri.machine - self.flake: str | Path = machine.flake_id._value - self.name: str = machine.name - self.data: MachineData = machine - else: - self.data: MachineData = machine + uri = ClanURI.from_str(str(flake), name) + self.flake_id = uri.flake_id + self.name: str = uri.machine_name self.eval_cache: dict[str, str] = {} self.build_cache: dict[str, Path] = {} @@ -60,7 +53,7 @@ class Machine: self.eval_cache.clear() def __str__(self) -> str: - return f"Machine(name={self.data.name}, flake={self.data.flake_id})" + return f"Machine(name={self.name}, flake={self.flake_id})" def __repr__(self) -> str: return str(self) @@ -81,7 +74,7 @@ class Machine: "deploymentAddress" ) if val is None: - msg = f"the 'clan.networking.targetHost' nixos option is not set for machine '{self.data.name}'" + msg = f"the 'clan.networking.targetHost' nixos option is not set for machine '{self.name}'" raise ClanError(msg) return val @@ -112,12 +105,12 @@ class Machine: if self._flake_path: return self._flake_path - if self.data.flake_id.is_local(): - self._flake_path = self.data.flake_id.path - elif self.data.flake_id.is_remote(): - self._flake_path = Path(nix_metadata(self.data.flake_id.url)["path"]) + if self.flake_id.is_local(): + self._flake_path = self.flake_id.path + elif self.flake_id.is_remote(): + self._flake_path = Path(nix_metadata(self.flake_id.url)["path"]) else: - raise ClanError(f"Unsupported flake url: {self.data.flake_id}") + raise ClanError(f"Unsupported flake url: {self.flake_id}") assert self._flake_path is not None return self._flake_path @@ -125,7 +118,7 @@ class Machine: @property def target_host(self) -> Host: return parse_deployment_address( - self.data.name, self.target_host_address, meta={"machine": self} + self.name, self.target_host_address, meta={"machine": self} ) @property @@ -139,7 +132,7 @@ class Machine: return self.target_host # enable ssh agent forwarding to allow the build host to access the target host return parse_deployment_address( - self.data.name, + self.name, build_host, forward_agent=True, meta={"machine": self, "target_host": self.target_host}, @@ -198,7 +191,7 @@ class Machine: args += [ "--expr", f""" - ((builtins.getFlake "{url}").clanInternals.machinesFunc."{system}"."{self.data.name}" {{ + ((builtins.getFlake "{url}").clanInternals.machinesFunc."{system}"."{self.name}" {{ extraConfig = builtins.fromJSON (builtins.readFile (builtins.fetchTree {{ type = "file"; url = if (builtins.compareVersions builtins.nixVersion "2.19") == -1 then "{file_info["path"]}" else "file:{file_info["path"]}"; @@ -213,9 +206,7 @@ class Machine: else: flake = f"path:{self.flake_dir}" - args += [ - f'{flake}#clanInternals.machines."{system}".{self.data.name}.{attr}' - ] + args += [f'{flake}#clanInternals.machines."{system}".{self.name}.{attr}'] args += nix_options + self.nix_options if method == "eval": diff --git a/pkgs/clan-cli/tests/test_clan_uri.py b/pkgs/clan-cli/tests/test_clan_uri.py index 891d022d..3b343080 100644 --- a/pkgs/clan-cli/tests/test_clan_uri.py +++ b/pkgs/clan-cli/tests/test_clan_uri.py @@ -46,25 +46,21 @@ def test_remote_with_clanparams() -> None: # Create a ClanURI object from a remote URI with parameters uri = ClanURI("clan://https://example.com") - assert uri.machine.name == "defaultVM" + assert uri.machine_name == "defaultVM" assert uri.flake_id.url == "https://example.com" def test_from_str_remote() -> None: uri = ClanURI.from_str(url="https://example.com", machine_name="myVM") assert uri.get_url() == "https://example.com" - assert uri.get_orig_uri() == "clan://https://example.com#myVM" - assert uri.machine.name == "myVM" - assert len(uri._machines) == 1 + assert uri.machine_name == "myVM" assert uri.flake_id.url == "https://example.com" def test_from_str_local() -> None: uri = ClanURI.from_str(url="~/Projects/democlan", machine_name="myVM") assert uri.get_url().endswith("/Projects/democlan") - assert uri.get_orig_uri() == "clan://~/Projects/democlan#myVM" - assert uri.machine.name == "myVM" - assert len(uri._machines) == 1 + assert uri.machine_name == "myVM" assert uri.flake_id.is_local() assert str(uri.flake_id).endswith("/Projects/democlan") # type: ignore @@ -72,9 +68,7 @@ def test_from_str_local() -> None: def test_from_str_local_no_machine() -> None: uri = ClanURI.from_str("~/Projects/democlan") assert uri.get_url().endswith("/Projects/democlan") - assert uri.get_orig_uri() == "clan://~/Projects/democlan" - assert uri.machine.name == "defaultVM" - assert len(uri._machines) == 1 + assert uri.machine_name == "defaultVM" assert uri.flake_id.is_local() assert str(uri.flake_id).endswith("/Projects/democlan") # type: ignore @@ -82,8 +76,6 @@ def test_from_str_local_no_machine() -> None: def test_from_str_local_no_machine2() -> None: uri = ClanURI.from_str("~/Projects/democlan#syncthing-peer1") assert uri.get_url().endswith("/Projects/democlan") - assert uri.get_orig_uri() == "clan://~/Projects/democlan#syncthing-peer1" - assert uri.machine.name == "syncthing-peer1" - assert len(uri._machines) == 1 + assert uri.machine_name == "syncthing-peer1" assert uri.flake_id.is_local() assert str(uri.flake_id).endswith("/Projects/democlan") # type: ignore