Skip to content

Honor UV_PROJECT_ENVIRONMENT in environments setup-local - #7026

Open
rugpanov wants to merge 29 commits into
mainfrom
uv-workspace-setup-local-3
Open

rugpanov wants to merge 29 commits into
mainfrom
uv-workspace-setup-local-3

Conversation

@rugpanov

@rugpanov rugpanov commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Stack (merge in this order):

  1. localenv: add venv-folder and per-file pyproject seams to setup-local #7017 localenv: add venv-folder and per-file pyproject seams to setup-local (see diff)
  2. Support uv workspace members in environments setup-local #7018 Support uv workspace members in environments setup-local (see diff)
  3. Honor UV_PROJECT_ENVIRONMENT in environments setup-local #7026 Honor UV_PROJECT_ENVIRONMENT in environments setup-local (see diff) <- this PR

Changes

When UV_PROJECT_ENVIRONMENT is set, databricks environments setup-local uses that environment, as uv sync does:

  • An absolute value is used as is, and venvPath reports it as is. A relative path cannot cross drives on Windows.
  • A Windows rooted value such as \envs\x keeps the drive of the root.
  • A relative value is joined to the workspace root (for a member) or to the project folder. On Unix the folder is symlink-resolved; on Windows it is used as given. This is how uv resolves it.
  • The pip seed, the validate probe, and venvPath use this folder.
  • The activate hint quotes the path: shellquote.BashArg on Unix, with ./ before a leading dash, and double quotes for cmd.exe.
  • Unit and acceptance tests clear the variable from the host shell.

Why

uv sync puts the project environment at UV_PROJECT_ENVIRONMENT. The command always used .venv, so the pip seed and the validate step looked at a folder that uv did not create, and the run failed. After #7018, a member that a user set up with this variable also failed.

Tests

  • Unit tests: relative values in a standalone project and in a member, .. through a symlinked project, a trailing slash, an absolute value, and a Windows rooted value (Windows only).
  • Unit tests for the activate hint: spaces, $, a leading dash, and cmd.exe special characters.
  • Acceptance test with a fake uv: a member with UV_PROJECT_ENVIRONMENT="custom env".
  • Integration test with real uv: a member with a relative value (gated by DATABRICKS_LOCALENV_TEST_PROVISION).

Reviewer notes

Known limitations

  • venvPath is absolute when UV_PROJECT_ENVIRONMENT is absolute. A consumer must resolve it (for example path.resolve), not join it.
  • The command cleans the value by text. If the value has a symlink followed by .. (for example link/../env), uv follows the symlink first, so the folders can differ.
  • Preflight does not check that an absolute UV_PROJECT_ENVIRONMENT folder is writable. If it is not, uv sync fails after the pyproject.toml files are written (the backups exist).
  • On Windows, the quoted activate hint works in cmd.exe but not in PowerShell (which needs & "…"), and quotes do not stop %VAR% expansion.

This pull request and its description were written by Isaac.

rugpanov and others added 4 commits October 12, 2026 13:08
Co-authored-by: Isaac <no-reply@databricks.com>
…elpers

Co-authored-by: Isaac <no-reply@databricks.com>
…ath at preflight

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 59068cb

Run: 38276559336

Env ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 276 21 5:22
✅​ aws-windows-latest-4core-16gb 278 19 3:55
✅​ azure linux-2core-8gb 275 21 5:19
✅​ azure-windows-latest-4core-16gb 277 19 3:50
✅​ gcp linux-2core-8gb 276 21 5:17
✅​ gcp-windows-latest-4core-16gb 278 19 4:03
Top 6 slowest tests (at least 2 minutes):
duration env testname
4:01 gcp-windows-latest-4core-16gb TestAccept
3:59 azure linux-2core-8gb TestAccept
3:53 aws-windows-latest-4core-16gb TestAccept
3:49 gcp linux-2core-8gb TestAccept
3:47 azure-windows-latest-4core-16gb TestAccept
3:46 aws linux-2core-8gb TestAccept

@rugpanov
rugpanov force-pushed the uv-workspace-setup-local-3 branch from 127fdbb to 0936065 Compare October 12, 2026 15:41
@rugpanov
rugpanov marked this pull request as ready for review October 12, 2026 15:42
@rugpanov
rugpanov requested review from a team as code owners October 12, 2026 15:42
rugpanov and others added 16 commits October 12, 2026 18:09
Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
…e root

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
…mber

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
uv prints the root in the on-disk letter case, while the shell keeps the case
the user typed, so a name comparison treated a standalone project on a
case-insensitive file system as a member of itself.

Co-authored-by: Isaac <no-reply@databricks.com>
…root

Removing a stale managed block from a member now keeps its [tool.uv] header
when user keys follow the block. A workspace root that defines [tool.uv] with
dotted keys fails the merge instead of getting a second [tool.uv] table.

