Skip to content

Commit 64a5907

Browse files
authored
Add bundle debug list-targets command (#5005)
## Why Provide a lightweight way to retrieve bundle target names along with their `default`, `mode`, and `workspace.host` fields. This is a prerequisite for running other bundle CLI commands (`deploy`, `validate`, `run`, etc.), which all require `--target`. ## Changes Adds a new hidden `bundle debug list-targets` subcommand that loads only the local YAML configuration (`bundle.MustLoad` + `phases.Load`) and returns each target's `name`, `default`, `mode`, and `workspace.host`. No target selection, no variable resolution, no authentication, no API calls. Text output: dev (default) development https://dev.example.com prod production https://prod.example.com staging https://staging.example.com JSON output: ```json { "targets": [ {"name": "dev", "default": true, "mode": "development", "host": "https://dev.example.com"}, {"name": "prod", "mode": "production", "host": "https://prod.example.com"}, {"name": "staging", "host": "https://staging.example.com"} ] } ``` ## Test plan - Unit tests for collectTargets (sorting, all fields, nil workspace, empty map) - Acceptance test covering text and JSON output - Command is hidden from bundle debug --help
1 parent 70b814e commit 64a5907

6 files changed

Lines changed: 173 additions & 0 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
bundle:
2+
name: test-list-targets
3+
4+
variables:
5+
is_default:
6+
default: false
7+
target_mode:
8+
default: production
9+
target_host:
10+
default: https://var.example.com
11+
12+
targets:
13+
dev:
14+
default: true
15+
mode: development
16+
workspace:
17+
host: https://dev.example.com
18+
staging: {}
19+
prod:
20+
mode: production
21+
workspace:
22+
host: https://prod.example.com
23+
with_vars:
24+
default: ${var.is_default}
25+
mode: ${var.target_mode}
26+
workspace:
27+
host: ${var.target_host}

acceptance/bundle/debug/list-targets/out.test.toml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
>>> [CLI] bundle debug list-targets
3+
dev (default) development https://dev.example.com
4+
prod production https://prod.example.com
5+
staging
6+
with_vars ${var.target_mode} ${var.target_host}
7+
8+
>>> [CLI] bundle debug list-targets --output json
9+
{
10+
"targets": [
11+
{
12+
"name": "dev",
13+
"default": true,
14+
"mode": "development",
15+
"host": "https://dev.example.com"
16+
},
17+
{
18+
"name": "prod",
19+
"mode": "production",
20+
"host": "https://prod.example.com"
21+
},
22+
{
23+
"name": "staging"
24+
},
25+
{
26+
"name": "with_vars",
27+
"mode": "${var.target_mode}",
28+
"host": "${var.target_host}"
29+
}
30+
]
31+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
trace $CLI bundle debug list-targets
2+
trace $CLI bundle debug list-targets --output json

cmd/bundle/debug.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ func newDebugCommand() *cobra.Command {
1717
cmd.AddCommand(debug.NewRefSchemaCommand())
1818
cmd.AddCommand(debug.NewStatesCommand())
1919
cmd.AddCommand(debug.NewRenderTemplateSchemaCommand())
20+
cmd.AddCommand(debug.NewListTargetsCommand())
2021
return cmd
2122
}

cmd/bundle/debug/list_targets.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package debug
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"maps"
7+
"slices"
8+
"strings"
9+
10+
"github.com/databricks/cli/bundle"
11+
"github.com/databricks/cli/bundle/config"
12+
"github.com/databricks/cli/bundle/phases"
13+
"github.com/databricks/cli/cmd/root"
14+
"github.com/databricks/cli/libs/cmdio"
15+
"github.com/databricks/cli/libs/diag"
16+
"github.com/databricks/cli/libs/flags"
17+
"github.com/databricks/cli/libs/logdiag"
18+
"github.com/spf13/cobra"
19+
)
20+
21+
type targetInfo struct {
22+
Name string `json:"name"`
23+
Default bool `json:"default,omitempty"`
24+
Mode config.Mode `json:"mode,omitempty"`
25+
Host string `json:"host,omitempty"`
26+
}
27+
28+
type listTargetsOutput struct {
29+
Targets []targetInfo `json:"targets"`
30+
}
31+
32+
func collectTargets(targets map[string]*config.Target) []targetInfo {
33+
names := slices.Sorted(maps.Keys(targets))
34+
35+
result := make([]targetInfo, 0, len(names))
36+
for _, name := range names {
37+
t := targets[name]
38+
info := targetInfo{
39+
Name: name,
40+
Default: t.Default,
41+
Mode: t.Mode,
42+
}
43+
if t.Workspace != nil {
44+
info.Host = t.Workspace.Host
45+
}
46+
result = append(result, info)
47+
}
48+
return result
49+
}
50+
51+
// NewListTargetsCommand returns a command that lists all bundle targets
52+
// with their name, default, mode, and workspace host fields.
53+
func NewListTargetsCommand() *cobra.Command {
54+
cmd := &cobra.Command{
55+
Use: "list-targets",
56+
Short: "List all available bundle targets",
57+
Args: root.NoArgs,
58+
Hidden: true,
59+
}
60+
61+
cmd.RunE = func(cmd *cobra.Command, args []string) error {
62+
ctx := logdiag.InitContext(cmd.Context())
63+
cmd.SetContext(ctx)
64+
logdiag.SetSeverity(ctx, diag.Warning)
65+
66+
b := bundle.MustLoad(ctx)
67+
if b == nil || logdiag.HasError(ctx) {
68+
return root.ErrAlreadyPrinted
69+
}
70+
71+
phases.Load(ctx, b)
72+
if logdiag.HasError(ctx) {
73+
return root.ErrAlreadyPrinted
74+
}
75+
76+
targets := collectTargets(b.Config.Targets)
77+
78+
switch root.OutputType(cmd) {
79+
case flags.OutputText:
80+
for _, t := range targets {
81+
parts := []string{t.Name}
82+
if t.Default {
83+
parts = append(parts, "(default)")
84+
}
85+
if t.Mode != "" {
86+
parts = append(parts, string(t.Mode))
87+
}
88+
if t.Host != "" {
89+
parts = append(parts, t.Host)
90+
}
91+
cmdio.LogString(ctx, strings.Join(parts, " "))
92+
}
93+
case flags.OutputJSON:
94+
buf, err := json.MarshalIndent(listTargetsOutput{Targets: targets}, "", " ")
95+
if err != nil {
96+
return err
97+
}
98+
_, _ = cmd.OutOrStdout().Write(buf)
99+
default:
100+
return fmt.Errorf("unknown output type %s", root.OutputType(cmd))
101+
}
102+
103+
return nil
104+
}
105+
106+
return cmd
107+
}

0 commit comments

Comments
 (0)