Skip to content

Commit 7d3776c

Browse files
committed
Upgrade golangci-lint to v2
For better or rwose, golangci-lint has released a v2 [1] that's incompatible with v1. It'll only be a matter of time until we're forced to upgrade to it, so I figure we may as well do it early. There's a bunch of new obnoxious linters that I've disabled. Most of these complain about "cyclomatic complexity" or "cognitive complexity" or functions being too long (they all seem to want everything broken down into functions of ten lines). Aside from that, `testifylint` seems to have gotten even more effective at finding misuses of testify, so it fixed a bunch more arguable misuses of various assertions, which seems good for normalizing code. The structure of the YAML file changes fairly significantly, but it's all basically the same thing with various aspects reorganized. I made the new one using the built-in `golangci-lint migrate` and copied comments over manually. If we can get this in, the next step will be to distribute it out to other River projects. Most of them are using copies of this repo's configuration file, so it should be pretty easy to do. [1] https://ldez.github.io/blog/2025/03/23/golangci-lint-v2/ [2] golangci/golangci-lint#5606
1 parent c81201e commit 7d3776c

File tree

10 files changed

+152
-132
lines changed

10 files changed

+152
-132
lines changed

.github/workflows/ci.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ jobs:
218218
name: lint
219219
runs-on: ubuntu-latest
220220
env:
221-
GOLANGCI_LINT_VERSION: v1.64.4
221+
GOLANGCI_LINT_VERSION: v2.0.0
222222
permissions:
223223
contents: read
224224
# allow read access to pull request. Use with `only-new-issues` option.
@@ -234,7 +234,7 @@ jobs:
234234
uses: actions/checkout@v4
235235

236236
- name: Lint
237-
uses: golangci/golangci-lint-action@v4
237+
uses: golangci/golangci-lint-action@v7
238238
with:
239239
# golangci-lint needs to be run separately for every Go module, and
240240
# its GitHub Action doesn't provide any way to do that. Have it fetch

.golangci.yaml

Lines changed: 90 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
1-
issues:
2-
exclude:
3-
- 'Error return value of .(\w+\.Rollback(.*)). is not checked'
1+
version: "2"
42

53
linters:
6-
presets:
7-
- bugs
8-
- comment
9-
- format
10-
- performance
11-
- style
12-
- test
13-
- unused
4+
default: all
145

156
disable:
167
# disabled, but which we should enable with discussion
@@ -21,82 +12,108 @@ linters:
2112
- testpackage # requires tests in test packages like `river_test`
2213

2314
# disabled because they're annoying/bad
15+
- cyclop # screams into the void at "cyclomatic complexity"
16+
- funlen # screams when functions are more than 60 lines long; what are we even doing here guys
2417
- interfacebloat # we do in fact want >10 methods on the Adapter interface or wherever we see fit.
18+
- gocognit # yells that "cognitive complexity" is too high; why
19+
- gocyclo # ANOTHER "cyclomatic complexity" checker (see also "cyclop" and "gocyclo")
2520
- godox # bans TODO statements; total non-starter at the moment
2621
- err113 # wants all errors to be defined as variables at the package level; quite obnoxious
22+
- maintidx # ANOTHER ANOTHER "cyclomatic complexity" lint (see also "cyclop" and "gocyclo")
2723
- mnd # detects "magic numbers", which it defines as any number; annoying
24+
- nestif # yells when if blocks are nested; what planet do these people come from?
2825
- ireturn # bans returning interfaces; questionable as is, but also buggy as hell; very, very annoying
2926
- lll # restricts maximum line length; annoying
3027
- nlreturn # requires a blank line before returns; annoying
3128
- wsl # a bunch of style/whitespace stuff; annoying
3229

33-
linters-settings:
34-
depguard:
35-
rules:
36-
all:
37-
files: ["$all"]
38-
allow:
39-
deny:
40-
- desc: "Use `github.com/google/uuid` package for UUIDs instead."
41-
pkg: "github.com/xtgo/uuid"
42-
not-test:
43-
files: ["!$test"]
44-
deny:
45-
- desc: "Don't use `dbadaptertest` package outside of test environments."
46-
pkg: "github.com/riverqueue/river/internal/dbadaptertest"
47-
- desc: "Don't use `riverinternaltest` package outside of test environments."
48-
pkg: "github.com/riverqueue/river/internal/riverinternaltest"
30+
settings:
31+
depguard:
32+
rules:
33+
all:
34+
files:
35+
- $all
36+
deny:
37+
- pkg: github.com/xtgo/uuid
38+
desc: Use `github.com/google/uuid` package for UUIDs instead.
39+
not-test:
40+
files:
41+
- "!$test"
42+
deny:
43+
- pkg: github.com/riverqueue/river/internal/dbadaptertest
44+
desc: Don't use `dbadaptertest` package outside of test environments.
45+
- pkg: github.com/riverqueue/river/internal/riverinternaltest
46+
desc: Don't use `riverinternaltest` package outside of test environments.
4947

