Skip to content

Commit 049afc1

Browse files
committed
+10% coverage
1 parent d036265 commit 049afc1

File tree

6 files changed

+84
-44
lines changed

6 files changed

+84
-44
lines changed

cmd/labs/project/installer.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import (
1010

1111
"github.com/databricks/cli/cmd/labs/github"
1212
"github.com/databricks/cli/cmd/labs/unpack"
13+
"github.com/databricks/cli/cmd/root"
1314
"github.com/databricks/cli/cmd/workspace/clusters"
1415
"github.com/databricks/cli/libs/cmdio"
1516
"github.com/databricks/cli/libs/log"
1617
"github.com/databricks/cli/libs/process"
1718
"github.com/databricks/cli/libs/python"
1819
"github.com/databricks/databricks-sdk-go"
19-
"github.com/databricks/databricks-sdk-go/config"
2020
"github.com/databricks/databricks-sdk-go/service/compute"
2121
"github.com/databricks/databricks-sdk-go/service/sql"
2222
"github.com/fatih/color"
@@ -76,7 +76,13 @@ func (i *installer) Install(ctx context.Context) error {
7676
}
7777
i.folder = PathInLabs(ctx, i.Name)
7878
w, err := i.login(ctx)
79-
if err != nil {
79+
if err != nil && errors.Is(err, root.ErrNoConfiguration) {
80+
cfg := i.Installer.envAwareConfig(ctx)
81+
w, err = databricks.NewWorkspaceClient((*databricks.Config)(cfg))
82+
if err != nil {
83+
return fmt.Errorf("no ~/.databrickscfg: %w", err)
84+
}
85+
} else if err != nil {
8086
return fmt.Errorf("login: %w", err)
8187
}
8288
err = i.downloadLibrary(ctx)
@@ -141,7 +147,7 @@ func (i *installer) login(ctx context.Context) (*databricks.WorkspaceClient, err
141147
}
142148
cfg, err := i.metaEntrypoint(ctx).validLogin(i.cmd)
143149
if errors.Is(err, ErrNoLoginConfig) {
144-
cfg = &config.Config{}
150+
cfg = i.Installer.envAwareConfig(ctx)
145151
} else if err != nil {
146152
return nil, fmt.Errorf("valid: %w", err)
147153
}

cmd/labs/project/installer_test.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/databricks/cli/libs/python"
2525
"github.com/databricks/databricks-sdk-go/service/compute"
2626
"github.com/databricks/databricks-sdk-go/service/iam"
27+
"github.com/databricks/databricks-sdk-go/service/sql"
2728
"github.com/stretchr/testify/require"
2829
)
2930

@@ -191,7 +192,6 @@ func TestInstallerWorksForReleases(t *testing.T) {
191192
}
192193

193194
func TestInstallerWorksForDevelopment(t *testing.T) {
194-
t.SkipNow()
195195
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
196196
if r.URL.Path == "/api/2.0/clusters/list" {
197197
respondWithJSON(t, w, compute.ListClustersResponse{
@@ -200,7 +200,7 @@ func TestInstallerWorksForDevelopment(t *testing.T) {
200200
ClusterId: "abc-id",
201201
ClusterName: "first shared",
202202
DataSecurityMode: compute.DataSecurityModeUserIsolation,
203-
SparkVersion: "14.5.x-whatever",
203+
SparkVersion: "12.2.x-whatever",
204204
State: compute.StateRunning,
205205
},
206206
{
@@ -238,6 +238,18 @@ func TestInstallerWorksForDevelopment(t *testing.T) {
238238
})
239239
return
240240
}
241+
if r.URL.Path == "/api/2.0/sql/warehouses" {
242+
respondWithJSON(t, w, sql.ListWarehousesResponse{
243+
Warehouses: []sql.EndpointInfo{
244+
{
245+
Id: "efg-id",
246+
Name: "First PRO Warehouse",
247+
WarehouseType: sql.EndpointInfoWarehouseTypePro,
248+
},
249+
},
250+
})
251+
return
252+
}
241253
t.Logf("Requested: %s", r.URL.Path)
242254
t.FailNow()
243255
}))
@@ -288,9 +300,5 @@ account_id = abc
288300
defer r.CloseStdin()
289301

290302
r.RunBackground()
291-
r.WaitForTextPrinted("Workspace profiles defined", 5*time.Second)
292-
r.SendText("profile-one\n")
293-
r.WaitForTextPrinted("Choose compatible cluster", 5*time.Second)
294-
r.SendText("\n\n")
295303
r.WaitForTextPrinted("setting up important infrastructure", 5*time.Second)
296304
}