Co-authored-by: Isaac <no-reply@databricks.com>
- Warn when the root pins are replaced, also when the user wrote them.
- Report diskMutated from both pyproject writes; name the workspace root in
  root write errors.
- Fix the Windows activate hint for a relative venv path.
- Say in the help that uv sync removes packages only other members need.
- Rename SkipToolUv to ConstraintsAtWorkspaceRoot and set it with the other
  merge options; test WorkspaceRoot; tidy tests and acceptance scripts.

Co-authored-by: Isaac <no-reply@databricks.com>
- Count the venv path levels from the symlink-resolved project folder, so a
  symlink that changes the folder depth reports the venv uv uses.
- Reject a root that defines [tool.uv] with quoted or inline keys too.
- Warn about replaced root pins only when the file had constraint pins, not
  when a comment names the key.
- Remove unmarked constraint pins that an older run left in a member.
- Run uv workspace dir through runUvOutput; label the root region in the
  dry-run plan; correct the greenfield comments; extend the help text.

Co-authored-by: Isaac <no-reply@databricks.com>
The line-based merge matches only the plain [tool.uv] spelling, so a root that
spells it differently could get a table or key defined twice. The merged root
must now parse as TOML. An empty managed block no longer counts as pins to
replace, and the member acceptance test re-runs in text mode.

Co-authored-by: Isaac <no-reply@databricks.com>
…nk lines

The dry-run plan now names the workspace root file only when the run would
change it. Removing a header-less managed block from a member keeps the user's
blank line before it, and an empty constraint-dependencies list no longer
counts as pins to replace.

Co-authored-by: Isaac <no-reply@databricks.com>
In this CLI, "workspace" usually means a Databricks workspace. The new fields
are uvWorkspaceRoot, uvWorkspaceBackupPath, plan.wouldWriteUvWorkspace, and
plan.wouldBackupUvWorkspace, and the text output says "uv workspace root".

Co-authored-by: Isaac <no-reply@databricks.com>
rugpanov and others added 9 commits October 12, 2026 18:13
…the names

- An interrupt while uv workspace dir runs no longer falls back to the
  standalone behavior: with cached constraints, that run went on to rewrite the
  member pyproject.toml before it reported E_CANCELED.
- Rename the warning to W_UV_WORKSPACE_CONSTRAINTS_REPLACED and the Go fields
  to match the uv-prefixed JSON names.

Co-authored-by: Isaac <no-reply@databricks.com>
uv sync puts the project environment at UV_PROJECT_ENVIRONMENT when set: an
absolute path as is, a relative one against the workspace root or the project
root. The pip seed, the validate probe, and venvPath now use that folder.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
- Join a relative value to the symlink-resolved root, so .. climbs the real
  folders as in uv.
- Report an absolute value as is; a relative path cannot cross drives. A
  Windows rooted path keeps the drive of the root, as in uv.
- Quote an activate hint path that holds a space.
- Clear the variable from the host shell in unit and acceptance tests; one
  table test; share the integration test setup.

Co-authored-by: Isaac <no-reply@databricks.com>
…e hint

- Do not clean the value lexically: uv follows a symlink in it before it
  applies "..". Drop only a trailing separator.
- Quote the Unix activate hint with shellquote.BashArg, so shell characters
  such as $ stay literal.
- Report a failed folder resolution as E_NOT_WRITABLE, not a usage error.
- Add an acceptance test for a member with UV_PROJECT_ENVIRONMENT and a
  Windows-only rooted-path case.

Co-authored-by: Isaac <no-reply@databricks.com>
- Clean the value with filepath like the rest of the venv paths; keep the
  join to the symlink-resolved root. This drops the trailing-separator trim,
  which also removed a valid backslash on Unix.
- Fix the Windows rooted-path test expectation (it includes the drive).
- Quote the cmd.exe hint for its special characters; prefix ./ for a path
  that starts with a dash.
- Document that venvPath can be absolute; fix stale comments.

Co-authored-by: Isaac <no-reply@databricks.com>
On Windows uv joins a relative value to the working folder as given, without
resolving symlinks, so the CLI does too. Narrow the cmd.exe quoting comment and
replace a sentinel in the table test with a function.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
uv uses a value such as C:envs\x as is, so the CLI does too, not joined to the
root. The table test now passes each subtest its own t.

Co-authored-by: Isaac <no-reply@databricks.com>
@rugpanov
rugpanov force-pushed the uv-workspace-setup-local-3 branch from 0936065 to 59068cb Compare October 12, 2026 16:18
@rugpanov
rugpanov requested a review from misha-db October 12, 2026 16:41

This branch has not been deployed

No deployments
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.

2 participants