Fail if a workspace package declares a development-release dependency pin. Development releases (``*.dev``) are not published to PyPI, so a package whose published metadata pins one cannot be installed by downstream users. This gate keeps such pins out of a release. Only each package's
(package_names: list[str])
| 485 | |
| 486 | |
| 487 | def check_dev_pins(package_names: list[str]) -> int: |
| 488 | """Fail if a workspace package declares a development-release dependency pin. |
| 489 | |
| 490 | Development releases (``*.dev``) are not published to PyPI, so a package whose published |
| 491 | metadata pins one cannot be installed by downstream users. This gate keeps such pins out |
| 492 | of a release. Only each package's *own* published dependencies are inspected — siblings |
| 493 | are not followed — so the usual leaf-first release flow (publish the depended-on package, |
| 494 | then drop the dev pin in the dependent) is never deadlocked by a pin in another package. |
| 495 | |
| 496 | Args: |
| 497 | package_names: Directory names to inspect (e.g. ``"reflex"``, ``"reflex-lucide"``). |
| 498 | Empty inspects every workspace package. |
| 499 | |
| 500 | Returns: |
| 501 | ``0`` if no development-release pins are found, ``1`` otherwise. |
| 502 | """ |
| 503 | pyprojects = dict(_workspace_pyprojects()) |
| 504 | unknown = [name for name in package_names if name not in pyprojects] |
| 505 | if unknown: |
| 506 | print( |
| 507 | f"unknown package(s): {', '.join(unknown)}. " |
| 508 | f"Choose from: {', '.join(pyprojects)}" |
| 509 | ) |
| 510 | return 1 |
| 511 | targets = ( |
| 512 | {name: pyprojects[name] for name in package_names} |
| 513 | if package_names |
| 514 | else pyprojects |
| 515 | ) |
| 516 | |
| 517 | offenders: list[tuple[str, str]] = [] |
| 518 | for name, project_file in targets.items(): |
| 519 | project = _load_pyproject(project_file).get("project", {}) |
| 520 | offenders += [ |
| 521 | (name, dependency) |
| 522 | for dependency in _published_dependencies(project) |
| 523 | if _parse_requirement(dependency)[1] |
| 524 | ] |
| 525 | |
| 526 | if offenders: |
| 527 | print("Development-release dependency pins must not be published:\n") |
| 528 | for name, dependency in offenders: |
| 529 | print(f" {name}: {dependency}") |
| 530 | print( |
| 531 | f"\n{len(offenders)} development-release pin(s) found. Release the depended-on " |
| 532 | "package(s) and re-pin to a published version before publishing." |
| 533 | ) |
| 534 | return 1 |
| 535 | |
| 536 | print(f"No development-release dependency pins found in {len(targets)} package(s).") |
| 537 | return 0 |
| 538 | |
| 539 | |
| 540 | def main() -> int: |
no test coverage detected