50-
forbidigo:
51-
forbid:
52-
- msg: "Use `require` variants instead."
53-
p: '^assert\.'
54-
- msg: "Use `Func` suffix for function variables instead."
55-
p: 'Fn\b'
56-
- msg: "Use built-in `max` function instead."
57-
p: '\bmath\.Max\b'
58-
- msg: "Use built-in `min` function instead."
59-
p: '\bmath\.Min\b'
48+
forbidigo:
49+
forbid:
50+
- pattern: ^assert\.
51+
msg: Use `require` variants instead.
52+
- pattern: Fn\b
53+
msg: Use `Func` suffix for function variables instead.
54+
- pattern: \bmath\.Max\b
55+
msg: Use built-in `max` function instead.
56+
- pattern: \bmath\.Min\b
57+
msg: Use built-in `min` function instead.
6058

61-
gci:
62-
sections:
63-
- Standard
64-
- Default
65-
- Prefix(github.com/riverqueue)
59+
gomoddirectives:
60+
replace-local: true
6661

67-
gomoddirectives:
68-
replace-local: true
62+
gosec:
63+
excludes:
64+
- G404 # use of non-crypto random; overly broad for our use case
6965

70-
gosec:
71-
excludes:
72-
- G404 # use of non-crypto random; overly broad for our use case
66+
revive:
67+
rules:
68+
- name: unused-parameter
69+
disabled: true
7370

74-
revive:
75-
rules:
76-
- name: unused-parameter
77-
disabled: true
71+
tagliatelle:
72+
case:
73+
rules:
74+
json: snake
7875

79-
tagliatelle:
80-
case:
81-
rules:
82-
json: snake
76+
testifylint:
77+
enable-all: true
78+
disable:
79+
- go-require
80+
81+
varnamelen:
82+
ignore-names:
83+
- db
84+
- eg
85+
- f
86+
- i
87+
- id
88+
- j
89+
- mu
90+
- sb # common convention for string builder
91+
- t
92+
- tt # common convention for table tests
93+
- tx
94+
- wg
95+
96+
exclusions:
97+
generated: lax
98+
presets:
99+
- comments
100+
- common-false-positives
101+
- legacy
102+
- std-error-handling
103+
rules:
104+
- path: (.+)\.go$
105+
text: Error return value of .(\w+\.Rollback(.*)). is not checked
83106

84-
testifylint:
85-
enable-all: true
86-
disable:
87-
- go-require
107+
formatters:
108+
enable:
109+
- gci
110+
- gofmt
111+
- gofumpt
112+
- goimports
88113

89-
varnamelen:
90-
ignore-names:
91-
- db
92-
- eg
93-
- f
94-
- i
95-
- id
96-
- j
97-
- mu
98-
- sb # common convention for string builder
99-
- t
100-
- tt # common convention for table tests
101-
- tx
102-
- wg
114+
settings:
115+
gci:
116+
sections:
117+
- Standard
118+
- Default
119+
- Prefix(github.com/riverqueue)

error_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func TestUnknownJobKindError_As(t *testing.T) {
3131
t.Parallel()
3232

3333
var err *river.UnknownJobKindError
34-
require.False(t, errors.As(errors.New("some other error"), &err))
34+
require.NotErrorAs(t, errors.New("some other error"), &err)
3535
})
3636
}
3737

