Merge pull request 'Added clan flakes inspect command. Improved ClanURI. Added democlan as dependency in flake.nix' (#635) from Qubasa-main into main
This commit is contained in:
@@ -88,7 +88,13 @@ class ClanURI:
|
||||
raise ClanError(f"Unsupported uri components: {comb}")
|
||||
|
||||
def get_internal(self) -> str:
|
||||
return self._nested_uri
|
||||
match self.scheme:
|
||||
case ClanScheme.FILE.value(path):
|
||||
return str(path) # type: ignore
|
||||
case ClanScheme.HTTP.value(url):
|
||||
return url # type: ignore
|
||||
case _:
|
||||
raise ClanError(f"Unsupported uri components: {self.scheme}")
|
||||
|
||||
@classmethod
|
||||
def from_path(cls, path: Path, params: ClanParameters) -> Self: # noqa
|
||||
|
||||
@@ -3,6 +3,7 @@ import argparse
|
||||
|
||||
from clan_cli.flakes.add import register_add_parser
|
||||
from clan_cli.flakes.history import register_list_parser
|
||||
from clan_cli.flakes.inspect import register_inspect_parser
|
||||
|
||||
from .create import register_create_parser
|
||||
|
||||
@@ -21,3 +22,5 @@ def register_parser(parser: argparse.ArgumentParser) -> None:
|
||||
register_add_parser(add_parser)
|
||||
list_parser = subparser.add_parser("list", help="List recently used flakes")
|
||||
register_list_parser(list_parser)
|
||||
inspect_parser = subparser.add_parser("inspect", help="Inspect a clan flake")
|
||||
register_inspect_parser(inspect_parser)
|
||||
|
||||
83
pkgs/clan-cli/clan_cli/flakes/inspect.py
Normal file
83
pkgs/clan-cli/clan_cli/flakes/inspect.py
Normal file
@@ -0,0 +1,83 @@
|
||||
import argparse
|
||||
import shlex
|
||||
import subprocess
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from ..errors import ClanError
|
||||
from ..nix import nix_config, nix_eval, nix_metadata
|
||||
|
||||
|
||||
@dataclass
|
||||
class FlakeConfig:
|
||||
flake_url: str | Path
|
||||
flake_attr: str
|
||||
|
||||
icon: str | None
|
||||
description: str | None
|
||||
last_updated: str
|
||||
revision: str | None
|
||||
|
||||
|
||||
def inspect_flake(flake_url: str | Path, flake_attr: str) -> FlakeConfig:
|
||||
config = nix_config()
|
||||
system = config["system"]
|
||||
|
||||
cmd = nix_eval(
|
||||
[
|
||||
f'{flake_url}#clanInternals.machines."{system}"."{flake_attr}".config.clanCore.clanIcon'
|
||||
]
|
||||
)
|
||||
|
||||
proc = subprocess.run(cmd, check=True, text=True, stdout=subprocess.PIPE)
|
||||
assert proc.stdout is not None
|
||||
if proc.returncode != 0:
|
||||
raise ClanError(
|
||||
f"""
|
||||
command: {shlex.join(cmd)}
|
||||
exit code: {proc.returncode}
|
||||
stdout:
|
||||
{proc.stdout}
|
||||
"""
|
||||
)
|
||||
res = proc.stdout.strip()
|
||||
if res == "null":
|
||||
icon_path = None
|
||||
else:
|
||||
icon_path = res
|
||||
|
||||
meta = nix_metadata(flake_url)
|
||||
|
||||
return FlakeConfig(
|
||||
flake_url=flake_url,
|
||||
flake_attr=flake_attr,
|
||||
icon=icon_path,
|
||||
description=meta.get("description"),
|
||||
last_updated=meta["lastModified"],
|
||||
revision=meta.get("revision"),
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class InspectOptions:
|
||||
machine: str
|
||||
flake: Path
|
||||
|
||||
|
||||
def inspect_command(args: argparse.Namespace) -> None:
|
||||
inspect_options = InspectOptions(
|
||||
machine=args.machine,
|
||||
flake=args.flake or Path.cwd(),
|
||||
)
|
||||
res = inspect_flake(
|
||||
flake_url=inspect_options.flake, flake_attr=inspect_options.machine
|
||||
)
|
||||
print("Icon:", res.icon)
|
||||
print("Description:", res.description)
|
||||
print("Last updated:", res.last_updated)
|
||||
print("Revision:", res.revision)
|
||||
|
||||
|
||||
def register_inspect_parser(parser: argparse.ArgumentParser) -> None:
|
||||
parser.add_argument("--machine", type=str, default="defaultVM")
|
||||
parser.set_defaults(func=inspect_command)
|
||||
@@ -10,7 +10,6 @@ from .dirs import nixpkgs_flake, nixpkgs_source
|
||||
from .errors import ClanError
|
||||
|
||||
|
||||
@deal.raises(ClanError)
|
||||
def nix_command(flags: list[str]) -> list[str]:
|
||||
return ["nix", "--extra-experimental-features", "nix-command flakes", *flags]
|
||||
|
||||
@@ -28,7 +27,6 @@ def nix_flake_show(flake_url: str | Path) -> list[str]:
|
||||
)
|
||||
|
||||
|
||||
@deal.raises(ClanError)
|
||||
def nix_build(
|
||||
flags: list[str],
|
||||
) -> list[str]:
|
||||
@@ -45,7 +43,6 @@ def nix_build(
|
||||
)
|
||||
|
||||
|
||||
@deal.raises(ClanError)
|
||||
def nix_config() -> dict[str, Any]:
|
||||
cmd = nix_command(["show-config", "--json"])
|
||||
proc = subprocess.run(cmd, check=True, text=True, stdout=subprocess.PIPE)
|
||||
@@ -56,7 +53,6 @@ def nix_config() -> dict[str, Any]:
|
||||
return config
|
||||
|
||||
|
||||
@deal.raises(ClanError)
|
||||
def nix_eval(flags: list[str]) -> list[str]:
|
||||
default_flags = nix_command(
|
||||
[
|
||||
@@ -82,9 +78,8 @@ def nix_eval(flags: list[str]) -> list[str]:
|
||||
return default_flags + flags
|
||||
|
||||
|
||||
@deal.raises(ClanError)
|
||||
def nix_metadata(flake: str) -> dict[str, Any]:
|
||||
cmd = nix_command(["flake", "metadata", "--json", flake])
|
||||
def nix_metadata(flake_url: str | Path) -> dict[str, Any]:
|
||||
cmd = nix_command(["flake", "metadata", "--json", f"{flake_url}"])
|
||||
proc = subprocess.run(cmd, check=True, text=True, stdout=subprocess.PIPE)
|
||||
data = json.loads(proc.stdout)
|
||||
return data
|
||||
|
||||
@@ -30,6 +30,7 @@ def inspect_vm(flake_url: str | Path, flake_attr: str) -> VmConfig:
|
||||
f'{flake_url}#clanInternals.machines."{system}"."{flake_attr}".config.system.clan.vm.config'
|
||||
]
|
||||
)
|
||||
|
||||
proc = subprocess.run(cmd, check=True, text=True, stdout=subprocess.PIPE)
|
||||
assert proc.stdout is not None
|
||||
if proc.returncode != 0:
|
||||
@@ -65,5 +66,5 @@ def inspect_command(args: argparse.Namespace) -> None:
|
||||
|
||||
|
||||
def register_inspect_parser(parser: argparse.ArgumentParser) -> None:
|
||||
parser.add_argument("machine", type=str)
|
||||
parser.add_argument("machine", type=str, default="defaultVM")
|
||||
parser.set_defaults(func=inspect_command)
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
, clan-core-path
|
||||
, writeShellScriptBin
|
||||
, nodePackages
|
||||
, schemathesis ? null
|
||||
}:
|
||||
let
|
||||
|
||||
@@ -155,6 +154,7 @@ python3.pkgs.buildPythonApplication {
|
||||
${checkPython}/bin/python -m pytest -m "not impure and with_core" -s ./tests
|
||||
touch $out
|
||||
'';
|
||||
|
||||
clan-pytest = runCommand "clan-pytest" { } ''
|
||||
echo ${clan-pytest-without-core}
|
||||
echo ${clan-pytest-with-core}
|
||||
|
||||
@@ -31,14 +31,15 @@
|
||||
{
|
||||
devShells.clan-cli = pkgs.callPackage ./shell.nix {
|
||||
inherit (self'.packages) clan-cli ui-assets nix-unit;
|
||||
|
||||
# inherit (inputs) democlan;
|
||||
};
|
||||
packages = {
|
||||
clan-cli = pkgs.python3.pkgs.callPackage ./default.nix {
|
||||
inherit (self'.packages) ui-assets;
|
||||
inherit (inputs) nixpkgs;
|
||||
# inherit (inputs) democlan;
|
||||
inherit (inputs.nixpkgs-for-deal.legacyPackages.${system}.python3Packages) deal;
|
||||
inherit (inputs.nixpkgs-for-deal.legacyPackages.${system}.python3Packages) schemathesis;
|
||||
#inherit (inputs.nixpkgs-for-deal.legacyPackages.${system}.python3Packages) schemathesis;
|
||||
clan-core-path = clanCoreWithVendoredDeps;
|
||||
};
|
||||
default = self'.packages.clan-cli;
|
||||
|
||||
@@ -118,6 +118,24 @@ def test_flake_with_core(
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_local_democlan(
|
||||
monkeypatch: pytest.MonkeyPatch, temporary_home: Path
|
||||
) -> Iterator[FlakeForTest]:
|
||||
democlan = os.getenv(key="DEMOCLAN_ROOT")
|
||||
if democlan is None:
|
||||
raise Exception(
|
||||
"DEMOCLAN_ROOT not set. This test requires the democlan flake to be present"
|
||||
)
|
||||
democlan_p = Path(democlan).resolve()
|
||||
if not democlan_p.is_dir():
|
||||
raise Exception(
|
||||
f"DEMOCLAN_ROOT ({democlan_p}) is not a directory. This test requires the democlan directory to be present"
|
||||
)
|
||||
|
||||
yield FlakeForTest(democlan_p)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_democlan_url(
|
||||
monkeypatch: pytest.MonkeyPatch, temporary_home: Path
|
||||
|
||||
@@ -6,6 +6,21 @@ from clan_cli.clan_uri import ClanParameters, ClanScheme, ClanURI
|
||||
from clan_cli.errors import ClanError
|
||||
|
||||
|
||||
def test_get_internal() -> None:
|
||||
# Create a ClanURI object from a remote URI with parameters
|
||||
uri = ClanURI("clan://https://example.com?flake_attr=myVM&password=1234")
|
||||
assert uri.get_internal() == "https://example.com?password=1234"
|
||||
|
||||
uri = ClanURI("clan://~/Downloads")
|
||||
assert uri.get_internal() == "~/Downloads"
|
||||
|
||||
uri = ClanURI("clan:///home/user/Downloads")
|
||||
assert uri.get_internal() == "/home/user/Downloads"
|
||||
|
||||
uri = ClanURI("clan://file:///home/user/Downloads")
|
||||
assert uri.get_internal() == "/home/user/Downloads"
|
||||
|
||||
|
||||
def test_local_uri() -> None:
|
||||
# Create a ClanURI object from a local URI
|
||||
uri = ClanURI("clan://file:///home/user/Downloads")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
from cli import Cli
|
||||
from fixtures_flakes import FlakeForTest
|
||||
from pytest import CaptureFixture
|
||||
@@ -46,3 +47,23 @@ def test_flakes_list(
|
||||
cli.run(["flakes", "add", str(test_flake.path)])
|
||||
cli.run(cmd)
|
||||
assert str(test_flake.path) in capsys.readouterr().out
|
||||
|
||||
|
||||
@pytest.mark.impure
|
||||
def test_flakes_inspect(
|
||||
test_flake_with_core: FlakeForTest, capsys: pytest.CaptureFixture
|
||||
) -> None:
|
||||
cli = Cli()
|
||||
cli.run(
|
||||
[
|
||||
"--flake",
|
||||
str(test_flake_with_core.path),
|
||||
"flakes",
|
||||
"inspect",
|
||||
"--machine",
|
||||
"vm1",
|
||||
]
|
||||
)
|
||||
out = capsys.readouterr() # empty the buffer
|
||||
|
||||
assert "Icon" in out.out
|
||||
|
||||
@@ -3,26 +3,6 @@ import deal
|
||||
from clan_cli import nix
|
||||
|
||||
|
||||
@deal.cases(nix.nix_command)
|
||||
def test_nix_command(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
|
||||
@deal.cases(nix.nix_build)
|
||||
def test_nix_build(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
|
||||
@deal.cases(nix.nix_config)
|
||||
def test_nix_config(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
|
||||
@deal.cases(nix.nix_eval)
|
||||
def test_nix_eval(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
|
||||
@deal.cases(nix.nix_shell)
|
||||
def test_nix_shell(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
Reference in New Issue
Block a user