Some checks failed
Mark stable commit / test-unit (push) Has been cancelled
Mark stable commit / test-integration (push) Has been cancelled
Mark stable commit / test-env-virtual (push) Has been cancelled
Mark stable commit / test-env-nix (push) Has been cancelled
Mark stable commit / test-e2e (push) Has been cancelled
Mark stable commit / test-virgin-user (push) Has been cancelled
Mark stable commit / test-virgin-root (push) Has been cancelled
Mark stable commit / mark-stable (push) Has been cancelled
* Remove legacy *main.py* and introduce *pkgmgr* module entry via *python -m pkgmgr* * Add ***main**.py* as the canonical entry point delegating to the CLI * Export *PYTHONPATH=src* in Makefile to ensure reliable imports in dev and CI * Update setup scripts (venv & nix) to use module execution * Refactor all E2E tests to execute the real module entry instead of file paths This aligns pkgmgr with standard Python packaging practices and simplifies testing, setup, and execution across environments. https://chatgpt.com/share/693c9056-716c-800f-b583-fc9245eab2b4
156 lines
4.4 KiB
Python
156 lines
4.4 KiB
Python
import runpy
|
||
import sys
|
||
import os
|
||
import unittest
|
||
import subprocess
|
||
|
||
|
||
def nix_profile_list_debug(label: str) -> None:
|
||
"""
|
||
Print `nix profile list` for debugging inside the test container.
|
||
Never fails the test.
|
||
"""
|
||
print(f"\n--- NIX PROFILE LIST ({label}) ---")
|
||
proc = subprocess.run(
|
||
["nix", "profile", "list"],
|
||
capture_output=True,
|
||
text=True,
|
||
check=False,
|
||
)
|
||
stdout = proc.stdout.strip()
|
||
stderr = proc.stderr.strip()
|
||
|
||
if stdout:
|
||
print(stdout)
|
||
if stderr:
|
||
print("stderr:", stderr)
|
||
print("--- END ---\n")
|
||
|
||
|
||
def remove_pkgmgr_from_nix_profile() -> None:
|
||
"""
|
||
Best-effort cleanup before running the integration test.
|
||
|
||
We *do not* try to parse profile indices here, because modern `nix profile list`
|
||
prints a descriptive format without an index column inside the container.
|
||
|
||
Instead, we directly try to remove possible names:
|
||
- 'pkgmgr'
|
||
- 'package-manager'
|
||
"""
|
||
for spec in ("pkgmgr", "package-manager"):
|
||
subprocess.run(
|
||
["nix", "profile", "remove", spec],
|
||
check=False, # never fail on cleanup
|
||
)
|
||
|
||
|
||
def configure_git_safe_directory() -> None:
|
||
"""
|
||
Configure Git to treat /src as a safe directory.
|
||
|
||
Needed because /src is a bind-mounted repository in CI, often owned by a
|
||
different UID. Modern Git aborts with:
|
||
'fatal: detected dubious ownership in repository at /src/.git'
|
||
|
||
This fix applies ONLY inside this test container.
|
||
"""
|
||
try:
|
||
subprocess.run(
|
||
["git", "config", "--global", "--add", "safe.directory", "/src"],
|
||
check=False,
|
||
)
|
||
except FileNotFoundError:
|
||
print("[WARN] git not found – skipping safe.directory configuration")
|
||
|
||
|
||
def pkgmgr_help_debug() -> None:
|
||
"""
|
||
Run `pkgmgr --help` after installation *inside an interactive bash shell*,
|
||
print its output and return code, but never fail the test.
|
||
|
||
This ensures the installer’s shell RC changes are actually loaded.
|
||
"""
|
||
print("\n--- PKGMGR HELP (after installation, via bash -i) ---")
|
||
|
||
proc = subprocess.run(
|
||
["bash", "-i", "-c", "pkgmgr --help"],
|
||
capture_output=True,
|
||
text=True,
|
||
check=False,
|
||
env=os.environ.copy(),
|
||
)
|
||
|
||
stdout = proc.stdout.strip()
|
||
stderr = proc.stderr.strip()
|
||
|
||
if stdout:
|
||
print(stdout)
|
||
if stderr:
|
||
print("stderr:", stderr)
|
||
|
||
print(f"returncode: {proc.returncode}")
|
||
print("--- END ---\n")
|
||
|
||
|
||
class TestIntegrationInstalPKGMGRShallow(unittest.TestCase):
|
||
def test_install_pkgmgr_self_install(self) -> None:
|
||
"""
|
||
End-to-end test that runs "python main.py install pkgmgr ..." inside
|
||
the test container.
|
||
|
||
HOME is isolated to avoid permission problems with Nix & repositories.
|
||
"""
|
||
temp_home = "/tmp/pkgmgr-self-install"
|
||
os.makedirs(temp_home, exist_ok=True)
|
||
|
||
original_argv = sys.argv
|
||
original_environ = os.environ.copy()
|
||
|
||
try:
|
||
# Isolate HOME so that ~ expands to /tmp/pkgmgr-self-install
|
||
os.environ["HOME"] = temp_home
|
||
|
||
# Optional XDG override for a fully isolated environment
|
||
os.environ.setdefault("XDG_CONFIG_HOME", os.path.join(temp_home, ".config"))
|
||
os.environ.setdefault("XDG_CACHE_HOME", os.path.join(temp_home, ".cache"))
|
||
os.environ.setdefault("XDG_DATA_HOME", os.path.join(temp_home, ".local", "share"))
|
||
|
||
# 🔧 IMPORTANT FIX: allow Git to access /src safely
|
||
configure_git_safe_directory()
|
||
|
||
# Debug before cleanup
|
||
nix_profile_list_debug("BEFORE CLEANUP")
|
||
|
||
# Cleanup: drop any pkgmgr entries from nix profile
|
||
remove_pkgmgr_from_nix_profile()
|
||
|
||
# Debug after cleanup
|
||
nix_profile_list_debug("AFTER CLEANUP")
|
||
|
||
# Prepare argv for module execution
|
||
sys.argv = [
|
||
"python",
|
||
"install",
|
||
"pkgmgr",
|
||
"--clone-mode",
|
||
"shallow",
|
||
"--no-verification",
|
||
]
|
||
|
||
# Execute installation via main.py
|
||
runpy.run_module("pkgmgr", run_name="__main__")
|
||
|
||
# Debug: interactive shell test
|
||
pkgmgr_help_debug()
|
||
|
||
finally:
|
||
# Restore system state
|
||
sys.argv = original_argv
|
||
os.environ.clear()
|
||
os.environ.update(original_environ)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|