Skip to content

Commit 7d4a13a

Browse files
authored
Use slices and cmp packages instead of sort (#4951)
## Summary Migrate from the `sort` package to the `slices` and `cmp` packages across the codebase. The `slices` package (stable since Go 1.21, extended in Go 1.23) provides type-safe, generic alternatives to `sort`. Go 1.23 added `slices.Sorted` and `slices.SortedFunc`, making the full migration more compelling since the `sort` import can often be dropped entirely. Key replacements: - `sort.Strings` → `slices.Sort` - `sort.Slice` → `slices.SortFunc` - `sort.SliceStable` → `slices.SortStableFunc` The original prompt identified ~25 `sort.Strings` call sites and ~3 `sort.SliceStable` call sites across ~46 files importing `sort`. This is a low-risk, mechanical migration. The `.golangci.yaml` configuration is updated to flag any new usage of the `sort` package. ## Test plan - [x] Existing unit tests pass (`make test`) - [x] Linter passes (`make lint`) This pull request was AI-assisted by Isaac.
1 parent 4adee6a commit 7d4a13a

46 files changed

Lines changed: 198 additions & 178 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.golangci.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ linters:
5050
msg: Use env.UserHomeDir(ctx) from libs/env instead.
5151
- pattern: 'os\.Getenv'
5252
msg: Use env.Get(ctx) from the libs/env package instead of os.Getenv.
53+
- pattern: 'sort\.Slice'
54+
msg: Use slices.SortFunc from the standard library instead.
55+
- pattern: 'sort\.SliceStable'
56+
msg: Use slices.SortStableFunc from the standard library instead.
57+
- pattern: 'sort\.Strings'
58+
msg: Use slices.Sort from the standard library instead.
59+
- pattern: 'sort\.Ints'
60+
msg: Use slices.Sort from the standard library instead.
61+
- pattern: 'sort\.Float64s'
62+
msg: Use slices.Sort from the standard library instead.
5363
analyze-types: true
5464
copyloopvar:
5565
check-alias: true

acceptance/acceptance_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
"regexp"
1818
"runtime"
1919
"slices"
20-
"sort"
2120
"strconv"
2221
"strings"
2322
"sync"
@@ -486,7 +485,7 @@ func getTests(t *testing.T) []string {
486485
})
487486
require.NoError(t, err)
488487

489-
sort.Strings(testDirs)
488+
slices.Sort(testDirs)
490489
return testDirs
491490
}
492491

acceptance/internal/config.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"path/filepath"
77
"reflect"
88
"slices"
9-
"sort"
109
"strings"
1110
"testing"
1211
"time"
@@ -350,7 +349,7 @@ func ExpandEnvMatrix(matrix, exclude map[string][]string, extraVars []string) []
350349
for key := range filteredMatrix {
351350
keys = append(keys, key)
352351
}
353-
sort.Strings(keys)
352+
slices.Sort(keys)
354353

355354
// Build an expansion of all combinations.
356355
// At each step we look at a given key and append each possible value to each

bundle/config/loader/process_include.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package loader
22

