refactor(update): move update logic to unified UpdateManager and extend system support
Some checks failed
CI / test-unit (push) Has been cancelled
CI / test-integration (push) Has been cancelled
CI / test-env-virtual (push) Has been cancelled
CI / test-env-nix (push) Has been cancelled
CI / test-e2e (push) Has been cancelled
CI / test-virgin-user (push) Has been cancelled
CI / test-virgin-root (push) Has been cancelled
CI / codesniffer-shellcheck (push) Has been cancelled
CI / codesniffer-ruff (push) Has been cancelled

- Move update orchestration from repository scope to actions/update
- Introduce UpdateManager and SystemUpdater with distro detection
- Add Arch, Debian/Ubuntu, and Fedora/RHEL system update handling
- Rename CLI flag from --system-update to --system
- Route update as a top-level command in CLI dispatch
- Remove legacy update_repos implementation
- Add E2E tests for:
  - update all without system updates
  - update single repo (pkgmgr) with system updates

https://chatgpt.com/share/693e76ec-5ee4-800f-9623-3983f56d5430
This commit is contained in:
Kevin Veen-Birkenbach
2025-12-14 09:35:52 +01:00
parent 2a4ec18532
commit 55f4a1e941
10 changed files with 390 additions and 92 deletions

View File

@@ -1,6 +1,6 @@
"""
Integration test: update all configured repositories using
--clone-mode https and --no-verification.
--clone-mode shallow and --no-verification, WITHOUT system updates.
This test is intended to be run inside the Docker container where:
- network access is available,
@@ -8,8 +8,8 @@ This test is intended to be run inside the Docker container where:
- and it is safe to perform real git operations.
It passes if BOTH commands complete successfully (in separate tests):
1) pkgmgr update --all --clone-mode https --no-verification --system-update
2) nix run .#pkgmgr -- update --all --clone-mode https --no-verification --system-update
1) pkgmgr update --all --clone-mode shallow --no-verification
2) nix run .#pkgmgr -- update --all --clone-mode shallow --no-verification
"""
from __future__ import annotations
@@ -38,7 +38,7 @@ def _make_temp_gitconfig_with_safe_dirs(home: Path) -> Path:
return gitconfig
class TestIntegrationUpdateAllHttps(unittest.TestCase):
class TestIntegrationUpdateAllshallowNoSystem(unittest.TestCase):
def _common_env(self, home_dir: str) -> dict[str, str]:
env = os.environ.copy()
env["HOME"] = home_dir
@@ -86,32 +86,30 @@ class TestIntegrationUpdateAllHttps(unittest.TestCase):
remove_pkgmgr_from_nix_profile()
nix_profile_list_debug("AFTER CLEANUP")
def test_update_all_repositories_https_pkgmgr(self) -> None:
def test_update_all_repositories_shallow_pkgmgr_no_system(self) -> None:
self._common_setup()
with tempfile.TemporaryDirectory(prefix="pkgmgr-updateall-") as tmp:
with tempfile.TemporaryDirectory(prefix="pkgmgr-updateall-nosys-") as tmp:
env = self._common_env(tmp)
args = [
"update",
"--all",
"--clone-mode",
"https",
"shallow",
"--no-verification",
"--system-update",
]
self._run_cmd(["pkgmgr", *args], label="pkgmgr", env=env)
pkgmgr_help_debug()
def test_update_all_repositories_https_nix_pkgmgr(self) -> None:
def test_update_all_repositories_shallow_nix_pkgmgr_no_system(self) -> None:
self._common_setup()
with tempfile.TemporaryDirectory(prefix="pkgmgr-updateall-nix-") as tmp:
with tempfile.TemporaryDirectory(prefix="pkgmgr-updateall-nosys-nix-") as tmp:
env = self._common_env(tmp)
args = [
"update",
"--all",
"--clone-mode",
"https",
"shallow",
"--no-verification",
"--system-update",
]
self._run_cmd(
["nix", "run", ".#pkgmgr", "--", *args],

View File

@@ -0,0 +1,124 @@
"""
Integration test: update ONLY the 'pkgmgr' repository with system updates enabled.
This test is intended to be run inside the Docker container where:
- network access is available,
- the config/config.yaml is present,
- and it is safe to perform real git operations.
It passes if BOTH commands complete successfully (in separate tests):
1) pkgmgr update pkgmgr --clone-mode shallow --no-verification --system
2) nix run .#pkgmgr -- update pkgmgr --clone-mode shallow --no-verification --system
"""
from __future__ import annotations
import os
import subprocess
import tempfile
import unittest
from pathlib import Path
from test_install_pkgmgr_shallow import (
nix_profile_list_debug,
remove_pkgmgr_from_nix_profile,
pkgmgr_help_debug,
)
def _make_temp_gitconfig_with_safe_dirs(home: Path) -> Path:
gitconfig = home / ".gitconfig"
gitconfig.write_text(
"[safe]\n"
"\tdirectory = /src\n"
"\tdirectory = /src/.git\n"
"\tdirectory = *\n"
)
return gitconfig
class TestIntegrationUpdatePkgmgrWithSystem(unittest.TestCase):
def _common_env(self, home_dir: str) -> dict[str, str]:
env = os.environ.copy()
env["HOME"] = home_dir
home = Path(home_dir)
home.mkdir(parents=True, exist_ok=True)
env["GIT_CONFIG_GLOBAL"] = str(_make_temp_gitconfig_with_safe_dirs(home))
# Ensure nix is discoverable if the container has it
env["PATH"] = "/nix/var/nix/profiles/default/bin:" + env.get("PATH", "")
return env
def _run_cmd(self, cmd: list[str], label: str, env: dict[str, str]) -> None:
cmd_repr = " ".join(cmd)
print(f"\n[TEST] Running ({label}): {cmd_repr}")
proc = subprocess.run(
cmd,
check=False,
cwd=os.getcwd(),
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
print(proc.stdout.rstrip())
if proc.returncode != 0:
print(f"\n[TEST] Command failed ({label})")
print(f"[TEST] Command : {cmd_repr}")
print(f"[TEST] Exit code: {proc.returncode}")
nix_profile_list_debug(f"ON FAILURE ({label})")
raise AssertionError(
f"({label}) {cmd_repr!r} failed with exit code {proc.returncode}.\n\n"
f"--- output ---\n{proc.stdout}\n"
)
def _common_setup(self) -> None:
nix_profile_list_debug("BEFORE CLEANUP")
remove_pkgmgr_from_nix_profile()
nix_profile_list_debug("AFTER CLEANUP")
def test_update_pkgmgr_shallow_pkgmgr_with_system(self) -> None:
self._common_setup()
with tempfile.TemporaryDirectory(prefix="pkgmgr-update-pkgmgr-sys-") as tmp:
env = self._common_env(tmp)
args = [
"update",
"pkgmgr",
"--clone-mode",
"shallow",
"--no-verification",
"--system",
]
self._run_cmd(["pkgmgr", *args], label="pkgmgr", env=env)
pkgmgr_help_debug()
def test_update_pkgmgr_shallow_nix_pkgmgr_with_system(self) -> None:
self._common_setup()
with tempfile.TemporaryDirectory(prefix="pkgmgr-update-pkgmgr-sys-nix-") as tmp:
env = self._common_env(tmp)
args = [
"update",
"pkgmgr",
"--clone-mode",
"shallow",
"--no-verification",
"--system",
]
self._run_cmd(
["nix", "run", ".#pkgmgr", "--", *args],
label="nix run .#pkgmgr",
env=env,
)
pkgmgr_help_debug()
if __name__ == "__main__":
unittest.main()