refactor: use slices.Sort where appropriate (#10858)
(cherry picked from commit b95845e539e481c22f1d37c0bc3d1a606d06f80b)
Andrew Gillis committed
Jul 8, 2025 at 08:27 UTC
ca2b8f69a67f8d5b13c330cb7b26f8249484b134
10 files changed
+67
-82
core/commands/active.go
+2
-2
@@ -3,7 +3,7 @@ package commands
3
import (
4
"fmt"
5
"io"
6
- "sort"
6
+ "slices"
7
"text/tabwriter"
8
"time"
9
@@ -60,7 +60,7 @@ Lists running and recently run commands.
60
for k := range req.Options {
61
keys = append(keys, k)
62
}
63
- sort.Strings(keys)
63
+ slices.Sort(keys)
64
65
for _, k := range keys {
66
fmt.Fprintf(tw, "%s=%v,", k, req.Options[k])
core/commands/bootstrap.go
+7
-5
@@ -4,14 +4,14 @@ import (
4
"errors"
5
"fmt"
6
"io"
7
- "sort"
7
+ "slices"
8
+ "strings"
9
10
+ cmds "github.com/ipfs/go-ipfs-cmds"
11
+ config "github.com/ipfs/kubo/config"
12
cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
13
repo "github.com/ipfs/kubo/repo"
14
fsrepo "github.com/ipfs/kubo/repo/fsrepo"
12
-
13
- cmds "github.com/ipfs/go-ipfs-cmds"
14
- config "github.com/ipfs/kubo/config"
15
peer "github.com/libp2p/go-libp2p/core/peer"
16
ma "github.com/multiformats/go-multiaddr"
17
)
@@ -284,7 +284,9 @@ var bootstrapListCmd = &cmds.Command{
284
}
285
286
func bootstrapWritePeers(w io.Writer, prefix string, peers []string) error {
287
- sort.Stable(sort.StringSlice(peers))
287
+ slices.SortStableFunc(peers, func(a, b string) int {
288
+ return strings.Compare(a, b)
289
+ })
290
for _, peer := range peers {
291
_, err := w.Write([]byte(prefix + peer + "\n"))
292
if err != nil {
core/commands/cid.go
+17
-17
@@ -1,10 +1,11 @@
1
package commands
2
3
import (
4
+ "cmp"
5
"errors"
6
"fmt"
7
"io"
7
- "sort"
8
+ "slices"
9
"strings"
10
"unicode"
11
@@ -287,7 +288,7 @@ var basesCmd = &cmds.Command{
288
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, val []CodeAndName) error {
289
prefixes, _ := req.Options[prefixOptionName].(bool)
290
numeric, _ := req.Options[numericOptionName].(bool)
290
- sort.Sort(multibaseSorter{val})
291
+ multibaseSorter{val}.Sort()
292
for _, v := range val {
293
code := v.Code
294
if code < 32 || code >= 127 {
@@ -357,7 +358,7 @@ var codecsCmd = &cmds.Command{
358
Encoders: cmds.EncoderMap{
359
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, val []CodeAndName) error {
360
numeric, _ := req.Options[codecsNumericOptionName].(bool)
360
- sort.Sort(codeAndNameSorter{val})
361
+ codeAndNameSorter{val}.Sort()
362
for _, v := range val {
363
if numeric {
364
fmt.Fprintf(w, "%5d %s\n", v.Code, v.Name)
@@ -398,23 +399,22 @@ type multibaseSorter struct {
399
data []CodeAndName
400
}
401
401
-func (s multibaseSorter) Len() int { return len(s.data) }
402
-func (s multibaseSorter) Swap(i, j int) { s.data[i], s.data[j] = s.data[j], s.data[i] }
403
-
404
-func (s multibaseSorter) Less(i, j int) bool {
405
- a := unicode.ToLower(rune(s.data[i].Code))
406
- b := unicode.ToLower(rune(s.data[j].Code))
407
- if a != b {
408
- return a < b
409
- }
410
- // lowecase letters should come before uppercase
411
- return s.data[i].Code > s.data[j].Code
402
+func (s multibaseSorter) Sort() {
403
+ slices.SortFunc(s.data, func(a, b CodeAndName) int {
404
+ if n := cmp.Compare(unicode.ToLower(rune(a.Code)), unicode.ToLower(rune(b.Code))); n != 0 {
405
+ return n
406
+ }
407
+ // lowecase letters should come before uppercase
408
+ return cmp.Compare(b.Code, a.Code)
409
+ })
410
}
411
412
type codeAndNameSorter struct {
413
data []CodeAndName
414
}
415
418
-func (s codeAndNameSorter) Len() int { return len(s.data) }
419
-func (s codeAndNameSorter) Swap(i, j int) { s.data[i], s.data[j] = s.data[j], s.data[i] }
420
-func (s codeAndNameSorter) Less(i, j int) bool { return s.data[i].Code < s.data[j].Code }
416
+func (s codeAndNameSorter) Sort() {
417
+ slices.SortFunc(s.data, func(a, b CodeAndName) int {
418
+ return cmp.Compare(a.Code, b.Code)
419
+ })
420
+}
core/commands/commands.go
+2
-2
@@ -10,7 +10,7 @@ import (
10
"fmt"
11
"io"
12
"os"
13
- "sort"
13
+ "slices"
14
"strings"
15
16
cmds "github.com/ipfs/go-ipfs-cmds"
@@ -131,7 +131,7 @@ func cmdPathStrings(cmd *Command, showOptions bool) []string {
131
}
132
133
recurse("", cmd)
134
- sort.Strings(cmds)
134
+ slices.Sort(cmds)
135
return cmds
136
}
137
core/commands/completion.go
+8
-15
@@ -2,7 +2,8 @@ package commands
2
3
import (
4
"io"
5
- "sort"
5
+ "slices"
6
+ "strings"
7
"text/template"
8
9
cmds "github.com/ipfs/go-ipfs-cmds"
@@ -39,8 +40,8 @@ func commandToCompletions(name string, fullName string, cmd *cmds.Command) *comp
40
parsed.Subcommands = append(parsed.Subcommands,
41
commandToCompletions(name, fullName+" "+name, subCmd))
42
}
42
- sort.Slice(parsed.Subcommands, func(i, j int) bool {
43
- return parsed.Subcommands[i].Name < parsed.Subcommands[j].Name
43
+ slices.SortFunc(parsed.Subcommands, func(a, b *completionCommand) int {
44
+ return strings.Compare(a.Name, b.Name)
45
})
46
47
for _, opt := range cmd.Options {
@@ -68,18 +69,10 @@ func commandToCompletions(name string, fullName string, cmd *cmds.Command) *comp
69
parsed.Options = append(parsed.Options, flag)
70
}
71
}
71
- sort.Slice(parsed.LongFlags, func(i, j int) bool {
72
- return parsed.LongFlags[i] < parsed.LongFlags[j]
73
- })
74
- sort.Slice(parsed.ShortFlags, func(i, j int) bool {
75
- return parsed.ShortFlags[i] < parsed.ShortFlags[j]
76
- })
77
- sort.Slice(parsed.LongOptions, func(i, j int) bool {
78
- return parsed.LongOptions[i] < parsed.LongOptions[j]
79
- })
80
- sort.Slice(parsed.ShortOptions, func(i, j int) bool {
81
- return parsed.ShortOptions[i] < parsed.ShortOptions[j]
82
- })
72
+ slices.Sort(parsed.LongFlags)
73
+ slices.Sort(parsed.ShortFlags)
74
+ slices.Sort(parsed.LongOptions)
75
+ slices.Sort(parsed.ShortOptions)
76
return parsed
77
}
78
core/commands/files.go
+3
-3
@@ -8,7 +8,7 @@ import (
8
"io"
9
"os"
10
gopath "path"
11
- "sort"
11
+ "slices"
12
"strconv"
13
"strings"
14
"time"
@@ -698,8 +698,8 @@ Examples:
698
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *filesLsOutput) error {
699
noSort, _ := req.Options[dontSortOptionName].(bool)
700
if !noSort {
701
- sort.Slice(out.Entries, func(i, j int) bool {
702
- return strings.Compare(out.Entries[i].Name, out.Entries[j].Name) < 0
701
+ slices.SortFunc(out.Entries, func(a, b mfs.NodeListing) int {
702
+ return strings.Compare(a.Name, b.Name)
703
})
704
}
705
core/commands/id.go
+5
-5
@@ -6,7 +6,7 @@ import (
6
"errors"
7
"fmt"
8
"io"
9
- "sort"
9
+ "slices"
10
"strings"
11
12
version "github.com/ipfs/kubo"
@@ -170,11 +170,11 @@ func printPeer(keyEnc ke.KeyEncoder, ps pstore.Peerstore, p peer.ID) (interface{
170
for _, a := range addrs {
171
info.Addresses = append(info.Addresses, a.String())
172
}
173
- sort.Strings(info.Addresses)
173
+ slices.Sort(info.Addresses)
174
175
protocols, _ := ps.GetProtocols(p) // don't care about errors here.
176
info.Protocols = append(info.Protocols, protocols...)
177
- sort.Slice(info.Protocols, func(i, j int) bool { return info.Protocols[i] < info.Protocols[j] })
177
+ slices.Sort(info.Protocols)
178
179
if v, err := ps.Get(p, "AgentVersion"); err == nil {
180
if vs, ok := v.(string); ok {
@@ -205,9 +205,9 @@ func printSelf(keyEnc ke.KeyEncoder, node *core.IpfsNode) (interface{}, error) {
205
for _, a := range addrs {
206
info.Addresses = append(info.Addresses, a.String())
207
}
208
- sort.Strings(info.Addresses)
208
+ slices.Sort(info.Addresses)
209
info.Protocols = node.PeerHost.Mux().Protocols()
210
- sort.Slice(info.Protocols, func(i, j int) bool { return info.Protocols[i] < info.Protocols[j] })
210
+ slices.Sort(info.Protocols)
211
}
212
info.AgentVersion = version.GetUserAgentVersion()
213
return info, nil
core/commands/ls.go
+4
-3
@@ -5,7 +5,8 @@ import (
5
"fmt"
6
"io"
7
"os"
8
- "sort"
8
+ "slices"
9
+ "strings"
10
"text/tabwriter"
11
"time"
12
@@ -118,8 +119,8 @@ The JSON output contains type information.
119
return nil
120
}, func(i int) {
121
// after each dir
121
- sort.Slice(outputLinks, func(i, j int) bool {
122
- return outputLinks[i].Name < outputLinks[j].Name
122
+ slices.SortFunc(outputLinks, func(a, b LsLink) int {
123
+ return strings.Compare(a.Name, b.Name)
124
})
125
126
output[i] = LsObject{
core/commands/pubsub.go
+2
-2
@@ -6,7 +6,7 @@ import (
6
"fmt"
7
"io"
8
"net/http"
9
- "sort"
9
+ "slices"
10
11
cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
12
mbase "github.com/multiformats/go-multibase"
@@ -325,7 +325,7 @@ TOPIC AND DATA ENCODING
325
for _, peer := range peers {
326
list.Strings = append(list.Strings, peer.String())
327
}
328
- sort.Strings(list.Strings)
328
+ slices.Sort(list.Strings)
329
return cmds.EmitOnce(res, list)
330
},
331
Type: stringList{},
core/commands/swarm.go
+17
-28
@@ -8,8 +8,9 @@ import (
8
"fmt"
9
"io"
10
"path"
11
- "sort"
11
+ "slices"
12
"strconv"
13
+ "strings"
14
"sync"
15
"text/tabwriter"
16
"time"
@@ -301,11 +302,11 @@ var swarmPeersCmd = &cmds.Command{
302
identifyResult, _ := ci.identifyPeer(n.Peerstore, c.ID())
303
ci.Identify = identifyResult
304
}
304
- sort.Sort(&ci)
305
+ ci.Sort()
306
out.Peers = append(out.Peers, ci)
307
}
308
308
- sort.Sort(&out)
309
+ out.Sort()
310
return cmds.EmitOnce(res, &out)
311
},
312
Encoders: cmds.EncoderMap{
@@ -435,32 +436,20 @@ type connInfo struct {
436
Identify IdOutput `json:",omitempty"`
437
}
438
438
-func (ci *connInfo) Less(i, j int) bool {
439
- return ci.Streams[i].Protocol < ci.Streams[j].Protocol
440
-}
441
-
442
-func (ci *connInfo) Len() int {
443
- return len(ci.Streams)
444
-}
445
-
446
-func (ci *connInfo) Swap(i, j int) {
447
- ci.Streams[i], ci.Streams[j] = ci.Streams[j], ci.Streams[i]
439
+func (ci *connInfo) Sort() {
440
+ slices.SortFunc(ci.Streams, func(a, b streamInfo) int {
441
+ return strings.Compare(a.Protocol, b.Protocol)
442
+ })
443
}
444
445
type connInfos struct {
446
Peers []connInfo
447
}
448
454
-func (ci connInfos) Less(i, j int) bool {
455
- return ci.Peers[i].Addr < ci.Peers[j].Addr
456
-}
457
-
458
-func (ci connInfos) Len() int {
459
- return len(ci.Peers)
460
-}
461
-
462
-func (ci connInfos) Swap(i, j int) {
463
- ci.Peers[i], ci.Peers[j] = ci.Peers[j], ci.Peers[i]
449
+func (ci *connInfos) Sort() {
450
+ slices.SortFunc(ci.Peers, func(a, b connInfo) int {
451
+ return strings.Compare(a.Addr, b.Addr)
452
+ })
453
}
454
455
func (ci *connInfo) identifyPeer(ps pstore.Peerstore, p peer.ID) (IdOutput, error) {
@@ -484,11 +473,11 @@ func (ci *connInfo) identifyPeer(ps pstore.Peerstore, p peer.ID) (IdOutput, erro
473
for _, a := range addrs {
474
info.Addresses = append(info.Addresses, a.String())
475
}
487
- sort.Strings(info.Addresses)
476
+ slices.Sort(info.Addresses)
477
478
if protocols, err := ps.GetProtocols(p); err == nil {
479
info.Protocols = append(info.Protocols, protocols...)
491
- sort.Slice(info.Protocols, func(i, j int) bool { return info.Protocols[i] < info.Protocols[j] })
480
+ slices.Sort(info.Protocols)
481
}
482
483
if v, err := ps.Get(p, "AgentVersion"); err == nil {
@@ -551,7 +540,7 @@ var swarmAddrsCmd = &cmds.Command{
540
for p := range am.Addrs {
541
ids = append(ids, p)
542
}
554
- sort.Strings(ids)
543
+ slices.Sort(ids)
544
545
for _, p := range ids {
546
paddrs := am.Addrs[p]
@@ -603,7 +592,7 @@ var swarmAddrsLocalCmd = &cmds.Command{
592
}
593
addrs = append(addrs, saddr)
594
}
606
- sort.Strings(addrs)
595
+ slices.Sort(addrs)
596
return cmds.EmitOnce(res, &stringList{addrs})
597
},
598
Type: stringList{},
@@ -634,7 +623,7 @@ var swarmAddrsListenCmd = &cmds.Command{
623
for _, addr := range maddrs {
624
addrs = append(addrs, addr.String())
625
}
637
- sort.Strings(addrs)
626
+ slices.Sort(addrs)
627
628
return cmds.EmitOnce(res, &stringList{addrs})
629
},