Review findings on PR #13: - release-branch-semver gives 0.1.0.devN without tags, so the 0.0 guard never fired; check_version() now requires >= 0.2 (unit-tested) - the APPSKELLINGTON_DEBUG child import could resolve the source tree from the cwd and false-pass; it now reports its location and must match - test_ci_workflow: no continue-on-error, matrix python drives container and UV_PYTHON, WIP gate compared whole (mutation-tested) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
"""Smoke-test an *installed* app_skellington (wheel, sdist or index release).
|
|
|
|
Run it from outside the source tree:
|
|
|
|
cd / && python /path/to/scripts/smoke_import.py [EXPECTED_VERSION]
|
|
|
|
The script's own directory (scripts/) heads sys.path, so the main import
|
|
can't see the source tree. But the APPSKELLINGTON_DEBUG child process puts
|
|
its cwd first, which is why the cwd must be outside the repo. The child's
|
|
import location is checked too, so a wrong cwd fails instead of passing.
|
|
"""
|
|
|
|
import importlib.metadata
|
|
import os
|
|
import pathlib
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
# Any real release is >= 0.2. With no tags reachable (a shallow clone),
|
|
# setuptools_scm's release-branch-semver scheme yields 0.1.0.devN, and other
|
|
# schemes yield 0.0.x.
|
|
MIN_RELEASE = (0, 2)
|
|
|
|
|
|
def fail(msg):
|
|
sys.exit("smoke FAILED: " + msg)
|
|
|
|
|
|
def check_version(version, expected):
|
|
major_minor = tuple(int(n) for n in re.match(r"(\d+)\.(\d+)", version).groups())
|
|
if major_minor < MIN_RELEASE:
|
|
fail("setuptools_scm found no tags (shallow clone?): %s" % version)
|
|
if expected is not None and version != expected:
|
|
fail("expected version %s, got %s" % (expected, version))
|
|
|
|
|
|
def main(argv):
|
|
expected = argv[1] if len(argv) > 1 else None
|
|
|
|
import app_skellington
|
|
|
|
location = pathlib.Path(app_skellington.__file__).resolve()
|
|
if "site-packages" not in location.parts:
|
|
fail("imported the source tree, not an installed copy: %s" % location)
|
|
|
|
from app_skellington import ( # noqa: F401 (the public API must import)
|
|
ApplicationContainer,
|
|
CommandTree,
|
|
Config,
|
|
LoggingLayer,
|
|
NoCommandSpecified,
|
|
ServiceNotFound,
|
|
SubMenu,
|
|
)
|
|
|
|
check_version(importlib.metadata.version("app_skellington"), expected)
|
|
|
|
# _bootstrap.py takes a different code path when APPSKELLINGTON_DEBUG is set.
|
|
env = dict(os.environ, APPSKELLINGTON_DEBUG="1")
|
|
proc = subprocess.run(
|
|
[
|
|
sys.executable,
|
|
"-c",
|
|
"import app_skellington, pathlib;"
|
|
"print(pathlib.Path(app_skellington.__file__).resolve())",
|
|
],
|
|
env=env,
|
|
stdout=subprocess.PIPE,
|
|
universal_newlines=True,
|
|
)
|
|
if proc.returncode != 0:
|
|
fail("import failed with APPSKELLINGTON_DEBUG=1")
|
|
child_location = proc.stdout.strip().splitlines()[-1]
|
|
if child_location != str(location):
|
|
fail(
|
|
"APPSKELLINGTON_DEBUG import resolved %s, not the installed %s"
|
|
" (run from outside the source tree)" % (child_location, location)
|
|
)
|
|
|
|
print("smoke ok:", importlib.metadata.version("app_skellington"), location)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv)
|