Skip to content

[VPEX][5a] Add local-env package-manager interface, detection, and preflight - #5850

Merged
rugpanov merged 2 commits into
mainfrom
dbconnect/05a-pkgmanager
Jul 13, 2026
Merged

[VPEX][5a] Add local-env package-manager interface, detection, and preflight#5850
rugpanov merged 2 commits into
mainfrom
dbconnect/05a-pkgmanager

Conversation

@rugpanov

Copy link
Copy Markdown
Contributor

Why

  • PR [VPEX][5/8] Add local-env pipeline, detection, and package-manager interface #5828 ([VPEX][5/8]) reads as +3,466 / 15 files on GitHub, but that is an artifact: PRs 1–4 were squash-merged into main while dbconnect/05-pipeline still sits on the pre-merge parent, so GitHub re-counts all of the already-merged code. The genuinely-new content in that layer is +1,165 / 5 files.
  • This splits that real delta at its one clean dependency seam. This PR is the leaf half: the PackageManager interface, manager detection, and the writability preflight — none of which reference the pipeline orchestrator.

What

  • pkgmanager.go — the PackageManager interface the pipeline provisions through (implemented by the uv backend in a later PR).
  • detect.go — uv-vs-not-uv detection (biased toward uv, whose native project file is the pyproject.toml this command drives), the non-blaming guidance message shown for an unsupported manager, and the ensureWritable preflight.
  • The pyprojectFile constant moves here from pipeline.go, since detection is its first consumer.

Testing strategy

  • detect_test.go covers the detection matrix (greenfield, uv lock, plain pyproject, conda/pip precedence), ensureWritable on a writable and a non-existent dir, and the unsupported-manager guidance message.
  • Gates: go build, go test, golangci-lint (0 issues), deadcode, gofmt — all green.

About this stack

This is one of a series of small, stacked PRs that together add the databricks local-env python sync command. It supersedes the pipeline half of #5828, split further at the interface/detection seam. Review bottom-up.

This PR and #5b (the six-phase pipeline orchestrator, stacked on this one) together replace #5828.

This pull request and its description were written by Isaac.

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: f24c320

Run: 28951586571

Env🟨​KNOWN💚​RECOVERED🙈​SKIP✅​pass🙈​skipTime
💚​aws linux4423010694:03
💚​aws windows4423210674:13
💚​aws-ucws linux443149877:02
💚​aws-ucws windows443169854:46
💚​azure linux4423010684:05
💚​azure windows4423210663:58
💚​azure-ucws linux443169847:33
🟨​azure-ucws windows1143189829:44
💚​gcp linux4422910703:52
💚​gcp windows4423110684:16
8 interesting tests: 4 SKIP, 3 RECOVERED, 1 KNOWN
Test Nameaws linuxaws windowsaws-ucws linuxaws-ucws windowsazure linuxazure windowsazure-ucws linuxazure-ucws windowsgcp linuxgcp windows
💚​TestAccept💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R
🙈​TestAccept/bundle/invariant/no_drift🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🙈​TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🙈​TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🙈​TestAccept/ssh/connection🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🟨​TestFetchRepositoryInfoAPI_FromRepo💚​R💚​R💚​R💚​R💚​R💚​R💚​R🟨​K💚​R💚​R
💚​TestFetchRepositoryInfoAPI_FromRepo/root💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R
💚​TestFetchRepositoryInfoAPI_FromRepo/subdir💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R
Top 6 slowest tests (at least 2 minutes):
durationenvtestname
3:23gcp windowsTestAccept
3:20aws windowsTestAccept
3:09aws-ucws windowsTestAccept
3:02azure windowsTestAccept
3:00azure-ucws windowsTestAccept
2:01azure-ucws windowsTestAccept/bundle/deploy/mlops-stacks/DATABRICKS_BUNDLE_ENGINE=terraform