33
import (
4+
"cmp"
45
"context"
56
"fmt"
67
"slices"
7-
"sort"
88
"strings"
99

1010
"github.com/databricks/cli/bundle"
@@ -98,7 +98,7 @@ func validateSingleResourceDefined(configRoot dyn.Value, ext, typ string) diag.D
9898
lines = append(lines, fmt.Sprintf(" - %s (%s)\n", r.key, r.typ))
9999
}
100100
// Sort the lines to print to make the output deterministic.
101-
sort.Strings(lines)
101+
slices.Sort(lines)
102102
// Compact the lines before writing them to the message to remove any duplicate lines.
103103
// This is needed because we do not dedup earlier when gathering the resources
104104
// and it's valid to define the same resource in both the resources and targets block.
@@ -114,11 +114,11 @@ func validateSingleResourceDefined(configRoot dyn.Value, ext, typ string) diag.D
114114
paths = append(paths, rr.path)
115115
}
116116
// Sort the locations and paths to make the output deterministic.
117-
sort.Slice(locations, func(i, j int) bool {
118-
return locations[i].String() < locations[j].String()
117+
slices.SortFunc(locations, func(a, b dyn.Location) int {
118+
return cmp.Compare(a.String(), b.String())
119119
})
120-
sort.Slice(paths, func(i, j int) bool {
121-
return paths[i].String() < paths[j].String()
120+
slices.SortFunc(paths, func(a, b dyn.Path) int {
121+
return cmp.Compare(a.String(), b.String())
122122
})
123123

124124
return diag.Diagnostics{

bundle/config/mutator/resourcemutator/apply_presets.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package resourcemutator
22

33
import (
4+
"cmp"
45
"context"
56
"path"
67
"slices"
7-
"sort"
88
"strings"
99

1010
"github.com/databricks/cli/bundle"
@@ -315,8 +315,8 @@ func toTagArray(tags map[string]string) []Tag {
315315
for key, value := range tags {
316316
tagArray = append(tagArray, Tag{Key: key, Value: value})
317317
}
318-
sort.Slice(tagArray, func(i, j int) bool {
319-
return tagArray[i].Key < tagArray[j].Key
318+
slices.SortFunc(tagArray, func(a, b Tag) int {
319+
return cmp.Compare(a.Key, b.Key)
320320
})
321321
return tagArray
322322
}

bundle/config/validate/enum.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package validate
22

33
import (
4+
"cmp"
45
"context"
56
"fmt"
67
"slices"
7-
"sort"
88

99
"github.com/databricks/cli/bundle"
1010
"github.com/databricks/cli/bundle/internal/validation/generated"
@@ -86,16 +86,14 @@ func (f *enum) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
8686
}
8787

8888
// Sort diagnostics to make them deterministic
89-
sort.Slice(diags, func(i, j int) bool {
89+
slices.SortFunc(diags, func(a, b diag.Diagnostic) int {
9090
// First sort by summary
91-
if diags[i].Summary != diags[j].Summary {
92-
return diags[i].Summary < diags[j].Summary
91+
if n := cmp.Compare(a.Summary, b.Summary); n != 0 {
92+
return n
9393
}
9494

9595
// Then sort by locations as a tie breaker if summaries are the same.
96-
iLocs := fmt.Sprintf("%v", diags[i].Locations)
97-
jLocs := fmt.Sprintf("%v", diags[j].Locations)
98-
return iLocs < jLocs
96+
return cmp.Compare(fmt.Sprintf("%v", a.Locations), fmt.Sprintf("%v", b.Locations))
9997
})
10098

10199
return diags

bundle/config/validate/required.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package validate
22

33
import (
4+
"cmp"
45
"context"
56
"fmt"
67
"slices"
7-
"sort"
88

99
"github.com/databricks/cli/bundle"
1010
"github.com/databricks/cli/bundle/internal/validation/generated"
@@ -69,16 +69,14 @@ func warnForMissingFields(ctx context.Context, b *bundle.Bundle) diag.Diagnostic
6969
}
7070

7171
// Sort diagnostics to make them deterministic
72-
sort.Slice(diags, func(i, j int) bool {
72+
slices.SortFunc(diags, func(a, b diag.Diagnostic) int {
7373
// First sort by summary
74-
if diags[i].Summary != diags[j].Summary {
75-
return diags[i].Summary < diags[j].Summary
74+
if n := cmp.Compare(a.Summary, b.Summary); n != 0 {
75+
return n
7676
}
7777

7878
// Finally sort by locations as a tie breaker if summaries are the same.
79-
iLocs := fmt.Sprintf("%v", diags[i].Locations)
80-
jLocs := fmt.Sprintf("%v", diags[j].Locations)
81-
return iLocs < jLocs
79+
return cmp.Compare(fmt.Sprintf("%v", a.Locations), fmt.Sprintf("%v", b.Locations))
8280
})
8381

8482
return diags

bundle/config/validate/unique_resource_keys.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package validate
22

33
import (
4+
"cmp"
45
"context"
5-
"sort"
6+
"slices"
67

78
"github.com/databricks/cli/bundle"
89
"github.com/databricks/cli/libs/diag"
@@ -99,20 +100,17 @@ func (m *uniqueResourceKeys) Apply(ctx context.Context, b *bundle.Bundle) diag.D
99100

100101
// Sort the locations and paths for consistent error messages. This helps
101102
// with unit testing.
102-
sort.Slice(v.locations, func(i, j int) bool {
103-
l1 := v.locations[i]
104-
l2 := v.locations[j]
105-
106-
if l1.File != l2.File {
107-
return l1.File < l2.File
103+
slices.SortFunc(v.locations, func(a, b dyn.Location) int {
104+
if n := cmp.Compare(a.File, b.File); n != 0 {
105+
return n
108106
}
109-
if l1.Line != l2.Line {
110-
return l1.Line < l2.Line
107+
if n := cmp.Compare(a.Line, b.Line); n != 0 {
108+
return n
111109
}
112-
return l1.Column < l2.Column
110+
return cmp.Compare(a.Column, b.Column)
113111
})
114-
sort.Slice(v.paths, func(i, j int) bool {
115-
return v.paths[i].String() < v.paths[j].String()
112+
slices.SortFunc(v.paths, func(a, b dyn.Path) int {
113+
return cmp.Compare(a.String(), b.String())
116114
})
117115

118116
// If there are multiple resources with the same key, report an error.

bundle/configsync/format.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package configsync
22

33
import (
44
"fmt"
5-
"sort"
5+
"slices"
66
"strings"
77
)
88

@@ -21,7 +21,7 @@ func FormatTextOutput(changes Changes) string {
2121
for key := range changes {
2222
resourceKeys = append(resourceKeys, key)
2323
}
24-
sort.Strings(resourceKeys)
24+
slices.Sort(resourceKeys)
2525

2626
for _, resourceKey := range resourceKeys {
2727
resourceChanges := changes[resourceKey]
@@ -31,7 +31,7 @@ func FormatTextOutput(changes Changes) string {
3131
for path := range resourceChanges {
3232
paths = append(paths, path)
3333
}
34-
sort.Strings(paths)
34+
slices.Sort(paths)
3535

3636
for _, path := range paths {
3737
configChange := resourceChanges[path]

bundle/configsync/patch.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ package configsync
22

33
import (
44
"bytes"
5+
"cmp"
56
"context"
67
"errors"
78
"fmt"
89
"os"
910
"regexp"
10-
"sort"
11+
"slices"
1112
"strconv"
1213
"strings"
1314

@@ -62,8 +63,8 @@ func ApplyChangesToYAML(ctx context.Context, b *bundle.Bundle, fieldChanges []Fi
6263
})
6364
}
6465

65-
sort.Slice(result, func(i, j int) bool {
66-
return result[i].Path < result[j].Path
66+
slices.SortFunc(result, func(a, b FileChange) int {
67+
return cmp.Compare(a.Path, b.Path)
6768
})
6869

6970
return result, nil

0 commit comments

Comments
 (0)