Skip to content

Commit 4be9afb

Browse files
authored
Merge pull request #6086 from thaJeztah/golangci_tweaks
golangci-lint: enable more linters, and some minor linting fixes
2 parents 68ef98d + 9d027df commit 4be9afb

File tree

9 files changed

+90
-74
lines changed

9 files changed

+90
-74
lines changed

.golangci.yml

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,49 @@ formatters:
2626

2727
linters:
2828
enable:
29+
- asasalint # Detects "[]any" used as argument for variadic "func(...any)".
2930
- bodyclose
30-
- copyloopvar # Detects places where loop variables are copied.
31+
- copyloopvar # Detects places where loop variables are copied.
3132
- depguard
32-
- dogsled
33-
- dupword # Detects duplicate words.
34-
- durationcheck
33+
- dogsled # Detects assignments with too many blank identifiers.
34+
- dupword # Detects duplicate words.
35+
- durationcheck # Detect cases where two time.Duration values are being multiplied in possibly erroneous ways.
3536
- errcheck
36-
- errchkjson
37+
- errchkjson # Detects unsupported types passed to json encoding functions and reports if checks for the returned error can be omitted.
38+
- exhaustive # Detects missing options in enum switch statements.
39+
- exptostd # Detects functions from golang.org/x/exp/ that can be replaced by std functions.
40+
- fatcontext # Detects nested contexts in loops and function literals.
3741
- forbidigo
38-
- gocritic # Metalinter; detects bugs, performance, and styling issues.
42+
- gocheckcompilerdirectives # Detects invalid go compiler directive comments (//go:).
43+
- gocritic # Metalinter; detects bugs, performance, and styling issues.
3944
- gocyclo
40-
- gosec # Detects security problems.
45+
- gosec # Detects security problems.
4146
- govet
47+
- iface # Detects incorrect use of interfaces. Currently only used for "identical" interfaces in the same package.
48+
- importas # Enforces consistent import aliases.
4249
- ineffassign
43-
- importas # Enforces consistent import aliases.
44-
- misspell # Detects commonly misspelled English words in comments.
45-
- nakedret # Detects uses of naked returns.
46-
- nilerr # Detects code that returns nil even if it checks that the error is not nil.
47-
- nolintlint # Detects ill-formed or insufficient nolint directives.
48-
- perfsprint # Detects fmt.Sprintf uses that can be replaced with a faster alternative.
49-
- prealloc # Detects slice declarations that could potentially be pre-allocated.
50-
- predeclared # Detects code that shadows one of Go's predeclared identifiers
51-
- reassign
52-
- revive # Metalinter; drop-in replacement for golint.
50+
- makezero # Finds slice declarations with non-zero initial length.
51+
- mirror # Detects wrong mirror patterns of bytes/strings usage.
52+
- misspell # Detects commonly misspelled English words in comments.
53+
- nakedret # Detects uses of naked returns.
54+
- nilnesserr # Detects returning nil errors. It combines the features of nilness and nilerr,
55+
- nosprintfhostport # Detects misuse of Sprintf to construct a host with port in a URL.
56+
- nolintlint # Detects ill-formed or insufficient nolint directives.
57+
- perfsprint # Detects fmt.Sprintf uses that can be replaced with a faster alternative.
58+
- prealloc # Detects slice declarations that could potentially be pre-allocated.
59+
- predeclared # Detects code that shadows one of Go's predeclared identifiers
60+
- reassign # Detects reassigning a top-level variable in another package.
61+
- revive # Metalinter; drop-in replacement for golint.
62+
- spancheck # Detects mistakes with OpenTelemetry/Census spans.
5363
- staticcheck
54-
- thelper # Detects test helpers without t.Helper().
55-
- tparallel # Detects inappropriate usage of t.Parallel().
56-
- unconvert # Detects unnecessary type conversions.
64+
- thelper # Detects test helpers without t.Helper().
65+
- tparallel # Detects inappropriate usage of t.Parallel().
66+
- unconvert # Detects unnecessary type conversions.
5767
- unparam
5868
- unused
59-
- usestdlibvars
60-
- usetesting # Reports uses of functions with replacement inside the testing package.
61-
- wastedassign
69+
- usestdlibvars # Detects the possibility to use variables/constants from the Go standard library.
70+
- usetesting # Reports uses of functions with replacement inside the testing package.
71+
- wastedassign # Detects wasted assignment statements.
6272