Split from the pipeline layer so the PackageManager seam (implemented by
the uv backend in a later PR), manager detection, and the writability
preflight land as a small, independently reviewable unit.
- pkgmanager.go: the PackageManager interface the pipeline provisions through.
- detect.go: uv-vs-not-uv detection (biased toward uv, whose native project
file is the pyproject.toml this command drives), the non-blaming guidance
message for unsupported managers, and the ensureWritable preflight.
Co-authored-by: Isaac
@rugpanov
rugpanovforce-pushed the dbconnect/05a-pkgmanager branch from cb166cb to f24c320CompareJuly 8, 2026 14:44
@rugpanov
rugpanovtemporarily deployed to test-trigger-is July 8, 2026 14:44 — with GitHub Actions Inactive
@rugpanov
rugpanovtemporarily deployed to test-trigger-is July 8, 2026 14:44 — with GitHub Actions Inactive

@anton-107anton-107 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approving. Clean leaf of the stack: detectManager is pure-fs with no telemetry (matches its doc), the uv-bias logic is well-reasoned and fully table-tested, and ensureWritable + managerGuidance are covered. PackageManager interface is small and well-documented (the PostProvision/pip-seeding comment captures a real VS Code quirk). No findings.

@rugpanov
rugpanov added this pull request to the merge queueJul 13, 2026
Merged via the queue into main with commit f7c9ceeJul 13, 2026
23 checks passed
@rugpanov
rugpanov deleted the dbconnect/05a-pkgmanager branch July 13, 2026 09:49
@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: f7c9cee

Run: 29240588827

