From cc7643c36b569ce257ce1cafdc65214e1f037019 Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Mon, 6 Jul 2026 11:35:03 +0200 Subject: [PATCH 01/10] Use integer ranges This is easier to read and can avoid a loop variable. Signed-off-by: Stephen Kitt --- buffer/ring_growing_test.go | 8 ++++---- diff/diff.go | 2 +- internal/third_party/forked/golang/net/ip.go | 2 +- io/read.go | 2 +- lru/lru_test.go | 2 +- net/multi_listen_test.go | 16 ++++++++-------- third_party/forked/golang/btree/btree_test.go | 6 +++--- trace/trace_test.go | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/buffer/ring_growing_test.go b/buffer/ring_growing_test.go index 1e6cdd16..cc2a0882 100644 --- a/buffer/ring_growing_test.go +++ b/buffer/ring_growing_test.go @@ -52,7 +52,7 @@ func TestGrowthGrowing(t *testing.T) { } x := 10 - for i := 0; i < x; i++ { + for i := range x { if e, a := i, g.readable; e != a { t.Fatalf("expected equal, got %#v, %#v", e, a) } @@ -133,7 +133,7 @@ func TestGrowth(t *testing.T) { } x := 10 - for i := 0; i < x; i++ { + for i := range x { if e, a := i, g.growing.readable; e != a { t.Fatalf("expected equal, got %#v, %#v", e, a) } @@ -193,7 +193,7 @@ func BenchmarkTypedRingGrowing_Spike(b *testing.B) { for i := 0; i < b.N; i++ { buffer := NewTypedRingGrowing[int](RingGrowingOptions{InitialSize: initialSize}) - for j := 0; j < spikeSize; j++ { + for j := range spikeSize { buffer.WriteOne(j) } @@ -215,7 +215,7 @@ func BenchmarkRing_Spike_And_Shrink(b *testing.B) { NormalSize: normalSize, }) - for j := 0; j < spikeSize; j++ { + for j := range spikeSize { buffer.WriteOne(j) } diff --git a/diff/diff.go b/diff/diff.go index 2a6e3aeb..a245904a 100644 --- a/diff/diff.go +++ b/diff/diff.go @@ -216,7 +216,7 @@ func objectReflectDiff(path *field.Path, a, b reflect.Value) []diff { return nil } var diffs []diff - for i := 0; i < l; i++ { + for i := range l { if !reflect.DeepEqual(a.Index(i), b.Index(i)) { diffs = append(diffs, objectReflectDiff(path.Index(i), a.Index(i), b.Index(i))...) } diff --git a/internal/third_party/forked/golang/net/ip.go b/internal/third_party/forked/golang/net/ip.go index 4340b6e7..407c2463 100644 --- a/internal/third_party/forked/golang/net/ip.go +++ b/internal/third_party/forked/golang/net/ip.go @@ -41,7 +41,7 @@ var IPv4 = stdnet.IPv4 // Parse IPv4 address (d.d.d.d). func parseIPv4(s string) IP { var p [IPv4len]byte - for i := 0; i < IPv4len; i++ { + for i := range IPv4len { if len(s) == 0 { // Missing octets. return nil diff --git a/io/read.go b/io/read.go index f0af3c8e..7323e78d 100644 --- a/io/read.go +++ b/io/read.go @@ -45,7 +45,7 @@ func consistentReadSync(filename string, attempts int, sync func(int)) ([]byte, if err != nil { return nil, err } - for i := 0; i < attempts; i++ { + for i := range attempts { if sync != nil { sync(i) } diff --git a/lru/lru_test.go b/lru/lru_test.go index 75cf0b1f..80e93f6a 100644 --- a/lru/lru_test.go +++ b/lru/lru_test.go @@ -96,7 +96,7 @@ func TestGetRace(_ *testing.T) { defer close(stop) // set up parallel getters/writers on 2x len keys - for key := 0; key < 50; key++ { + for key := range 50 { go func(key int) { for { select { diff --git a/net/multi_listen_test.go b/net/multi_listen_test.go index 84c2e603..db3f7697 100644 --- a/net/multi_listen_test.go +++ b/net/multi_listen_test.go @@ -233,7 +233,7 @@ func TestMultiListen_Close(t *testing.T) { name: "close", addrs: []string{"10.10.10.10:5000", "192.168.1.10:5000", "127.0.0.1:5000"}, runner: func(ml net.Listener, acceptCalls int) error { - for i := 0; i < acceptCalls; i++ { + for range acceptCalls { _, err := ml.Accept() if err != nil { return err @@ -251,7 +251,7 @@ func TestMultiListen_Close(t *testing.T) { name: "close with pending connections", addrs: []string{"10.10.10.10:5001", "192.168.1.10:5002", "127.0.0.1:5003"}, runner: func(ml net.Listener, acceptCalls int) error { - for i := 0; i < acceptCalls; i++ { + for range acceptCalls { _, err := ml.Accept() if err != nil { return err @@ -280,7 +280,7 @@ func TestMultiListen_Close(t *testing.T) { name: "close with no pending connections", addrs: []string{"10.10.10.10:3001", "192.168.1.10:3002", "127.0.0.1:3003"}, runner: func(ml net.Listener, acceptCalls int) error { - for i := 0; i < acceptCalls; i++ { + for range acceptCalls { _, err := ml.Accept() if err != nil { return err @@ -309,7 +309,7 @@ func TestMultiListen_Close(t *testing.T) { name: "close on close", addrs: []string{"10.10.10.10:5000", "192.168.1.10:5000", "127.0.0.1:5000"}, runner: func(ml net.Listener, acceptCalls int) error { - for i := 0; i < acceptCalls; i++ { + for range acceptCalls { _, err := ml.Accept() if err != nil { return err @@ -367,7 +367,7 @@ func TestMultiListen_Accept(t *testing.T) { name: "accept all connections", addrs: []string{"10.10.10.10:3000", "192.168.1.103:4000", "127.0.0.1:5000"}, runner: func(ml net.Listener, acceptCalls int) error { - for i := 0; i < acceptCalls; i++ { + for range acceptCalls { _, err := ml.Accept() if err != nil { return err @@ -397,7 +397,7 @@ func TestMultiListen_Accept(t *testing.T) { addrs: []string{"10.10.10.10:3000", "192.168.1.103:4000", "172.16.20.10:5000", "127.0.0.1:6000"}, runner: func(ml net.Listener, acceptCalls int) error { - for i := 0; i < acceptCalls; i++ { + for range acceptCalls { _, err := ml.Accept() if err != nil { return err @@ -442,7 +442,7 @@ func TestMultiListen_Accept(t *testing.T) { if err != nil { return err } - for i := 0; i < acceptCalls; i++ { + for range acceptCalls { _, err := ml.Accept() if err != nil { return err @@ -508,7 +508,7 @@ func TestMultiListen_HTTP(t *testing.T) { // Wait for server awake := false - for i := 0; i < 5; i++ { + for range 5 { _, err = http.Get("http://" + addrs[0].String()) if err == nil { awake = true diff --git a/third_party/forked/golang/btree/btree_test.go b/third_party/forked/golang/btree/btree_test.go index 396aac15..52154e84 100644 --- a/third_party/forked/golang/btree/btree_test.go +++ b/third_party/forked/golang/btree/btree_test.go @@ -30,7 +30,7 @@ import ( func intRange(s int, reverse bool) []int { out := make([]int, s) - for i := 0; i < s; i++ { + for i := range s { v := i if reverse { v = s - i - 1 @@ -61,7 +61,7 @@ var btreeDegree = flag.Int("degree", 32, "B-Tree degree") func TestBTree(t *testing.T) { tr := NewOrdered[int](*btreeDegree) const treeSize = 10000 - for i := 0; i < 10; i++ { + for range 10 { if min, ok := tr.Min(); ok || min != 0 { t.Fatalf("empty min, got %+v", min) } @@ -114,7 +114,7 @@ func TestBTree(t *testing.T) { func ExampleBTree() { tr := NewOrdered[int](*btreeDegree) - for i := 0; i < 10; i++ { + for i := range 10 { tr.ReplaceOrInsert(i) } fmt.Println("len: ", tr.Len()) diff --git a/trace/trace_test.go b/trace/trace_test.go index 88fc2d7a..58e42f69 100644 --- a/trace/trace_test.go +++ b/trace/trace_test.go @@ -649,7 +649,7 @@ func TestParentEndedBeforeChild(_ *testing.T) { var buf bytes.Buffer klog.SetOutput(&buf) parent := New("foo") - for i := 0; i < 1000; i++ { + for range 1000 { go func(parent *Trace) { child := parent.Nest("bar") child.Step("hello") From c4d3ec257ef8c630f487ee63ab39152c5ae4bc4d Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Mon, 6 Jul 2026 13:32:32 +0200 Subject: [PATCH 02/10] Switch to any instead of interface{} This produces surprising results in tests: go-spew outputs "interface {}", so the tests specify "any" but verify "interface {}". Signed-off-by: Stephen Kitt --- diff/diff.go | 14 +++++++------- diff/diff_test.go | 8 ++++---- dump/dump.go | 6 +++--- dump/dump_test.go | 12 ++++++------ .../third_party/forked/golang/golang-lru/lru.go | 16 ++++++++-------- keymutex/keymutex_test.go | 14 +++++++------- lru/lru.go | 6 +++--- lru/lru_test.go | 14 +++++++------- mount/mount.go | 2 +- pointer/pointer_test.go | 2 +- ptr/ptr.go | 2 +- ptr/ptr_test.go | 2 +- semantic/deep_equal.go | 2 +- third_party/forked/golang/reflect/deep_equal.go | 10 +++++----- .../forked/golang/reflect/deep_equal_test.go | 4 ++-- trace/trace.go | 2 +- 16 files changed, 58 insertions(+), 58 deletions(-) diff --git a/diff/diff.go b/diff/diff.go index a245904a..108b4889 100644 --- a/diff/diff.go +++ b/diff/diff.go @@ -53,7 +53,7 @@ func StringDiff(a, b string) string { // ObjectDiff writes the two objects out as JSON and prints out the identical part of // the objects followed by the remaining part of 'a' and finally the remaining part of 'b'. // For debugging tests. -func ObjectDiff(a, b interface{}) string { +func ObjectDiff(a, b any) string { ab, err := json.Marshal(a) if err != nil { panic(fmt.Sprintf("a: %v", err)) @@ -70,7 +70,7 @@ func ObjectDiff(a, b interface{}) string { // (go's %#v formatters OTOH stop at a certain point). This is needed when you // can't figure out why reflect.DeepEqual is returning false and nothing is // showing you differences. This will. -func ObjectGoPrintDiff(a, b interface{}) string { +func ObjectGoPrintDiff(a, b any) string { s := spew.ConfigState{DisableMethods: true} return StringDiff( s.Sprintf("%#v", a), @@ -79,7 +79,7 @@ func ObjectGoPrintDiff(a, b interface{}) string { } // ObjectReflectDiff returns a diff computed through reflection, without serializing to JSON. -func ObjectReflectDiff(a, b interface{}) string { +func ObjectReflectDiff(a, b any) string { vA, vB := reflect.ValueOf(a), reflect.ValueOf(b) if vA.Type() != vB.Type() { return fmt.Sprintf("type A %T and type B %T do not match", a, b) @@ -104,7 +104,7 @@ func ObjectReflectDiff(a, b interface{}) string { // 1. stringifies aObj and bObj // 2. elides identical prefixes if either is too long // 3. elides remaining content from the end if either is too long -func limit(aObj, bObj interface{}, max int) (string, string) { +func limit(aObj, bObj any, max int) (string, string) { elidedPrefix := "" elidedASuffix := "" elidedBSuffix := "" @@ -155,7 +155,7 @@ func public(s string) bool { type diff struct { path *field.Path - a, b interface{} + a, b any } type orderedDiffs []diff @@ -232,7 +232,7 @@ func objectReflectDiff(path *field.Path, a, b reflect.Value) []diff { if reflect.DeepEqual(a.Interface(), b.Interface()) { return nil } - aKeys := make(map[interface{}]interface{}) + aKeys := make(map[any]any) for _, key := range a.MapKeys() { aKeys[key.Interface()] = a.MapIndex(key).Interface() } @@ -269,7 +269,7 @@ func objectReflectDiff(path *field.Path, a, b reflect.Value) []diff { // ObjectGoPrintSideBySide prints a and b as textual dumps side by side, // enabling easy visual scanning for mismatches. -func ObjectGoPrintSideBySide(a, b interface{}) string { +func ObjectGoPrintSideBySide(a, b any) string { s := spew.ConfigState{ Indent: " ", // Extra deep spew. diff --git a/diff/diff_test.go b/diff/diff_test.go index 79ea2216..419bc112 100644 --- a/diff/diff_test.go +++ b/diff/diff_test.go @@ -24,7 +24,7 @@ func TestObjectReflectDiff(t *testing.T) { type struct1 struct{ A []int } testCases := map[string]struct { - a, b interface{} + a, b any out string }{ "map": { @@ -75,7 +75,7 @@ object.A: a: []int(nil) b: []int{}`, }, - "display type differences": {a: []interface{}{int64(1)}, b: []interface{}{uint64(1)}, out: ` + "display type differences": {a: []any{int64(1)}, b: []any{uint64(1)}, out: ` object[0]: a: 1 (int64) b: 0x1 (uint64)`, @@ -102,8 +102,8 @@ func TestStringDiff(t *testing.T) { func TestLimit(t *testing.T) { testcases := []struct { - a interface{} - b interface{} + a any + b any expectA string expectB string }{ diff --git a/dump/dump.go b/dump/dump.go index cf61ef76..d50465b3 100644 --- a/dump/dump.go +++ b/dump/dump.go @@ -39,16 +39,16 @@ var prettyPrintConfigForHash = &spew.ConfigState{ // Pretty wrap the spew.Sdump with Indent, and disabled methods like error() and String() // The output may change over time, so for guaranteed output please take more direct control -func Pretty(a interface{}) string { +func Pretty(a any) string { return prettyPrintConfig.Sdump(a) } // ForHash keeps the original Spew.Sprintf format to ensure the same checksum -func ForHash(a interface{}) string { +func ForHash(a any) string { return prettyPrintConfigForHash.Sprintf("%#v", a) } // OneLine outputs the object in one line -func OneLine(a interface{}) string { +func OneLine(a any) string { return prettyPrintConfig.Sprintf("%#v", a) } diff --git a/dump/dump_test.go b/dump/dump_test.go index 6c641a31..71ea9bc5 100644 --- a/dump/dump_test.go +++ b/dump/dump_test.go @@ -77,7 +77,7 @@ func TestPretty(t *testing.T) { tebw := embedwrap{teb, &teb} testCases := []struct { - a interface{} + a any want string }{ {int8(93), "(int8) 93\n"}, @@ -130,7 +130,7 @@ func TestPretty(t *testing.T) { {tebw, "(dump.embedwrap) {\n embed: (dump.embed) {\n s: (string) (len=4) \"test\"\n },\n e: (*dump.embed)({\n s: (string) (len=4) \"test\"\n })\n}\n"}, {map[string]int{}, "(map[string]int) {\n}\n"}, {map[string]int{"one": 1}, "(map[string]int) (len=1) {\n (string) (len=3) \"one\": (int) 1\n}\n"}, - {map[string]interface{}{"one": 1}, "(map[string]interface {}) (len=1) {\n (string) (len=3) \"one\": (int) 1\n}\n"}, + {map[string]any{"one": 1}, "(map[string]interface {}) (len=1) {\n (string) (len=3) \"one\": (int) 1\n}\n"}, {map[string]customString{"key": tcs}, "(map[string]dump.customString) (len=1) {\n (string) (len=3) \"key\": (dump.customString) (len=4) \"test\"\n}\n"}, {map[string]customError{"key": tce}, "(map[string]dump.customError) (len=1) {\n (string) (len=3) \"key\": (dump.customError) 0\n}\n"}, {map[string]embed{"key": teb}, "(map[string]dump.embed) (len=1) {\n (string) (len=3) \"key\": (dump.embed) {\n s: (string) (len=4) \"test\"\n }\n}\n"}, @@ -156,7 +156,7 @@ func TestForHash(t *testing.T) { tebw := embedwrap{teb, &teb} testCases := []struct { - a interface{} + a any want string }{ {int8(93), "(int8)93"}, @@ -209,7 +209,7 @@ func TestForHash(t *testing.T) { {tebw, "(dump.embedwrap){embed:(dump.embed){s:(string)test} e:(*dump.embed){s:(string)test}}"}, {map[string]int{}, "(map[string]int)map[]"}, {map[string]int{"one": 1, "two": 2}, "(map[string]int)map[one:1 two:2]"}, - {map[string]interface{}{"one": 1}, "(map[string]interface {})map[one:(int)1]"}, + {map[string]any{"one": 1}, "(map[string]interface {})map[one:(int)1]"}, {map[string]customString{"key": tcs}, "(map[string]dump.customString)map[key:test]"}, {map[string]customError{"key": tce}, "(map[string]dump.customError)map[key:0]"}, {map[string]embed{"key": teb}, "(map[string]dump.embed)map[key:{s:(string)test}]"}, @@ -235,7 +235,7 @@ func TestOneLine(t *testing.T) { tebw := embedwrap{teb, &teb} testCases := []struct { - a interface{} + a any want string }{ {int8(93), "(int8)93"}, @@ -288,7 +288,7 @@ func TestOneLine(t *testing.T) { {tebw, "(dump.embedwrap){embed:(dump.embed){s:(string)test} e:(*dump.embed){s:(string)test}}"}, {map[string]int{}, "(map[string]int)map[]"}, {map[string]int{"one": 1}, "(map[string]int)map[one:1]"}, - {map[string]interface{}{"one": 1}, "(map[string]interface {})map[one:(int)1]"}, + {map[string]any{"one": 1}, "(map[string]interface {})map[one:(int)1]"}, {map[string]customString{"key": tcs}, "(map[string]dump.customString)map[key:test]"}, {map[string]customError{"key": tce}, "(map[string]dump.customError)map[key:0]"}, {map[string]embed{"key": teb}, "(map[string]dump.embed)map[key:{s:(string)test}]"}, diff --git a/internal/third_party/forked/golang/golang-lru/lru.go b/internal/third_party/forked/golang/golang-lru/lru.go index fd4db440..f486aa64 100644 --- a/internal/third_party/forked/golang/golang-lru/lru.go +++ b/internal/third_party/forked/golang/golang-lru/lru.go @@ -27,18 +27,18 @@ type Cache struct { // OnEvicted optionally specifies a callback function to be // executed when an entry is purged from the cache. - OnEvicted func(key Key, value interface{}) + OnEvicted func(key Key, value any) ll *list.List - cache map[interface{}]*list.Element + cache map[any]*list.Element } // A Key may be any value that is comparable. See http://golang.org/ref/spec#Comparison_operators -type Key interface{} +type Key any type entry struct { key Key - value interface{} + value any } // New creates a new Cache. @@ -48,14 +48,14 @@ func New(maxEntries int) *Cache { return &Cache{ MaxEntries: maxEntries, ll: list.New(), - cache: make(map[interface{}]*list.Element), + cache: make(map[any]*list.Element), } } // Add adds a value to the cache. -func (c *Cache) Add(key Key, value interface{}) { +func (c *Cache) Add(key Key, value any) { if c.cache == nil { - c.cache = make(map[interface{}]*list.Element) + c.cache = make(map[any]*list.Element) c.ll = list.New() } if ee, ok := c.cache[key]; ok { @@ -71,7 +71,7 @@ func (c *Cache) Add(key Key, value interface{}) { } // Get looks up a key's value from the cache. -func (c *Cache) Get(key Key) (value interface{}, ok bool) { +func (c *Cache) Get(key Key) (value any, ok bool) { if c.cache == nil { return } diff --git a/keymutex/keymutex_test.go b/keymutex/keymutex_test.go index ce2f567b..b17ef9c3 100644 --- a/keymutex/keymutex_test.go +++ b/keymutex/keymutex_test.go @@ -38,7 +38,7 @@ func Test_SingleLock_NoUnlock(t *testing.T) { for _, km := range newKeyMutexes() { // Arrange key := "fakeid" - callbackCh := make(chan interface{}) + callbackCh := make(chan any) // Act go lockAndCallback(km, key, callbackCh) @@ -52,7 +52,7 @@ func Test_SingleLock_SingleUnlock(t *testing.T) { for _, km := range newKeyMutexes() { // Arrange key := "fakeid" - callbackCh := make(chan interface{}) + callbackCh := make(chan any) // Act & Assert go lockAndCallback(km, key, callbackCh) @@ -65,8 +65,8 @@ func Test_DoubleLock_DoubleUnlock(t *testing.T) { for _, km := range newKeyMutexes() { // Arrange key := "fakeid" - callbackCh1stLock := make(chan interface{}) - callbackCh2ndLock := make(chan interface{}) + callbackCh1stLock := make(chan any) + callbackCh2ndLock := make(chan any) // Act & Assert go lockAndCallback(km, key, callbackCh1stLock) @@ -79,12 +79,12 @@ func Test_DoubleLock_DoubleUnlock(t *testing.T) { } } -func lockAndCallback(km KeyMutex, id string, callbackCh chan<- interface{}) { +func lockAndCallback(km KeyMutex, id string, callbackCh chan<- any) { km.LockKey(id) callbackCh <- true } -func verifyCallbackHappens(t *testing.T, callbackCh <-chan interface{}) bool { +func verifyCallbackHappens(t *testing.T, callbackCh <-chan any) bool { select { case <-callbackCh: return true @@ -94,7 +94,7 @@ func verifyCallbackHappens(t *testing.T, callbackCh <-chan interface{}) bool { } } -func verifyCallbackDoesntHappens(t *testing.T, callbackCh <-chan interface{}) bool { +func verifyCallbackDoesntHappens(t *testing.T, callbackCh <-chan any) bool { select { case <-callbackCh: t.Fatalf("Unexpected callback.") diff --git a/lru/lru.go b/lru/lru.go index 40c22ece..4fad3f6d 100644 --- a/lru/lru.go +++ b/lru/lru.go @@ -23,7 +23,7 @@ import ( ) type Key = groupcache.Key -type EvictionFunc = func(key Key, value interface{}) +type EvictionFunc = func(key Key, value any) // Cache is a thread-safe fixed size LRU cache. type Cache struct { @@ -57,14 +57,14 @@ func (c *Cache) SetEvictionFunc(f EvictionFunc) error { } // Add adds a value to the cache. -func (c *Cache) Add(key Key, value interface{}) { +func (c *Cache) Add(key Key, value any) { c.lock.Lock() defer c.lock.Unlock() c.cache.Add(key, value) } // Get looks up a key's value from the cache. -func (c *Cache) Get(key Key) (value interface{}, ok bool) { +func (c *Cache) Get(key Key) (value any, ok bool) { c.lock.Lock() defer c.lock.Unlock() return c.cache.Get(key) diff --git a/lru/lru_test.go b/lru/lru_test.go index 80e93f6a..433fef45 100644 --- a/lru/lru_test.go +++ b/lru/lru_test.go @@ -48,8 +48,8 @@ type complexStruct struct { var getTests = []struct { name string - keyToAdd interface{} - keyToGet interface{} + keyToAdd any + keyToGet any expectedOk bool }{ {"string_hit", "myKey", "myKey", true}, @@ -116,9 +116,9 @@ func TestGetRace(_ *testing.T) { func TestEviction(t *testing.T) { var seenKey Key - var seenVal interface{} + var seenVal any - lru := NewWithEvictionFunc(1, func(key Key, value interface{}) { + lru := NewWithEvictionFunc(1, func(key Key, value any) { seenKey = key seenVal = value }) @@ -133,11 +133,11 @@ func TestEviction(t *testing.T) { func TestSetEviction(t *testing.T) { var seenKey Key - var seenVal interface{} + var seenVal any lru := New(1) - err := lru.SetEvictionFunc(func(key Key, value interface{}) { + err := lru.SetEvictionFunc(func(key Key, value any) { seenKey = key seenVal = value }) @@ -153,7 +153,7 @@ func TestSetEviction(t *testing.T) { t.Errorf("unexpected eviction data: key=%v val=%v", seenKey, seenVal) } - err = lru.SetEvictionFunc(func(_ Key, _ interface{}) {}) + err = lru.SetEvictionFunc(func(_ Key, _ any) {}) if err == nil { t.Errorf("expected error but got none") } diff --git a/mount/mount.go b/mount/mount.go index c44acfd5..5e49ccf3 100644 --- a/mount/mount.go +++ b/mount/mount.go @@ -110,7 +110,7 @@ func (mountError MountError) Error() string { return mountError.Message } -func NewMountError(mountErrorValue MountErrorType, format string, args ...interface{}) error { +func NewMountError(mountErrorValue MountErrorType, format string, args ...any) error { mountError := MountError{ Type: mountErrorValue, Message: fmt.Sprintf(format, args...), diff --git a/pointer/pointer_test.go b/pointer/pointer_test.go index a41286f0..1fc0aa4d 100644 --- a/pointer/pointer_test.go +++ b/pointer/pointer_test.go @@ -24,7 +24,7 @@ import ( func TestAllPtrFieldsNil(t *testing.T) { testCases := []struct { - obj interface{} + obj any expected bool }{ {struct{}{}, true}, diff --git a/ptr/ptr.go b/ptr/ptr.go index ea847fd3..dbacfdaa 100644 --- a/ptr/ptr.go +++ b/ptr/ptr.go @@ -27,7 +27,7 @@ import ( // // This function is only valid for structs and pointers to structs. Any other // type will cause a panic. Passing a typed nil pointer will return true. -func AllPtrFieldsNil(obj interface{}) bool { +func AllPtrFieldsNil(obj any) bool { v := reflect.ValueOf(obj) if !v.IsValid() { panic(fmt.Sprintf("reflect.ValueOf() produced a non-valid Value for %#v", obj)) diff --git a/ptr/ptr_test.go b/ptr/ptr_test.go index 046d8967..f9dd5db3 100644 --- a/ptr/ptr_test.go +++ b/ptr/ptr_test.go @@ -25,7 +25,7 @@ import ( func TestAllPtrFieldsNil(t *testing.T) { testCases := []struct { - obj interface{} + obj any expected bool }{ {struct{}{}, true}, diff --git a/semantic/deep_equal.go b/semantic/deep_equal.go index 2f56974c..779a039a 100644 --- a/semantic/deep_equal.go +++ b/semantic/deep_equal.go @@ -25,6 +25,6 @@ import ( type Equalities = reflect.Equalities // EqualitiesOrDie adds the given funcs and panics on any error. -func EqualitiesOrDie(funcs ...interface{}) Equalities { +func EqualitiesOrDie(funcs ...any) Equalities { return reflect.EqualitiesOrDie(funcs...) } diff --git a/third_party/forked/golang/reflect/deep_equal.go b/third_party/forked/golang/reflect/deep_equal.go index 7603b9a1..0a39ca3a 100644 --- a/third_party/forked/golang/reflect/deep_equal.go +++ b/third_party/forked/golang/reflect/deep_equal.go @@ -17,7 +17,7 @@ import ( type Equalities map[reflect.Type]reflect.Value // EqualitiesOrDie adds the given funcs and panics on any error. -func EqualitiesOrDie(funcs ...interface{}) Equalities { +func EqualitiesOrDie(funcs ...any) Equalities { e := Equalities{} if err := e.AddFuncs(funcs...); err != nil { panic(err) @@ -26,7 +26,7 @@ func EqualitiesOrDie(funcs ...interface{}) Equalities { } // AddFuncs is a shortcut for multiple calls to AddFunc. -func (e Equalities) AddFuncs(funcs ...interface{}) error { +func (e Equalities) AddFuncs(funcs ...any) error { for _, f := range funcs { if err := e.AddFunc(f); err != nil { return err @@ -37,7 +37,7 @@ func (e Equalities) AddFuncs(funcs ...interface{}) error { // AddFunc uses func as an equality function: it must take // two parameters of the same type, and return a boolean. -func (e Equalities) AddFunc(eqFunc interface{}) error { +func (e Equalities) AddFunc(eqFunc any) error { fv := reflect.ValueOf(eqFunc) ft := fv.Type() if ft.Kind() != reflect.Func { @@ -236,7 +236,7 @@ func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, // // Unexported field members cannot be compared and will cause an informative panic; you must add an Equality // function for these types. -func (e Equalities) DeepEqual(a1, a2 interface{}) bool { +func (e Equalities) DeepEqual(a1, a2 any) bool { if a1 == nil || a2 == nil { return a1 == a2 } @@ -385,7 +385,7 @@ func (e Equalities) deepValueDerive(v1, v2 reflect.Value, visited map[visit]bool // the semantic comparison. // // The unset fields include a nil pointer and an empty string. -func (e Equalities) DeepDerivative(a1, a2 interface{}) bool { +func (e Equalities) DeepDerivative(a1, a2 any) bool { if a1 == nil { return true } diff --git a/third_party/forked/golang/reflect/deep_equal_test.go b/third_party/forked/golang/reflect/deep_equal_test.go index 4a062993..9f50380a 100644 --- a/third_party/forked/golang/reflect/deep_equal_test.go +++ b/third_party/forked/golang/reflect/deep_equal_test.go @@ -33,7 +33,7 @@ func TestEqualities(t *testing.T) { } table := []struct { - a, b interface{} + a, b any equal bool }{ {1, 2, true}, @@ -97,7 +97,7 @@ func TestDerivates(t *testing.T) { } table := []struct { - a, b interface{} + a, b any equal bool }{ {1, 2, true}, diff --git a/trace/trace.go b/trace/trace.go index 559aebb5..7fa54645 100644 --- a/trace/trace.go +++ b/trace/trace.go @@ -34,7 +34,7 @@ var klogV = func(lvl klog.Level) bool { // Field is a key value pair that provides additional details about the trace. type Field struct { Key string - Value interface{} + Value any } func (f Field) format() string { From 010418433accbcc6c555d64598998440e141da5e Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Mon, 6 Jul 2026 13:34:09 +0200 Subject: [PATCH 03/10] Switch to reflect.Pointer instead of reflect.Ptr Signed-off-by: Stephen Kitt --- diff/diff.go | 2 +- ptr/ptr.go | 4 ++-- third_party/forked/golang/reflect/deep_equal.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/diff/diff.go b/diff/diff.go index 108b4889..c5d531fb 100644 --- a/diff/diff.go +++ b/diff/diff.go @@ -186,7 +186,7 @@ func objectReflectDiff(path *field.Path, a, b reflect.Value) []diff { } } return changes - case reflect.Ptr, reflect.Interface: + case reflect.Pointer, reflect.Interface: if a.IsNil() || b.IsNil() { switch { case a.IsNil() && b.IsNil(): diff --git a/ptr/ptr.go b/ptr/ptr.go index dbacfdaa..260f4f29 100644 --- a/ptr/ptr.go +++ b/ptr/ptr.go @@ -32,14 +32,14 @@ func AllPtrFieldsNil(obj any) bool { if !v.IsValid() { panic(fmt.Sprintf("reflect.ValueOf() produced a non-valid Value for %#v", obj)) } - if v.Kind() == reflect.Ptr { + if v.Kind() == reflect.Pointer { if v.IsNil() { return true } v = v.Elem() } for i := 0; i < v.NumField(); i++ { - if v.Field(i).Kind() == reflect.Ptr && !v.Field(i).IsNil() { + if v.Field(i).Kind() == reflect.Pointer && !v.Field(i).IsNil() { return false } } diff --git a/third_party/forked/golang/reflect/deep_equal.go b/third_party/forked/golang/reflect/deep_equal.go index 0a39ca3a..e8403e79 100644 --- a/third_party/forked/golang/reflect/deep_equal.go +++ b/third_party/forked/golang/reflect/deep_equal.go @@ -184,7 +184,7 @@ func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, return v1.IsNil() == v2.IsNil() } return e.deepValueEqual(v1.Elem(), v2.Elem(), visited, depth+1) - case reflect.Ptr: + case reflect.Pointer: return e.deepValueEqual(v1.Elem(), v2.Elem(), visited, depth+1) case reflect.Struct: for i, n := 0, v1.NumField(); i < n; i++ { @@ -337,7 +337,7 @@ func (e Equalities) deepValueDerive(v1, v2 reflect.Value, visited map[visit]bool return true } return e.deepValueDerive(v1.Elem(), v2.Elem(), visited, depth+1) - case reflect.Ptr: + case reflect.Pointer: if v1.IsNil() { return true } From 84841597c490145d64d47793239e970221e902b8 Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Mon, 6 Jul 2026 13:36:15 +0200 Subject: [PATCH 04/10] Call min() instead of open-coding it Signed-off-by: Stephen Kitt --- diff/diff.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/diff/diff.go b/diff/diff.go index c5d531fb..0510dd33 100644 --- a/diff/diff.go +++ b/diff/diff.go @@ -205,10 +205,7 @@ func objectReflectDiff(path *field.Path, a, b reflect.Value) []diff { return nil case reflect.Slice: lA, lB := a.Len(), b.Len() - l := lA - if lB < lA { - l = lB - } + l := min(lB, lA) if lA == lB && lA == 0 { if a.IsNil() != b.IsNil() { return []diff{{path: path, a: a.Interface(), b: b.Interface()}} From 584dbcacf80345dd33f6e11462d036d854929e7b Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Mon, 6 Jul 2026 13:36:42 +0200 Subject: [PATCH 05/10] Drop obsolete +build statements Signed-off-by: Stephen Kitt --- inotify/inotify_linux.go | 1 - inotify/inotify_linux_test.go | 1 - mount/mount_helper_unix.go | 1 - mount/mount_helper_unix_test.go | 1 - mount/mount_helper_windows.go | 1 - mount/mount_helper_windows_test.go | 1 - mount/mount_linux.go | 1 - mount/mount_linux_test.go | 1 - mount/mount_unsupported.go | 1 - mount/mount_windows.go | 1 - mount/mount_windows_test.go | 1 - nsenter/nsenter.go | 1 - nsenter/nsenter_test.go | 1 - nsenter/nsenter_unsupported.go | 1 - 14 files changed, 14 deletions(-) diff --git a/inotify/inotify_linux.go b/inotify/inotify_linux.go index 2b9eabbd..8b024c11 100644 --- a/inotify/inotify_linux.go +++ b/inotify/inotify_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux // Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style diff --git a/inotify/inotify_linux_test.go b/inotify/inotify_linux_test.go index 31d448a5..cb9fe9f0 100644 --- a/inotify/inotify_linux_test.go +++ b/inotify/inotify_linux_test.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux // Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style diff --git a/mount/mount_helper_unix.go b/mount/mount_helper_unix.go index 966ddc38..1d786b00 100644 --- a/mount/mount_helper_unix.go +++ b/mount/mount_helper_unix.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2019 The Kubernetes Authors. diff --git a/mount/mount_helper_unix_test.go b/mount/mount_helper_unix_test.go index e63e30ae..a1a7892b 100644 --- a/mount/mount_helper_unix_test.go +++ b/mount/mount_helper_unix_test.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2019 The Kubernetes Authors. diff --git a/mount/mount_helper_windows.go b/mount/mount_helper_windows.go index 72d45ab5..3fc6e984 100644 --- a/mount/mount_helper_windows.go +++ b/mount/mount_helper_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2019 The Kubernetes Authors. diff --git a/mount/mount_helper_windows_test.go b/mount/mount_helper_windows_test.go index 20dea07e..4987c02b 100644 --- a/mount/mount_helper_windows_test.go +++ b/mount/mount_helper_windows_test.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/mount/mount_linux.go b/mount/mount_linux.go index a2bd3a96..e77f4200 100644 --- a/mount/mount_linux.go +++ b/mount/mount_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2014 The Kubernetes Authors. diff --git a/mount/mount_linux_test.go b/mount/mount_linux_test.go index 64a6a219..0c99f53b 100644 --- a/mount/mount_linux_test.go +++ b/mount/mount_linux_test.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2014 The Kubernetes Authors. diff --git a/mount/mount_unsupported.go b/mount/mount_unsupported.go index fd17ef46..63cce9c9 100644 --- a/mount/mount_unsupported.go +++ b/mount/mount_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2014 The Kubernetes Authors. diff --git a/mount/mount_windows.go b/mount/mount_windows.go index 787e1af1..c8f3cfcb 100644 --- a/mount/mount_windows.go +++ b/mount/mount_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/mount/mount_windows_test.go b/mount/mount_windows_test.go index 8005e89c..a316e278 100644 --- a/mount/mount_windows_test.go +++ b/mount/mount_windows_test.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/nsenter/nsenter.go b/nsenter/nsenter.go index 5b86e708..806f7f3c 100644 --- a/nsenter/nsenter.go +++ b/nsenter/nsenter.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2017 The Kubernetes Authors. diff --git a/nsenter/nsenter_test.go b/nsenter/nsenter_test.go index 94ec5323..8cccfc2b 100644 --- a/nsenter/nsenter_test.go +++ b/nsenter/nsenter_test.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. diff --git a/nsenter/nsenter_unsupported.go b/nsenter/nsenter_unsupported.go index 8b56e91d..957aac0d 100644 --- a/nsenter/nsenter_unsupported.go +++ b/nsenter/nsenter_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2017 The Kubernetes Authors. From f47727f9de0577331aef3d5f1bb354d2bc6cd5c3 Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Mon, 6 Jul 2026 13:38:44 +0200 Subject: [PATCH 06/10] Use slices.Contains or .ContainsFunc instead of open-coding Signed-off-by: Stephen Kitt --- mount/mount.go | 13 ++----------- mount/mount_linux.go | 18 ++---------------- set/set.go | 8 ++------ 3 files changed, 6 insertions(+), 33 deletions(-) diff --git a/mount/mount.go b/mount/mount.go index 5e49ccf3..0883a895 100644 --- a/mount/mount.go +++ b/mount/mount.go @@ -23,6 +23,7 @@ import ( "fmt" "os" "path/filepath" + "slices" "strings" utilexec "k8s.io/utils/exec" @@ -311,17 +312,7 @@ func MakeBindOptsSensitive(options []string, sensitiveOptions []string) (bool, [ } func checkForNetDev(options []string, sensitiveOptions []string) bool { - for _, option := range options { - if option == "_netdev" { - return true - } - } - for _, sensitiveOption := range sensitiveOptions { - if sensitiveOption == "_netdev" { - return true - } - } - return false + return slices.Contains(options, "_netdev") || slices.Contains(sensitiveOptions, "_netdev") } // PathWithinBase checks if give path is within given base directory. diff --git a/mount/mount_linux.go b/mount/mount_linux.go index e77f4200..c4c17de2 100644 --- a/mount/mount_linux.go +++ b/mount/mount_linux.go @@ -23,6 +23,7 @@ import ( "os" "os/exec" "path/filepath" + "slices" "strconv" "strings" "syscall" @@ -316,22 +317,7 @@ func (mounter *SafeFormatAndMount) checkAndRepairFilesystem(source string) error // formatAndMount uses unix utils to format and mount the given disk func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error { - readOnly := false - for _, option := range options { - if option == "ro" { - readOnly = true - break - } - } - if !readOnly { - // Check sensitiveOptions for ro - for _, option := range sensitiveOptions { - if option == "ro" { - readOnly = true - break - } - } - } + readOnly := slices.Contains(options, "ro") || slices.Contains(sensitiveOptions, "ro") options = append(options, "defaults") mountErrorValue := UnknownMountError diff --git a/set/set.go b/set/set.go index 446c1373..d52e6d97 100644 --- a/set/set.go +++ b/set/set.go @@ -17,6 +17,7 @@ limitations under the License. package set import ( + "slices" "sort" ) @@ -85,12 +86,7 @@ func (s Set[E]) HasAll(items ...E) bool { // HasAny returns true if any items are contained in the set. func (s Set[E]) HasAny(items ...E) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false + return slices.ContainsFunc(items, s.Has) } // Union returns a new set which includes items in either s1 or s2. From b1db2ff3f16e0da686726e6c759bc0bc61dd5b1d Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Mon, 6 Jul 2026 13:39:03 +0200 Subject: [PATCH 07/10] Switch to reflect.TypeFor instead of TypeOf Signed-off-by: Stephen Kitt --- third_party/forked/golang/reflect/deep_equal.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/third_party/forked/golang/reflect/deep_equal.go b/third_party/forked/golang/reflect/deep_equal.go index e8403e79..495b471d 100644 --- a/third_party/forked/golang/reflect/deep_equal.go +++ b/third_party/forked/golang/reflect/deep_equal.go @@ -52,8 +52,7 @@ func (e Equalities) AddFunc(eqFunc any) error { if ft.In(0) != ft.In(1) { return fmt.Errorf("expected arg 1 and 2 to have same type, but got %v", ft) } - var forReturnType bool - boolType := reflect.TypeOf(forReturnType) + boolType := reflect.TypeFor[bool]() if ft.Out(0) != boolType { return fmt.Errorf("expected bool return, got: %v", ft) } From f9676c33576e7bafa445fffbaca02211ea635d6c Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Mon, 6 Jul 2026 13:54:59 +0200 Subject: [PATCH 08/10] Bump to Go 1.25 This is the version used by the oldest Kubernetes branch we still support (1.34). golangci-lint 2.4.0 is the oldest version supporting Go 1.25. This requires bumping golangci-lint-action and changing the command-line; gofmt is disabled because it's a formatter, not a linter (and golangci-lint now distinguishes between the two), and revive is disabled because it mandates more documentation. This should be addressed later. Building with Go 1.25 requires fixing a couple of non-constant format string stragglers. Signed-off-by: Stephen Kitt --- .github/workflows/test.yml | 14 +++++++------- Makefile | 6 +++--- go.mod | 2 +- mount/mount_windows_test.go | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c72e88ea..10aa7ada 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ jobs: build: strategy: matrix: - go-version: [1.23.x, 1.25.x] + go-version: [1.25.x, 1.26.x] platform: [windows-latest] runs-on: ${{ matrix.platform }} steps: @@ -24,7 +24,7 @@ jobs: test: strategy: matrix: - go-version: [1.23.x, 1.25.x] + go-version: [1.25.x, 1.26.x] platform: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: @@ -40,7 +40,7 @@ jobs: verify-go-directive: strategy: matrix: - go-version: [1.23.x, 1.25.x] + go-version: [1.25.x, 1.26.x] platform: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: @@ -59,14 +59,14 @@ jobs: - name: Install Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: - go-version: v1.23 + go-version: v1.25 - name: Checkout code uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Lint - uses: golangci/golangci-lint-action@55c2c1448f86e01eaae002a5a3a9624417608d84 # v6 + uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0 with: - version: v1.60.1 - args: --disable-all -v -E govet -E misspell -E gofmt -E ineffassign -E revive + version: v2.4.0 + args: -v --enable-only govet,misspell,ineffassign apidiff: runs-on: ubuntu-latest if: github.base_ref diff --git a/Makefile b/Makefile index b758a8a4..8d7cf8aa 100644 --- a/Makefile +++ b/Makefile @@ -39,9 +39,9 @@ vet: update-fmt: gofmt -s -w . -# We set the maximum version of the go directive as 1.23 here +# We set the maximum version of the go directive as 1.25 here # because the oldest go directive that exists on our supported -# release branches in k/k is 1.23. +# release branches in k/k is 1.25. .PHONY: verify-go-directive verify-go-directive: - ./hack/verify-go-directive.sh -g 1.23 + ./hack/verify-go-directive.sh -g 1.25 diff --git a/go.mod b/go.mod index 29ee77db..733255d7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module k8s.io/utils -go 1.23 +go 1.25 require ( github.com/davecgh/go-spew v1.1.1 diff --git a/mount/mount_windows_test.go b/mount/mount_windows_test.go index a316e278..b1bfe9cc 100644 --- a/mount/mount_windows_test.go +++ b/mount/mount_windows_test.go @@ -207,7 +207,7 @@ func TestIsLikelyNotMountPoint(t *testing.T) { for _, test := range tests { base, err := ioutil.TempDir("", test.fileName) if err != nil { - t.Fatalf(err.Error()) + t.Fatal(err.Error()) } defer os.RemoveAll(base) @@ -292,7 +292,7 @@ func TestFormatAndMount(t *testing.T) { } base, err := ioutil.TempDir("", test.device) if err != nil { - t.Fatalf(err.Error()) + t.Fatal(err.Error()) } defer os.RemoveAll(base) From 5a293f62227e8bcbd2562c817a83b2c71b1713f4 Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Mon, 6 Jul 2026 13:55:49 +0200 Subject: [PATCH 09/10] Switch to strings.SplitSeq instead of strings.Split Signed-off-by: Stephen Kitt --- cpuset/cpuset.go | 4 +--- mount/mount_helper_unix.go | 2 +- mount/mount_linux.go | 6 ++---- net/ebtables/ebtables.go | 2 +- strings/line_delimiter.go | 3 +-- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/cpuset/cpuset.go b/cpuset/cpuset.go index 52912d95..a29447b8 100644 --- a/cpuset/cpuset.go +++ b/cpuset/cpuset.go @@ -210,9 +210,7 @@ func Parse(s string) (CPUSet, error) { // Split CPU list string: // "0-5,34,46-48" => ["0-5", "34", "46-48"] - ranges := strings.Split(s, ",") - - for _, r := range ranges { + for r := range strings.SplitSeq(s, ",") { boundaries := strings.SplitN(r, "-", 2) if len(boundaries) == 1 { // Handle ranges that consist of only one element like "34". diff --git a/mount/mount_helper_unix.go b/mount/mount_helper_unix.go index 1d786b00..6e10fd07 100644 --- a/mount/mount_helper_unix.go +++ b/mount/mount_helper_unix.go @@ -92,7 +92,7 @@ func ParseMountInfo(filename string) ([]MountInfo, error) { contentStr := string(content) infos := []MountInfo{} - for _, line := range strings.Split(contentStr, "\n") { + for line := range strings.SplitSeq(contentStr, "\n") { if line == "" { // the last split() item is empty string following the last \n continue diff --git a/mount/mount_linux.go b/mount/mount_linux.go index c4c17de2..2c2f6470 100644 --- a/mount/mount_linux.go +++ b/mount/mount_linux.go @@ -409,8 +409,7 @@ func (mounter *SafeFormatAndMount) GetDiskFormat(disk string) (string, error) { var fstype, pttype string - lines := strings.Split(output, "\n") - for _, l := range lines { + for l := range strings.SplitSeq(output, "\n") { if len(l) <= 0 { // Ignore empty line. continue @@ -449,8 +448,7 @@ func ListProcMounts(mountFilePath string) ([]MountPoint, error) { func parseProcMounts(content []byte) ([]MountPoint, error) { out := []MountPoint{} - lines := strings.Split(string(content), "\n") - for _, line := range lines { + for line := range strings.SplitSeq(string(content), "\n") { if line == "" { // the last split() item is empty string following the last \n continue diff --git a/net/ebtables/ebtables.go b/net/ebtables/ebtables.go index 88b6e3b3..ef84454e 100644 --- a/net/ebtables/ebtables.go +++ b/net/ebtables/ebtables.go @@ -202,7 +202,7 @@ func (runner *runner) EnsureChain(table Table, chain Chain) (bool, error) { // WARNING: checkIfRuleExists expects the input args matches the format and sequence of ebtables list output func checkIfRuleExists(listChainOutput string, args ...string) bool { rule := strings.Join(args, " ") - for _, line := range strings.Split(listChainOutput, "\n") { + for line := range strings.SplitSeq(listChainOutput, "\n") { if strings.TrimSpace(line) == rule { return true } diff --git a/strings/line_delimiter.go b/strings/line_delimiter.go index 8907869c..749500b9 100644 --- a/strings/line_delimiter.go +++ b/strings/line_delimiter.go @@ -45,8 +45,7 @@ func (ld *LineDelimiter) Write(buf []byte) (n int, err error) { // Flush all lines up until now. This will assume insert a linebreak at the current point of the stream. func (ld *LineDelimiter) Flush() (err error) { - lines := strings.Split(ld.buf.String(), "\n") - for _, line := range lines { + for line := range strings.SplitSeq(ld.buf.String(), "\n") { if _, err = ld.output.Write(ld.delimiter); err != nil { return } From 39406a26ec6a66d2938e3ac7f545b84f52ece94e Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Mon, 6 Jul 2026 13:56:03 +0200 Subject: [PATCH 10/10] Switch to wg.Go instead of open-coding Signed-off-by: Stephen Kitt --- third_party/forked/golang/btree/btree_test.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/third_party/forked/golang/btree/btree_test.go b/third_party/forked/golang/btree/btree_test.go index 52154e84..d4aab529 100644 --- a/third_party/forked/golang/btree/btree_test.go +++ b/third_party/forked/golang/btree/btree_test.go @@ -667,13 +667,11 @@ func TestCloneConcurrentOperations(t *testing.T) { toRemove := intRange(cloneTestSize, false)[cloneTestSize/2:] for i := 0; i < len(trees)/2; i++ { tree := trees[i] - wg.Add(1) - go func() { + wg.Go(func() { for _, item := range toRemove { tree.Delete(item) } - wg.Done() - }() + }) } wg.Wait() t.Log("Checking all values again")