feat: add sync-pyproject target to non-destructively patch pyproject.toml via template.yml#838
Draft
feat: add sync-pyproject target to non-destructively patch pyproject.toml via template.yml#838
Conversation
…matting) Co-authored-by: tschm <2046079+tschm@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add ability for rhiza to control fields in pyproject.toml
feat: add sync-pyproject target to non-destructively patch pyproject.toml via template.yml
Mar 13, 2026
Member
|
@copilot: can I have license and readme variables for pyproject section? |
Contributor
Author
Done in commit pyproject:
license: "MIT" # plain string (PEP 639)
# or table form:
# license:
# text: "MIT"
readme: "README.md"
|
…toml via template.yml Co-authored-by: tschm <2046079+tschm@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
make sync-pyprojecttarget and.rhiza/utils/sync_pyproject.pyutility that non-destructively patches selectedpyproject.tomlfields declared in a new optionalpyproject:section of.rhiza/template.yml. Project-owned fields (name,version,dependencies, etc.) are never touched.Changes
.rhiza/utils/sync_pyproject.py— New stdlib+tomlkitutility that readspyproject:from.rhiza/template.ymland patchespyproject.tomlin-place with comment/formatting preservation. Supports five controlled keys:requires-python→ sets[project].requires-pythonclassifiers→ replaces[project].classifierswholesalelicense→ sets[project].license; accepts a plain string ("MIT", PEP 639) or a mapping ({text: "MIT"}/{file: "LICENSE"}, PEP 517 inline table)readme→ sets[project].readme(string file path, e.g."README.md")tool-sections→ syncs named[tool.*]subtrees from rhiza's ownpyproject.toml.rhiza/make.d/releasing.mk— Newsync-pyprojecttarget (alongsidebump); supportsDRY_RUN=1andCHECK=1(CI-friendly exit-nonzero-on-drift).rhiza/template-bundles.yml— Addedsync_pyproject.pytocorebundle so it flows to all downstream projectspyproject.toml/.rhiza/requirements/tools.txt— Addedtomlkit>=0.13,<1.0as dev dependency; added totool.deptry.package_module_name_map.rhiza/tests/deps/test_sync_pyproject.py— 27 tests covering: no-op, patching, field preservation,license(string and table forms),readme,--dry-run,--check.rhiza/docs/WORKFLOWS.md— Newpyproject.toml Field Synchronizationsection.rhiza/docs/TEMPLATE_YML_EXAMPLE.md— Annotated example of thepyproject:sectionExample downstream
.rhiza/template.yml:Testing
make testpasses locallymake fmthas been runChecklist
make deptrypasses (no unused or missing dependencies)Original prompt
Summary
Add the ability for rhiza to control selected fields in a downstream project's
pyproject.tomlvia a newpyproject:section in.rhiza/template.yml. This is implemented entirely within rhiza (norhiza-clichanges needed) using a Python utility script and a newmake sync-pyprojecttarget.Background
Currently,
pyproject.tomlis completely excluded from rhiza's sync system — it is project-owned. However, several fields are naturally "rhiza-owned" and drift across downstream projects:requires-python— should match rhiza's supported Python version matrixclassifiers— Python version classifiers should mirror.python-version/requires-python[tool.*]sections like[tool.deptry.package_module_name_map]— currently duplicated manuallyThe idea: extend
.rhiza/template.ymlwith an optionalpyproject:section. A newmake sync-pyprojecttarget reads it and non-destructively patchespyproject.toml, preserving all project-specific fields (name,version,description,authors,dependencies, etc.).Changes Required
1. New utility script:
.rhiza/utils/sync_pyproject.pyA Python script (stdlib only — no
tomlkitdep needed for the basic patch, usestomllibto read and string-based TOML writing to patch) that:.rhiza/template.yml(usingpyyaml, already a dev dep) and extracts thepyproject:sectionpyproject.tomlpyproject:section; never touches anything elsepyproject.tomlpreserving structure as much as possible--dry-runflag to preview changes without writing--checkflag (exits non-zero if changes would be made, for CI)The script should use
tomlkit(which preserves comments and formatting) as the TOML write backend. Addtomlkit>=0.13,<1.0topyproject.toml's[dependency-groups].devand to.rhiza/requirements/tools.txt.Supported
pyproject:keys in template.yml:requires-python— sets[project].requires-pythonclassifiers— replaces[project].classifiersentirely (it's a list rhiza owns)tool-sections— a list of dotted TOML paths (e.g.tool.deptry.package_module_name_map) that are synced wholesale from rhiza's ownpyproject.tomlinto the downstream project'spyproject.tomlThe script must:
name,version,description,authors,keywords,dependencies,[dependency-groups],[project.urls]unless explicitly listed[INFO] No pyproject: section in template.yml, nothing to do.and exit 0 if the section is absent (graceful no-op)[INFO] pyproject.toml is already up to date.if no changes are neededuv run python .rhiza/utils/sync_pyproject.py [--dry-run] [--check]2. New Makefile target in
.rhiza/make.d/releasing.mkAdd a
sync-pyprojecttarget:Add
sync-pyprojectto the.PHONYlist inreleasing.mk.3. Update rhiza's own
.rhiza/template.yml(create it — it doesn't exist in the repo itself)Wait — rhiza skips sync on itself (the
make synctarget checks forjebel-quant/rhizaremote and skips). The.rhiza/template.ymlfile doesn't exist in the repo itself by design. Instead, add a well-documented example as.rhiza/docs/TEMPLATE_YML_EXAMPLE.mdshowing the newpyproject:section.4. Update
.rhiza/template-bundles.ymlAdd
.rhiza/utils/sync_pyproject.pyto thecorebundle'sfileslist (so it syncs to all downstream projects):- .rhiza/utils/sync_pyproject.py5. Update
pyproject.tomlin rhiza itselfAdd
tomlkitto[dependency-groups].dev:Also add it to
[tool.deptry.package_module_name_map]:6. Update
.rhiza/requirements/tools.txtAdd:
7. New test file:
.rhiza/tests/deps/test_sync_pyproject.pyAdd tests that verify:
sync_pyproject.pyexists and is importable / syntax-validpyproject:section is absent fromtemplate.ymlrequires-pythonwhen specifiedclassifierswhen specifiedname,version,description, `dependenc...This pull request was created from Copilot chat.
📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.