6373
disable:
6474
- errcheck
@@ -132,9 +142,7 @@ linters:
132142
staticcheck:
133143
checks:
134144
- all
135-
- -QF1008 # Omit embedded fields from selector expression
136-
- -ST1020 # The documentation of an exported function should start with the function’s name
137-
- -ST1022 # The documentation of an exported variable or constant should start with variable’s name
145+
- -QF1008 # Omit embedded fields from selector expression; https://staticcheck.dev/docs/checks/#QF1008
138146

139147
revive:
140148
rules:
@@ -159,8 +167,8 @@ linters:
159167
# (unlike the "include" option), the "exclude" option does not take exclusion
160168
# ID's.
161169
#
162-
# These exclusion patterns are copied from the default excluses at:
163-
# https://github.com/golangci/golangci-lint/blob/v1.44.0/pkg/config/issues.go#L10-L104
170+
# These exclusion patterns are copied from the default excludes at:
171+
# https://github.com/golangci/golangci-lint/blob/v1.61.0/pkg/config/issues.go#L11-L104
164172
#
165173
# The default list of exclusions can be found at:
166174
# https://golangci-lint.run/usage/false-positives/#default-exclusions
@@ -207,6 +215,12 @@ linters:
207215
linters:
208216
- govet
209217

218+
# Ignore for cli/command/formatter/tabwriter, which is forked from go stdlib, so we want to align with it.
219+
- text: '^(ST1020|ST1022): comment on exported'
220+
path: "cli/command/formatter/tabwriter"
221+
linters:
222+
- staticcheck
223+
210224
# Log a warning if an exclusion rule is unused.
211225
# Default: false
212226
warn-unused: true

