Skip to content

Commit 6aa1be0

Browse files
[skip-changelog] Use golangci-lint (#2338)
1 parent c004b42 commit 6aa1be0

File tree

34 files changed

+297
-304
lines changed

34 files changed

+297
-304
lines changed

.github/workflows/check-go-task.yml

+4-35
Original file line numberDiff line numberDiff line change
@@ -49,39 +49,6 @@ jobs:
4949
5050
echo "result=$RESULT" >> $GITHUB_OUTPUT
5151
52-
check-errors:
53-
name: check-errors (${{ matrix.module.path }})
54-
needs: run-determination
55-
if: needs.run-determination.outputs.result == 'true'
56-
runs-on: ubuntu-latest
57-
58-
strategy:
59-
fail-fast: false
60-
61-
matrix:
62-
module:
63-
- path: ./
64-
65-
steps:
66-
- name: Checkout repository
67-
uses: actions/checkout@v4
68-
69-
- name: Install Go
70-
uses: actions/setup-go@v4
71-
with:
72-
go-version: ${{ env.GO_VERSION }}
73-
74-
- name: Install Task
75-
uses: arduino/setup-task@v1
76-
with:
77-
repo-token: ${{ secrets.GITHUB_TOKEN }}
78-
version: 3.x
79-
80-
- name: Check for errors
81-
env:
82-
GO_MODULE_PATH: ${{ matrix.module.path }}
83-
run: task go:vet
84-
8552
check-outdated:
8653
name: check-outdated (${{ matrix.module.path }})
8754
needs: run-determination
@@ -146,8 +113,10 @@ jobs:
146113
repo-token: ${{ secrets.GITHUB_TOKEN }}
147114
version: 3.x
148115

149-
- name: Install golint
150-
run: go install golang.org/x/lint/golint@latest
116+
- name: golangci-lint
117+
uses: golangci/golangci-lint-action@v3
118+
with:
119+
version: v1.54
151120

152121
- name: Check style
153122
env:

.golangci.yml

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
run:
2+
timeout: 10m
3+
go: "1.21"
4+
tests: true
5+
6+
linters:
7+
# Disable all linters.
8+
disable-all: true
9+
# Enable specific linter
10+
enable:
11+
# Nice to have
12+
#- depguard
13+
#- errcheck
14+
#- gocritic
15+
#- thelper
16+
- errorlint
17+
- dupword
18+
- exportloopref
19+
- forbidigo
20+
- gofmt
21+
- goimports
22+
- gosec
23+
- gosimple
24+
- govet
25+
- ineffassign
26+
- misspell
27+
- revive
28+
- staticcheck
29+
- tenv
30+
- typecheck
31+
- unconvert
32+
33+
linters-settings:
34+
forbidigo:
35+
forbid:
36+
- p: ^(fmt\.Print(|f|ln)|print|println)$
37+
msg: in cli package use `feedback.*` instead
38+
- p: (os\.(Stdout|Stderr|Stdin))(# )?
39+
msg: in cli package use `feedback.*` instead
40+
analyze-types: true
41+
42+
revive:
43+
confidence: 0.8
44+
rules:
45+
#- name: error-return
46+
#- name: unused-parameter
47+
#- name: var-naming
48+
- name: blank-imports
49+
- name: context-as-argument
50+
- name: context-keys-type
51+
- name: dot-imports
52+
- name: empty-block
53+
- name: error-naming
54+
- name: error-strings
55+
- name: errorf
56+
- name: exported
57+
- name: increment-decrement
58+
- name: indent-error-flow
59+
- name: package-comments
60+
- name: range
61+
- name: receiver-naming
62+
- name: redefines-builtin-id
63+
- name: superfluous-else
64+
- name: time-naming
65+
- name: unexported-return
66+
- name: unreachable-code
67+
- name: var-declaration
68+
- name: defer
69+
- name: atomic
70+
- name: waitgroup-by-value
71+
72+
errorlint:
73+
# Check for plain error comparisons.
74+
comparison: true
75+
76+
# We might evalute to allow the asserts and errofs in the future
77+
# Do not check for plain type assertions and type switches.
78+
asserts: false
79+
# Do not check whether fmt.Errorf uses the %w verb for formatting errors.
80+
errorf: false
81+
82+
issues:
83+
# Fix found issues (if it's supported by the linter).
84+
fix: true
85+
# List of regexps of issue texts to exclude.
86+
#
87+
# But independently of this option we use default exclude patterns,
88+
# it can be disabled by `exclude-use-default: false`.
89+
# To list all excluded by default patterns execute `golangci-lint run --help`
90+
#
91+
# Default: https://golangci-lint.run/usage/false-positives/#default-exclusions
92+
exclude-rules:
93+
# Exclude some linters from running on tests files.
94+
- path: _test\.go
95+
linters: [gosec, errcheck]
96+
# G401: Use of weak cryptographic primitive
97+
- linters: [gosec]
98+
text: "G401"
99+
# G501: Blocklisted import crypto/md5: weak cryptographic primitive
100+
- linters: [gosec]
101+
text: "G501"
102+
# G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server
103+
- linters: [gosec]
104+
path: internal/integrationtest/
105+
text: "G112"
106+
# G204: Subprocess launched with a potential tainted input or cmd arguments
107+
- linters: [gosec]
108+
path: executils/process.go
109+
text: "G204"
110+
# SA1019: req.GetQuery is deprecated: Marked as deprecated in cc/arduino/cli/commands/v1/lib.proto.
111+
- linters: [staticcheck]
112+
path: commands/lib/search.go
113+
text: "SA1019"
114+
115+
# Ignore revive emptyblock
116+
- linters: [revive]
117+
path: arduino/libraries/loader.go
118+
text: "empty-block"
119+
- linters: [revive]
120+
path: arduino/serialutils/serialutils.go
121+
text: "empty-block"
122+
- linters: [revive]
123+
path: arduino/resources/download.go
124+
text: "empty-block"
125+
- linters: [revive]
126+
path: arduino/builder/internal/progress/progress_test.go
127+
text: "empty-block"
128+
- linters: [revive]
129+
path: internal/algorithms/channels.go
130+
text: "empty-block"
131+
132+
# Run linters only on specific path
133+
- path-except: internal/cli/
134+
linters:
135+
- forbidigo
136+
- path: internal/cli/feedback/
137+
linters: [forbidigo]

Taskfile.yml

+3-13
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,12 @@ tasks:
8080
dir: '{{default "./" .GO_MODULE_PATH}}'
8181
cmds:
8282
- |
83-
if ! which golint &>/dev/null; then
84-
echo "golint not installed or not in PATH. Please install: https://github.com/golang/lint#installation"
83+
if ! which golangci-lint &>/dev/null; then
84+
echo "golangci-lint not installed or not in PATH. Please install: https://golangci-lint.run/usage/install/"
8585
exit 1
8686
fi
8787
- |
88-
golint \
89-
{{default "-min_confidence 0.8 -set_exit_status" .GO_LINT_FLAGS}} \
90-
{{default .DEFAULT_GO_PACKAGES .GO_PACKAGES}}
88+
golangci-lint run
9189
9290
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/test-go-task/Taskfile.yml
9391
go:test:
@@ -128,13 +126,6 @@ tasks:
128126
{{.TEST_LDFLAGS}}
129127
go tool covdata textfmt -i=coverage_data -o coverage_integration.txt
130128
131-
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-go-task/Taskfile.yml
132-
go:vet:
133-
desc: Check for errors in Go code
134-
dir: '{{default "./" .GO_MODULE_PATH}}'
135-
cmds:
136-
- go vet {{default .DEFAULT_GO_PACKAGES .GO_PACKAGES}}
137-
138129
go:easyjson-generate:
139130
desc: Run easyjson code generation
140131
cmds:
@@ -303,7 +294,6 @@ tasks:
303294
check:
304295
desc: Check fmt and lint
305296
cmds:
306-
- task: go:vet
307297
- task: go:lint
308298
- task: protoc:check
309299

arduino/builder/internal/preprocessor/internal/ctags/ctags_has_issues.go

+51-53
Original file line numberDiff line numberDiff line change
@@ -206,78 +206,76 @@ func removeComments(text string, multilinecomment bool) (string, bool) {
206206
// FindCLinkageLines scans the source files searching for "extern C" context
207207
// It save the line numbers in a map filename -> {lines...}
208208
func (p *Parser) FindCLinkageLines(tags []*Tag) map[string][]int {
209-
210209
lines := make(map[string][]int)
211210

212211
for _, tag := range tags {
213-
214212
if lines[tag.Filename] != nil {
215213
break
216214
}
217215

218216
file, err := os.Open(tag.Filename)
219-
if err == nil {
220-
defer file.Close()
217+
if err != nil {
218+
continue
219+
}
220+
lines[tag.Filename] = append(lines[tag.Filename], -1)
221221

222-
lines[tag.Filename] = append(lines[tag.Filename], -1)
222+
scanner := bufio.NewScanner(file)
223223

224-
scanner := bufio.NewScanner(file)
224+
// we can't remove the comments otherwise the line number will be wrong
225+
// there are three cases:
226+
// 1 - extern "C" void foo()
227+
// 2 - extern "C" {
228+
// void foo();
229+
// void bar();
230+
// }
231+
// 3 - extern "C"
232+
// {
233+
// void foo();
234+
// void bar();
235+
// }
236+
// case 1 and 2 can be simply recognized with string matching and indent level count
237+
// case 3 needs specia attention: if the line ONLY contains `extern "C"` string, don't bail out on indent level = 0
238+
239+
inScope := false
240+
enteringScope := false
241+
indentLevels := 0
242+
line := 0
225243

226-
// we can't remove the comments otherwise the line number will be wrong
227-
// there are three cases:
228-
// 1 - extern "C" void foo()
229-
// 2 - extern "C" {
230-
// void foo();
231-
// void bar();
232-
// }
233-
// 3 - extern "C"
234-
// {
235-
// void foo();
236-
// void bar();
237-
// }
238-
// case 1 and 2 can be simply recognized with string matching and indent level count
239-
// case 3 needs specia attention: if the line ONLY contains `extern "C"` string, don't bail out on indent level = 0
240-
241-
inScope := false
242-
enteringScope := false
243-
indentLevels := 0
244-
line := 0
245-
246-
externCDecl := removeSpacesAndTabs(keywordExternC)
247-
248-
for scanner.Scan() {
249-
line++
250-
str := removeSpacesAndTabs(scanner.Text())
244+
externCDecl := removeSpacesAndTabs(keywordExternC)
251245

252-
if len(str) == 0 {
253-
continue
254-
}
246+
for scanner.Scan() {
247+
line++
248+
str := removeSpacesAndTabs(scanner.Text())
255249

256-
// check if we are on the first non empty line after externCDecl in case 3
257-
if enteringScope {
258-
enteringScope = false
259-
}
250+
if len(str) == 0 {
251+
continue
252+
}
260253

261-
// check if the line contains externCDecl
262-
if strings.Contains(str, externCDecl) {
263-
inScope = true
264-
if len(str) == len(externCDecl) {
265-
// case 3
266-
enteringScope = true
267-
}
268-
}
269-
if inScope {
270-
lines[tag.Filename] = append(lines[tag.Filename], line)
271-
}
272-
indentLevels += strings.Count(str, "{") - strings.Count(str, "}")
254+
// check if we are on the first non empty line after externCDecl in case 3
255+
if enteringScope {
256+
enteringScope = false
257+
}
273258

274-
// Bail out if indentLevel is zero and we are not in case 3
275-
if indentLevels == 0 && !enteringScope {
276-
inScope = false
259+
// check if the line contains externCDecl
260+
if strings.Contains(str, externCDecl) {
261+
inScope = true
262+
if len(str) == len(externCDecl) {
263+
// case 3
264+
enteringScope = true
277265
}
278266
}
267+
if inScope {
268+
lines[tag.Filename] = append(lines[tag.Filename], line)
269+
}
270+
indentLevels += strings.Count(str, "{") - strings.Count(str, "}")
271+
272+
// Bail out if indentLevel is zero and we are not in case 3
273+
if indentLevels == 0 && !enteringScope {
274+
inScope = false
275+
}
279276
}
280277

278+
file.Close()
281279
}
282280
return lines
283281
}

arduino/builder/internal/utils/utils.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ func ExecCommand(
277277
return verboseInfoBuf.Bytes(), stdoutBuffer.Bytes(), stderrBuffer.Bytes(), errors.WithStack(err)
278278
}
279279

280-
// DirContentIsOlderThan DirContentIsOlderThan returns true if the content of the given directory is
280+
// DirContentIsOlderThan returns true if the content of the given directory is
281281
// older than target file. If extensions are given, only the files with these
282282
// extensions are tested.
283283
func DirContentIsOlderThan(dir *paths.Path, target *paths.Path, extensions ...string) (bool, error) {

arduino/builder/linker.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func (b *Builder) link() error {
5050
// and use that archives to complete the build.
5151
if len(objectFileList) > 30000 {
5252

53-
// We must create an object file for each visited directory: this is required becuase gcc-ar checks
53+
// We must create an object file for each visited directory: this is required because gcc-ar checks
5454
// if an object file is already in the archive by looking ONLY at the filename WITHOUT the path, so
5555
// it may happen that a subdir/spi.o inside the archive may be overwritten by a anotherdir/spi.o
5656
// because thery are both named spi.o.

arduino/builder/sketch.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (b *Builder) sketchCopyAdditionalFiles(buildPath *paths.Path, overrides map
140140
sourceBytes = s
141141
}
142142

143-
// tag each addtional file with the filename of the source it was copied from
143+
// tag each additional file with the filename of the source it was copied from
144144
sourceBytes = append([]byte("#line 1 "+cpp.QuoteString(file.String())+"\n"), sourceBytes...)
145145

146146
err = writeIfDifferent(sourceBytes, targetPath)

arduino/cores/packagemanager/package_manager.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ func (pme *Explorer) ResolveFQBN(fqbn *cores.FQBN) (
319319
}
320320

321321
// Create the build properties map by overlaying the properties of the
322-
// referenced platform propeties, the board platform properties and the
322+
// referenced platform properties, the board platform properties and the
323323
// board specific properties.
324324
buildProperties := properties.NewMap()
325325
buildProperties.Merge(variantPlatformRelease.Properties)

0 commit comments

Comments
 (0)