Packaging: the wheel carries the PWA, so a release install serves the UI (v2.7.10)
- pyproject declared build-backend = "setuptools.backends._legacy:_Backend", which does not exist: `python -m build`, `pip install .` and even `pip install -e .` died with "Backend ... is not available". It is setuptools.build_meta now. - the wheel and sdist carried only the Python packages, and _default_web_dir() resolved <site-packages>/../frontend, so an installed server started fine but answered every static request with 404. setup.py's build_py now copies the checkout's frontend/ into simtrace_analyser/web/ inside the build (the PWA's tests excluded), and _default_web_dir() prefers that packaged copy, falling back to <repo>/frontend for source and editable runs. The source directory is resolved from setup.py (so an sdist build works) and a missing frontend/ fails the build loudly instead of shipping a package without its UI. - MANIFEST.in grafts frontend/ (with the READMEs, the udev rule and the four launch scripts) into the sdist, so a wheel built from the sdist has the PWA. - README (EN/RU): an install-from-a-release section (pipx/pip with the wheel, the direct release URL for pip) and the --web-dir default documented as the bundled PWA, or <repo>/frontend from source. - tests/test_packaging.py pins the packaged-first resolution (including the empty-directory fallback), the source checkout default, the real build backend, the manifest graft and setup.py's bundling. - verified: a fresh venv install from the wheel and from the sdist serve GET / (200, byte-identical index.html, PWA v2.7.10) out of site-packages/simtrace_analyser/web; an editable install still resolves <repo>/frontend. 547 Python + 80 Node tests.
This commit is contained in:
1 parent
4a03f83459
commit
25aa87ba1e
11 files changed
+196
-16
No files matched your search
@@ -0,0 +1,83 @@
|
||||
"""Tests for the distributable packaging (bundled PWA, backend, manifest)."""
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from simtrace_analyser.__main__ import _default_web_dir, _pick_web_dir
|
||||
|
||||
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
def _touch(path):
|
||||
with open(path, 'w') as f:
|
||||
f.write('')
|
||||
|
||||
|
||||
class TestPickWebDir(unittest.TestCase):
|
||||
def test_prefers_packaged_pwa(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
pkg = os.path.join(tmp, 'simtrace_analyser')
|
||||
repo = os.path.join(tmp, 'repo')
|
||||
os.makedirs(os.path.join(pkg, 'web'))
|
||||
os.makedirs(os.path.join(repo, 'frontend'))
|
||||
_touch(os.path.join(pkg, 'web', 'index.html'))
|
||||
_touch(os.path.join(repo, 'frontend', 'index.html'))
|
||||
self.assertEqual(_pick_web_dir(pkg, repo),
|
||||
os.path.join(pkg, 'web'))
|
||||
|
||||
def test_falls_back_when_packaged_dir_is_missing(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
pkg = os.path.join(tmp, 'simtrace_analyser')
|
||||
repo = os.path.join(tmp, 'repo')
|
||||
os.makedirs(pkg)
|
||||
os.makedirs(os.path.join(repo, 'frontend'))
|
||||
_touch(os.path.join(repo, 'frontend', 'index.html'))
|
||||
self.assertEqual(_pick_web_dir(pkg, repo),
|
||||
os.path.join(repo, 'frontend'))
|
||||
|
||||
def test_falls_back_when_packaged_dir_has_no_index(self):
|
||||
# A stale/empty simtrace_analyser/web directory must not shadow the
|
||||
# source checkout (e.g. an editable install of a half-built tree).
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
pkg = os.path.join(tmp, 'simtrace_analyser')
|
||||
repo = os.path.join(tmp, 'repo')
|
||||
os.makedirs(os.path.join(pkg, 'web'))
|
||||
os.makedirs(os.path.join(repo, 'frontend'))
|
||||
_touch(os.path.join(repo, 'frontend', 'index.html'))
|
||||
self.assertEqual(_pick_web_dir(pkg, repo),
|
||||
os.path.join(repo, 'frontend'))
|
||||
|
||||
|
||||
class TestDefaultWebDir(unittest.TestCase):
|
||||
def test_source_checkout(self):
|
||||
web = _default_web_dir()
|
||||
self.assertTrue(os.path.isfile(os.path.join(web, 'index.html')),
|
||||
'no index.html in %s' % web)
|
||||
|
||||
|
||||
class TestDistributionMetadata(unittest.TestCase):
|
||||
def _read(self, name):
|
||||
with open(os.path.join(REPO, name)) as f:
|
||||
return f.read()
|
||||
|
||||
def test_build_backend_exists(self):
|
||||
pyproject = self._read('pyproject.toml')
|
||||
self.assertIn('build-backend = "setuptools.build_meta"', pyproject)
|
||||
self.assertNotIn('backends._legacy', pyproject)
|
||||
|
||||
def test_manifest_ships_the_pwa(self):
|
||||
# The sdist carries frontend/, so a wheel built from it has the PWA.
|
||||
self.assertIn('graft frontend', self._read('MANIFEST.in'))
|
||||
|
||||
def test_setup_py_bundles_the_pwa(self):
|
||||
setup_py = self._read('setup.py')
|
||||
self.assertIn('frontend', setup_py)
|
||||
self.assertIn('copytree', setup_py)
|
||||
self.assertIn("'web'", setup_py)
|
||||
self.assertIn("'build_py'", setup_py)
|
||||
self.assertIn('ignore_patterns', setup_py)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user