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