Skip to content

refactor: drop bundled content — Python side becomes core-only - #6

Open
tbsvttr wants to merge 1 commit into
feat/root-model-type-aliasesfrom
refactor/core-only
Open

refactor: drop bundled content — Python side becomes core-only#6
tbsvttr wants to merge 1 commit into
feat/root-model-type-aliasesfrom
refactor/core-only

Conversation

@tbsvttr

@tbsvttr tbsvttr commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #5 (which is stacked on #4). Base branch is `feat/root-model-type-aliases`; will re-target to `main` after both merge.

Why

Directly addresses @scottbenton's review:

My largest concern is the content in the bindings repos drifting from the content in the "main" repos.

He's right. The initial port bundled each ruleset's JSON inside `packages//src/.../json/`, which was cute for `pip install datasworn-community-classic` ergonomics but structurally guaranteed drift.

This PR adopts Scott's suggested core-only shape: one PyPI package (`datasworn-community-core`) containing the Pydantic models, no bundled JSON. Users load content however they want — HTTP from `official-content` / `community-content`, local file, npm tarball, whatever — and hand it to `Ruleset.model_validate`.

What changed

Before After
10 workspace packages (core + 9 rulesets) 1 workspace package (core)
Bundled JSON per ruleset No bundled JSON anywhere
Tests loaded from bundled packages Tests fetch live JSON from content repos, cache locally
`pip install datasworn-community-` `pip install datasworn-community-core` (then load JSON yourself)

Known drift — surfaced, not hidden

While rewriting the tests to fetch live content, I confirmed the exact drift Scott warned about. Loading current `main`-branch content today fails validation:

datasworn_version
  Input should be '0.1.0' [type=literal_error, input_value='0.2.0', input_type=str]

`models.py` here is on schema 0.1.0. Content on main is 0.2.0. So the 9 end-to-end validation tests in `tests/test_load_rules_packages.py` are marked `xfail` with a documented reason. When someone regenerates `models.py` against the current schema and re-runs the post-processor, those tests should flip green and the `xfail` markers should be removed.

The README's new Regenerating models.py section has the exact commands (`datamodel-code-generator` invocation + post-process step).

Test plan

  • `uv sync` — only 1 workspace member now
  • `uv run pytest tests/ -q` — 3 passed, 9 xfailed (0 unexpected failures)
  • Deleted packages don't appear in the tree, no stale refs

Follow-ups (not this PR)

  1. Regenerate `models.py` against schema 0.2.0. Post-processor should still apply cleanly since patterns are structural.
  2. Publish `datasworn-community-core` to PyPI (needs trusted-publishing setup on org side).
  3. Scott's phase-2 idea — moving Python codegen alongside JS in the `datasworn` core repo — is still worth discussing but out of scope here.

Per @scottbenton's review on the initial port, the biggest concern was
Python-bindings content silently drifting from what actually ships in
official-content / community-content. The initial port bundled a copy
of every ruleset's JSON inside packages/<ruleset>/src/.../json/ — nice
for `pip install datasworn-community-classic` ergonomics, but nothing
kept those copies in sync with the JS side.

Fix: adopt the "core-only" shape Scott suggested. This repo now publishes
one PyPI package (datasworn-community-core) containing just the Pydantic
models. Users load JSON however they want — HTTP fetch from the content
repos, local file, npm tarball, whatever — and pass it to
Ruleset.model_validate.

## What changed

- **Deleted 9 per-ruleset workspace packages** — classic, delve, lodestar,
  starforged, sundered_isles, ancient_wonders, fe_runners, ironsmith,
  starsmith. Their JSON was drift-prone by design.
- **Reduced root pyproject.toml workspace** to just `packages/core`.
- **tests/conftest.py** — new shared `content_path` fixture that fetches
  main-branch JSON from official-content / community-content and caches
  under tests/.cache/. `DATASWORN_TESTS_OFFLINE=1` skips network.
- **tests/test_load_rules_packages.py** — validates fetched content
  against the models. Currently xfail because models.py is on schema
  0.1.0 while content is on 0.2.0 (also documented drift, see below).
- **tests/test_type_alias_ergonomics.py** — trimmed. The end-to-end
  content tests moved to the new xfail set; kept here are three
  post-processor-invariant checks (RootModel[str] wrappers gone,
  discriminated-union bases resolved, `.id` reads as str).
- **README** rewritten around "one package, one purpose": install core,
  load your own JSON, validate. Adds a **Regenerating models.py**
  section with the exact `datamodel-code-generator` invocation +
  post-process step for whoever picks up the drift fix.

## Known drift, called out

The bundled models.py was generated from schema line 0.1.0. Content on
main is 0.2.0. Real content validation therefore fails today — hence the
9 xfail markers on test_load_rules_packages.py. Fix = regenerate
models.py from the current schema and re-run the post-processor;
xfail markers should then flip green and be removed. Instructions in
the README.
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