Skip to content

Commit 7842331

Browse files
authored
Enable linter for exhaustive coverage in enum switch statements (#3641)
## Changes Linter will error for switch statements on an enum where not all enum values are covered. The statement can still use a `default:` clause to explicitly fall through. ## Why Observation here: #3546 (comment)
1 parent d2cfdcb commit 7842331

File tree

18 files changed

+96
-59
lines changed

18 files changed

+96
-59
lines changed

.golangci.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ linters:
1515
- unconvert
1616
- unused
1717
- exhaustruct
18+
- exhaustive
1819
- copyloopvar
1920
- forbidigo
2021
settings:
@@ -59,6 +60,8 @@ linters:
5960
- len
6061
- equal-values
6162
- encoded-compare # Always replaces Equal() with JSONEq, but sometimes exact string match is wanted for JSON
63+
exhaustive:
64+
default-signifies-exhaustive: true
6265
exclusions:
6366
generated: lax
6467
presets:

bundle/config/mutator/sync_default_path.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ func (m *syncDefaultPath) Apply(ctx context.Context, b *bundle.Bundle) diag.Diag
2626

2727
// If the sync paths field is already set, do nothing.
2828
// We know it is set if its value is either a nil or a sequence (empty or not).
29-
switch pv.Kind() {
30-
case dyn.KindNil, dyn.KindSequence:
29+
if pv.Kind() == dyn.KindNil || pv.Kind() == dyn.KindSequence {
3130
isset = true
3231
}
3332

bundle/run/job.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ func (r *jobRunner) Run(ctx context.Context, opts *Options) (output.RunOutput, e
235235
case jobs.RunResultStateTimedout:
236236
log.Infof(ctx, "Run has timed out!")
237237
return nil, fmt.Errorf("run timed out: %s", run.State.StateMessage)
238+
239+
// TODO: handle other result states.
240+
default:
238241
}
239242

240243
return nil, err

cmd/labs/project/installer_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,15 @@ func TestInstallerWorksForDevelopment(t *testing.T) {
297297
{
298298
ClusterId: "abc-id",
299299
ClusterName: "first shared",
300+
ClusterSource: compute.ClusterSourceApi,
300301
DataSecurityMode: compute.DataSecurityModeUserIsolation,
301302
SparkVersion: "12.2.x-whatever",
302303
State: compute.StateRunning,
303304
},
304305
{
305306
ClusterId: "bcd-id",
306307
ClusterName: "second personal",
308+
ClusterSource: compute.ClusterSourceApi,
307309
DataSecurityMode: compute.DataSecurityModeSingleUser,
308310
SparkVersion: "14.5.x-whatever",
309311
State: compute.StateRunning,

cmd/sync/completion.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ func fetchDirs(ctx context.Context, wsc *databricks.WorkspaceClient, path string
2828
// We're interested only in paths we can sync to.
2929
var dirs []string
3030
for _, file := range files {
31-
switch file.ObjectType {
32-
case workspace.ObjectTypeDirectory, workspace.ObjectTypeRepo:
31+
if file.ObjectType == workspace.ObjectTypeDirectory || file.ObjectType == workspace.ObjectTypeRepo {
3332
dirs = append(dirs, file.Path)
3433
}
3534
}

libs/databrickscfg/cfgpickers/clusters.go

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,19 +98,19 @@ func (v compatibleCluster) State() string {
9898

9999
type clusterFilter func(cluster *compute.ClusterDetails, me *iam.User) bool
100100

101+
// Filter function to check if a cluster is created through the UI or an API call.
102+
func isUsableCluster(cluster *compute.ClusterDetails) bool {
103+
return cluster.ClusterSource == compute.ClusterSourceUi || cluster.ClusterSource == compute.ClusterSourceApi
104+
}
105+
101106
func WithDatabricksConnect(minVersion string) func(*compute.ClusterDetails, *iam.User) bool {
102107
return func(cluster *compute.ClusterDetails, me *iam.User) bool {
103108
if !IsCompatibleWithUC(*cluster, minVersion) {
104109
return false
105110
}
106-
switch cluster.ClusterSource {
107-
case compute.ClusterSourceJob,
108-
compute.ClusterSourceModels,
109-
compute.ClusterSourcePipeline,
110-
compute.ClusterSourcePipelineMaintenance,
111-
compute.ClusterSourceSql:
112-
// only UI and API clusters are usable for DBConnect.
113-
// `CanUseClient: "NOTEBOOKS"`` didn't seem to have an effect.
111+
// Only clusters created through the UI or an API call are usable for DBConnect.
112+
// `CanUseClient: "NOTEBOOKS"`` didn't seem to have an effect.
113+
if !isUsableCluster(cluster) {
114114
return false
115115
}
116116
if cluster.SingleUserName != "" && cluster.SingleUserName != me.UserName {
@@ -124,11 +124,7 @@ func WithDatabricksConnect(minVersion string) func(*compute.ClusterDetails, *iam
124124
// It does this by keeping only clusters created through the UI or an API call.
125125
func WithoutSystemClusters() func(*compute.ClusterDetails, *iam.User) bool {
126126
return func(cluster *compute.ClusterDetails, me *iam.User) bool {
127-
switch cluster.ClusterSource {
128-
case compute.ClusterSourceApi, compute.ClusterSourceUi:
129-
return true
130-
}
131-
return false
127+
return isUsableCluster(cluster)
132128
}
133129
}
134130

libs/databrickscfg/cfgpickers/clusters_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,15 @@ func TestFirstCompatibleCluster(t *testing.T) {
7474
{
7575
ClusterId: "abc-id",
7676
ClusterName: "first shared",
77+
ClusterSource: compute.ClusterSourceApi,
7778
DataSecurityMode: compute.DataSecurityModeUserIsolation,
7879
SparkVersion: "12.2.x-whatever",
7980
State: compute.StateRunning,
8081
},
8182
{
8283
ClusterId: "bcd-id",
8384
ClusterName: "second personal",
85+
ClusterSource: compute.ClusterSourceUi,
8486
DataSecurityMode: compute.DataSecurityModeSingleUser,
8587
SparkVersion: "14.5.x-whatever",
8688
State: compute.StateRunning,

libs/diag/diagnostic.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,6 @@ func Warningf(format string, args ...any) Diagnostics {
7777
}
7878
}
7979

80-
// Infof creates a new info diagnostic.
81-
func Infof(format string, args ...any) Diagnostics {
82-
return []Diagnostic{
83-
{
84-
Severity: Info,
85-
Summary: fmt.Sprintf(format, args...),
86-
},
87-
}
88-
}
89-
9080
// Recommendationf creates a new recommendation diagnostic.
9181
func Recommendationf(format string, args ...any) Diagnostics {
9282
return []Diagnostic{

libs/diag/severity.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,5 @@ type Severity int
55
const (
66
Error Severity = iota
77
Warning
8-
Info
98
Recommendation
109
)

libs/dyn/convert/from_typed.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ func fromTypedString(src reflect.Value, ref dyn.Value, options ...fromTypedOptio
255255
return dyn.NilValue, nil
256256
}
257257
return dyn.V(src.String()), nil
258+
default:
259+
// Fall through to the error case.
258260
}
259261

260262
return dyn.InvalidValue, fmt.Errorf("cannot convert string field to dynamic type %#v: src=%#v ref=%#v", ref.Kind().String(), src, ref.AsAny())
@@ -280,6 +282,8 @@ func fromTypedBool(src reflect.Value, ref dyn.Value, options ...fromTypedOptions
280282
if dynvar.IsPureVariableReference(ref.MustString()) {
281283
return ref, nil
282284
}
285+
default:
286+
// Fall through to the error case.
283287
}
284288

285289
return dyn.InvalidValue, fmt.Errorf("cannot convert bool field to dynamic type %#v: src=%#v ref=%#v", ref.Kind().String(), src, ref.AsAny())
@@ -305,6 +309,8 @@ func fromTypedInt(src reflect.Value, ref dyn.Value, options ...fromTypedOptions)
305309
if dynvar.IsPureVariableReference(ref.MustString()) {
306310
return ref, nil
307311
}
312+
default:
313+
// Fall through to the error case.
308314
}
309315

310316
return dyn.InvalidValue, fmt.Errorf("cannot convert int field to dynamic type %#v: src=%#v ref=%#v", ref.Kind().String(), src, ref.AsAny())
@@ -330,6 +336,8 @@ func fromTypedFloat(src reflect.Value, ref dyn.Value, options ...fromTypedOption
330336
if dynvar.IsPureVariableReference(ref.MustString()) {
331337
return ref, nil
332338
}
339+
default:
340+
// Fall through to the error case.
333341
}
334342

335343
return dyn.InvalidValue, fmt.Errorf("cannot convert float field to dynamic type %#v: src=%#v ref=%#v", ref.Kind().String(), src, ref.AsAny())

0 commit comments

Comments
 (0)