Env❌​FAIL🟨​KNOWN🔄​flaky💚​RECOVERED🙈​SKIP✅​pass🙈​skipTime
💚​aws linux44529101040:46
❌​aws windows61434476102359:00
❌​aws-ucws linux111252990820172:52
❌​aws-ucws windows111252932838185:00
🔄​azure linux434520101148:45
💚​azure windows44480102455:11
🔄​azure-ucws linux352896855145:47
🔄​azure-ucws windows242840873151:34
💚​gcp linux44514101654:19
💚​gcp windows44471102960:42
37 interesting tests: 17 FAIL, 15 flaky, 2 RECOVERED, 2 SKIP, 1 KNOWN
Test Nameaws linuxaws windowsaws-ucws linuxaws-ucws windowsazure linuxazure windowsazure-ucws linuxazure-ucws windowsgcp linuxgcp windows
🟨​TestAccept💚​R🟨​K🟨​K🟨​K💚​R💚​R🔄​f💚​R💚​R💚​R
💚​TestAccept/bundle/invariant/no_drift🙈​S🙈​S💚​R💚​R🙈​S🙈​S💚​R💚​R🙈​S🙈​S
🔄​TestAccept/bundle/resources/dashboards/change-name✅​p✅​p🔄​f✅​p✅​p✅​p🔄​f✅​p✅​p✅​p
🔄​TestAccept/bundle/resources/dashboards/change-name/DATABRICKS_BUNDLE_ENGINE=direct✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p✅​p✅​p
🔄​TestAccept/bundle/resources/dashboards/change-name/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p✅​p
❌​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions✅​p❌​F✅​p✅​p🙈​s🙈​s🙈​s🙈​s🙈​s🙈​s
❌​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=direct✅​p❌​F✅​p✅​p
❌​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=terraform✅​p❌​F✅​p✅​p
❌​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions✅​p❌​F✅​p✅​p🙈​s🙈​s🙈​s🙈​s🙈​s🙈​s
❌​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=direct✅​p❌​F✅​p✅​p
❌​TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=terraform✅​p❌​F✅​p✅​p
❌​TestAccept/bundle/resources/postgres_databases/live_errors/missing_role🙈​s🙈​s❌​F❌​F🙈​s🙈​s🙈​s🙈​s🙈​s🙈​s
❌​TestAccept/bundle/resources/postgres_databases/live_errors/missing_role/DATABRICKS_BUNDLE_ENGINE=direct❌​F❌​F
❌​TestAccept/bundle/resources/postgres_endpoints/basic🙈​s🙈​s❌​F❌​F🙈​s🙈​s🙈​s🙈​s🙈​s🙈​s
❌​TestAccept/bundle/resources/postgres_endpoints/basic/DATABRICKS_BUNDLE_ENGINE=direct❌​F❌​F
❌​TestAccept/bundle/resources/postgres_endpoints/basic/DATABRICKS_BUNDLE_ENGINE=terraform❌​F❌​F
❌​TestAccept/bundle/resources/postgres_endpoints/replace_existing🙈​s🙈​s❌​F❌​F🙈​s🙈​s🙈​s🙈​s🙈​s🙈​s
❌​TestAccept/bundle/resources/postgres_endpoints/replace_existing/DATABRICKS_BUNDLE_ENGINE=direct❌​F❌​F
❌​TestAccept/bundle/resources/postgres_endpoints/replace_existing/DATABRICKS_BUNDLE_ENGINE=terraform❌​F❌​F
❌​TestAccept/bundle/resources/postgres_endpoints/update_autoscaling🙈​s🙈​s❌​F❌​F🙈​s🙈​s🙈​s🙈​s🙈​s🙈​s
❌​TestAccept/bundle/resources/postgres_endpoints/update_autoscaling/DATABRICKS_BUNDLE_ENGINE=direct❌​F❌​F
❌​TestAccept/bundle/resources/postgres_endpoints/update_autoscaling/DATABRICKS_BUNDLE_ENGINE=terraform❌​F❌​F
🔄​TestAccept/bundle/resources/secret_scopes/basic✅​p✅​p✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p
🔄​TestAccept/bundle/resources/secret_scopes/basic/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p
💚​TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name🙈​S🙈​S💚​R💚​R🙈​S🙈​S💚​R💚​R🙈​S🙈​S
🙈​TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🔄​TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=direct/DLT=no/NBOOK=yes/PY=no/READPLAN=✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p
🔄​TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=direct/DLT=no/NBOOK=yes/PY=yes/READPLAN=1✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p
🔄​TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=no/NBOOK=no/PY=no/READPLAN=✅​p✅​p✅​p✅​p🔄​f✅​p✅​p✅​p✅​p✅​p
🔄​TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=no/NBOOK=no/PY=yes/READPLAN=✅​p✅​p✅​p✅​p🔄​f✅​p✅​p✅​p✅​p✅​p
🔄​TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=no/NBOOK=yes/PY=no/READPLAN=✅​p✅​p✅​p✅​p🔄​f✅​p✅​p✅​p✅​p✅​p
🔄​TestAccept/bundle/templates/default-python/integration_classic✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p
🔄​TestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_BUNDLE_ENGINE=terraform/UV_PYTHON=3.11✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p
🙈​TestAccept/ssh/connection🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🔄​TestFetchRepositoryInfoAPI_FromRepo💚​R💚​R💚​R💚​R🔄​f💚​R💚​R💚​R💚​R💚​R
🔄​TestFetchRepositoryInfoAPI_FromRepo/root💚​R💚​R💚​R💚​R💚​R💚​R💚​R🔄​f💚​R💚​R
🔄​TestFetchRepositoryInfoAPI_FromRepo/subdir💚​R💚​R💚​R💚​R💚​R💚​R💚​R🔄​f💚​R💚​R
Top 50 slowest tests (at least 2 minutes):
durationenvtestname
12:39gcp linuxTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
12:22gcp windowsTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
11:44gcp windowsTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
11:05gcp linuxTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
10:00gcp windowsTestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
9:44gcp windowsTestAccept/bundle/resources/clusters/deploy/local_ssd_count/DATABRICKS_BUNDLE_ENGINE=direct
9:28azure windowsTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
9:04aws-ucws windowsTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
8:37aws-ucws linuxTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
8:34aws-ucws windowsTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
8:29azure-ucws linuxTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
8:09azure windowsTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
8:08aws windowsTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:54azure linuxTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:47azure-ucws windowsTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:41azure linuxTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:40aws-ucws linuxTestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=direct
7:26gcp linuxTestAccept/bundle/resources/clusters/deploy/local_ssd_count/DATABRICKS_BUNDLE_ENGINE=direct
7:18azure-ucws windowsTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:17aws linuxTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:16azure-ucws linuxTestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=terraform
6:51gcp windowsTestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
6:46azure windowsTestAccept
6:34gcp windowsTestAccept
6:33azure-ucws linuxTestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=direct/DLT=no/NBOOK=yes/PY=yes/READPLAN=
6:32azure-ucws windowsTestAccept
6:10aws-ucws linuxTestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
6:09aws linuxTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
6:02azure-ucws linuxTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
6:01aws windowsTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
6:00aws-ucws windowsTestAccept/bundle/templates/default-python/combinations/serverless/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=yes/NBOOK=yes/PY=yes/READPLAN=
5:54azure-ucws windowsTestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_BUNDLE_ENGINE=terraform/UV_PYTHON=3.11
5:51aws-ucws linuxTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
5:35gcp linuxTestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
5:32azure-ucws windowsTestAccept/bundle/resources/registered_models/basic/DATABRICKS_BUNDLE_ENGINE=terraform
5:21gcp windowsTestAccept/bundle/resources/apps/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
5:20aws-ucws windowsTestAccept/bundle/resources/registered_models/basic/DATABRICKS_BUNDLE_ENGINE=terraform
5:05aws-ucws windowsTestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
5:01aws-ucws windowsTestAccept/bundle/templates/default-python/combinations/serverless/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=no/NBOOK=yes/PY=yes/READPLAN=
4:59azure-ucws windowsTestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
4:50azure-ucws windowsTestAccept/bundle/resources/registered_models/basic/DATABRICKS_BUNDLE_ENGINE=direct
4:50azure-ucws linuxTestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=direct
4:48gcp linuxTestAccept/bundle/resources/apps/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
4:47aws-ucws windowsTestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=direct
4:41azure-ucws windowsTestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=yes/NBOOK=yes/PY=yes/READPLAN=
4:40azure-ucws linuxTestAccept/bundle/resources/secret_scopes/permissions/DATABRICKS_BUNDLE_ENGINE=terraform
4:39gcp windowsTestAccept/bundle/resources/apps/lifecycle-started-omitted/DATABRICKS_BUNDLE_ENGINE=direct
4:38aws-ucws linuxTestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=no/NBOOK=yes/PY=yes/READPLAN=
4:36aws-ucws linuxTestAccept/bundle/resources/apps/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
4:34azure-ucws linuxTestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct

