Skip to content

Modernize packaging: setup.cfg to pyproject.toml + wads uv CI stub - #2

Merged
thorwhalen merged 3 commits into
masterfrom
claude/rollout-modernize
Aug 4, 2026
Merged

Modernize packaging: setup.cfg to pyproject.toml + wads uv CI stub#2
thorwhalen merged 3 commits into
masterfrom
claude/rollout-modernize

Conversation

@thorwhalen

Copy link
Copy Markdown
Member

Modernizes replize from legacy setuptools packaging + the pre-uv CI template
to pyproject.toml (Hatchling) + the wads uv reusable-workflow stub. Part of the
fleet-wide wads repo-improvement rollout.

⚠️ Merging this PR publishes a release. With the uv CI in place, a push to
master runs validation and then the publish job, which auto-bumps the version
and uploads to PyPI. [project].version is set to 0.1.5 — exactly what is
on PyPI today — so the first post-merge publish produces 0.1.6. Nothing is
published by this PR itself: the branch run's Publish job is skipped
(publishing is gated on the default branch).

What changed

1. setup.cfg / setup.pypyproject.toml (wads-migrate setup-to-pyproject,
then hand-corrected for the tool's known rough edges).

Full inventory carried across from setup.cfg — nothing dropped:

setup.cfg pyproject.toml
name = replize [project].name
version = 0.1.5 [project].version (matches the released PyPI version)
description [project].description
long_description = file:README.md + text/markdown readme = "README.md"
license = apache-2.0 license = "Apache-2.0" (SPDX string, not the deprecated [project.license] table); LICENSE kept
url [project.urls].Homepage
keywords = REPL [project].keywords (broadened: REPL, CLI, shell, subprocess, console)
console_scripts: replize = replize.replize:_replize_cli [project.scripts]
install_requires (empty) dependencies = []
packages = find: Hatchling auto-discovery of replize/
include_package_data = True no-op — the package ships no non-Python data (no MANIFEST.in, no requirements.txt in the repo)
zip_safe = False obsolete under Hatchling/wheels

Added while here: requires-python = ">=3.10", trove classifiers, author, and the
ecosystem-standard [tool.ruff] block (without it the repo falls through to ruff's
moving default and can go red on unrelated style drift).

Verified by building: uv build produces a clean sdist + wheel, and the wheel's
entry_points.txt contains the replize console script.

2. wads CI config corrections (the migration tool's documented rough edges):

  • [tool.wads.ci].project_name was emitted empty → set to "replize" (it is the
    lint/coverage target in the reusable workflow).
  • testpaths was emitted as ["tests"] → set to ["replize"]. This matters:
    wads CI runs pytest --doctest-modules with no path argument, so collection
    is driven entirely by testpaths, and this repo has no top-level tests/
    directory — ["tests"] would have collected nothing while still reporting green.
    Verified locally: pytest --doctest-modules -q (no path arg, i.e. exactly what
    CI runs) collects and passes 1 doctest.
  • docsrc added to [tool.wads.ci.testing].exclude_paths.
  • No test extra existed to wire into [tool.wads.ci.install] (the package has no
    dependencies at all), so nothing to do there.

3. Legacy CI → uv stub (wads-migrate ci-to-uv, then ci-to-stub).

The old workflow was the pre-uv generation (actions/checkout@v2,
actions/setup-python@v2, axblack + pylint + isee, hand-rolled twine publish).
It is replaced by the 5-line stub calling
i2mint/wads/.github/workflows/uv-ci.yml@master, configured entirely from
[tool.wads.ci.*].

Secrets: the migration commands scan the old workflow for secrets.* references.
The only ones present were PYPI_USERNAME and PYPI_PASSWORD. The uv CI uses
token-only PyPI auth, so PYPI_PASSWORD (already in the stub's pass-through
block) is sufficient and PYPI_USERNAME is no longer referenced. No secret was
lost.

4. Housekeeping: added .editorconfig (wads templates ship one; this repo
predates that). Repo settings were also aligned outside this PR: homepage set to
the docs URL and topics populated from the pyproject keywords. Pages
(gh-pages / root) and Discussions were already correct.

Verification

Check Result
Local gate test-dependents replizebaseline 1 suites: 1 pass, 0 fail, 0 no-tests
Local gate test-dependents replizefinal 1 suites: 1 pass, 0 fail, 0 no-tests (unchanged)
pytest --doctest-modules -q (no path arg, as CI runs it) 1 passed
uv build sdist + wheel OK; console script present in wheel metadata
ruff check replize All checks passed
Branch CI ✅ success — https://github.com/i2mint/replize/actions/runs/30859035968

Branch CI jobs: Read Configuration success · Validation (3.10) success ·
Validation (3.12) success · Windows Tests success · Publish skipped ·
Publish GitHub Pages skipped.

wads.repo_audit findings: HIGH 1 → 0, MEDIUM 3 → 1, LOW 3 → 1
(after the repo-settings alignment). Cleared: no pyproject.toml, legacy
packaging files present
, CI is the legacy generation, missing .editorconfig,
homepage/topics drift. No new findings introduced.

Not done here (deliberately)

  • No test suite. The only doctest that exercises behaviour is marked +SKIP
    (it would open an interactive REPL), so real coverage is effectively nil. Out
    of scope for a packaging pass — filed separately as No behavioural test coverage: the only doctest is +SKIP #1
    (not closed by this PR).
  • No source reformatting. The code still uses the old axblack single-quote
    style; ruff format will normalise it on the first publish push-back. Keeping
    it out of this PR keeps the diff reviewable.
  • No latent bugs surfaced — the package is two small modules with no third-party
    dependencies, and it imports and runs clean on modern Python.

Legacy setuptools packaging replaced by a Hatchling-backed pyproject.toml.
Everything declared in setup.cfg is carried across:

- name / version (0.1.5, matching the released PyPI version) / description
- long_description -> readme = "README.md" (text/markdown)
- license apache-2.0 -> SPDX string `license = "Apache-2.0"` (LICENSE kept)
- url -> [project.urls] Homepage
- keywords "REPL" (broadened with CLI/shell/subprocess/console)
- console_scripts `replize = replize.replize:_replize_cli`
  -> [project.scripts] (verified present in the built wheel's
  entry_points.txt)
- install_requires was empty -> dependencies = []
- packages = find: -> Hatchling auto-discovery of the `replize` package
- include_package_data: the package ships no non-Python data, so nothing
  to carry (no MANIFEST.in, no requirements.txt in the repo)

Added while here: requires-python, classifiers, author, and the
ecosystem-standard [tool.ruff] block so the repo does not drift with
ruff's moving defaults.

wads CI config notes:
- [tool.wads.ci].project_name set to "replize" (the migration tool leaves
  it empty, which would break the lint/coverage target)
- testpaths set to ["replize"] rather than the tool's default ["tests"]:
  wads CI runs `pytest --doctest-modules` with no path argument, so
  ["tests"] (a directory this repo does not have) would collect nothing
  and still report green. Verified locally: 1 doctest collected, passing.
- docsrc added to [tool.wads.ci.testing].exclude_paths

Verified with `uv build`: sdist + wheel build clean, metadata and console
script intact.

Claude-Session: https://claude.ai/code/session_01VipiLaG4xy7WctqY9w2475
`.github/workflows/ci.yml` was the pre-uv generation (setup-python v2,
checkout v2, axblack/pylint/isee, hand-rolled publish). It is replaced by
the 5-line stub calling `i2mint/wads/.github/workflows/uv-ci.yml@master`,
which reads all of its configuration from [tool.wads.ci.*] in
pyproject.toml.

Migration path: `wads-migrate ci-to-uv` then `wads-migrate ci-to-stub`.
Both scan the old workflow for secret references; the only ones the old
workflow used were PYPI_USERNAME and PYPI_PASSWORD. The uv CI uses
token-only PyPI auth, so PYPI_PASSWORD (already passed by the stub) is
sufficient and PYPI_USERNAME is no longer referenced.

This also retires the last consumer of setup.cfg (isee update-setup-cfg),
which the previous commit removed.

Claude-Session: https://claude.ai/code/session_01VipiLaG4xy7WctqY9w2475
Copied verbatim from a healthy repo in the ecosystem; the wads project
templates ship one and this repo predates that.

Claude-Session: https://claude.ai/code/session_01VipiLaG4xy7WctqY9w2475
@thorwhalen
thorwhalen merged commit 3e0821b into master Aug 4, 2026
12 checks passed
@thorwhalen
thorwhalen deleted the claude/rollout-modernize branch August 4, 2026 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant