Skip to content

Commit 08ffefe

Browse files
committed
fix(entry-point): rename hatch entry point from 'decorators' to 'reqstool'
The entry point key must match the hook name used in pyproject.toml ([tool.hatch.build.hooks.reqstool]). The previous 'decorators' key caused 'Unknown build hook: reqstool' errors for all users following the README. Also: - Fix addopts: remove broken '-m not slow or not integration' filter - Drop unused 'flaky'/'slow' markers; add 'integration' and 'e2e' markers - Add tests/integration/ and tests/e2e/ directory structure - Add e2e test: runs hatchling directly in an isolated venv to verify the build hook generates annotations.yml and bundles reqstool_config.yml - Fix CI: correct cov package name, add --junitxml, build wheel before tests
1 parent c734ceb commit 08ffefe

7 files changed

Lines changed: 79 additions & 6 deletions

File tree

.github/workflows/build.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ jobs:
2828
python-version: "3.13"
2929
- name: Install dependencies
3030
run: pip install hatch
31-
- name: Run unit and integrations tests
32-
run: hatch run dev:pytest --cov=reqstool-python-decorators --cov-report=xml --cov-report=html
31+
- name: Build wheel (used by e2e tests via PIP_FIND_LINKS)
32+
run: hatch build --target wheel
33+
- name: Run tests
34+
run: hatch run dev:pytest --junitxml=build/junit.xml --cov=reqstool_python_hatch_plugin --cov-report=xml:build/coverage.xml
3335
- name: Build project
3436
run: hatch build
3537
# Upload artifacts for later use

pyproject.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Source = "https://github.com/reqstool/reqstool-python-hatch-plugin.git"
2727
Documentation = "https://github.com/reqstool/reqstool-python-hatch-plugin.git"
2828

2929
[project.entry-points.hatch]
30-
decorators = "reqstool_python_hatch_plugin.hooks"
30+
reqstool = "reqstool_python_hatch_plugin.hooks"
3131

3232
[tool.hatch.version]
3333
source = "vcs"
@@ -52,15 +52,13 @@ addopts = [
5252
"-s",
5353
"--import-mode=importlib",
5454
"--log-cli-level=DEBUG",
55-
'-m not slow or not integration',
5655
]
5756
pythonpath = [".", "src", "tests"]
5857
testpaths = ["tests"]
5958
norecursedirs = ["tests/fixtures"]
6059
markers = [
61-
"flaky: tests that can randomly fail through no change to the code",
62-
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
6360
"integration: tests that require external resources",
61+
"e2e: end-to-end tests that run the full pipeline locally",
6462
]
6563

6664
[tool.black]

tests/e2e/__init__.py

Whitespace-only changes.

tests/e2e/reqstool_python_hatch_plugin/__init__.py

Whitespace-only changes.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Copyright © LFV
2+
import shutil
3+
import subprocess
4+
import sys
5+
import tarfile
6+
import tempfile
7+
import venv
8+
from pathlib import Path
9+
10+
import pytest
11+
12+
FIXTURE_DIR = Path(__file__).parents[2] / "fixtures" / "test_project"
13+
DIST_DIR = Path(__file__).parents[3] / "dist"
14+
15+
# The hatch plugin appends reqstool_config.yml to the tar.gz and generates
16+
# annotations.yml on disk. requirements.yml and software_verification_cases.yml
17+
# are included via the sdist include config (docs/reqstool/**).
18+
EXPECTED_IN_TARBALL = [
19+
"reqstool_config.yml",
20+
"requirements.yml",
21+
"software_verification_cases.yml",
22+
]
23+
24+
25+
@pytest.mark.e2e
26+
def test_hatch_build_sdist_contains_reqstool_artifacts():
27+
"""hatch build (sdist) triggers the reqstool hook and bundles all artifacts.
28+
29+
Runs hatchling directly inside an isolated venv that has the local plugin wheel
30+
pre-installed, bypassing hatch's own build-env management (which can't resolve
31+
@ file:// hook dependencies reliably across pip/uv versions).
32+
"""
33+
wheels = sorted(DIST_DIR.glob("reqstool_python_hatch_plugin-*.whl"))
34+
if not wheels:
35+
pytest.skip("No local wheel found — run `hatch build --target wheel` first")
36+
37+
with tempfile.TemporaryDirectory() as tmpdir:
38+
tmp_project = Path(tmpdir) / "test_project"
39+
shutil.copytree(FIXTURE_DIR, tmp_project, ignore=shutil.ignore_patterns("dist", "build", "__pycache__"))
40+
41+
# Build an isolated venv with hatchling + the local plugin wheel.
42+
# We call hatchling directly so we fully control what's installed.
43+
venv_dir = Path(tmpdir) / "build-venv"
44+
venv.create(str(venv_dir), with_pip=True)
45+
python = str(venv_dir / "bin" / "python")
46+
47+
subprocess.run(
48+
[python, "-m", "pip", "install", "--quiet", "hatchling", str(wheels[-1])],
49+
check=True,
50+
)
51+
52+
result = subprocess.run(
53+
[python, "-m", "hatchling", "build", "--target", "sdist"],
54+
cwd=tmp_project,
55+
capture_output=True,
56+
text=True,
57+
)
58+
assert result.returncode == 0, f"hatchling build failed:\n{result.stderr}"
59+
60+
tarballs = sorted((tmp_project / "dist").glob("mypackage-*.tar.gz"))
61+
assert tarballs, "No tarball found in dist/"
62+
63+
with tarfile.open(tarballs[-1]) as tf:
64+
names = tf.getnames()
65+
66+
for expected in EXPECTED_IN_TARBALL:
67+
assert any(expected in n for n in names), (
68+
f"{expected!r} missing from {tarballs[-1].name};\ngot: {names}"
69+
)
70+
71+
# annotations.yml is generated on disk (not bundled in the tarball)
72+
annotations_file = tmp_project / "build" / "reqstool" / "annotations.yml"
73+
assert annotations_file.exists(), f"annotations.yml not generated at {annotations_file}"

tests/integration/__init__.py

Whitespace-only changes.

tests/integration/reqstool_python_hatch_plugin/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)