bradleyjamrozik-origindigital pushed a commit to Origin-Digital-LLC/databricks-cli that referenced this pull request Jul 13, 2026
…5851)
## Why
- The earlier layers (resolve / fetch / merge) need an orchestrator that
runs them in order, reports structured per-phase status, and provisions
the environment — without mutating disk in `--check` dry-run mode.
- This is the core half of the split described in databricks#5850: the six-phase
pipeline itself, stacked on the package-manager/detection layer.
## What
- **`pipeline.go`** — the six-phase orchestrator (`preflight → resolve →
fetch → merge → provision → validate`). It records per-phase status into
`Result` and returns typed `PipelineError`s carrying `FailurePhase` and
`DiskMutated`. Under `--check` it computes and reports the plan (with a
diff) and performs no writes, skipping the writability probe and
package-manager availability (neither is needed to compute the plan).
- The merge base is the **live `pyproject.toml`**. `MergeManaged`
rewrites only the three managed regions and is idempotent on its own
output, so a re-run preserves edits the user made between syncs. The
`.bak` is a one-time safety copy of the pre-sync original (created only
when none exists, on the first sync of an existing project); an
unreadable or unstattable existing file fails loudly rather than being
misread as greenfield and overwritten.
- `constraints-only` stops *managing* the databricks-connect pin rather
than removing it: a greenfield project renders `dev = []` (no
databricks-connect), and an existing project that already pins
databricks-connect keeps its pin untouched.
## Testing strategy
- End-to-end unit tests of the phase machine against a fake
`PackageManager` + stub compute + `httptest` server: `--check` mutates
nothing (even on a read-only dir / without a package manager) and
reports a plan that matches a real re-run (no spurious backup, empty
diff when idempotent), greenfield vs. existing, the merge basing on the
live file so between-sync edits survive, backup safety on
unreadable/unstattable files, constraints-only behavior, preflight exits
(`E_MANAGER_UNSUPPORTED` / `E_UV_MISSING`), and phase/error attribution
(`pipeline_test.go`).
- Gates: `go build`, `go test`, `golangci-lint` (0 issues), `deadcode`,
`gofmt` — all green.
---
## About this stack
**Review bottom-up.** This PR targets databricks#5850 as its base, so its diff
shows only the pipeline layer.
This PR and databricks#5850 together supersede databricks#5828.
This pull request and its description were written by Isaac.
swearyangupta pushed a commit to swearyangupta/cli that referenced this pull request Jul 17, 2026
…ks#5832)
## Why
- The engine needs a real `PackageManager` implementation (uv) and a CLI
entry point so a user can actually run the feature.
- Wiring it in while keeping it `Hidden` lets the command be dogfooded
and exercised by acceptance tests without becoming user-visible until
the stack is complete.
- This is the first layer reachable from `main`, so it also makes the
whole `libs/localenv` package live for the `deadcode` checker.
## What
- **`libs/localenv/uv.go`** — the uv implementation of `PackageManager`:
discover/install uv, install the Python minor, `uv sync`, seed pip into
the venv, validate; plus the `pip.conf` → `UV_INDEX_URL` bridge for
Databricks-managed machines.
- **`cmd/localenv/`** — the command tree matching `local-env python
sync`: a `local-env` group (`Hidden: true`), a `python` subgroup, and
the `sync` verb. Parent nodes use `root.ReportUnknownSubcommand`; `sync`
uses `cobra.NoArgs`, resolves flags/bundle target, builds the `Pipeline`
with the uv manager, and renders text or `--json`. All Cobra `Use`
values + the `--json` command field come from the `libs/localenv`
constants.
- **`cmd/cmd.go`** — registers the group.
## Testing strategy
- Unit tests for uv helper logic (discovery, `pip.conf` index-url, arg
builders, stderr surfacing) (`uv_test.go`).
- Runtime smoke test of the hidden 3-level command: absent from
top-level help; help works at each level; unknown subcommand exits
non-zero; bare group shows help; flags + mutual-exclusion + `NoArgs`
behave.
- Gates: `go build ./...`, `go test`, `golangci-lint`, `deadcode` (whole
tree, no pragmas), `gofmt` — all green.
- `cmd/localenv/` unit tests are intentionally deferred to the
acceptance PR (databricks#5833), per the repo convention that user-visible CLI
output is covered by acceptance tests.
---
## About this stack
This is one of a series of small, stacked PRs that together add the
`databricks local-env python sync` command — it provisions a local
Python environment (Python version, `databricks-connect` pin, and
dependency constraints) matched to a selected Databricks compute target.
The work was split from one large branch into single-concern layers so
each is independently reviewable; the command is kept hidden until the
final PR so nothing is user-visible mid-stack.
**Review bottom-up.** Each PR targets the previous one as its base
branch (this PR targets `main`), so its diff shows only that layer.
Layers 1–5 have merged; the original layer-5 PR (databricks#5828) was split into
5a/5b/5c during review.
| # | PR | What | Status |
|---|----|------|--------|
| 1 | databricks#5823 | foundation: result types + env-key mapping | merged |
| 2 | databricks#5824 | compute-target resolution | merged |
| 3 | databricks#5826 | constraint fetch + offline cache | merged |
| 4 | databricks#5827 | formatting-preserving pyproject.toml merge | merged |
| 5a | databricks#5850 | package-manager interface + detection | merged |
| 5b | databricks#5851 | six-phase pipeline orchestrator | merged |
| 5c | databricks#5854 | --check cache purity, greenfield name, dbc insertion |
merged |
| 6 | **databricks#5832 ← you are here** | uv backend + CLI command (registered
hidden) | |
| 7 | databricks#5833 | acceptance tests | |
| 8 | databricks#5835 | unveil (unhide + help + changelog) | |
This pull request and its description were written by Isaac.
swearyangupta pushed a commit to swearyangupta/cli that referenced this pull request Jul 17, 2026
## Why
- The command's user-visible behavior — text and `--json` output, and
every error path — needs end-to-end coverage against the real CLI.
- `cmd/localenv/` carries no unit tests by design, so acceptance tests
are where that surface is verified (repo convention: user-visible CLI
output is covered by acceptance tests).
## What
- **`acceptance/localenv/`** — 9 scenarios driven through the (hidden)
command against the in-process fake server: `help` (three-level tree),
`no-target` (`E_NO_TARGET`), `flag-conflict` (Cobra mutual-exclusion),
`manager-unsupported` (conda project → clean P1 exit), `env-unsupported`
(404 → `E_ENV_UNSUPPORTED` at fetch), `json-error` (`--output json`
error object), `serverless-check` (dry-run plan), `serverless-json`
(`--json` plan), and `constraints-only`.
- Scripts use `local-env python sync` and the
`DATABRICKS_LOCALENV_CONSTRAINT_SOURCE` override; goldens show the
`local-env python sync` command field and managed marker. No source
changes.
## Testing strategy
- Goldens generated with `-update` and verified **stable on a clean
re-run** (no `-update`); all 9 subtests pass.
- `musterr` guards the five expected-failure scenarios; `trace` shows
the three output-producing ones.
- Full acceptance suite run to confirm no regressions elsewhere (only
pre-existing, environment-specific failures unrelated to this change).
- Diff confined to `acceptance/localenv/`.
- Independently verified by a review subagent (PASS — goldens, scripts,
stubs, stale-refs, hygiene) and by codex (no issues).
---
## About this stack
This is one of a series of small, stacked PRs that together add the
`databricks local-env python sync` command — it provisions a local
Python environment (Python version, `databricks-connect` pin, and
dependency constraints) matched to a selected Databricks compute target.
The work was split from one large branch into single-concern layers so
each is independently reviewable; the command is kept hidden until the
final PR so nothing is user-visible mid-stack.
**Review bottom-up.** Layers 1–5 have merged (the original layer-5 PR
databricks#5828 was split into 5a/5b/5c during review).
| # | PR | What | Status |
|---|----|------|--------|
| 1 | databricks#5823 | foundation: result types + env-key mapping | merged |
| 2 | databricks#5824 | compute-target resolution | merged |
| 3 | databricks#5826 | constraint fetch + offline cache | merged |
| 4 | databricks#5827 | formatting-preserving pyproject.toml merge | merged |
| 5a | databricks#5850 | package-manager interface + detection | merged |
| 5b | databricks#5851 | six-phase pipeline orchestrator | merged |
| 5c | databricks#5854 | --check cache purity, greenfield name, dbc insertion |
merged |
| 6 | databricks#5832 | uv backend + CLI command (registered hidden) | |
| 7 | **databricks#5833 ← you are here** | acceptance tests | |
| 8 | databricks#5835 | unveil (unhide + help + changelog) | |
This pull request and its description were written by Isaac.
Sign up for freeto 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.

3 participants

@rugpanov@eng-dev-ecosystem-bot@anton-107