From 6c86298b05fe16b61fecdcdcc3da471f4fa47c96 Mon Sep 17 00:00:00 2001 From: Grigory Panov Date: Fri, 17 Jul 2026 11:59:08 +0200 Subject: [PATCH 1/2] Rename command to `environments setup-local` and move to correct package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The command is renamed from `local-env python sync` to `environments setup-local` and relocated under the existing (generated) `environments` command group, per the updated spec: that group spans both server-side environment-resource APIs and local provisioning, so a local-install verb belongs there. - Move cmd/localenv → cmd/environments, exposing Commands() (mirrors how cmd/apps extends the generated apps group). - Attach it to the generated group via a new, non-generated cmd/workspace/environments/overrides.go that appends to cmdOverrides; drop the standalone cli.AddCommand(localenv.New()) from cmd/cmd.go. - P0 is Python-only with no language selector, so the `python` subgroup is removed and the verb is bare `setup-local` (a language axis would be additive). Command stays Hidden until the constraints repo is public. - Update the command-name constants (CommandGroup/CommandVerb/CommandName) and derive the pyproject managed-block markers from CommandName so the name lives in one place. - Flag names are unchanged in this PR (--cluster/--serverless/--job/--check/ --constraint-source); the spec's flag renames are a separate follow-up. - Regenerate acceptance goldens and help output. Co-authored-by: Isaac --- .../localenv/constraints-only/output.txt | 6 +-- acceptance/localenv/constraints-only/script | 2 +- acceptance/localenv/env-unsupported/script | 2 +- acceptance/localenv/flag-conflict/script | 2 +- acceptance/localenv/help/output.txt | 23 +--------- acceptance/localenv/help/script | 3 +- .../localenv/job-ambiguous-compute/script | 2 +- .../localenv/job-classic-check/output.txt | 2 +- acceptance/localenv/job-classic-check/script | 2 +- .../localenv/job-multicluster-mismatch/script | 2 +- .../localenv/job-serverless-check/output.txt | 2 +- .../localenv/job-serverless-check/script | 2 +- .../job-serverless-version-mismatch/script | 2 +- acceptance/localenv/json-error/output.txt | 2 +- acceptance/localenv/json-error/script | 2 +- .../localenv/manager-unsupported/script | 2 +- acceptance/localenv/no-target/script | 2 +- .../localenv/serverless-check/output.txt | 2 +- acceptance/localenv/serverless-check/script | 2 +- .../localenv/serverless-json/output.txt | 6 +-- acceptance/localenv/serverless-json/script | 2 +- cmd/cmd.go | 2 - cmd/{localenv => environments}/compute.go | 2 +- .../compute_test.go | 2 +- cmd/{localenv => environments}/output.go | 2 +- cmd/environments/setup_local.go | 18 ++++++++ cmd/{localenv => environments}/sync.go | 7 ++- cmd/localenv/localenv.go | 45 ------------------- cmd/workspace/environments/overrides.go | 19 ++++++++ libs/localenv/merge.go | 13 +++--- libs/localenv/result.go | 18 +++++--- libs/localenv/result_test.go | 4 +- 32 files changed, 92 insertions(+), 112 deletions(-) rename cmd/{localenv => environments}/compute.go (99%) rename cmd/{localenv => environments}/compute_test.go (98%) rename cmd/{localenv => environments}/output.go (99%) create mode 100644 cmd/environments/setup_local.go rename cmd/{localenv => environments}/sync.go (95%) delete mode 100644 cmd/localenv/localenv.go create mode 100644 cmd/workspace/environments/overrides.go diff --git a/acceptance/localenv/constraints-only/output.txt b/acceptance/localenv/constraints-only/output.txt index d2f12be5db6..26f097b0fe3 100644 --- a/acceptance/localenv/constraints-only/output.txt +++ b/acceptance/localenv/constraints-only/output.txt @@ -1,8 +1,8 @@ ->>> [CLI] local-env python sync --serverless v4 --constraints-only --check --output json +>>> [CLI] environments setup-local --serverless v4 --constraints-only --check --output json { "schemaVersion": 1, - "command": "local-env python sync", + "command": "environments setup-local", "ok": true, "mode": "constraints-only", "dryRun": true, @@ -19,7 +19,7 @@ "plan": { "wouldWrite": "[TEST_TMP_DIR]/pyproject.toml", "wouldInstallPython": "3.12", - "diff": "--- pyproject.toml\n+++ pyproject.toml\n@@ -1 +1,15 @@\n+[project]\n+name = \"001\"\n+version = \"0.0.0\"\n+requires-python = \"\u003e=3.12\"\n+\n+[dependency-groups]\n+dev = []\n+\n+# managed by databricks local-env python sync — do not edit\n+[tool.uv]\n+constraint-dependencies = [\n+ \"pyarrow\u003c19\",\n+ \"pandas\u003c3\",\n+]\n+# end managed by databricks local-env python sync\n" + "diff": "--- pyproject.toml\n+++ pyproject.toml\n@@ -1 +1,15 @@\n+[project]\n+name = \"001\"\n+version = \"0.0.0\"\n+requires-python = \"\u003e=3.12\"\n+\n+[dependency-groups]\n+dev = []\n+\n+# managed by databricks environments setup-local — do not edit\n+[tool.uv]\n+constraint-dependencies = [\n+ \"pyarrow\u003c19\",\n+ \"pandas\u003c3\",\n+]\n+# end managed by databricks environments setup-local\n" }, "phases": [ { diff --git a/acceptance/localenv/constraints-only/script b/acceptance/localenv/constraints-only/script index 354eac49963..9ccee24213f 100644 --- a/acceptance/localenv/constraints-only/script +++ b/acceptance/localenv/constraints-only/script @@ -1 +1 @@ -trace $CLI local-env python sync --serverless v4 --constraints-only --check --output json +trace $CLI environments setup-local --serverless v4 --constraints-only --check --output json diff --git a/acceptance/localenv/env-unsupported/script b/acceptance/localenv/env-unsupported/script index 924f04b9d97..e0a8500e0c2 100644 --- a/acceptance/localenv/env-unsupported/script +++ b/acceptance/localenv/env-unsupported/script @@ -1 +1 @@ -musterr $CLI local-env python sync --cluster test-cluster-id --check +musterr $CLI environments setup-local --cluster test-cluster-id --check diff --git a/acceptance/localenv/flag-conflict/script b/acceptance/localenv/flag-conflict/script index 3309cd52205..6cf0475dab8 100644 --- a/acceptance/localenv/flag-conflict/script +++ b/acceptance/localenv/flag-conflict/script @@ -1 +1 @@ -musterr $CLI local-env python sync --cluster abc --serverless v4 +musterr $CLI environments setup-local --cluster abc --serverless v4 diff --git a/acceptance/localenv/help/output.txt b/acceptance/localenv/help/output.txt index 03fffb2be77..599cadb8cf4 100644 --- a/acceptance/localenv/help/output.txt +++ b/acceptance/localenv/help/output.txt @@ -1,22 +1,3 @@ -Manage the local Python environment matched to a Databricks compute target. - -Usage: - databricks local-env python [flags] - databricks local-env python [command] - -Available Commands: - sync Provision a local Python environment matched to a Databricks compute target - -Flags: - -h, --help help for python - -Global Flags: - --debug enable debug logging - -o, --output type output type: text or json (default text) - -p, --profile string ~/.databrickscfg profile - -t, --target string bundle target to use (if applicable) - -Use "databricks local-env python [command] --help" for more information about a command. Provision (or update) a local Python environment matched to a Databricks compute target. Resolves the target to an environment key, fetches the pinned Python version, @@ -26,13 +7,13 @@ initialized from scratch; an existing pyproject.toml is merged in place (its env-owned sections are refreshed, user-owned content is preserved). Usage: - databricks local-env python sync [flags] + databricks environments setup-local [flags] Flags: --check compute the plan without writing files or provisioning --cluster string cluster ID to use as the compute target --constraints-only apply the Python version and constraints without adding the databricks-connect dependency - -h, --help help for sync + -h, --help help for setup-local --job string job ID to use as the compute target --serverless string serverless version to use as the compute target (e.g. v4) diff --git a/acceptance/localenv/help/script b/acceptance/localenv/help/script index cca1e85aad4..d8c393d010a 100644 --- a/acceptance/localenv/help/script +++ b/acceptance/localenv/help/script @@ -1,2 +1 @@ -$CLI local-env python --help -$CLI local-env python sync --help +$CLI environments setup-local --help diff --git a/acceptance/localenv/job-ambiguous-compute/script b/acceptance/localenv/job-ambiguous-compute/script index 507f2344ce1..38318f3cf17 100644 --- a/acceptance/localenv/job-ambiguous-compute/script +++ b/acceptance/localenv/job-ambiguous-compute/script @@ -1 +1 @@ -musterr $CLI local-env python sync --job 12345 --check +musterr $CLI environments setup-local --job 12345 --check diff --git a/acceptance/localenv/job-classic-check/output.txt b/acceptance/localenv/job-classic-check/output.txt index b4481ce0484..72b89c9006f 100644 --- a/acceptance/localenv/job-classic-check/output.txt +++ b/acceptance/localenv/job-classic-check/output.txt @@ -1,5 +1,5 @@ ->>> [CLI] local-env python sync --job 12345 --check +>>> [CLI] environments setup-local --job 12345 --check preflight ok check resolve ok source=job envKey=dbr/15.4.x-scala2.12 fetch ok source=[DATABRICKS_URL]/dbr/15.4.x-scala2.12/pyproject.toml fromCache=false diff --git a/acceptance/localenv/job-classic-check/script b/acceptance/localenv/job-classic-check/script index 7469c95a844..6055757f965 100644 --- a/acceptance/localenv/job-classic-check/script +++ b/acceptance/localenv/job-classic-check/script @@ -1 +1 @@ -trace $CLI local-env python sync --job 12345 --check +trace $CLI environments setup-local --job 12345 --check diff --git a/acceptance/localenv/job-multicluster-mismatch/script b/acceptance/localenv/job-multicluster-mismatch/script index 507f2344ce1..38318f3cf17 100644 --- a/acceptance/localenv/job-multicluster-mismatch/script +++ b/acceptance/localenv/job-multicluster-mismatch/script @@ -1 +1 @@ -musterr $CLI local-env python sync --job 12345 --check +musterr $CLI environments setup-local --job 12345 --check diff --git a/acceptance/localenv/job-serverless-check/output.txt b/acceptance/localenv/job-serverless-check/output.txt index 0b8d44d2ae7..612edd745b7 100644 --- a/acceptance/localenv/job-serverless-check/output.txt +++ b/acceptance/localenv/job-serverless-check/output.txt @@ -1,5 +1,5 @@ ->>> [CLI] local-env python sync --job 12345 --check +>>> [CLI] environments setup-local --job 12345 --check preflight ok check resolve ok source=job envKey=serverless/serverless-v3 fetch ok source=[DATABRICKS_URL]/serverless/serverless-v3/pyproject.toml fromCache=false diff --git a/acceptance/localenv/job-serverless-check/script b/acceptance/localenv/job-serverless-check/script index 7469c95a844..6055757f965 100644 --- a/acceptance/localenv/job-serverless-check/script +++ b/acceptance/localenv/job-serverless-check/script @@ -1 +1 @@ -trace $CLI local-env python sync --job 12345 --check +trace $CLI environments setup-local --job 12345 --check diff --git a/acceptance/localenv/job-serverless-version-mismatch/script b/acceptance/localenv/job-serverless-version-mismatch/script index 507f2344ce1..38318f3cf17 100644 --- a/acceptance/localenv/job-serverless-version-mismatch/script +++ b/acceptance/localenv/job-serverless-version-mismatch/script @@ -1 +1 @@ -musterr $CLI local-env python sync --job 12345 --check +musterr $CLI environments setup-local --job 12345 --check diff --git a/acceptance/localenv/json-error/output.txt b/acceptance/localenv/json-error/output.txt index e76a8f74798..21bea6acf4f 100644 --- a/acceptance/localenv/json-error/output.txt +++ b/acceptance/localenv/json-error/output.txt @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "command": "local-env python sync", + "command": "environments setup-local", "ok": false, "mode": "default", "dryRun": false, diff --git a/acceptance/localenv/json-error/script b/acceptance/localenv/json-error/script index bffcc264af6..fc3931eadd5 100644 --- a/acceptance/localenv/json-error/script +++ b/acceptance/localenv/json-error/script @@ -1 +1 @@ -musterr $CLI local-env python sync --output json +musterr $CLI environments setup-local --output json diff --git a/acceptance/localenv/manager-unsupported/script b/acceptance/localenv/manager-unsupported/script index aae187d00cb..f85be8f249f 100644 --- a/acceptance/localenv/manager-unsupported/script +++ b/acceptance/localenv/manager-unsupported/script @@ -1 +1 @@ -musterr $CLI local-env python sync --serverless v4 --check +musterr $CLI environments setup-local --serverless v4 --check diff --git a/acceptance/localenv/no-target/script b/acceptance/localenv/no-target/script index 3460d1b8cf1..712272f0e56 100644 --- a/acceptance/localenv/no-target/script +++ b/acceptance/localenv/no-target/script @@ -1 +1 @@ -musterr $CLI local-env python sync +musterr $CLI environments setup-local diff --git a/acceptance/localenv/serverless-check/output.txt b/acceptance/localenv/serverless-check/output.txt index 927da068d45..9eb9c678eaf 100644 --- a/acceptance/localenv/serverless-check/output.txt +++ b/acceptance/localenv/serverless-check/output.txt @@ -1,5 +1,5 @@ ->>> [CLI] local-env python sync --serverless v4 --check +>>> [CLI] environments setup-local --serverless v4 --check preflight ok check resolve ok source=serverless envKey=serverless/serverless-v4 fetch ok source=[DATABRICKS_URL]/serverless/serverless-v4/pyproject.toml fromCache=false diff --git a/acceptance/localenv/serverless-check/script b/acceptance/localenv/serverless-check/script index 8c202ab129c..6cf12e92504 100644 --- a/acceptance/localenv/serverless-check/script +++ b/acceptance/localenv/serverless-check/script @@ -1 +1 @@ -trace $CLI local-env python sync --serverless v4 --check +trace $CLI environments setup-local --serverless v4 --check diff --git a/acceptance/localenv/serverless-json/output.txt b/acceptance/localenv/serverless-json/output.txt index c53fa61031a..4a340be560e 100644 --- a/acceptance/localenv/serverless-json/output.txt +++ b/acceptance/localenv/serverless-json/output.txt @@ -1,8 +1,8 @@ ->>> [CLI] local-env python sync --serverless v4 --check --output json +>>> [CLI] environments setup-local --serverless v4 --check --output json { "schemaVersion": 1, - "command": "local-env python sync", + "command": "environments setup-local", "ok": true, "mode": "default", "dryRun": true, @@ -20,7 +20,7 @@ "plan": { "wouldWrite": "[TEST_TMP_DIR]/pyproject.toml", "wouldInstallPython": "3.12", - "diff": "--- pyproject.toml\n+++ pyproject.toml\n@@ -1 +1,17 @@\n+[project]\n+name = \"001\"\n+version = \"0.0.0\"\n+requires-python = \"\u003e=3.12\"\n+\n+[dependency-groups]\n+dev = [\n+ \"databricks-connect~=17.2.0\",\n+]\n+\n+# managed by databricks local-env python sync — do not edit\n+[tool.uv]\n+constraint-dependencies = [\n+ \"pyarrow\u003c19\",\n+ \"pandas\u003c3\",\n+]\n+# end managed by databricks local-env python sync\n" + "diff": "--- pyproject.toml\n+++ pyproject.toml\n@@ -1 +1,17 @@\n+[project]\n+name = \"001\"\n+version = \"0.0.0\"\n+requires-python = \"\u003e=3.12\"\n+\n+[dependency-groups]\n+dev = [\n+ \"databricks-connect~=17.2.0\",\n+]\n+\n+# managed by databricks environments setup-local — do not edit\n+[tool.uv]\n+constraint-dependencies = [\n+ \"pyarrow\u003c19\",\n+ \"pandas\u003c3\",\n+]\n+# end managed by databricks environments setup-local\n" }, "phases": [ { diff --git a/acceptance/localenv/serverless-json/script b/acceptance/localenv/serverless-json/script index 84ff5620456..ed38bf3c84d 100644 --- a/acceptance/localenv/serverless-json/script +++ b/acceptance/localenv/serverless-json/script @@ -1 +1 @@ -trace $CLI local-env python sync --serverless v4 --check --output json +trace $CLI environments setup-local --serverless v4 --check --output json diff --git a/cmd/cmd.go b/cmd/cmd.go index bcd81619fca..a2c3280b940 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -18,7 +18,6 @@ import ( "github.com/databricks/cli/cmd/experimental" "github.com/databricks/cli/cmd/fs" "github.com/databricks/cli/cmd/labs" - "github.com/databricks/cli/cmd/localenv" "github.com/databricks/cli/cmd/pipelines" "github.com/databricks/cli/cmd/quickstart" "github.com/databricks/cli/cmd/root" @@ -114,7 +113,6 @@ func New(ctx context.Context) *cobra.Command { cli.AddCommand(cache.New()) cli.AddCommand(experimental.New()) cli.AddCommand(psql.New()) - cli.AddCommand(localenv.New()) cli.AddCommand(configure.New()) cli.AddCommand(fs.New()) cli.AddCommand(labs.New(ctx)) diff --git a/cmd/localenv/compute.go b/cmd/environments/compute.go similarity index 99% rename from cmd/localenv/compute.go rename to cmd/environments/compute.go index 8ce8c91314d..fa5451e70c3 100644 --- a/cmd/localenv/compute.go +++ b/cmd/environments/compute.go @@ -1,4 +1,4 @@ -package localenv +package environments import ( "context" diff --git a/cmd/localenv/compute_test.go b/cmd/environments/compute_test.go similarity index 98% rename from cmd/localenv/compute_test.go rename to cmd/environments/compute_test.go index 8620821a8f3..7b4b9300b75 100644 --- a/cmd/localenv/compute_test.go +++ b/cmd/environments/compute_test.go @@ -1,4 +1,4 @@ -package localenv +package environments import ( "testing" diff --git a/cmd/localenv/output.go b/cmd/environments/output.go similarity index 99% rename from cmd/localenv/output.go rename to cmd/environments/output.go index 85152462e26..85d60d5c235 100644 --- a/cmd/localenv/output.go +++ b/cmd/environments/output.go @@ -1,4 +1,4 @@ -package localenv +package environments import ( "context" diff --git a/cmd/environments/setup_local.go b/cmd/environments/setup_local.go new file mode 100644 index 00000000000..98dd7233c8c --- /dev/null +++ b/cmd/environments/setup_local.go @@ -0,0 +1,18 @@ +package environments + +import "github.com/spf13/cobra" + +// Commands returns the hand-written subcommands to add to the auto-generated +// "environments" command group. They are attached via the group's cmdOverrides +// hook (see cmd/workspace/environments/overrides.go), mirroring how cmd/apps +// extends the generated apps group. +// +// P0 exposes a single verb, "setup-local", which provisions a local Python +// environment matched to a Databricks compute target. It is Python-only and +// takes no language selector (spec §naming); a language axis (setup-local +// python / scala) would be additive if more languages are ever supported. +func Commands() []*cobra.Command { + return []*cobra.Command{ + newSyncCommand(), + } +} diff --git a/cmd/localenv/sync.go b/cmd/environments/sync.go similarity index 95% rename from cmd/localenv/sync.go rename to cmd/environments/sync.go index 28146278012..0765ae366f1 100644 --- a/cmd/localenv/sync.go +++ b/cmd/environments/sync.go @@ -1,4 +1,4 @@ -package localenv +package environments import ( "context" @@ -29,6 +29,11 @@ databricks-connect version, and dependency constraints published for that key, then provisions a matched .venv with uv. A project with no pyproject.toml is initialized from scratch; an existing pyproject.toml is merged in place (its env-owned sections are refreshed, user-owned content is preserved).`, + // Hidden until the environment constraints repository is publicly + // available: the command is runnable for dogfooding but stays out of + // help and completion until it is unveiled (mirrors the pre-rename state + // on main, where the local-env group carried this flag). + Hidden: true, } // The target is selected via flags; reject stray positional args rather than // silently ignoring them. diff --git a/cmd/localenv/localenv.go b/cmd/localenv/localenv.go deleted file mode 100644 index b93c36f7102..00000000000 --- a/cmd/localenv/localenv.go +++ /dev/null @@ -1,45 +0,0 @@ -package localenv - -import ( - "github.com/databricks/cli/cmd/root" - libslocalenv "github.com/databricks/cli/libs/localenv" - "github.com/spf13/cobra" -) - -// New returns the local-env command group. The group, subgroup, and verb names -// come from the single command-name constants in libs/localenv so a rename is a -// one-location change (spec §0 / invariant 8). -// -// The command is Hidden while the feature lands across the stacked PRs: it is -// wired and runnable for dogfooding, but stays out of help and completion until -// the final PR unveils it (removes this flag, adds the help line and changelog). -func New() *cobra.Command { - cmd := &cobra.Command{ - Use: libslocalenv.CommandGroup, - Short: "Manage local development environments matched to Databricks compute", - GroupID: "development", - Hidden: true, - Long: `Manage local development environments matched to a Databricks compute target. - -Derives the Python version, databricks-connect version, and dependency -constraints from the selected compute (cluster, serverless, or job) so that -local resolution matches the Databricks runtime.`, - RunE: root.ReportUnknownSubcommand, - } - cmd.AddCommand(newPythonCommand()) - return cmd -} - -// newPythonCommand returns the "python" subgroup. It is a parent-only node: with -// no verb it reports an unknown-subcommand error (mirroring the generated command -// groups) rather than doing nothing. -func newPythonCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: libslocalenv.CommandSubgroup, - Short: "Manage the local Python environment", - Long: `Manage the local Python environment matched to a Databricks compute target.`, - RunE: root.ReportUnknownSubcommand, - } - cmd.AddCommand(newSyncCommand()) - return cmd -} diff --git a/cmd/workspace/environments/overrides.go b/cmd/workspace/environments/overrides.go new file mode 100644 index 00000000000..08f760ff597 --- /dev/null +++ b/cmd/workspace/environments/overrides.go @@ -0,0 +1,19 @@ +package environments + +import ( + environmentsCli "github.com/databricks/cli/cmd/environments" + "github.com/spf13/cobra" +) + +func init() { + cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { + // Attach the hand-written local-environment commands (e.g. setup-local) + // to the auto-generated "environments" group. The group intentionally + // spans server-side environment-resource APIs and local provisioning, so + // a local-install verb belongs here (spec §naming). This mirrors how + // cmd/apps extends the generated apps group. + for _, c := range environmentsCli.Commands() { + cmd.AddCommand(c) + } + }) +} diff --git a/libs/localenv/merge.go b/libs/localenv/merge.go index d0bc39ad1da..f8a8a88e45e 100644 --- a/libs/localenv/merge.go +++ b/libs/localenv/merge.go @@ -15,12 +15,13 @@ var ( errNoProjectTable = errors.New("pyproject.toml has no [project] table to hold requires-python") ) -// managedMarkerStart and managedMarkerEnd bracket the region of pyproject.toml that -// "databricks local-env python sync" owns. Everything between them is rewritten on each merge; -// everything outside is preserved byte-for-byte. -const ( - managedMarkerStart = "# managed by databricks local-env python sync — do not edit" - managedMarkerEnd = "# end managed by databricks local-env python sync" +// managedMarkerStart and managedMarkerEnd bracket the region of pyproject.toml +// that this command owns. Everything between them is rewritten on each merge; +// everything outside is preserved byte-for-byte. They derive from CommandName so +// a command rename stays a single-place change (spec §0 / invariant 8). +var ( + managedMarkerStart = "# managed by databricks " + CommandName + " — do not edit" + managedMarkerEnd = "# end managed by databricks " + CommandName ) // Region names reported back to the caller via MergeManaged's regions return value. diff --git a/libs/localenv/result.go b/libs/localenv/result.go index 1de8f66ba50..052ce80042d 100644 --- a/libs/localenv/result.go +++ b/libs/localenv/result.go @@ -3,14 +3,18 @@ package localenv import "fmt" // Command path components, defined once so a rename touches a single place -// (spec §0 / invariant 8 / scenario 21). The cmd layer builds the Cobra -// command tree from CommandGroup/CommandSubgroup/CommandVerb; the --json -// "command" field uses CommandName. No other string re-spells the command path. +// (spec §0 / invariant 8 / scenario 21). The verb is a subcommand of the +// generated "environments" group; the --json "command" field uses CommandName. +// No other string re-spells the command path. +// +// P0 is Python-only and takes no language selector: the verb is bare +// "setup-local" (spec §naming). A language axis (setup-local python / scala) is +// the preferred shape only if more languages are ever added, and nothing is +// reserved for it here. const ( - CommandGroup = "local-env" - CommandSubgroup = "python" - CommandVerb = "sync" - CommandName = CommandGroup + " " + CommandSubgroup + " " + CommandVerb + CommandGroup = "environments" + CommandVerb = "setup-local" + CommandName = CommandGroup + " " + CommandVerb // SchemaVersion is the version of the --json output contract (spec §6). // Bump it on any breaking change to the JSON shape. diff --git a/libs/localenv/result_test.go b/libs/localenv/result_test.go index 75fe60ea66d..f8f2d60c618 100644 --- a/libs/localenv/result_test.go +++ b/libs/localenv/result_test.go @@ -24,8 +24,8 @@ func TestModeString(t *testing.T) { func TestCommandName(t *testing.T) { // The --json "command" field and all help text derive from these; the - // three-part path must join to the full command a user types. - assert.Equal(t, "local-env python sync", CommandName) + // path must join to the full command a user types. + assert.Equal(t, "environments setup-local", CommandName) } func TestNewResultEmitsEmptyArraysNotNull(t *testing.T) { From 1a5d74e70e8a996227462edcd712fd7d2526ece6 Mon Sep 17 00:00:00 2001 From: Grigory Panov Date: Fri, 17 Jul 2026 14:26:33 +0200 Subject: [PATCH 2/2] Clean up remaining old-command-name references after rename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audit follow-up for the local-env → environments setup-local rename: - pipeline.go: the --debug log line was prefixed with the literal old name 'local-env:'; derive the prefix from CommandName so it tracks the command name (now 'environments setup-local:'). - sync.go: fix two stale doc comments (the runPipeline doc and the Hidden-flag rationale referencing the removed 'local-env group'). - Rename newSyncCommand → newSetupLocalCommand so the constructor matches the verb. - overrides.go: reword comment to 'local-provisioning commands'. No user-facing behavior change; goldens unaffected (the debug prefix is not captured by acceptance output). Co-authored-by: Isaac --- cmd/environments/setup_local.go | 2 +- cmd/environments/sync.go | 7 +++---- cmd/workspace/environments/overrides.go | 2 +- libs/localenv/pipeline.go | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cmd/environments/setup_local.go b/cmd/environments/setup_local.go index 98dd7233c8c..dee8292bb5f 100644 --- a/cmd/environments/setup_local.go +++ b/cmd/environments/setup_local.go @@ -13,6 +13,6 @@ import "github.com/spf13/cobra" // python / scala) would be additive if more languages are ever supported. func Commands() []*cobra.Command { return []*cobra.Command{ - newSyncCommand(), + newSetupLocalCommand(), } } diff --git a/cmd/environments/sync.go b/cmd/environments/sync.go index 0765ae366f1..e78aa8afec9 100644 --- a/cmd/environments/sync.go +++ b/cmd/environments/sync.go @@ -18,7 +18,7 @@ import ( // libslocalenv.RepoConstraintBaseURL (which reads its own repo env var). const envConstraintSource = "DATABRICKS_LOCALENV_CONSTRAINT_SOURCE" -func newSyncCommand() *cobra.Command { +func newSetupLocalCommand() *cobra.Command { cmd := &cobra.Command{ Use: libslocalenv.CommandVerb, Short: "Provision a local Python environment matched to a Databricks compute target", @@ -31,8 +31,7 @@ initialized from scratch; an existing pyproject.toml is merged in place (its env-owned sections are refreshed, user-owned content is preserved).`, // Hidden until the environment constraints repository is publicly // available: the command is runnable for dogfooding but stays out of - // help and completion until it is unveiled (mirrors the pre-rename state - // on main, where the local-env group carried this flag). + // help and completion until it is unveiled. Hidden: true, } // The target is selected via flags; reject stray positional args rather than @@ -59,7 +58,7 @@ func addTargetFlags(cmd *cobra.Command) { cmd.MarkFlagsMutuallyExclusive("cluster", "serverless", "job") } -// runPipeline builds and runs the local-env Pipeline. +// runPipeline builds and runs the setup-local Pipeline. func runPipeline(cmd *cobra.Command) error { ctx := cmd.Context() diff --git a/cmd/workspace/environments/overrides.go b/cmd/workspace/environments/overrides.go index 08f760ff597..39864abceaf 100644 --- a/cmd/workspace/environments/overrides.go +++ b/cmd/workspace/environments/overrides.go @@ -7,7 +7,7 @@ import ( func init() { cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) { - // Attach the hand-written local-environment commands (e.g. setup-local) + // Attach the hand-written local-provisioning commands (e.g. setup-local) // to the auto-generated "environments" group. The group intentionally // spans server-side environment-resource APIs and local provisioning, so // a local-install verb belongs here (spec §naming). This mirrors how diff --git a/libs/localenv/pipeline.go b/libs/localenv/pipeline.go index db8496f85fa..cc081246320 100644 --- a/libs/localenv/pipeline.go +++ b/libs/localenv/pipeline.go @@ -61,7 +61,7 @@ type Pipeline struct { // Result always carries the full canonical phase list: phases completed before a // failure are "ok", the failing phase is "error", and the rest are "pending". func (p *Pipeline) Run(ctx context.Context) (*Result, error) { - log.Debugf(ctx, "local-env: mode=%s check=%v project=%s cacheDir=%s constraintBaseURL=%s flags=%+v", + log.Debugf(ctx, CommandName+": mode=%s check=%v project=%s cacheDir=%s constraintBaseURL=%s flags=%+v", p.Mode, p.Check, filepath.ToSlash(p.ProjectDir),