Skip to content

Commit d8f5a7e

Browse files
committed
Document and test the presence of readme in project.dynamic
1 parent 8de6eb8 commit d8f5a7e

File tree

5 files changed

+49
-13
lines changed

5 files changed

+49
-13
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,15 @@ requires = ["hatchling", "hatch-fancy-pypi-readme"]
4949
build-backend = "hatchling.build"
5050
```
5151

52-
Next you must add a `[tool.hatch.metadata.hooks.fancy-pypi-readme]` section.
52+
Next, you must tell the build system that your readme is dynamic by adding it to the `project.dynamic` list:
53+
54+
```toml
55+
[project]
56+
# ...
57+
dynamic = ["readme"]
58+
```
59+
60+
Next, you must add a `[tool.hatch.metadata.hooks.fancy-pypi-readme]` section.
5361

5462
Here, you **must** supply a `content-type`.
5563
Currently, only `text/markdown` and `text/x-rst` are supported.

src/hatch_fancy_pypi_readme/_cli.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import sys
88

9-
from typing import Any, TextIO
9+
from typing import Any, NoReturn, TextIO
1010

1111
from hatch_fancy_pypi_readme.exceptions import ConfigurationError
1212

@@ -15,26 +15,39 @@
1515

1616

1717
def cli_run(pyproject: dict[str, Any], out: TextIO) -> None:
18+
"""
19+
Best-effort verify config and print resulting PyPI readme.
20+
"""
21+
is_dynamic = False
22+
try:
23+
is_dynamic = "readme" in pyproject["project"]["dynamic"]
24+
except KeyError:
25+
pass
26+
27+
if not is_dynamic:
28+
_fail("You must add 'readme' to 'project.dynamic'.")
29+
1830
try:
1931
cfg = pyproject["tool"]["hatch"]["metadata"]["hooks"][
2032
"fancy-pypi-readme"
2133
]
2234
except KeyError:
23-
print(
35+
_fail(
2436
"Missing configuration "
2537
"(`[tool.hatch.metadata.hooks.fancy-pypi-readme]`)",
26-
file=sys.stderr,
2738
)
28-
sys.exit(1)
2939

3040
try:
3141
config = load_and_validate_config(cfg)
3242
except ConfigurationError as e:
33-
print(
43+
_fail(
3444
"Configuration has errors:\n\n"
3545
+ "\n".join(f"- {msg}" for msg in e.errors),
36-
file=sys.stderr,
3746
)
38-
sys.exit(1)
3947

4048
print(build_text(config.fragments), file=out)
49+
50+
51+
def _fail(msg: str) -> NoReturn:
52+
print(msg, file=sys.stderr)
53+
sys.exit(1)

tests/conftest.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import os
66
import shutil
7-
import sys
87

98
from pathlib import Path
109

@@ -19,7 +18,7 @@ def _project_directory_uri(tmp_path):
1918

2019
@pytest.fixture(name="new_project")
2120
def new_project(project_directory_uri, tmp_path, monkeypatch):
22-
shutil.copytree(Path.cwd(), tmp_path / 'plugin')
21+
shutil.copytree(Path.cwd(), tmp_path / "plugin")
2322
project_dir = tmp_path / "my-app"
2423
project_dir.mkdir()
2524

tests/example_pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ build-backend = "hatchling.build"
66
[project]
77
name = "my-pkg"
88
version = "1.0"
9+
dynamic = ["readme"]
910

1011

1112
[tool.hatch.metadata.hooks.fancy-pypi-readme]

tests/test_cli.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ def _pyproject():
2424
@pytest.fixture(name="empty_pyproject")
2525
def _empty_pyproject():
2626
return {
27-
"tool": {"hatch": {"metadata": {"hooks": {"fancy-pypi-readme": {}}}}}
27+
"project": {"dynamic": ["foo", "readme", "bar"]},
28+
"tool": {"hatch": {"metadata": {"hooks": {"fancy-pypi-readme": {}}}}},
2829
}
2930

3031

32+
@pytest.mark.slow
3133
class TestCLIEndToEnd:
3234
@pytest.mark.usefixtures("new_project")
3335
def test_missing_config(self):
@@ -68,13 +70,26 @@ def test_ok_redirect(self, tmp_path):
6870

6971

7072
class TestCLI:
71-
@pytest.mark.usefixtures("new_project")
73+
def test_cli_run_missing_dynamic(self, capfd):
74+
"""
75+
Missing readme in dynamic is caught and gives helpful advice.
76+
"""
77+
with pytest.raises(SystemExit):
78+
cli_run({}, sys.stdout)
79+
80+
out, err = capfd.readouterr()
81+
82+
assert "You must add 'readme' to 'project.dynamic'.\n" == err
83+
assert "" == out
84+
7285
def test_cli_run_missing_config(self, capfd):
7386
"""
7487
Missing configuration is caught and gives helpful advice.
7588
"""
7689
with pytest.raises(SystemExit):
77-
cli_run({}, sys.stdout)
90+
cli_run(
91+
{"project": {"dynamic": ["foo", "readme", "bar"]}}, sys.stdout
92+
)
7893

7994
out, err = capfd.readouterr()
8095

0 commit comments

Comments
 (0)