diff --git a/pkgs/clan-cli/clan_cli/clan_uri.py b/pkgs/clan-cli/clan_cli/clan_uri.py new file mode 100644 index 00000000..f140474f --- /dev/null +++ b/pkgs/clan-cli/clan_cli/clan_uri.py @@ -0,0 +1,50 @@ +# Import the urllib.parse module +import urllib.parse +from enum import Enum + +from .errors import ClanError + + +class ClanScheme(Enum): + HTTP = "http" + HTTPS = "https" + FILE = "file" + + +# Define the ClanURI class +class ClanURI: + # Initialize the class with a clan:// URI + def __init__(self, uri: str) -> None: + if uri.startswith("clan://"): + uri = uri[7:] + else: + raise ClanError("Invalid scheme: expected clan://, got {}".format(uri)) + + # Parse the URI into components + self.components = urllib.parse.urlparse(uri) + + try: + self.scheme = ClanScheme(self.components.scheme) + except ValueError: + raise ClanError("Unsupported scheme: {}".format(self.components.scheme)) + + # Define a method to get the path of the URI + @property + def path(self) -> str: + return self.components.path + + @property + def url(self) -> str: + return self.components.geturl() + + # Define a method to check if the URI is a remote HTTP URL + def is_remote(self) -> bool: + match self.scheme: + case ClanScheme.HTTP | ClanScheme.HTTPS: + return True + case ClanScheme.FILE: + return False + + # Define a method to check if the URI is a local path + def is_local(self) -> bool: + return not self.is_remote() diff --git a/pkgs/clan-cli/tests/test_clan_uri.py b/pkgs/clan-cli/tests/test_clan_uri.py new file mode 100644 index 00000000..72588b4e --- /dev/null +++ b/pkgs/clan-cli/tests/test_clan_uri.py @@ -0,0 +1,34 @@ +import pytest + +from clan_cli.clan_uri import ClanURI +from clan_cli.errors import ClanError + + +def test_local_uri() -> None: + # Create a ClanURI object from a local URI + uri = ClanURI("clan://file:///home/user/Downloads") + # Check that the URI is local + assert uri.is_local() + # Check that the URI is not remote + assert not uri.is_remote() + # Check that the URI path is correct + assert uri.path == "/home/user/Downloads" + + +def test_unsupported_schema() -> None: + with pytest.raises(ClanError, match="Unsupported scheme: ftp"): + # Create a ClanURI object from an unsupported URI + ClanURI("clan://ftp://ftp.example.com") + + +def test_is_remote() -> None: + # Create a ClanURI object from a remote URI + uri = ClanURI("clan://https://example.com") + # Check that the URI is remote + assert uri.is_remote() + # Check that the URI is not local + assert not uri.is_local() + # Check that the URI path is correct + assert uri.path == "" + + assert uri.url == "https://example.com" diff --git a/pkgs/clan-vm-manager/clan-vm-manager.code-workspace b/pkgs/clan-vm-manager/clan-vm-manager.code-workspace index 50ec088e..6f28f07d 100644 --- a/pkgs/clan-vm-manager/clan-vm-manager.code-workspace +++ b/pkgs/clan-vm-manager/clan-vm-manager.code-workspace @@ -5,6 +5,9 @@ }, { "path": "../clan-cli/clan_cli" + }, + { + "path": "../clan-cli/tests" } ], "settings": { diff --git a/pkgs/clan-vm-manager/shell.nix b/pkgs/clan-vm-manager/shell.nix index 36dccaf8..d949f45d 100644 --- a/pkgs/clan-vm-manager/shell.nix +++ b/pkgs/clan-vm-manager/shell.nix @@ -1,8 +1,10 @@ -{ clan-vm-manager, clan-cli, mkShell, ruff }: +{ clan-vm-manager, clan-cli, mkShell, ruff, desktop-file-utils, xdg-utils }: mkShell { inherit (clan-vm-manager) propagatedBuildInputs buildInputs; nativeBuildInputs = [ ruff + desktop-file-utils + xdg-utils ] ++ clan-vm-manager.nativeBuildInputs; PYTHONBREAKPOINT = "ipdb.set_trace"; @@ -13,14 +15,22 @@ mkShell { # prepend clan-cli for development export PYTHONPATH=../clan-cli:$PYTHONPATH - ln -sf ${clan-vm-manager} result + ln -snf ${clan-vm-manager} result + - set -euox # install desktop file - cp -f ${clan-vm-manager}/share/applications/clan-vm-manager.desktop ~/.local/share/applications/clan-vm-manager.desktop + set -eou pipefail + DESKTOP_DST=~/.local/share/applications/clan-vm-manager.desktop + DESKTOP_SRC=${clan-vm-manager}/share/applications/clan-vm-manager.desktop + UI_BIN=${clan-vm-manager}/bin/clan-vm-manager + + cp -f $DESKTOP_SRC $DESKTOP_DST sleep 2 - sed -i "s|Exec=.*clan-vm-manager|Exec=${clan-vm-manager}/bin/clan-vm-manager|" ~/.local/share/applications/clan-vm-manager.desktop + sed -i "s|Exec=.*clan-vm-manager|Exec=$UI_BIN|" $DESKTOP_DST xdg-mime default clan-vm-manager.desktop x-scheme-handler/clan - set +x + echo "==== Validating desktop file installation ====" + set -x + desktop-file-validate $DESKTOP_DST + set +xeou pipefail ''; }