Skip to content

✨ feat(packaging): add monorepo with bare and meta packages#296

Merged
gaborbernat merged 10 commits intotox-dev:mainfrom
gaborbernat:feat/monorepo-bare-meta
Feb 24, 2026
Merged

✨ feat(packaging): add monorepo with bare and meta packages#296
gaborbernat merged 10 commits intotox-dev:mainfrom
gaborbernat:feat/monorepo-bare-meta

Conversation

@gaborbernat
Copy link
Member

Docker users with system-installed uv were forced to download and bundle uv again when installing tox-uv, wasting bandwidth and storage in CI environments. 🐳 This became particularly problematic in containerized builds where uv is pre-installed at the system level but pip install tox-uv would download another copy.

The monorepo structure splits the project into tox-uv-bare (core plugin without uv dependency) and tox-uv (meta package that depends on tox-uv-bare plus uv). ✨ The uv detection logic implements a three-tier fallback: check TOX_UV_PATH environment variable first, then attempt to import bundled uv from the meta package, and finally fall back to system uv from PATH. Both packages share the same codebase and version number, with the release workflow building both on every tag.

Existing users installing tox-uv experience no change in behavior and continue to receive bundled uv. Docker users can now install tox-uv-bare to leverage their system uv installation without duplication. The fallback chain ensures graceful degradation with clear error messages when uv is unavailable.

Fixes #280

@gaborbernat gaborbernat added the enhancement New feature or request label Feb 24, 2026
@gaborbernat gaborbernat force-pushed the feat/monorepo-bare-meta branch 2 times, most recently from dea8756 to da6f41a Compare February 24, 2026 09:13
Docker users with system-installed uv were forced to download and bundle
uv again when installing tox-uv, wasting bandwidth and storage in CI
environments. This became particularly problematic in containerized builds
where uv is pre-installed at the system level but pip install tox-uv would
download another copy.

The monorepo structure splits the project into tox-uv-bare (core plugin
without uv dependency) and tox-uv (meta package that depends on tox-uv-bare
plus uv). The uv detection logic implements a three-tier fallback: check
TOX_UV_PATH environment variable first, then attempt to import bundled uv
from the meta package, and finally fall back to system uv from PATH.

The meta package uses a hatchling metadata hook to inject the VCS-derived
version into the tox-uv-bare dependency at build time, ensuring both
packages always have matching versions in published releases. A dedicated
test suite verifies the build process and version injection.

Both packages share the same codebase and version number, with the release
workflow building both on every tag. Existing users installing tox-uv
experience no change in behavior and continue to receive bundled uv. Docker
users can now install tox-uv-bare to leverage their system uv installation
without duplication.

Fixes tox-dev#280
@gaborbernat gaborbernat force-pushed the feat/monorepo-bare-meta branch 2 times, most recently from 0ece36a to cc820de Compare February 24, 2026 13:32
Docker users with system-installed uv were forced to download and bundle
uv again when installing tox-uv, wasting bandwidth and storage in CI
environments. This became particularly problematic in containerized builds
where uv is pre-installed at the system level but pip install tox-uv would
download another copy.

The monorepo structure splits the project into tox-uv-bare (core plugin
without uv dependency) and tox-uv (meta package that depends on tox-uv-bare
plus uv). The uv detection logic implements a three-tier fallback: check
TOX_UV_PATH environment variable first, then attempt to import bundled uv
from the meta package, and finally fall back to system uv from PATH.

The meta package uses a hatchling metadata hook to inject the VCS-derived
version into the tox-uv-bare dependency at build time, ensuring both
packages always have matching versions in published releases. A dedicated
test suite verifies the build process and version injection.

Both packages share the same codebase and version number, with the release
workflow building both on every tag. Existing users installing tox-uv
experience no change in behavior and continue to receive bundled uv. Docker
users can now install tox-uv-bare to leverage their system uv installation
without duplication.

When using system uv (via tox-uv-bare or TOX_UV_PATH), the version is logged
at warning level to help users understand which uv is being used.

Fixes tox-dev#280
@gaborbernat gaborbernat force-pushed the feat/monorepo-bare-meta branch from cc820de to 0800fe9 Compare February 24, 2026 13:39
pre-commit-ci bot and others added 8 commits February 24, 2026 13:39
CI was failing with 99% coverage because defensive error paths in the uv
discovery logic were untested. These paths handle edge cases like bundled uv
installation and complete uv absence, which are impractical to test in the
CI environment where system uv is always present.

Added coverage pragmas for the untestable bundled uv paths and the error
case when no uv is found. Added tests for exception handling in version
detection (timeout and OS errors) to cover remaining testable paths.

Also added the meta test environment to CI workflow to ensure meta package
build and version injection tests run on every PR.
The test_uv_bundled_import_error test failed on Python 3.13 because
__builtins__ is a dict in some contexts rather than a module, causing
AttributeError when accessing __builtins__.__import__.

Fixed by explicitly importing the builtins module and accessing __import__
from it, which works consistently across all Python versions.
Added meta test environments for Python 3.10-3.14 to match the consistency
of running all test suites across supported Python versions, even though
meta package tests verify build-time behavior that is independent of the
Python runtime version.

Used TOML inline table syntax to keep each environment definition compact
on single lines rather than duplicating the full multi-line configuration,
reducing verbosity while maintaining explicitness about each environment.
The type environment was failing because the meta package uses hatchling
as a build dependency which is not available during type checking, and
because optional imports like the uv package were being flagged as
unresolved.

Excluded the meta directory from type checking since it contains build-time
code only, and added type ignore comments for the optional uv import and
test helper functions that need to accept Any types.
The meta environment configuration was duplicated across all five Python
version environments (3.10-3.14), requiring any change to be made in five
places. This increased maintenance burden and risk of inconsistencies.

Tox's base inheritance feature allows defining the configuration once in a
base environment and having versioned environments inherit from it. This
reduces the configuration from 189 lines to 52 lines while preserving
identical behavior across all environments.
@gaborbernat gaborbernat merged commit 7d6ec78 into tox-dev:main Feb 24, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make the uv dependency optional

1 participant