diff --git a/CHANGELOG.md b/CHANGELOG.md index af7055c..9634850 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and Base versions are tracked in the repo-root `VERSION` file. ### Added +- Added the design target for a future structured `python:` manifest section. - Added the user-local IDE preference design for `~/.base.d/config.yaml`. - Added documentation guidance for using `mise` with Go and Java projects. - Added documentation for the boundary between `basectl onboard` and diff --git a/README.md b/README.md index 70ffa0a..f8aa06b 100644 --- a/README.md +++ b/README.md @@ -218,6 +218,11 @@ PyPI package names and install into the project virtual environment at delegation. Pinned Homebrew versions fail clearly until Base grows explicit versioned tool support. +A future structured `python:` manifest section can make project venv and +requirement-file behavior clearer when `python-package` artifact rows become too +limited. The current supported contract remains `python-package`; the future +shape is documented in [Python Manifest Section](docs/python-manifest.md). + Artifacts may include `bootstrap: true` when they are part of the minimum Python runtime contract needed before Base can reconcile a project's remaining artifacts. Base currently uses this marker in `lib/base/default_manifest.yaml` diff --git a/docs/README.md b/docs/README.md index 6e2d441..c1885d1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,6 +41,9 @@ reference. The filename should answer "what is this about?" sync guidance, and the user/project boundary. - [Project Installers](project-installers.md) defines how project-owned installers should use Base without moving product-specific logic into Base. +- [Python Manifest Section](python-manifest.md) records the future structured + Python manifest shape and its relationship to current `python-package` + artifacts. - [`basectl onboard`](basectl-onboard.md) captures the guided setup experience and its relationship to project installers. - [`basectl ci`](basectl-ci.md) defines the future non-interactive CI entry diff --git a/docs/architecture.md b/docs/architecture.md index 84dce1d..e8fe535 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -376,6 +376,12 @@ project venv is therefore `~/.base.d/base/.venv`. The wrapper `bin/base-wrapper` runs Python packages through that project-scoped venv. +A structured `python:` manifest section is the preferred future shape when +projects need to express requirement files, package requirement strings, or venv +settings more clearly than artifact rows allow. That section is not part of the +current manifest contract. See [python-manifest.md](python-manifest.md) for the +design target and migration boundary. + Homebrew-managed `tool` artifacts currently support `version: latest`. If a project requests a pinned Homebrew version, setup fails clearly instead of silently installing a different version. New ordinary Homebrew tools should diff --git a/docs/python-manifest.md b/docs/python-manifest.md new file mode 100644 index 0000000..dea294c --- /dev/null +++ b/docs/python-manifest.md @@ -0,0 +1,109 @@ +# Python Manifest Section + +Base currently supports Python dependencies through `python-package` artifact +entries: + +```yaml +artifacts: + - type: python-package + name: requests + version: latest +``` + +That contract remains valid. It is simple, implemented, and maps directly to the +Base-managed project virtual environment at: + +```text +~/.base.d//.venv +``` + +## Decision + +Base should grow a structured `python:` manifest section only when the Python +contract needs to express more than a small package list. The structured section +is the right long-term shape because it makes the project virtual environment, +requirement files, and inline package requirements explicit instead of encoding +all Python behavior as generic artifact rows. + +The future shape should be: + +```yaml +python: + venv: default + requirements: + - requirements.txt + packages: + - requests + - pytest==8.4.1 +``` + +This is a design target, not the current manifest contract. + +## Field Semantics + +`venv` should default to `default`, meaning Base's current project venv location: + +```text +~/.base.d//.venv +``` + +A custom venv path should be deferred until a real project needs it. If Base +adds it later, the path should be relative to the project root, must stay inside +the project root unless explicitly allowed, and must not silently change the +activation or `basectl test` contract. + +`requirements` should be a list of requirement file paths relative to the +project root. Base should install them with `pip install -r ` and reject +paths outside the project root. + +`packages` should use normal pip requirement strings such as: + +```text +requests +pytest==8.4.1 +rich>=13,<14 +``` + +Using pip requirement strings avoids inventing a parallel Python package syntax. + +## Relationship To Current Artifacts + +`python-package` artifacts should remain supported during and after the first +structured `python:` implementation. A migration can translate: + +```yaml +artifacts: + - type: python-package + name: requests + version: latest + - type: python-package + name: pytest + version: 8.4.1 +``` + +into: + +```yaml +python: + packages: + - requests + - pytest==8.4.1 +``` + +The implementation should reject duplicate requirements only when it can do so +without guessing. Exact duplicate strings can be de-duplicated; semantically +overlapping requirement ranges should be left to pip. + +## Non-Goals + +The structured Python section should not turn Base into a Python packaging +manager. Base should not: + +- generate or own `requirements.txt` +- replace Poetry, PDM, Hatch, uv, pip-tools, or setuptools +- solve dependency versions +- support multiple project virtual environments in one Base manifest +- automatically migrate manifests without an explicit user action + +Base owns the project venv convention and setup/check/doctor orchestration. +Python packaging tools own dependency resolution and lockfile semantics.