Skip to content

feat(python-setup): route the setup command to the uv flow when active - #2118

Merged
rugpanov merged 2 commits into
mainfrom
feat/route-setup-to-uv-flow
Aug 14, 2026
Merged

feat(python-setup): route the setup command to the uv flow when active#2118
rugpanov merged 2 commits into
mainfrom
feat/route-setup-to-uv-flow

Conversation

@rugpanov

@rugpanov rugpanov commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Why

When the uv-native Python setup is the active surface for a project — the environment.pythonSetup opt-in plus a uv-suitable project, the same gate the configuration view already dispatches on — the databricks.environment.setup command still ran the legacy checklist. Every "set up my Python env" trigger funnels through that command:

  • the Databricks Connect status bar button,
  • the config-view legacy rows,
  • the command palette entry,
  • the Run/Debug current file gate's own executeCommand("databricks.environment.setup").

So all of them drove the wrong flow for uv projects. Separately, the legacy interpreter-change listener would pop a second install prompt on top of the uv flow.

What

  • pythonSetupRouting.ts — a narrow UvPythonSetup seam plus routeEnvironmentSetup, which sends databricks.environment.setup to the uv flow when it is visible, else the legacy checklist. One change reroutes every trigger surface (the palette command is not hidden — it routes).
  • Interpreter-change guard (EnvironmentDependenciesVerifier) — suppress the legacy auto-install prompt when uv is active, so the two flows don't both prompt.
  • extension.ts — wire both.

On readiness (deliberate design choice)

The run/debug gate and the status bar keep reading the legacy environment.dependencies check for readiness. That check reads real installed state (interpreter version + databricks-connect presence/version), so it is reload-safe and interpreter-safe — unlike the uv flow's session-only ready flag, which is empty after a window reload and is never invalidated when the user switches interpreters. Routing only the setup trigger (not the readiness signal) drives the uv setup from every surface while avoiding a reload / interpreter-staleness regression. No cross-fallback: when uv is active it is the only setup path.

All new dependencies are optional and default to legacy behavior, so nothing changes for users who have not opted in (the uv gate returns false → every surface behaves exactly as before). No new settings, persisted state, telemetry events, or when-clause flags.

Verification

  • Unit tests for the command routing and the interpreter-change guard.
  • yarn test:unit: 790 passing, 0 failing (10 pre-existing pending).
  • eslint + prettier -c clean on all touched files.
  • Reviewed with Isaac Review (0 findings), Codex, a Claude code-review agent, a devil's-advocate pass, and a CODE_CONVENTIONS.md compliance pass; this design incorporates their feedback (the earlier readiness-routing approach was dropped after review flagged the reload/interpreter regressions).

This pull request and its description were written by Isaac.

@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 12:06 — with GitHub Actions Active
@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 12:06 — with GitHub Actions Active
@rugpanov

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests triggered for 02532f27 — ⏳ running.
View run

@rugpanov
rugpanov force-pushed the feat/route-setup-to-uv-flow branch from 02532f2 to 9d331a2 Compare August 14, 2026 12:19
@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 12:19 — with GitHub Actions Active
@rugpanov rugpanov changed the title feat(python-setup): route setup surfaces to the uv flow when active feat(python-setup): route the setup command to the uv flow when active Aug 14, 2026
@rugpanov

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests triggered for 9d331a2a — ⏳ running.
View run

@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 12:20 — with GitHub Actions Active
*Why*
When the uv-native Python setup is the active surface for a project (the
`environment.pythonSetup` opt-in plus a uv-suitable project — the same gate the
configuration view already dispatches on), the `databricks.environment.setup`
command still ran the legacy checklist. Every "set up my Python env" trigger —
the status bar, the config-view legacy rows, the command palette, and the
run/debug gate's own `executeCommand("databricks.environment.setup")` — funnels
through that command, so all of them drove the wrong flow. Separately, the legacy
interpreter-change listener would pop a second install prompt on top of the uv
flow.

*What*
- Add `pythonSetupRouting.ts`: a narrow `UvPythonSetup` seam and
  `routeEnvironmentSetup`, which sends `databricks.environment.setup` to the uv
  flow when it is visible, else the legacy checklist. One change reroutes every
  trigger surface; the palette command is not hidden — it routes.
- Suppress the legacy interpreter-change auto-install prompt when uv is active,
  so the two flows don't both prompt.
- Force the run/debug gate's post-setup readiness re-check: routing to the uv
  flow adopts the interpreter and refreshes legacy state only on the async
  interpreter-change event, so reading the cache could abort the first launch.
- Wire everything in extension.ts.

Readiness (the run/debug gate and the status bar) intentionally stays on the
legacy `environment.dependencies` check: it reads real installed state, so it is
reload-safe and interpreter-safe — unlike the uv flow's session-only `ready`
flag. Routing only the setup trigger avoids a reload/interpreter-staleness
regression while still driving the uv setup from every surface. No cross-fallback:
when uv is active it is the only setup path.

All new dependencies are optional and default to legacy behavior, so nothing
changes for users who haven't opted in (the uv gate returns false → every surface
behaves exactly as before).

*Verification*
- Unit tests for the command routing, the interpreter-change guard, and the
  forced post-setup re-check.
- `yarn test:unit`: 790 passing, 0 failing (10 pre-existing pending).
- `eslint` + `prettier -c` clean on all touched files.

Co-authored-by: Isaac
@rugpanov
rugpanov force-pushed the feat/route-setup-to-uv-flow branch from 9d331a2 to 3fc9637 Compare August 14, 2026 12:24
@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 12:24 — with GitHub Actions Active
@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 12:24 — with GitHub Actions Active
@rugpanov

rugpanov commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests ❌ 1 of 35 test jobs failed for 3fc96370 (34 passed).
View run

@rugpanov
rugpanov enabled auto-merge (squash) August 14, 2026 14:03
@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 14:03 — with GitHub Actions Active
@rugpanov
rugpanov merged commit 5978be0 into main Aug 14, 2026
5 of 6 checks passed
@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 14:03 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown
Contributor

If integration tests don't run automatically, an authorized user can run them manually by following the instructions below:

Trigger:
go/deco-tests-run/vscode

Inputs:

  • PR number: 2118
  • Commit SHA: e8010088053a26756172bda48c3ea2213daadb6b

Checks will be approved automatically on success.

@rugpanov
rugpanov deleted the feat/route-setup-to-uv-flow branch August 14, 2026 14:04
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