cli-plugins/manager/manager.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func addPluginCandidatesFromDir(res map[string][]string, d string) {
8181
return
8282
}
8383
for _, dentry := range dentries {
84-
switch dentry.Type() & os.ModeType {
84+
switch dentry.Type() & os.ModeType { //nolint:exhaustive,nolintlint // no need to include all possible file-modes in this list
8585
case 0, os.ModeSymlink:
8686
// Regular file or symlink, keep going
8787
default:

cli/command/container/formatter_stats_test.go

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ container2 -- --
148148
`,
149149
},
150150
}
151-
stats := []StatsEntry{
151+
entries := []StatsEntry{
152152
{
153153
Container: "container1",
154154
CPUPercentage: 20,
@@ -181,7 +181,7 @@ container2 -- --
181181
t.Run(string(tc.context.Format), func(t *testing.T) {
182182
var out bytes.Buffer
183183
tc.context.Output = &out
184-
err := statsFormatWrite(tc.context, stats, "windows", false)
184+
err := statsFormatWrite(tc.context, entries, "windows", false)
185185
if err != nil {
186186
assert.Error(t, err, tc.expected)
187187
} else {
@@ -273,45 +273,46 @@ func TestContainerStatsContextWriteWithNoStatsWindows(t *testing.T) {
273273
}
274274

275275
func TestContainerStatsContextWriteTrunc(t *testing.T) {
276-
var out bytes.Buffer
277-
278-
contexts := []struct {
276+
tests := []struct {
277+
doc string
279278
context formatter.Context
280279
trunc bool
281280
expected string
282281
}{
283282
{
284-
formatter.Context{
283+
doc: "non-truncated",
284+
context: formatter.Context{
285285
Format: "{{.ID}}",
286-
Output: &out,
287286
},
288-
false,
289-
"b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc\n",
287+
expected: "b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc\n",
290288
},
291289
{
292-
formatter.Context{
290+
doc: "truncated",
291+
context: formatter.Context{
293292
Format: "{{.ID}}",
294-
Output: &out,
295293
},
296-
true,
297-
"b95a83497c91\n",
294+
trunc: true,
295+
expected: "b95a83497c91\n",
298296
},
299297
}
300298

301-
for _, context := range contexts {
302-
statsFormatWrite(context.context, []StatsEntry{{ID: "b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc"}}, "linux", context.trunc)
303-
assert.Check(t, is.Equal(context.expected, out.String()))
304-
// Clean buffer
305-
out.Reset()
299+
for _, tc := range tests {
300+
t.Run(tc.doc, func(t *testing.T) {
301+
var out bytes.Buffer
302+
tc.context.Output = &out
303+
err := statsFormatWrite(tc.context, []StatsEntry{{ID: "b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc"}}, "linux", tc.trunc)
304+
assert.NilError(t, err)
305+
assert.Check(t, is.Equal(tc.expected, out.String()))
306+
})
306307
}
307308
}
308309

309310
func BenchmarkStatsFormat(b *testing.B) {
310311
b.ReportAllocs()
311-
stats := genStats()
312+
entries := genStats()
312313

313314
for i := 0; i < b.N; i++ {
314-
for _, s := range stats {
315+
for _, s := range entries {
315316
_ = s.CPUPerc()
316317
_ = s.MemUsage()
317318
_ = s.MemPerc()
@@ -334,9 +335,9 @@ func genStats() []statsContext {
334335
NetworkTx: 987.654321,
335336
PidsCurrent: 123456789,
336337
}}
337-
stats := make([]statsContext, 100)
338-
for i := 0; i < 100; i++ {
339-
stats = append(stats, entry)
338+
entries := make([]statsContext, 0, 100)
339+
for range 100 {
340+
entries = append(entries, entry)
340341
}
341-
return stats
342+
return entries
342343
}

cli/command/formatter/displayutils.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ func charWidth(r rune) int {
2020
switch width.LookupRune(r).Kind() {
2121
case width.EastAsianWide, width.EastAsianFullwidth:
2222
return 2
23+
case width.Neutral, width.EastAsianAmbiguous, width.EastAsianNarrow, width.EastAsianHalfwidth:
24+
return 1
2325
default:
2426
return 1
2527
}

cli/command/swarm/ca_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func writeFile(data string) (string, error) {
6969
if err != nil {
7070
return "", err
7171
}
72-
_, err = tmpfile.Write([]byte(data))
72+
_, err = tmpfile.WriteString(data)
7373
if err != nil {
7474
return "", err
7575
}

cli/command/swarm/unlock.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,18 @@ func runUnlock(ctx context.Context, dockerCli command.Cli) error {
5050
return errors.New("Error: This node is not part of a swarm")
5151
case swarm.LocalNodeStateLocked:
5252
break
53-
default:
53+
case swarm.LocalNodeStatePending, swarm.LocalNodeStateActive, swarm.LocalNodeStateError:
5454
return errors.New("Error: swarm is not locked")
5555
}
5656

5757
key, err := readKey(dockerCli.In(), "Enter unlock key: ")
5858
if err != nil {
5959
return err
6060
}
61-
req := swarm.UnlockRequest{
62-
UnlockKey: key,
63-
}
6461

65-
return client.SwarmUnlock(ctx, req)
62+
return client.SwarmUnlock(ctx, swarm.UnlockRequest{
63+
UnlockKey: key,
64+
})
6665
}
6766

6867
func readKey(in *streams.In, prompt string) (string, error) {

dockerfiles/Dockerfile.lint

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
ARG GO_VERSION=1.24.3
44
ARG ALPINE_VERSION=3.21
5-
ARG GOLANGCI_LINT_VERSION=v2.1.2
5+
ARG GOLANGCI_LINT_VERSION=v2.1.5
66

77
FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint
88

e2e/cli-plugins/socket_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func TestPluginSocketBackwardsCompatible(t *testing.T) {
5858

5959
ptmx, err := pty.Start(command)
6060
assert.NilError(t, err, "failed to launch command with fake TTY")
61-
_, _ = ptmx.Write([]byte("hello!"))
61+
_, _ = ptmx.WriteString("hello!")
6262

6363
done := make(chan error)
6464
go func() {

opts/hosts_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package opts
22

33
import (
4-
"fmt"
4+
"net"
55
"testing"
66

77
"gotest.tools/v3/assert"
@@ -25,13 +25,13 @@ func TestParseHost(t *testing.T) {
2525
"fd://something": "fd://something",
2626
"tcp://host:": "tcp://host:" + defaultHTTPPort,
2727
"tcp://": defaultTCPHost,
28-
"tcp://:2375": fmt.Sprintf("tcp://%s:%s", defaultHTTPHost, defaultHTTPPort),
29-
"tcp://:2376": fmt.Sprintf("tcp://%s:%s", defaultHTTPHost, defaultTLSHTTPPort),
28+
"tcp://:2375": "tcp://" + net.JoinHostPort(defaultHTTPHost, defaultHTTPPort),
29+
"tcp://:2376": "tcp://" + net.JoinHostPort(defaultHTTPHost, defaultTLSHTTPPort),
3030
"tcp://0.0.0.0:8080": "tcp://0.0.0.0:8080",
3131
"tcp://192.168.0.0:12000": "tcp://192.168.0.0:12000",
3232
"tcp://192.168:8080": "tcp://192.168:8080",
3333
"tcp://0.0.0.0:1234567890": "tcp://0.0.0.0:1234567890", // yeah it's valid :P
34-
" tcp://:7777/path ": fmt.Sprintf("tcp://%s:7777/path", defaultHTTPHost),
34+
" tcp://:7777/path ": "tcp://" + net.JoinHostPort(defaultHTTPHost, "7777") + "/path",
3535
"tcp://docker.com:2375": "tcp://docker.com:2375",
3636
"unix://": "unix://" + defaultUnixSocket,
3737
"unix://path/to/socket": "unix://path/to/socket",
@@ -70,11 +70,11 @@ func TestParseDockerDaemonHost(t *testing.T) {
7070
"[::1]:5555/path": "tcp://[::1]:5555/path",
7171
"[0:0:0:0:0:0:0:1]:": "tcp://[0:0:0:0:0:0:0:1]:2375",
7272
"[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path",
73-
":6666": fmt.Sprintf("tcp://%s:6666", defaultHTTPHost),
74-
":6666/path": fmt.Sprintf("tcp://%s:6666/path", defaultHTTPHost),
73+
":6666": "tcp://" + net.JoinHostPort(defaultHTTPHost, "6666"),
74+
":6666/path": "tcp://" + net.JoinHostPort(defaultHTTPHost, "6666") + "/path",
7575
"tcp://": defaultTCPHost,
76-
"tcp://:7777": fmt.Sprintf("tcp://%s:7777", defaultHTTPHost),
77-
"tcp://:7777/path": fmt.Sprintf("tcp://%s:7777/path", defaultHTTPHost),
76+
"tcp://:7777": "tcp://" + net.JoinHostPort(defaultHTTPHost, "7777"),
77+
"tcp://:7777/path": "tcp://" + net.JoinHostPort(defaultHTTPHost, "7777") + "/path",
7878
"unix:///run/docker.sock": "unix:///run/docker.sock",
7979
"unix://": "unix://" + defaultUnixSocket,
8080
"fd://": "fd://",
@@ -96,16 +96,16 @@ func TestParseDockerDaemonHost(t *testing.T) {
9696
}
9797

9898
func TestParseTCP(t *testing.T) {
99-
defaultHTTPHost := "tcp://127.0.0.1:2376"
99+
const defaultHost = "tcp://127.0.0.1:2376"
100100
invalids := map[string]string{
101101
"tcp:a.b.c.d": "",
102102
"tcp:a.b.c.d/path": "",
103103
"udp://127.0.0.1": "invalid proto, expected tcp: udp://127.0.0.1",
104104
"udp://127.0.0.1:2375": "invalid proto, expected tcp: udp://127.0.0.1:2375",
105105
}
106106
valids := map[string]string{
107-
"": defaultHTTPHost,
108-
"tcp://": defaultHTTPHost,
107+
"": defaultHost,
108+
"tcp://": defaultHost,
109109
"0.0.0.1:": "tcp://0.0.0.1:2376",
110110
"0.0.0.1:5555": "tcp://0.0.0.1:5555",
111111
"0.0.0.1:5555/path": "tcp://0.0.0.1:5555/path",
@@ -124,12 +124,12 @@ func TestParseTCP(t *testing.T) {
124124
"localhost:5555/path": "tcp://localhost:5555/path",
125125
}
126126
for invalidAddr, expectedError := range invalids {
127-
if addr, err := ParseTCPAddr(invalidAddr, defaultHTTPHost); err == nil || expectedError != "" && err.Error() != expectedError {
127+
if addr, err := ParseTCPAddr(invalidAddr, defaultHost); err == nil || expectedError != "" && err.Error() != expectedError {
128128
t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr)
129129
}
130130
}
131131
for validAddr, expectedAddr := range valids {
132-
if addr, err := ParseTCPAddr(validAddr, defaultHTTPHost); err != nil || addr != expectedAddr {
132+
if addr, err := ParseTCPAddr(validAddr, defaultHost); err != nil || addr != expectedAddr {
133133
t.Errorf("%v -> expected %v, got %v and addr %v", validAddr, expectedAddr, err, addr)
134134
}
135135
}

0 commit comments

Comments
 (0)