Skip to content

fix(uv): read and write workspace uv.lock in lock() .run target - #4343

Merged
aignas merged 3 commits into
bazel-contrib:mainfrom
rickeylev:fix_uv_lock_runfiles
Oct 25, 2026
Merged

aignas merged 3 commits into
bazel-contrib:mainfrom
rickeylev:fix_uv_lock_runfiles

Conversation

@rickeylev

Copy link
Copy Markdown
Collaborator

Unlike uv pip compile, uv lock has no output path flag and always
reads and writes uv.lock in the project directory alongside
pyproject.toml. Previously, running the .run target for a uv.lock
output executed uv lock directly in the runfiles directory without
including the existing workspace lock file in runfiles or writing the
updated lock file back to BUILD_WORKSPACE_DIRECTORY. As a result,
commands like bazel run //:lock.run -- --upgrade-package foo ignored
the existing workspace uv.lock and wrote output only inside the
runfiles tree.

Include the existing lock file in the .run target's runfiles and
update the wrapper scripts to resolve uv.lock against the workspace
output path. When uv.lock in runfiles is already a writable symlink to
the workspace output file, execute uv in place; otherwise, stage the
runfiles tree in a temporary directory and write the resulting lock file
back to the workspace.

Fixes #4339

Verify that running a uv.lock .run target writes uv.lock to the
workspace root and preserves existing locked versions when upgrading a
single package.

Refs bazel-contrib#4339
Explain why pyproject.toml and uv.lock must be restored after
test_project_lock_run_updates_existing_lock_in_workspace.
Unlike `uv pip compile`, `uv lock` has no output path flag and always
reads and writes `uv.lock` in the project directory alongside
`pyproject.toml`. Previously, running the `.run` target for a `uv.lock`
output executed `uv lock` directly in the runfiles directory without
including the existing workspace lock file in runfiles or writing the
updated lock file back to `BUILD_WORKSPACE_DIRECTORY`. As a result,
commands like `bazel run //:lock.run -- --upgrade-package foo` ignored
the existing workspace `uv.lock` and wrote output only inside the
runfiles tree.

Include the existing lock file in the `.run` target's runfiles and
update the wrapper scripts to resolve `uv.lock` against the workspace
output path. When `uv.lock` in runfiles is already a writable symlink to
the workspace output file, execute `uv` in place; otherwise, stage the
runfiles tree in a temporary directory and write the resulting lock file
back to the workspace.

Fixes bazel-contrib#4339
@rickeylev
rickeylev requested a review from aignas as a code owner October 25, 2026 22:44

@aignas aignas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix!

@aignas
aignas added this pull request to the merge queue Oct 25, 2026
Merged via the queue into bazel-contrib:main with commit 7f08f2f Oct 25, 2026
13 checks passed
@rickeylev
rickeylev deleted the fix_uv_lock_runfiles branch October 26, 2026 02:14
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.

uv: lock() .run target for uv.lock omits existing lock and writes to runfiles

2 participants