refactor: update Go loops to `for range` syntax and enhance `golangci.yml` configuration with new linters and errcheck exclusions.
cognitive-glitch committed
Dec 9, 2025 at 12:08 UTC
9a312bb2028599658e41680126b39e96aa5b0730
9 files changed
+84
-111
.golangci.yml
+72
-7
@@ -1,17 +1,82 @@
1
version: "2"
2
3
+run:
4
+ tests: true
5
+ # Go 1.25+ will handle modules impeccably; ensure the linter knows the version.
6
+ go: "1.25"
7
+
8
linters:
4
- # Default set of linters.
5
- # The value can be:
6
- # - `standard`: https://golangci-lint.run/docs/linters/#enabled-by-default
7
- # - `all`: enables all linters by default.
8
- # - `none`: disables all linters by default.
9
- # - `fast`: enables only linters considered as "fast" (`golangci-lint help linters --json | jq '[ .[] | select(.fast==true) ] | map(.name)'`).
10
- # Default: standard
9
default: standard
10
11
+ enable:
12
+ # --- The Essentials (Bugs & Correctness) ---
13
+ - govet # Standard vet
14
+ - errcheck # Unchecked errors are fatal
15
+ - staticcheck # Dominant static analysis
16
+ - gochecknoglobals # Disallows global variables (improves concurrency safety)
17
+ - gochecknoinits # Disallows init functions (can have concurrency implications)
18
+ - gocritic # General linter with many checks, including some concurrency-related ones like deferInLoop
19
+ - containedctx # Ensures context.Context is the first argument (improves context propagation)
20
+
21
+ # --- The Dark Arts (Performance & Concurrency) ---
22
+ - prealloc # Encourages slice pre-allocation (critical for low latency)
23
+ - bodyclose # Ensures HTTP response bodies are closed
24
+ - noctx # HTTP requests must have context (prevents goroutine leaks)
25
+ - copyloopvar # Detects loop variable copying (Modern Go replacement for exportloopref)
26
+ - intrange # Suggests using newer `for i := range n` syntax (Go 1.22+)
27
+
28
exclusions:
29
rules:
30
- linters:
31
- errcheck
32
source: "^\\s*defer\\s+"
33
+
34
+ settings:
35
+ errcheck:
36
+ # FALSE: Allows you to explicitly ignore an error using `_ = func()`
37
+ # If true, `_ = func()` is still a violation.
38
+ check-blank: false
39
+
40
+ # FALSE: Does not force checking type assertion results (v, ok := x.(T))
41
+ check-type-assertions: false
42
+
43
+ # List of functions to exclude from checking.
44
+ # These are the most common sources of "noise" in standard Go development.
45
+ exclude-functions:
46
+ - fmt.Printf
47
+ - fmt.Println
48
+ - fmt.Print
49
+ - fmt.Fprintf
50
+ - fmt.Fprint
51
+ - fmt.Fprintln
52
+ - fmt.Sprintf # Rarely fails unless OOM
53
+ - os.Unsetenv # Usually safe to ignore
54
+ - encoding/json.Marshal # Safe ONLY if you trust the struct tags/types
55
+ - encoding/json.Unmarshal # Safe ONLY if you trust the input data
56
+ - encoding/json.NewEncoder # Encoder setup
57
+ - encoding/json.NewDecoder # Decoder setup
58
+ - strings.Builder.WriteString # Writes to memory; usually safe
59
+ - strings.Builder.Write # Writes to memory; usually safe
60
+ - bytes.Buffer.Write # Writes to memory; usually safe
61
+ - bytes.Buffer.WriteString # Writes to memory; usually safe
62
+ - io.Copy # Standard I/O operation
63
+ - context.WithTimeout # Context creation
64
+ - context.WithCancel # Context creation
65
+ - log.Printf # Standard logging
66
+ - log.Println # Standard logging
67
+ - log.Print # Standard logging
68
+ - time.Now # Time retrieval
69
+ - time.Sleep # Time operations
70
+ - sync.Mutex.Lock # Mutex operations
71
+ - sync.Mutex.Unlock # Mutex operations
72
+ - sync.RWMutex.RLock # RWMutex operations
73
+ - sync.RWMutex.RUnlock # RWMutex operations
74
+ - atomic.AddInt64 # Atomic operations
75
+ - atomic.StoreInt64 # Atomic operations
76
+ - atomic.LoadInt64 # Atomic operations
77
+ - rand.Read # Cryptographically secure random
78
+ - crypto/rand.Read # Secure random source
79
+
80
+issues:
81
+ max-issues-per-linter: 0
82
+ max-same-issues: 0
cmd/relay-server/view.go
+1
-1
@@ -558,7 +558,7 @@ func convertLeaseEntriesToRows(serv *portal.RelayServer) []leaseRow {
558
Metadata: lease.Metadata,
559
}
560
561
- if row.Hide != true {
561
+ if !row.Hide {
562
rows = append(rows, row)
563
}
564
}
cmd/vanity-id/main.go
+1
-1
@@ -44,7 +44,7 @@ func main() {
44
)
45
46
// Start worker goroutines
47
- for i := 0; i < *workers; i++ {
47
+ for range *workers {
48
wg.Add(1)
49
go worker(*prefix, &attempts, &found, results, &wg, *maxResults, ctx)
50
}
golangci.yml
deleted
-92
@@ -1,92 +0,0 @@
1
-version: "2"
2
-
3
-run:
4
- tests: true
5
- # Go 1.25+ will handle modules impeccably; ensure the linter knows the version.
6
- go: "1.25"
7
-
8
-linters:
9
- default: standard
10
-
11
- enable:
12
- # --- The Essentials (Bugs & Correctness) ---
13
- - govet # Standard vet
14
- - errcheck # Unchecked errors are fatal
15
- - staticcheck # Dominant static analysis
16
- - gochecknoglobals # Disallows global variables (improves concurrency safety)
17
- - gochecknoinits # Disallows init functions (can have concurrency implications)
18
- - gocritic # General linter with many checks, including some concurrency-related ones like deferInLoop
19
- - containedctx # Ensures context.Context is the first argument (improves context propagation)
20
-
21
- # --- The Dark Arts (Performance & Concurrency) ---
22
- - prealloc # Encourages slice pre-allocation (critical for low latency)
23
- - bodyclose # Ensures HTTP response bodies are closed
24
- - noctx # HTTP requests must have context (prevents goroutine leaks)
25
- - copyloopvar # Detects loop variable copying (Modern Go replacement for exportloopref)
26
- - intrange # Suggests using newer `for i := range n` syntax (Go 1.22+)
27
-
28
- # --- The Hygienists (Style & Formatting) ---
29
- - godot # Comments should end in a period
30
- - misspell # Fixes typos
31
- - whitespace # Detects leading and trailing whitespace
32
- - nolintlint # Forces documentation on why you are ignoring a linter
33
-
34
- # --- Cognitive Load ---
35
- - gocognit # Cognitive complexity (better than cyclomatic)
36
- - nestif # Detects deeply nested if-statements
37
-
38
- exclusions:
39
- rules:
40
- - linters:
41
- - errcheck
42
- source: "^\\s*defer\\s+"
43
-
44
- settings:
45
- errcheck:
46
- # FALSE: Allows you to explicitly ignore an error using `_ = func()`
47
- # If true, `_ = func()` is still a violation.
48
- check-blank: false
49
-
50
- # FALSE: Does not force checking type assertion results (v, ok := x.(T))
51
- check-type-assertions: false
52
-
53
- # List of functions to exclude from checking.
54
- # These are the most common sources of "noise" in standard Go development.
55
- exclude-functions:
56
- - fmt.Printf
57
- - fmt.Println
58
- - fmt.Print
59
- - fmt.Fprintf
60
- - fmt.Fprint
61
- - fmt.Fprintln
62
- - fmt.Sprintf # Rarely fails unless OOM
63
- - os.Unsetenv # Usually safe to ignore
64
- - encoding/json.Marshal # Safe ONLY if you trust the struct tags/types
65
- - encoding/json.Unmarshal # Safe ONLY if you trust the input data
66
- - encoding/json.NewEncoder # Encoder setup
67
- - encoding/json.NewDecoder # Decoder setup
68
- - strings.Builder.WriteString # Writes to memory; usually safe
69
- - strings.Builder.Write # Writes to memory; usually safe
70
- - bytes.Buffer.Write # Writes to memory; usually safe
71
- - bytes.Buffer.WriteString # Writes to memory; usually safe
72
- - io.Copy # Standard I/O operation
73
- - context.WithTimeout # Context creation
74
- - context.WithCancel # Context creation
75
- - log.Printf # Standard logging
76
- - log.Println # Standard logging
77
- - log.Print # Standard logging
78
- - time.Now # Time retrieval
79
- - time.Sleep # Time operations
80
- - sync.Mutex.Lock # Mutex operations
81
- - sync.Mutex.Unlock # Mutex operations
82
- - sync.RWMutex.RLock # RWMutex operations
83
- - sync.RWMutex.RUnlock # RWMutex operations
84
- - atomic.AddInt64 # Atomic operations
85
- - atomic.StoreInt64 # Atomic operations
86
- - atomic.LoadInt64 # Atomic operations
87
- - rand.Read # Cryptographically secure random
88
- - crypto/rand.Read # Secure random source
89
-
90
-issues:
91
- max-issues-per-linter: 0
92
- max-same-issues: 0
portal/core/cryptoops/handshaker.go
+1
-1
@@ -158,7 +158,7 @@ func (sc *SecureConnection) Write(p []byte) (int, error) {
158
159
const fragSize = maxRawPacketSize / 2
160
if len(p) > fragSize {
161
- for i := 0; i < (len(p)+fragSize-1)/fragSize; i++ {
161
+ for i := range / fragSize {
162
start := i * fragSize
163
end := min(start+fragSize, len(p))
164
_, err := sc.writeFragmentation(p[start:end])
portal/core/cryptoops/handshaker_test.go
+5
-5
@@ -346,13 +346,13 @@ func TestConcurrentWrites(t *testing.T) {
346
347
const numMessages = 100
348
messages := make([][]byte, numMessages)
349
- for i := 0; i < numMessages; i++ {
349
+ for i := range numMessages {
350
messages[i] = []byte{byte(i), byte(i >> 8)}
351
}
352
353
// Write concurrently from client
354
var writeWg sync.WaitGroup
355
- for i := 0; i < numMessages; i++ {
355
+ for i := range numMessages {
356
writeWg.Add(1)
357
go func(msg []byte) {
358
defer writeWg.Done()
@@ -363,7 +363,7 @@ func TestConcurrentWrites(t *testing.T) {
363
364
// Read all messages
365
received := make(map[string]bool)
366
- for i := 0; i < numMessages; i++ {
366
+ for range numMessages {
367
buf := make([]byte, 2)
368
_, err := io.ReadFull(serverSecure, buf)
369
if err != nil {
@@ -753,7 +753,7 @@ func BenchmarkHandshake(b *testing.B) {
753
serverCred, _ := NewCredential()
754
755
b.ResetTimer()
756
- for i := 0; i < b.N; i++ {
756
+ for range b.N {
757
clientConn, serverConn := pipeConn()
758
759
clientHandshaker := NewHandshaker(clientCred)
@@ -814,7 +814,7 @@ func BenchmarkEncryption(b *testing.B) {
814
b.ResetTimer()
815
b.SetBytes(int64(len(message)))
816
817
- for i := 0; i < b.N; i++ {
817
+ for range b.N {
818
clientSecure.Write(message)
819
}
820
portal/utils/randpool/randpool_test.go
+2
-2
@@ -38,14 +38,14 @@ func TestRandConcurrency(t *testing.T) {
38
// Just run a bunch of goroutines to trigger the pool and potential race conditions
39
// (though the fallback race is hard to trigger without fault injection)
40
done := make(chan bool)
41
- for i := 0; i < 100; i++ {
41
+ for range 100 {
42
go func() {
43
buf := make([]byte, 32)
44
Rand(buf)
45
done <- true
46
}()
47
}
48
- for i := 0; i < 100; i++ {
48
+ for range 100 {
49
<-done
50
}
51
}
sdk/sdk.go
+1
-1
@@ -302,7 +302,7 @@ func (g *Client) listenerWorker(server *connRelay) {
302
303
if !exists {
304
log.Warn().Str("lease_id", lease).Msg("[SDK] No listener found for lease, closing connection")
305
- incoming.SecureConnection.Close() // Close unused connection
305
+ incoming.Close() // Close unused connection
306
continue
307
}
308
sdk/sdk_e2e_test.go
+1
-1
@@ -278,7 +278,7 @@ func TestE2E_MultipleConnections(t *testing.T) {
278
log.Info().Int("count", numConnections).Msg("[TEST] Testing multiple concurrent connections")
279
280
for i := 0; i < numConnections; i++ {
281
- i := i
281
+
282
go func() {
283
log.Debug().Int("conn_num", i).Msg("[TEST] Starting connection")
284