|
26 | 26 | ROOT = Path(__file__).resolve().parent.parent |
27 | 27 | INDEXES = {"pypi": "https://pypi.org", "testpypi": "https://test.pypi.org"} |
28 | 28 |
|
29 | | -_VERSION = re.compile(r"\d+\.\d+\.\d+") |
| 29 | +# Stable X.Y.Z or a PEP 440 pre-release X.Y.Z{a|b|rc}N, in canonical form. |
| 30 | +_VERSION = re.compile( |
| 31 | + r"(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:(?:a|b|rc)(?:0|[1-9]\d*))?" |
| 32 | +) |
30 | 33 | _PROJECT_VERSION = re.compile(r'^version\s*=\s*"([^"]*)"\s*$', re.MULTILINE) |
31 | 34 | _INIT_VERSION = re.compile(r'^__version__\s*=\s*"([^"]*)"\s*$', re.MULTILINE) |
32 | 35 | _CHANGELOG_HEADING = re.compile(r"^## (\S+) · (\d{4}-\d{2}-\d{2})\s*$", re.MULTILINE) |
@@ -73,19 +76,22 @@ def check_metadata(root: Path = ROOT, tag: str | None = None) -> str: |
73 | 76 | version = meta.project_version |
74 | 77 | problems: list[str] = [] |
75 | 78 | if version is None or not _VERSION.fullmatch(version): |
76 | | - problems.append(f"pyproject.toml [project].version must be X.Y.Z; found {version!r}.") |
| 79 | + problems.append( |
| 80 | + "pyproject.toml [project].version must be X.Y.Z or X.Y.Z{a|b|rc}N; " |
| 81 | + f"found {version!r}." |
| 82 | + ) |
77 | 83 | if meta.init_version != version: |
78 | 84 | problems.append( |
79 | 85 | f"src/{IMPORT_NAME}/__init__.py __version__ is {meta.init_version!r}, " |
80 | 86 | f"pyproject.toml has {version!r}." |
81 | 87 | ) |
82 | 88 | if meta.changelog_version != version: |
83 | 89 | problems.append( |
84 | | - "The first CHANGELOG.md heading must be '## X.Y.Z · YYYY-MM-DD' for the release " |
| 90 | + "The first CHANGELOG.md heading must be '## <version> · YYYY-MM-DD' for the release " |
85 | 91 | f"version {version!r}; found {meta.changelog_version!r}." |
86 | 92 | ) |
87 | 93 | if tag is not None and tag != f"{TAG_PREFIX}{version}": |
88 | | - problems.append(f"Tag {tag!r} does not match version {version!r} ({TAG_PREFIX}X.Y.Z).") |
| 94 | + problems.append(f"Tag {tag!r} does not match version {version!r} ({TAG_PREFIX}<version>).") |
89 | 95 | if problems: |
90 | 96 | raise ReleaseCheckError("\n".join(problems)) |
91 | 97 | assert version is not None |
@@ -178,7 +184,7 @@ def main(argv: list[str] | None = None) -> int: |
178 | 184 | parser = argparse.ArgumentParser(description=__doc__.splitlines()[0] if __doc__ else None) |
179 | 185 | sub = parser.add_subparsers(dest="command", required=True) |
180 | 186 | meta = sub.add_parser("metadata", help="check versions, changelog and tag") |
181 | | - meta.add_argument("--tag", help=f"release tag, {TAG_PREFIX}X.Y.Z") |
| 187 | + meta.add_argument("--tag", help=f"release tag, {TAG_PREFIX}<version>") |
182 | 188 | meta.add_argument("--index", choices=sorted(INDEXES), help="fail if already published there") |
183 | 189 | dist = sub.add_parser("dist", help="check the built wheel and sdist") |
184 | 190 | dist.add_argument("dist_dir", type=Path) |
|
0 commit comments