cmd/labs/project/login.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ func (lc *loginConfig) askCluster(ctx context.Context, w *databricks.WorkspaceCl
7070
if !cmdio.IsInteractive(ctx) {
7171
return ErrNotInTTY
7272
}
73-
lc.ClusterID, err = clusters.AskForCompatibleCluster(ctx, w, lc.Installer.MinRuntimeVersion)
73+
clusterID, err := clusters.AskForCompatibleCluster(ctx, w, lc.Installer.MinRuntimeVersion)
74+
if err != nil {
75+
return fmt.Errorf("select: %w", err)
76+
}
77+
lc.ClusterID = clusterID
7478
return
7579
}
7680

cmd/root/auth.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"io/fs"
78
"net/http"
89
"os"
910

@@ -173,9 +174,13 @@ func SetWorkspaceClient(ctx context.Context, w *databricks.WorkspaceClient) cont
173174
return context.WithValue(ctx, &workspaceClient, w)
174175
}
175176

177+
var ErrNoConfiguration = errors.New("no configuration file found")
178+
176179
func transformLoadError(path string, err error) error {
177-
if os.IsNotExist(err) {
178-
return fmt.Errorf("no configuration file found at %s; please create one first", path)
180+
if os.IsNotExist(err) || errors.Is(err, fs.ErrNotExist) {
181+
// downstreams need to handle these errors properly, but we erase the fs.ErrNotExist
182+
// TODO: expose this as error through SDK
183+
return fmt.Errorf("%w at %s; please create one first", ErrNoConfiguration, path)
179184
}
180185
return err
181186
}

cmd/workspace/clusters/uc.go

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,39 @@ func IsUnityCatalogCompatible(cluster *compute.ClusterDetails, minVersion string
5454

5555
var ErrNoCompatibleClusters = errors.New("no compatible clusters found")
5656

57+
type compatibleCluster struct {
58+
compute.ClusterDetails
59+
versionName string
60+
}
61+
62+
func (v compatibleCluster) Access() string {
63+
switch v.DataSecurityMode {
64+
case compute.DataSecurityModeUserIsolation:
65+
return "Shared"
66+
case compute.DataSecurityModeSingleUser:
67+
return "Assigned"
68+
default:
69+
return "Unknown"
70+
}
71+
}
72+
73+
func (v compatibleCluster) Runtime() string {
74+
runtime, _, _ := strings.Cut(v.versionName, " (")
75+
return runtime
76+
}
77+
78+
func (v compatibleCluster) State() string {
79+
state := v.ClusterDetails.State
80+
switch state {
81+
case compute.StateRunning, compute.StateResizing:
82+
return color.GreenString(state.String())
83+
case compute.StateError, compute.StateTerminated, compute.StateTerminating, compute.StateUnknown:
84+
return color.RedString(state.String())
85+
default:
86+
return color.BlueString(state.String())
87+
}
88+
}
89+
5790
func AskForCompatibleCluster(ctx context.Context, w *databricks.WorkspaceClient, minVersion string) (string, error) {
5891
all, err := w.Clusters.ListAll(ctx, compute.ListClustersRequest{
5992
CanUseClient: "NOTEBOOKS",
@@ -73,13 +106,6 @@ func AskForCompatibleCluster(ctx context.Context, w *databricks.WorkspaceClient,
73106
for _, v := range sv.Versions {
74107
versions[v.Key] = v.Name
75108
}
76-
type compatibleCluster struct {
77-
Id string
78-
Name string
79-
Access string
80-
State string
81-
Runtime string
82-
}
83109
var compatible []compatibleCluster
84110
for _, v := range all {
85111
if !IsUnityCatalogCompatible(&v, minVersion) {
@@ -88,48 +114,34 @@ func AskForCompatibleCluster(ctx context.Context, w *databricks.WorkspaceClient,
88114
if v.SingleUserName != "" && v.SingleUserName != me.UserName {
89115
continue
90116
}
91-
var cluster compatibleCluster
92-
switch v.DataSecurityMode {
93-
case compute.DataSecurityModeUserIsolation:
94-
cluster.Access = "Shared"
95-
case compute.DataSecurityModeSingleUser:
96-
cluster.Access = "Assigned"
97-
}
98-
switch v.State {
99-
case compute.StateRunning, compute.StateResizing:
100-
cluster.State = color.GreenString(v.State.String())
101-
case compute.StateError, compute.StateTerminated, compute.StateTerminating, compute.StateUnknown:
102-
cluster.State = color.RedString(v.State.String())
103-
default:
104-
cluster.State = color.BlueString(v.State.String())
105-
}
106-
runtime, _, _ := strings.Cut(versions[v.SparkVersion], " (")
107-
cluster.Runtime = runtime
108-
compatible = append(compatible, cluster)
117+
compatible = append(compatible, compatibleCluster{
118+
ClusterDetails: v,
119+
versionName: versions[v.SparkVersion],
120+
})
109121
}
110122
if len(compatible) == 0 {
111123
return "", ErrNoCompatibleClusters
112124
}
113125
if len(compatible) == 1 {
114-
return compatible[0].Id, nil
126+
return compatible[0].ClusterId, nil
115127
}
116128
i, _, err := cmdio.RunSelect(ctx, &promptui.Select{
117129
Label: "Choose compatible cluster",
118130
Items: compatible,
119131
Searcher: func(input string, idx int) bool {
120-
lower := strings.ToLower(compatible[idx].Name)
132+
lower := strings.ToLower(compatible[idx].ClusterName)
121133
return strings.Contains(lower, input)
122134
},
123135
StartInSearchMode: true,
124136
Templates: &promptui.SelectTemplates{
125-
Label: "{{ . | faint }}",
126-
Active: `{{.Name | bold}} ({{.State}} {{.Access}} Runtime {{.Runtime}})`,
127-
Inactive: `{{.Name}}`,
128-
Selected: `{{ "Configured cluster" | faint }}: {{ .Name | bold }} ({{.Id | faint}})`,
137+
Label: "{{.ClusterName | faint}}",
138+
Active: `{{.ClusterName | bold}} ({{.State}} {{.Access}} Runtime {{.Runtime}})`,
139+
Inactive: `{{.ClusterName}} ({{.State}} {{.Access}} Runtime {{.Runtime}})`,
140+
Selected: `{{ "Configured cluster" | faint }}: {{ .ClusterName | bold }} ({{.ClusterId | faint}})`,
129141
},
130142
})
131143
if err != nil {
132144
return "", err
133145
}
134-
return compatible[i].Id, nil
146+
return compatible[i].ClusterId, nil
135147
}

cmd/workspace/warehouses/ask.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ func AskForCompatibleWarehouses(ctx context.Context, w *databricks.WorkspaceClie
2222
for _, v := range types {
2323
allowed[v] = true
2424
}
25+
var lastWarehouseID string
2526
names := map[string]string{}
2627
for _, v := range all {
2728
if !allowed[v.WarehouseType] {
@@ -38,9 +39,13 @@ func AskForCompatibleWarehouses(ctx context.Context, w *databricks.WorkspaceClie
3839
}
3940
visibleTouser := fmt.Sprintf("%s (%s %s)", v.Name, state, v.WarehouseType)
4041
names[visibleTouser] = v.Id
42+
lastWarehouseID = v.Id
4143
}
4244
if len(names) == 0 {
4345
return "", ErrNoCompatibleWarehouses
4446
}
47+
if len(names) == 1 {
48+
return lastWarehouseID, nil
49+
}
4550
return cmdio.Select(ctx, names, "Choose SQL Warehouse")
4651
}

0 commit comments

Comments
 (0)