Skip to content

feat(plugins): add pylock craft-parts plugin - #3

Open
tonyandrewmeyer wants to merge 1 commit into
mainfrom
pylock-plugin
Open

feat(plugins): add pylock craft-parts plugin#3
tonyandrewmeyer wants to merge 1 commit into
mainfrom
pylock-plugin

Conversation

@tonyandrewmeyer

Copy link
Copy Markdown
Owner

This PR is against my own fork, not upstream — opened for self-review before raising upstream.

Summary

Adds a pylock craft-parts plugin to charmcraft that installs a charm's venv from a PEP 751 pylock.toml lock file. The plugin is tool-agnostic: a pylock.toml produced by uv, PDM, pip-tools or `pip lock` is installed with pip itself, so the producing tool doesn't need to be present in the build environment.

Because pip's `-r pylock.toml` support is experimental and only landed in pip 26.1, the plugin upgrades pip inside the venv before installing the lock file. Unlike the existing `python`/`poetry`/`uv` plugins, the venv is created with pip available and without `PIP_NO_BINARY`, so the wheel hashes pinned in `pylock.toml` match at install time; the resulting venv's `bin/` is still stripped by the normal cleanup.

Ships with 15 unit tests, a `pylock_plugin` fixture, an integration test mirroring `test_uv.py`, a spread fixture under `tests/spread/ubuntu-26.04/charm/pylock/`, and reference + migration docs.

Provenance

The patch tree of record is `non-roadmap/pylock-charmcraft/` in `tonyandrewmeyer/canonical-work-queue`:

  • `PLAN.md` — design + spike write-up.
  • `patches/charmcraft-pylock.patch` — the patch, generated against charmcraft `main` at `9f6b1373` (2026-05-19).
  • `REBASE-REPORT.md` — dry-run report from 2026-06-05, recording a clean apply against upstream tip `4ef9d389` (2026-06-04), with 15 / 76 / 2 tests passing.

This branch is the patch applied on top of upstream `4ef9d389` (fork `main` was fast-forwarded to match), then committed.

Local verification (re-run today before pushing)

Command Result
`uv run pytest tests/unit/parts/plugins/` 76 passed in 0.51s
`uv run ruff check charmcraft/parts/plugins/_pylock.py` All checks passed
`uv run mypy charmcraft/parts/plugins/_pylock.py` Success: no issues found

Integration tests (`tests/integration/parts/plugins/test_pylock.py`) and the spread fixture were exercised in the original prototype run — see PLAN.md §"Verification done locally" and REBASE-REPORT.md.

Notable design choices (worth a second look during self-review)

  • No `--without-pip`, no `PIP_NO_BINARY` — the venv keeps pip so it can read the lock; binary wheels are allowed so the recorded hashes match. Trade-off: pip lands in the built venv's `site-packages` (bin/ is still stripped). PLAN.md §"Two deviations from the sketch" has the full reasoning.
  • `pylock-file` filename is validated against `pylock.toml` / `pylock..toml` because pip recognises the format by filename — any other name is parsed as a requirements.txt and fails.
  • `pylock_extras`/`pylock_groups` plugin properties were dropped — pip has no install-time `--extra`/`--group` for pylock; extras must be baked into the lock file (`pip lock 'requests[socks]'`).

Test plan

  • Eyeball plugin design vs the python/poetry/uv siblings.
  • Sanity-check the deviations listed above.
  • Decide whether to take `PylockPlugin` upstream into craft-parts (deferred decision per PLAN.md option (c)).
  • Open upstream PR against `canonical/charmcraft` once happy.

Add a `pylock` craft-parts plugin to charmcraft that installs a charm's
venv from a PEP 751 pylock.toml lock file. The plugin is tool-agnostic:
a pylock.toml produced by uv, PDM, pip-tools or `pip lock` is installed
with pip itself, so the producing tool doesn't need to be present in
the build environment.

Because pip's `-r pylock.toml` support is experimental and only landed
in pip 26.1, the plugin upgrades pip inside the venv before installing
the lock file. Unlike the existing python/poetry/uv plugins, the venv
is created with pip available and without `PIP_NO_BINARY`, so the wheel
hashes pinned in pylock.toml match at install time; the resulting venv's
`bin/` is still stripped by the normal cleanup.

Ships with 15 unit tests, a pylock_plugin fixture, an integration test
mirroring test_uv.py, a spread fixture under
`tests/spread/ubuntu-26.04/charm/pylock/`, and reference + migration
docs.
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