On this page
Local editable overlays for `rlsbl dev sync`, installing sibling project checkouts as editable packages without committing path dependencies.
#rlsbl.commands.dev_sync
#rlsbl.commands.dev_sync
Local editable overlays for rlsbl dev sync, installing sibling project checkouts as editable packages without committing path dependencies.
Overlays sibling checkouts (e.g. ../strictcli/python) onto the project's locked environment without committing machine-local [tool.uv.sources] path dependencies. Driven by a git-invisible TOML file at the project root (dev-sources.toml.local-only -- the scaffold gitignore ignores *.local-only).
Why a wrapper is required (verified against uv 0.9.17):
uv pip install -e ../xalone is wiped by the nextuv sync: exact sync
reinstalls the locked registry wheel even at equal versions.
uv sync --inexact --no-install-package <name>preserves a pre-existing
editable install; neither flag has an env-var equivalent.
- Bare
uv runauto-syncs (and wipes overlays) unless UV_NO_SYNC=1 is set,
hence the hard gate below.
#_repo_root
def _repo_root(project_root)The git repository project_root is in, or None when it is in none.
The scope guard below is about THIS REPOSITORY, so it asks git rather than comparing against the project directory: a member of a workspace is inside the repository without being inside the sub-project, and a checkout that is its own repository is outside it however close by it sits on disk.
#_is_inside
def _is_inside(path, root)Is path the same directory as root, or under it?
#_member_spellings
def _member_spellings(project_root)Every name a member of this workspace can be installed under.
Its workspace name and the registry_name it publishes as, normalized the way uv normalizes a distribution name, mapped to the member path that declared it. Empty when the project is not in a workspace.
#_scope_refusal
def _scope_refusal(project_root, package, path)The refusal for an overlay that names something inside this repository.
An overlay puts a SIBLING repository's checkout in front of the registry wheel this project locked. Two things it therefore cannot name, each with its own reason:
- a package this workspace itself builds. The member IS that package's
source, so an editable second copy of it means the code under test is decided by install order rather than by declaration -- and what the overlay would shadow is not a released wheel at all.
- a path inside this repository.
uv pip install -eon it makes the
environment depend on a tree that ships with the repository, which is the hazard the committed-path-source ban exists for, in a different medium: it resolves here and nowhere else.
Returns the message, or None when the overlay names neither.
#_load_overlays
def _load_overlays(project_root)Parse and validate the overlay file. Returns a list of {"package": str, "path": str (absolute), "version": str | None} dicts, or None after printing a hard error. Never a silent no-op.
#_write_sentinel
def _write_sentinel(project_root, overlays)Atomically record the intended overlay state after a successful sync.
Writes SENTINEL_FILENAME alongside the overrides file (gitignored via the *.local-only pattern), capturing per overlaid package: its distribution name, the editable checkout path, and the overlaid version (read from the checkout's pyproject at sync time). The drift check and rlsbl dev status read this to detect when a later bare uv sync/uv run reinstalled the locked registry wheel over the overlay -- a silent wipe that would run the consuming project's tests against stale RELEASED dependency code.
Atomic write (tmp + os.replace) per the codebase convention for shared state. overlays is the list returned by _load_overlays.
#run_status
def run_status(project_root)Entry point for rlsbl dev status. Prints the declared overlays and their actual venv state, then returns a process exit code: 1 if any declared overlay was wiped or is missing (scriptable), 0 otherwise -- including when no overlays are declared (no sentinel).
#run_sync
def run_sync(project_root)Entry point for rlsbl dev sync. Returns a process exit code.