Clan create: migrate to inventory

This commit is contained in:
Johannes Kirschbauer
2024-07-10 15:11:45 +02:00
parent c23b44c4f3
commit 4c4f55f309
9 changed files with 79 additions and 158 deletions

View File

@@ -1,12 +1,12 @@
# !/usr/bin/env python3
import argparse
import json
import os
from dataclasses import dataclass, fields
from pathlib import Path
from clan_cli.api import API
from clan_cli.arg_actions import AppendOptionAction
from clan_cli.inventory import Inventory, InventoryMeta
from ..cmd import CmdOut, run
from ..errors import ClanError
@@ -24,19 +24,12 @@ class CreateClanResponse:
flake_update: CmdOut
@dataclass
class ClanMetaInfo:
name: str
description: str | None
icon: str | None
@dataclass
class CreateOptions:
directory: Path | str
# Metadata for the clan
# Metadata can be shown with `clan show`
meta: ClanMetaInfo | None = None
meta: InventoryMeta | None = None
# URL to the template to use. Defaults to the "minimal" template
template_url: str = minimal_template_url
@@ -70,17 +63,18 @@ def create_clan(options: CreateOptions) -> CreateClanResponse:
)
out = run(command, cwd=directory)
# Write meta.json file if meta is provided
# Write inventory.json file
inventory = Inventory.load_file(directory)
if options.meta is not None:
meta_file = Path(directory / "clan/meta.json")
meta_file.parent.mkdir(parents=True, exist_ok=True)
with open(meta_file, "w") as f:
json.dump(options.meta.__dict__, f)
inventory.meta = options.meta
command = nix_shell(["nixpkgs#git"], ["git", "init"])
out = run(command, cwd=directory)
cmd_responses["git init"] = out
# Persist also create a commit message for each change
inventory.persist(directory, "Init inventory")
command = nix_shell(["nixpkgs#git"], ["git", "add", "."])
out = run(command, cwd=directory)
cmd_responses["git add"] = out
@@ -118,7 +112,7 @@ def register_create_parser(parser: argparse.ArgumentParser) -> None:
parser.add_argument(
"--meta",
help=f"""Metadata to set for the clan. Available options are: {", ".join([f.name for f in fields(ClanMetaInfo)]) }""",
help=f"""Metadata to set for the clan. Available options are: {", ".join([f.name for f in fields(InventoryMeta)]) }""",
nargs=2,
metavar=("name", "value"),
action=AppendOptionAction,

View File

@@ -5,8 +5,8 @@ from pathlib import Path
from urllib.parse import urlparse
from clan_cli.api import API
from clan_cli.clan.create import ClanMetaInfo
from clan_cli.errors import ClanCmdError, ClanError
from clan_cli.inventory import InventoryMeta
from ..cmd import run_no_stdout
from ..nix import nix_eval
@@ -15,10 +15,10 @@ log = logging.getLogger(__name__)
@API.register
def show_clan_meta(uri: str | Path) -> ClanMetaInfo:
def show_clan_meta(uri: str | Path) -> InventoryMeta:
cmd = nix_eval(
[
f"{uri}#clanInternals.meta",
f"{uri}#clanInternals.inventory.meta",
"--json",
]
)
@@ -27,11 +27,11 @@ def show_clan_meta(uri: str | Path) -> ClanMetaInfo:
try:
proc = run_no_stdout(cmd)
res = proc.stdout.strip()
except ClanCmdError:
except ClanCmdError as e:
raise ClanError(
"Clan might not have meta attributes",
"Evaluation failed on meta attribute",
location=f"show_clan {uri}",
description="Evaluation failed on clanInternals.meta attribute",
description=str(e.cmd),
)
clan_meta = json.loads(res)
@@ -61,7 +61,7 @@ def show_clan_meta(uri: str | Path) -> ClanMetaInfo:
description="Icon path must be a URL or a relative path.",
)
return ClanMetaInfo(
return InventoryMeta(
name=clan_meta.get("name"),
description=clan_meta.get("description", None),
icon=icon_path,
@@ -73,8 +73,8 @@ def show_command(args: argparse.Namespace) -> None:
meta = show_clan_meta(flake_path)
print(f"Name: {meta.name}")
print(f"Description: {meta.description or ''}")
print(f"Icon: {meta.icon or ''}")
print(f"Description: {meta.description or '-'}")
print(f"Icon: {meta.icon or '-'}")
def register_parser(parser: argparse.ArgumentParser) -> None:

View File

@@ -1,35 +1,20 @@
import json
from dataclasses import dataclass
from pathlib import Path
from clan_cli.api import API
from clan_cli.clan.create import ClanMetaInfo
from clan_cli.errors import ClanError
from clan_cli.inventory import Inventory, InventoryMeta
@dataclass
class UpdateOptions:
directory: str
meta: ClanMetaInfo | None = None
meta: InventoryMeta
@API.register
def update_clan_meta(options: UpdateOptions) -> ClanMetaInfo:
meta_file = Path(options.directory) / Path("clan/meta.json")
if not meta_file.exists():
raise ClanError(
"File not found",
description=f"Could not find {meta_file} to update.",
location="update_clan_meta",
)
def update_clan_meta(options: UpdateOptions) -> InventoryMeta:
inventory = Inventory.load_file(options.directory)
inventory.meta = options.meta
meta_content: dict[str, str] = {}
with open(meta_file) as f:
meta_content = json.load(f)
inventory.persist(options.directory, "Update clan meta")
meta_content = {**meta_content, **options.meta.__dict__}
with open(meta_file) as f:
json.dump(meta_content, f)
return ClanMetaInfo(**meta_content)
return inventory.meta