fix(cli): resolve golangci-lint errcheck and noctx violations
- Replace client.Head/client.Get with client.Do(http.NewRequestWithContext) to satisfy the noctx linter (3 fixes) - Add `_ =` to all best-effort Close/Remove/Rename calls to satisfy errcheck (13 fixes) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Yechan Kim committed
Apr 16, 2026 at 20:24 UTC
fb6ab8466abf0bd077c5bed26a87bd17673d7b50
2 files changed
+38
-22
cmd/portal-tunnel/update.go
+34
-18
@@ -1,6 +1,7 @@
1
package main
2
3
import (
4
+ "context"
5
"crypto/sha256"
6
"encoding/hex"
7
"fmt"
@@ -55,17 +56,17 @@ func runUpdateCommand(args []string) error {
56
if err != nil {
57
return fmt.Errorf("failed to create temp file: %w", err)
58
}
58
- defer os.Remove(tmpFile.Name())
59
+ defer func() { _ = os.Remove(tmpFile.Name()) }()
60
61
if err := downloadBinary(binURL, tmpFile); err != nil {
61
- tmpFile.Close()
62
+ _ = tmpFile.Close()
63
return fmt.Errorf("failed to download binary: %w", err)
64
}
65
if err := tmpFile.Sync(); err != nil {
65
- tmpFile.Close()
66
+ _ = tmpFile.Close()
67
return fmt.Errorf("failed to sync downloaded binary: %w", err)
68
}
68
- tmpFile.Close()
69
+ _ = tmpFile.Close()
70
71
checksumURL, _ := installer.OfficialAssetURL(slug, true)
72
if err := verifyChecksum(tmpFile.Name(), checksumURL); err != nil {
@@ -90,11 +91,16 @@ func detectLatestVersion(latestURL string) (string, error) {
91
},
92
}
93
93
- resp, err := client.Head(latestURL)
94
+ req, err := http.NewRequestWithContext(context.Background(), http.MethodHead, latestURL, nil)
95
+ if err != nil {
96
+ return "", fmt.Errorf("failed to create request: %w", err)
97
+ }
98
+
99
+ resp, err := client.Do(req)
100
if err != nil {
101
return "", fmt.Errorf("HEAD request failed: %w", err)
102
}
97
- resp.Body.Close()
103
+ _ = resp.Body.Close()
104
105
location := resp.Header.Get("Location")
106
if location == "" {
@@ -124,11 +130,16 @@ func detectLatestVersion(latestURL string) (string, error) {
130
func downloadBinary(binURL string, dst *os.File) error {
131
client := &http.Client{Timeout: 120 * time.Second}
132
127
- resp, err := client.Get(binURL)
133
+ req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, binURL, nil)
134
+ if err != nil {
135
+ return fmt.Errorf("failed to create request: %w", err)
136
+ }
137
+
138
+ resp, err := client.Do(req)
139
if err != nil {
140
return err
141
}
131
- defer resp.Body.Close()
142
+ defer func() { _ = resp.Body.Close() }()
143
144
if resp.StatusCode != http.StatusOK {
145
return fmt.Errorf("unexpected status %d", resp.StatusCode)
@@ -141,11 +152,16 @@ func downloadBinary(binURL string, dst *os.File) error {
152
func verifyChecksum(filePath, checksumURL string) error {
153
client := &http.Client{Timeout: 10 * time.Second}
154
144
- resp, err := client.Get(checksumURL)
155
+ req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, checksumURL, nil)
156
+ if err != nil {
157
+ return fmt.Errorf("failed to create request: %w", err)
158
+ }
159
+
160
+ resp, err := client.Do(req)
161
if err != nil {
162
return fmt.Errorf("failed to download checksum: %w", err)
163
}
148
- defer resp.Body.Close()
164
+ defer func() { _ = resp.Body.Close() }()
165
166
if resp.StatusCode != http.StatusOK {
167
return fmt.Errorf("checksum download returned status %d", resp.StatusCode)
@@ -165,7 +181,7 @@ func verifyChecksum(filePath, checksumURL string) error {
181
if err != nil {
182
return fmt.Errorf("failed to open downloaded file: %w", err)
183
}
168
- defer f.Close()
184
+ defer func() { _ = f.Close() }()
185
186
h := sha256.New()
187
if _, err := io.Copy(h, f); err != nil {
@@ -186,8 +202,8 @@ func checkWritable(dir string) error {
202
return fmt.Errorf("directory %s is not writable: %w", dir, err)
203
}
204
name := f.Name()
189
- f.Close()
190
- os.Remove(name)
205
+ _ = f.Close()
206
+ _ = os.Remove(name)
207
return nil
208
}
209
@@ -213,13 +229,13 @@ func replaceBinaryUnix(srcPath, dstPath string) error {
229
if err != nil {
230
return err
231
}
216
- defer src.Close()
232
+ defer func() { _ = src.Close() }()
233
234
dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
235
if err != nil {
236
return fmt.Errorf("failed to open destination: %w", err)
237
}
222
- defer dst.Close()
238
+ defer func() { _ = dst.Close() }()
239
240
if _, err := io.Copy(dst, src); err != nil {
241
return fmt.Errorf("failed to copy binary: %w", err)
@@ -231,7 +247,7 @@ func replaceBinaryWindows(srcPath, dstPath string) error {
247
oldPath := dstPath + ".old"
248
249
// Remove leftover .old file from a previous update.
234
- os.Remove(oldPath)
250
+ _ = os.Remove(oldPath)
251
252
// Rename the running binary out of the way, then move the new one in.
253
if err := os.Rename(dstPath, oldPath); err != nil {
@@ -240,11 +256,11 @@ func replaceBinaryWindows(srcPath, dstPath string) error {
256
257
if err := os.Rename(srcPath, dstPath); err != nil {
258
// Attempt to restore the old binary on failure.
243
- os.Rename(oldPath, dstPath)
259
+ _ = os.Rename(oldPath, dstPath)
260
return fmt.Errorf("failed to place new binary: %w", err)
261
}
262
263
// Best-effort cleanup of the old binary.
248
- os.Remove(oldPath)
264
+ _ = os.Remove(oldPath)
265
return nil
266
}
cmd/portal-tunnel/update_check.go
+4
-4
@@ -129,11 +129,11 @@ func writeUpdateCache(path string, c updateCache) {
129
tmpName := tmp.Name()
130
131
if _, err := tmp.Write(data); err != nil {
132
- tmp.Close()
133
- os.Remove(tmpName)
132
+ _ = tmp.Close()
133
+ _ = os.Remove(tmpName)
134
return
135
}
136
- tmp.Close()
136
+ _ = tmp.Close()
137
138
- os.Rename(tmpName, path)
138
+ _ = os.Rename(tmpName, path)
139
}