Skip to content

Commit e1e55ac

Browse files
committed
lint: transition to golangci-lint v2
Signed-off-by: Alex Aizman <[email protected]>
1 parent 808836b commit e1e55ac

File tree

29 files changed

+205
-162
lines changed

29 files changed

+205
-162
lines changed

.github/workflows/lint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ jobs:
2626
go-version: ${{ matrix.go-version }}
2727

2828
- name: Install `golangci-lint`
29-
uses: golangci/golangci-lint-action@v6
29+
uses: golangci/golangci-lint-action@v7
3030
with:
3131
# NOTE: See `lint-update-ci` target in Makefile.
32-
version: v1.64.5
32+
version: v2.0.2
3333
args: --timeout=30m
3434

3535
- name: Lint

.golangci.yml

Lines changed: 145 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
version: "2"
2+
13
linters:
2-
disable-all: true
4+
default: standard ## TODO: 'none|standard|all'; enable these 3 with rules
5+
disable:
6+
- errcheck
7+
- gosec
8+
# staticcheck
39
enable:
410
- asciicheck
511
- bodyclose
@@ -8,137 +14,173 @@ linters:
814
- depguard
915
- dogsled
1016
- dupl
17+
- dupword
1118
- durationcheck
12-
- errcheck
19+
# errcheck
1320
- fatcontext
14-
# gci
1521
- gochecksumtype
1622
- gocritic
17-
- gofmt
1823
- goheader
19-
- goimports
2024
- gomoddirectives
2125
- goprintffuncname
22-
- gosec
23-
- gosimple
26+
# gosec
2427
- govet
25-
# iface
2628
- importas
2729
- ineffassign
2830
- intrange
2931
- misspell
30-
# nakedret ## (TODO run/review periodically)
32+
# nakedret ## TODO (wtp)
3133
- nilnesserr
3234
- nolintlint
3335
- perfsprint
3436
- prealloc
3537
- protogetter
3638
- reassign
37-
# recvcheck
3839
- revive
3940
- staticcheck
4041
- testpackage
41-
- typecheck
4242
- unconvert
4343
- unparam
4444
- unused
4545
- usetesting
46+
- wastedassign
4647
- whitespace
4748

