From 55af8d8fb39ea2fa8f31a9447f6e591b43993baf Mon Sep 17 00:00:00 2001 From: dschlueter Date: Tue, 7 Jul 2026 11:20:57 +0200 Subject: [PATCH] test: cover build_archive and add it to the ruff scope build_archive.py had no lint or test coverage, which is how the obsolete requirements/pyproject mirror check slipped through unnoticed. Close that gap: - Add tests/test_build_archive.py: a network-free smoke test that runs the manifest check, dependency parsing, tarball build, and re-verification, and asserts the moved docs/ files, LICENSE, and package sources are packaged. - Lint build_archive.py in both the local gate (scripts/check.sh) and the CI workflow; fix the one issue this surfaced (unused variable py_bin). - List the new test in the REQUIRED_FILES manifest. Co-Authored-By: Claude Opus 4.8 --- .forgejo/workflows/ci.yml | 2 +- build_archive.py | 2 +- scripts/check.sh | 2 +- tests/test_build_archive.py | 40 +++++++++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 tests/test_build_archive.py diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 5849df1..8041541 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: run: pip install -e ".[dev]" - name: Ruff (lint) - run: ruff check src/ tests/ + run: ruff check src/ tests/ build_archive.py - name: Mypy (type check) run: mypy diff --git a/build_archive.py b/build_archive.py index c21ed89..5b25269 100644 --- a/build_archive.py +++ b/build_archive.py @@ -72,6 +72,7 @@ REQUIRED_FILES = [ "tests/test_http_ops.py", "tests/test_lock_ops.py", "tests/test_actions.py", + "tests/test_build_archive.py", "scripts/smoke.sh", "docs/BEDIENUNGSANLEITUNG.md", "docs/INSTALL_FROM_ARCHIVE.md", @@ -285,7 +286,6 @@ def smoke_test_install(output_path: Path) -> None: venv_dir = tmp_path / "venv" venv.EnvBuilder(with_pip=True, clear=True).create(venv_dir) pip_bin = venv_dir / "bin" / "pip" - py_bin = venv_dir / "bin" / "python" llamacppctl_bin = venv_dir / "bin" / "llamacppctl" result = subprocess.run( diff --git a/scripts/check.sh b/scripts/check.sh index 5f7fdd7..a7e59c7 100755 --- a/scripts/check.sh +++ b/scripts/check.sh @@ -27,7 +27,7 @@ run() { fi } -run "ruff (lint)" "${BIN}ruff" check src/ tests/ +run "ruff (lint)" "${BIN}ruff" check src/ tests/ build_archive.py run "mypy (types)" "${BIN}mypy" # Use `python -m pytest` (not the pytest console script) so the repo root is on # sys.path — the test modules import `from tests.test_docker_ops import ...`. diff --git a/tests/test_build_archive.py b/tests/test_build_archive.py new file mode 100644 index 0000000..ec4dfc8 --- /dev/null +++ b/tests/test_build_archive.py @@ -0,0 +1,40 @@ +"""Smoke test for the archive builder (build_archive.py). + +Guards the packaging manifest and dependency parsing so regressions -- a moved +or renamed file, a broken REQUIRED_FILES entry, or the requirements/pyproject +dependency handling -- fail here in the normal test run instead of only +surfacing at release time. Runs the pure build steps (no network, no pip). +""" + +import tarfile +from pathlib import Path + +import build_archive + +# build_archive.py lives at the repo root, so its directory is the project root. +PROJECT_ROOT = Path(build_archive.__file__).resolve().parent + + +def test_build_archive_builds_and_verifies(tmp_path): + out = tmp_path / "llamacppctl-test.tar.gz" + + # Manifest + dependency declaration must be consistent with the real tree. + build_archive.verify_required_files(PROJECT_ROOT) + deps = build_archive.verify_dependencies_declared(PROJECT_ROOT) + assert deps, "expected runtime dependencies declared in pyproject.toml" + + # Build the tarball and re-open it to verify every required file is present. + build_archive.build_tarball(PROJECT_ROOT, out) + build_archive.verify_tarball(out) + assert out.is_file() + + with tarfile.open(out) as tar: + names = set(tar.getnames()) + + root = build_archive.ARCHIVE_ROOT_NAME + # Docs moved under docs/; LICENSE ships at the archive root; package present. + assert f"{root}/docs/BEDIENUNGSANLEITUNG.md" in names + assert f"{root}/docs/INSTALL_FROM_ARCHIVE.md" in names + assert f"{root}/docs/SECURITY_AND_OPERATIONS.md" in names + assert f"{root}/LICENSE" in names + assert f"{root}/src/llamacppctl/main.py" in names