internal/dblist/db_list.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,12 @@ func JobList(ctx context.Context, exec riverdriver.Executor, params *JobListPara
9999

100100
for i, orderBy := range params.OrderBy {
101101
orderByBuilder.WriteString(orderBy.Expr)
102-
if orderBy.Order == SortOrderAsc {
102+
switch orderBy.Order {
103+
case SortOrderAsc:
103104
orderByBuilder.WriteString(" ASC")
104-
} else if orderBy.Order == SortOrderDesc {
105+
case SortOrderDesc:
105106
orderByBuilder.WriteString(" DESC")
107+
case SortOrderUnspecified:
106108
}
107109
if i < len(params.OrderBy)-1 {
108110
orderByBuilder.WriteString(", ")

internal/jobexecutor/job_executor_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ func TestJobExecutor_Execute(t *testing.T) {
233233

234234
executor, bundle := setup(t)
235235

236-
now := executor.Archetype.Time.StubNowUTC(time.Now().UTC())
236+
now := executor.Time.StubNowUTC(time.Now().UTC())
237237

238238
workerErr := errors.New("job error")
239239
executor.WorkUnit = newWorkUnitFactoryWithCustomRetry(func() error { return workerErr }, nil).MakeUnit(bundle.jobRow)
@@ -249,7 +249,7 @@ func TestJobExecutor_Execute(t *testing.T) {
249249
require.Equal(t, now.Truncate(1*time.Microsecond), job.Errors[0].At.Truncate(1*time.Microsecond))
250250
require.Equal(t, 1, job.Errors[0].Attempt)
251251
require.Equal(t, "job error", job.Errors[0].Error)
252-
require.Equal(t, "", job.Errors[0].Trace)
252+
require.Empty(t, job.Errors[0].Trace)
253253
})
254254

255255
t.Run("ErrorAgainAfterRetry", func(t *testing.T) {
@@ -361,7 +361,7 @@ func TestJobExecutor_Execute(t *testing.T) {
361361
require.WithinDuration(t, time.Now(), job.Errors[0].At, 2*time.Second)
362362
require.Equal(t, 1, job.Errors[0].Attempt)
363363
require.Equal(t, "JobCancelError: throw away this job", job.Errors[0].Error)
364-
require.Equal(t, "", job.Errors[0].Trace)
364+
require.Empty(t, job.Errors[0].Trace)
365365
})
366366

367367
t.Run("JobSnoozeErrorReschedulesJobAndDecrementsAttempt", func(t *testing.T) {
@@ -721,7 +721,7 @@ func TestJobExecutor_Execute(t *testing.T) {
721721
require.Equal(t, 1, job.Errors[0].Attempt)
722722
require.Equal(t, "JobCancelError: job cancelled remotely", job.Errors[0].Error)
723723
require.Equal(t, rivertype.ErrJobCancelledRemotely.Error(), job.Errors[0].Error)
724-
require.Equal(t, "", job.Errors[0].Trace)
724+
require.Empty(t, job.Errors[0].Trace)
725725
})
726726

727727
t.Run("RemoteCancellationJobNotCancelledIfNoErrorReturned", func(t *testing.T) {

job_list_params_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ func Test_JobListCursor_JobListCursorFromJob(t *testing.T) {
2525
cursor := JobListCursorFromJob(jobRow)
2626
require.Zero(t, cursor.id)
2727
require.Equal(t, jobRow, cursor.job)
28-
require.Zero(t, cursor.kind)
29-
require.Zero(t, cursor.queue)
28+
require.Empty(t, cursor.kind)
29+
require.Empty(t, cursor.queue)
3030
require.Zero(t, cursor.sortField)
3131
require.Zero(t, cursor.time)
3232
}
@@ -163,7 +163,7 @@ func Test_JobListCursor_MarshalJSON(t *testing.T) {
163163

164164
text, err := json.Marshal(cursor)
165165
require.NoError(t, err)
166-
require.NotEqual(t, "", text)
166+
require.NotEmpty(t, text)
167167

168168
unmarshaledParams := &JobListCursor{}
169169
require.NoError(t, json.Unmarshal(text, unmarshaledParams))

producer.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -525,10 +525,7 @@ func (p *producer) innerFetchLoop(workCtx context.Context, fetchResultCh chan pr
525525
func (p *producer) executorShutdownLoop() {
526526
// No more jobs will be fetched or executed. However, we must wait for all
527527
// in-progress jobs to complete.
528-
for {
529-
if len(p.activeJobs) == 0 {
530-
break
531-
}
528+
for len(p.activeJobs) != 0 {
532529
result := <-p.jobResultCh
533530
p.removeActiveJob(result.ID)
534531
}

rivershared/testfactory/test_factory.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func Job(ctx context.Context, tb testing.TB, exec riverdriver.Executor, opts *Jo
4646
return job
4747
}
4848

49-
func Job_Build(tb testing.TB, opts *JobOpts) *riverdriver.JobInsertFullParams { //nolint:stylecheck
49+
func Job_Build(tb testing.TB, opts *JobOpts) *riverdriver.JobInsertFullParams {
5050
tb.Helper()
5151

5252
encodedArgs := opts.EncodedArgs

0 commit comments

Comments
 (0)