4849
# See: https://golangci-lint.run/usage/linters/
49-
linters-settings:
50-
## dupl: ## (TODO run/review periodically)
51-
## threshold: 100
52-
revive:
53-
ignore-generated-header: true
54-
severity: warning
55-
rules:
56-
# name: import-shadowing ## (e.g., url)
57-
# name: unhandled-error ## (TODO run/review periodically)
58-
# name: line-length-limit
59-
# name: dot-imports
60-
- name: blank-imports
61-
- name: context-as-argument
62-
- name: context-keys-type
63-
- name: early-return
64-
- name: error-naming
65-
- name: error-strings
66-
- name: exported
67-
- name: if-return
68-
- name: increment-decrement
69-
- name: indent-error-flow
70-
- name: modifies-value-receiver
71-
- name: package-comments
72-
- name: range
73-
- name: receiver-naming
74-
- name: redefines-builtin-id
75-
- name: string-of-int
76-
- name: superfluous-else
77-
- name: time-naming
78-
- name: var-naming
79-
- name: var-declaration
80-
- name: unconditional-recursion
81-
- name: unexported-naming
82-
- name: unexported-return
83-
- name: unnecessary-stmt
84-
- name: unreachable-code
85-
- name: unused-parameter
86-
- name: unused-receiver
87-
- name: waitgroup-by-value
88-
gci:
89-
skip-generated: true
90-
govet:
91-
enable-all: true
92-
disable:
93-
- fieldalignment # (TODO run/review periodically)
94-
- shadow # (e.g., proxyURL)
95-
errcheck:
96-
check-blank: true
97-
check-type-assertions: false
98-
gocritic:
99-
enabled-tags:
100-
- performance
101-
- style
102-
disabled-checks:
103-
- unnamedResult
104-
gosec:
105-
excludes: ## integer overflow; weak rand
106-
- G115
107-
- G402
108-
- G404
109-
prealloc:
110-
simple: true # Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them
111-
range-loops: true # Report preallocation suggestions on range loops, true by default
112-
for-loops: true # Report preallocation suggestions on for loops, false by default
113-
misspell:
114-
# Correct spellings using locale preferences for US or UK.
115-
# Default is to use a neutral variety of English.
116-
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
117-
locale: US
118-
depguard:
50+
settings:
51+
dupl:
52+
threshold: 150 ## TODO (make it 100; skip test)
53+
54+
revive:
55+
# ignore-generated-header: true
56+
severity: warning
57+
rules:
58+
# name: import-shadowing ## (e.g., url)
59+
# name: unhandled-error ## TODO (wtp)
60+
# name: line-length-limit
61+
# name: dot-imports
62+
- name: blank-imports
63+
- name: context-as-argument
64+
- name: context-keys-type
65+
- name: early-return
66+
- name: error-naming
67+
- name: error-strings
68+
# name: exported
69+
- name: if-return
70+
- name: increment-decrement
71+
- name: indent-error-flow
72+
- name: modifies-value-receiver
73+
# name: package-comments TODO (wtp)
74+
- name: range
75+
- name: receiver-naming
76+
- name: redefines-builtin-id
77+
- name: string-of-int
78+
- name: superfluous-else
79+
- name: time-naming
80+
- name: var-naming
81+
- name: var-declaration
82+
- name: unconditional-recursion
83+
- name: unexported-naming
84+
- name: unexported-return
85+
- name: unnecessary-stmt
86+
- name: unreachable-code
87+
- name: unused-parameter
88+
- name: unused-receiver
89+
- name: waitgroup-by-value
90+
91+
errcheck:
92+
check-type-assertions: true
93+
check-blank: true
94+
disable-default-exclusions: false
95+
exclude-functions:
96+
- io/ioutil.ReadFile
97+
- io.Copy(*bytes.Buffer)
98+
- io.Copy(os.Stdout)
99+
100+
govet:
101+
enable-all: true
102+
disable:
103+
- fieldalignment ## TODO (wtp)
104+
- shadow ## ditto
105+
106+
gocritic:
107+
enabled-tags:
108+
- performance
109+
- style
110+
disabled-checks:
111+
- unnamedResult
112+
- unnecessaryBlock
113+
114+
gosec:
115+
excludes: ## integer overflow; weak rand
116+
- G115
117+
- G402
118+
- G404
119+
120+
prealloc:
121+
simple: true # Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them
122+
range-loops: true # Report preallocation suggestions on range loops, true by default
123+
for-loops: true # Report preallocation suggestions on for loops, false by default
124+
125+
misspell:
126+
# Correct spellings using locale preferences for US or UK.
127+
# Default is to use a neutral variety of English.
128+
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
129+
locale: US
130+
131+
depguard:
132+
rules:
133+
main:
134+
deny:
135+
- pkg: io/ioutil
136+
desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil"
137+
- pkg: 'math/rand$'
138+
desc: "`math/rand` package has been deprecated use `math/rand/v2`"
139+
140+
# Defines a set of rules to ignore issues.
141+
# It does not skip the analysis, and so does not ignore "typecheck" errors.
142+
exclusions:
143+
warn-unused: false ## TODO (wtp)
144+
# Predefined exclusion rules.
145+
# Default: []
146+
presets:
147+
# comments
148+
# std-error-handling
149+
# common-false-positives
150+
- legacy
151+
152+
# Excluding configuration per-path, per-linter, per-text and per-source.
119153
rules:
120-
main:
121-
deny:
122-
- pkg: io/ioutil
123-
desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil"
124-
- pkg: 'math/rand$'
125-
desc: "`math/rand` package has been deprecated use `math/rand/v2`"
126-
127-
issues:
128-
# use default exclude rules
129-
exclude-use-default: true
130-
131-
# additional exclude rules
132-
exclude-rules:
133-
- linters: [errcheck]
134-
text: "Error return value of" # ignores 'error return value of ... is unchecked'
135-
136-
- linters: [gocritic]
137-
text: "block doesn't have definitions" # Sometimes blocks are useful for better readability.
138-
139-
# Set to 0 to disable limit
140-
max-same-issues: 0
141-
max-issues-per-linter: 0
154+
# Exclude some linters from running on tests files.
155+
- path: _test\.go
156+
linters:
157+
- errcheck
158+
- dupl
159+
- gosec
160+
161+
# Exclude some `staticcheck` messages.
162+
- linters:
163+
- staticcheck
164+
text: "QF1008:"
165+
# linters:
166+
# - staticcheck
167+
# text: "ST1005:"
168+
169+
formatters:
170+
enable:
171+
- gofmt
172+
- goimports
173+
settings:
174+
gofmt:
175+
rewrite-rules:
176+
- pattern: 'interface{}'
177+
replacement: 'any'
178+
goimports:
179+
local-prefixes:
180+
- github.com/NVIDIA/aistore
181+
# exclusions:
182+
# paths:
183+
# test/testdata
142184

143185
run:
144186
go: '1.24'

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ lint-update:
265265
## See also: .github/workflows/lint.yml
266266
lint-update-ci:
267267
@rm -f $(GOPATH)/bin/golangci-lint
268-
@curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin v1.64.5
268+
@curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin v2.0.2
269269

270270
lint:
271271
@([[ -x "$(command -v golangci-lint)" ]] && echo "Cannot find golangci-lint, run 'make lint-update' to install" && exit 1) || true

ais/backend/oci.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ func (bp *ocibp) PutObj(ctx context.Context, r io.ReadCloser, lom *core.LOM, _ *
493493
avoidingMPU bool // true if object size is not known or known to be <= bp.mpuThreshold
494494
cloudBck = lom.Bck().RemoteBck()
495495
err error
496-
objectAttrs *cmn.ObjAttrs = lom.ObjAttrs()
496+
objectAttrs = lom.ObjAttrs()
497497
objectSize int64
498498
)
499499

ais/clustermap.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ func (m *smapX) isValid() bool {
255255
}
256256

257257
// a stronger version of the above
258+
//
259+
//nolint:staticcheck // making an exception for Smap
258260
func (m *smapX) validate() error {
259261
if m == nil {
260262
return errors.New(clusterMap + " is <nil>")

ais/prxs3.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ func (p *proxy) getBckVersioningS3(w http.ResponseWriter, r *http.Request, bucke
695695

696696
// GET /s3/<bucket-name>?lifecycle|cors|policy|acl
697697
func (p *proxy) unsupported(w http.ResponseWriter, r *http.Request, bucket string) {
698-
if _, err, ecode := meta.InitByNameOnly(bucket, p.owner.bmd); err != nil {
698+
if _, ecode, err := meta.InitByNameOnly(bucket, p.owner.bmd); err != nil {
699699
s3.WriteErr(w, r, err, ecode)
700700
return
701701
}
@@ -738,7 +738,7 @@ func (p *proxy) putBckVersioningS3(w http.ResponseWriter, r *http.Request, bucke
738738
//
739739

740740
func (p *proxy) initByNameOnly(w http.ResponseWriter, r *http.Request, bucket string) *meta.Bck {
741-
bck, err, ecode := meta.InitByNameOnly(bucket, p.owner.bmd)
741+
bck, ecode, err := meta.InitByNameOnly(bucket, p.owner.bmd)
742742
if err != nil {
743743
s3.WriteErr(w, r, err, ecode)
744744
return nil

ais/test/downloader_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ func TestDownloadStatusError(t *testing.T) {
720720
invalidAddressCausedError := resp.Errs[0].Name == "invalidURL" || resp.Errs[1].Name == "invalidURL"
721721
notFoundFileCausedError := resp.Errs[0].Name == "notFoundFile" || resp.Errs[1].Name == "notFoundFile"
722722

723-
if !(invalidAddressCausedError && notFoundFileCausedError) {
723+
if !invalidAddressCausedError || !notFoundFileCausedError {
724724
t.Errorf("expected objects that cause errors to be (%s, %s), but got: (%s, %s)",
725725
"invalidURL", "notFoundFile", resp.Errs[0].Name, resp.Errs[1].Name)
726726
}

ais/test/dsort_test.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//nolint:dupl // copy-paste benign and can wait
21
// Package integration_test.
32
/*
43
* Copyright (c) 2018-2025, NVIDIA CORPORATION. All rights reserved.
@@ -443,12 +442,13 @@ outer:
443442
}
444443

445444
for _, file := range files {
446-
if df.alg.Kind == "" || df.alg.Kind == dsort.Alphanumeric {
445+
switch df.alg.Kind {
446+
case "", dsort.Alphanumeric:
447447
if lastName > file.Name() && canonicalName(lastName) != canonicalName(file.Name()) {
448448
df.m.t.Fatalf("%s: names out of order (shard: %s, lastName: %s, curName: %s)",
449449
df.job(), shardName, lastName, file.Name())
450450
}
451-
} else if df.alg.Kind == dsort.Shuffle {
451+
case dsort.Shuffle:
452452
if lastName > file.Name() {
453453
inversions++
454454
}
@@ -515,10 +515,7 @@ func (df *dsortFramework) checkOutputShardsWithEKM(ekm *shard.ExternalKeyMap) {
515515
for tmpl, pool := range shardNamePools {
516516
pt, _ := cos.NewParsedTemplate(tmpl)
517517
pt.InitIter()
518-
for {
519-
if len(pool) == 0 {
520-
break
521-
}
518+
for len(pool) > 0 {
522519
shardName, hasNext := pt.Next()
523520
if !hasNext {
524521
df.m.t.Fatalf("Shard name template (%v) does not match the corresponding shard name pool, remaining names: %v", tmpl, pool)

0 commit comments

Comments
 (0)