Skip to content

Commit dff73bc

Browse files
committed
Setup golangci-lint configuration with dedicated lint workflow
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
1 parent a031f60 commit dff73bc

22 files changed

+278
-79
lines changed

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# ensure that line endings for Windows builds are properly formatted
2+
# see https://github.com/golangci/golangci-lint-action?tab=readme-ov-file#how-to-use
3+
# at "Multiple OS Example" section
4+
*.go text eol=lf

.github/workflows/lint.yml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: Lint
2+
3+
on: [push, pull_request]
4+
5+
concurrency:
6+
group: ${{ github.workflow }}-${{ github.ref }}
7+
cancel-in-progress: true
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
golangci-lint:
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
include:
18+
# macOS combinations
19+
- {os: macos-latest, CGO_ENABLED: "0", GOOS: darwin, GOARCH: amd64}
20+
- {os: macos-latest, CGO_ENABLED: "1", GOOS: darwin, GOARCH: amd64}
21+
- {os: macos-latest, CGO_ENABLED: "0", GOOS: darwin, GOARCH: arm64}
22+
- {os: macos-latest, CGO_ENABLED: "1", GOOS: darwin, GOARCH: arm64}
23+
24+
# Linux combinations
25+
- {os: ubuntu-latest, CGO_ENABLED: "0", GOOS: linux, GOARCH: amd64}
26+
- {os: ubuntu-latest, CGO_ENABLED: "1", GOOS: linux, GOARCH: amd64}
27+
- {os: ubuntu-latest, CGO_ENABLED: "0", GOOS: linux, GOARCH: arm64}
28+
- {os: ubuntu-latest, CGO_ENABLED: "0", GOOS: linux, GOARCH: 386}
29+
# - {os: ubuntu-latest, CGO_ENABLED: "0", GOOS: linux, GOARCH: loong64} # Not available on go1.18
30+
31+
# FreeBSD/NetBSD combinations sans CGO_ENABLED=1
32+
- {os: ubuntu-latest, CGO_ENABLED: "0", GOOS: freebsd, GOARCH: amd64}
33+
- {os: ubuntu-latest, CGO_ENABLED: "0", GOOS: freebsd, GOARCH: arm64}
34+
- {os: ubuntu-latest, CGO_ENABLED: "0", GOOS: netbsd, GOARCH: amd64}
35+
- {os: ubuntu-latest, CGO_ENABLED: "0", GOOS: netbsd, GOARCH: arm64}
36+
37+
# Windows combinations
38+
- {os: windows-latest, CGO_ENABLED: "0", GOOS: windows, GOARCH: amd64}
39+
- {os: windows-latest, CGO_ENABLED: "1", GOOS: windows, GOARCH: amd64}
40+
- {os: windows-latest, CGO_ENABLED: "0", GOOS: windows, GOARCH: arm64}
41+
- {os: windows-latest, CGO_ENABLED: "0", GOOS: windows, GOARCH: 386}
42+
permissions:
43+
contents: read
44+
pull-requests: read
45+
name: lint (${{ matrix.GOOS }}/${{ matrix.GOARCH }}/cgo=${{ matrix.CGO_ENABLED }})
46+
runs-on: ${{ matrix.os }}
47+
env:
48+
CGO_ENABLED: "${{ matrix.CGO_ENABLED }}"
49+
GOARCH: ${{ matrix.GOARCH }}
50+
GOOS: ${{ matrix.GOOS }}
51+
steps:
52+
- name: Checkout
53+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
54+
- name: Setup Go
55+
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
56+
with:
57+
go-version-file: go.mod
58+
- name: Run golangci-lint
59+
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
60+
with:
61+
args: --verbose
62+
63+
lint-cgo:
64+
name: lint (FreeBSD/NetBSD CGO)
65+
runs-on: ubuntu-latest
66+
strategy:
67+
matrix:
68+
include:
69+
- {GOOS: freebsd, GOARCH: amd64}
70+
- {GOOS: netbsd, GOARCH: amd64}
71+
env:
72+
CGO_ENABLED: "1"
73+
GOARCH: ${{ matrix.GOARCH }}
74+
GOOS: ${{ matrix.GOOS }}
75+
steps:
76+
- name: Checkout
77+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
78+
- name: Setup Go
79+
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
80+
with:
81+
go-version-file: go.mod
82+
- name: Install C toolchain
83+
run: sudo apt-get update && sudo apt-get install -y clang gcc g++ libc6-dev
84+
- name: Set CC/CXX
85+
run: |
86+
echo 'CC=clang' >> $GITHUB_ENV
87+
echo 'CXX=clang++' >> $GITHUB_ENV
88+
- name: Run golangci-lint
89+
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
90+
with:
91+
args: --verbose

.golangci.yml

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
formatters:
2+
enable:
3+
- gci
4+
- gofumpt
5+
settings:
6+
gci:
7+
# Section configuration to compare against.
8+
# Section names are case-insensitive and may contain parameters in ().
9+
# The default order of sections is `standard > default > custom > blank > dot > alias > localmodule`.
10+
# If `custom-order` is `true`, it follows the order of `sections` option.
11+
# Default: ["standard", "default"]
12+
sections:
13+
- standard # Standard section: captures all standard packages.
14+
- default # Default section: contains all imports that could not be matched to another section type.
15+
- prefix(github.com/ebitengine/purego) # Custom section: groups all imports with the specified Prefix.
16+
- blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled.
17+
- dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled.
18+
- localmodule # Local module section: contains all local packages. This section is not present unless explicitly enabled.
19+
20+
issues:
21+
# Show all issues
22+
max-issues-per-linter: 0
23+
max-same-issues: 0
24+
25+
linters:
26+
# Use standard set of linters as default
27+
default: standard
28+
29+
# Disable linters that are not suitable for this low-level library
30+
disable:
31+
- errcheck
32+
- gosec # Reports "unsafe" operations which are intentional in this library
33+
- unconvert # Removes unnecessary type conversions
34+
- unused
35+
36+
# Enable additional linters beyond the standard set
37+
enable:
38+
# Code quality linters
39+
- contextcheck
40+
- errorlint # Finds code that will cause problems with error wrapping
41+
- gocritic # Provides diagnostics for bugs, performance and style
42+
- govet
43+
- ineffassign
44+
- misspell # Finds commonly misspelled English words
45+
- modernize
46+
- noctx
47+
- revive # Fast, configurable linter for Go
48+
- staticcheck
49+
- unparam # Reports unused function parameters
50+
- usetesting
51+
52+
exclusions:
53+
presets:
54+
- comments
55+
warn-unused: true
56+
57+
settings:
58+
gocritic:
59+
disabled-checks:
60+
- commentedOutCode
61+
- dupImport
62+
- hugeParam
63+
- paramTypeCombine
64+
enable-all: true
65+
govet:
66+
disable:
67+
- fieldalignment
68+
enable-all: true
69+
revive:
70+
# Revive handles the default rules in a way that can be unexpected:
71+
# - If there are no explicit rules, the default rules are used.
72+
# - If there is at least one explicit rule, the default rules are not used.
73+
# Run `GL_DEBUG=revive golangci-lint run --enable-only=revive` to see default, all available rules, and enabled rules.
74+
rules:
75+
- name: blank-imports
76+
disabled: true
77+
- name: context-as-argument
78+
- name: context-keys-type
79+
- name: dot-imports
80+
- name: error-naming
81+
- name: error-return
82+
- name: error-strings
83+
- name: errorf
84+
- name: exported
85+
- name: if-return
86+
- name: increment-decrement
87+
- name: indent-error-flow
88+
- name: package-comments
89+
- name: range
90+
- name: receiver-naming
91+
- name: redefines-builtin-id
92+
- name: superfluous-else
93+
- name: time-equal
94+
- name: time-naming
95+
- name: unexported-return
96+
- name: unreachable-code
97+
- name: unused-parameter
98+
arguments:
99+
- allow-regex: "^_"
100+
- name: unused-receiver
101+
- name: var-naming
102+
disabled: true
103+
- name: waitgroup-by-value
104+
usetesting:
105+
os-setenv: false
106+
107+
run:
108+
# Minimum Go version to support
109+
go: "1.18"
110+
111+
version: "2"

callback_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package purego_test
77

88
import (
9+
"context"
910
"fmt"
1011
"os"
1112
"path/filepath"
@@ -21,7 +22,7 @@ func TestCallGoFromSharedLib(t *testing.T) {
2122
libFileName := filepath.Join(t.TempDir(), "libcbtest.so")
2223
t.Logf("Build %v", libFileName)
2324

24-
if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_test.c")); err != nil {
25+
if err := buildSharedLib(context.Background(), "CC", libFileName, filepath.Join("testdata", "libcbtest", "callback_test.c")); err != nil {
2526
t.Fatal(err)
2627
}
2728
defer os.Remove(libFileName)

dlfcn_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package purego_test
77

88
import (
9+
"context"
910
"os"
1011
"path/filepath"
1112
"testing"
@@ -24,7 +25,7 @@ func TestNestedDlopenCall(t *testing.T) {
2425
libFileName := filepath.Join(t.TempDir(), "libdlnested.so")
2526
t.Logf("Build %v", libFileName)
2627

27-
if err := buildSharedLib("CXX", libFileName, filepath.Join("testdata", "libdlnested", "nested_test.cpp")); err != nil {
28+
if err := buildSharedLib(context.Background(), "CXX", libFileName, filepath.Join("testdata", "libdlnested", "nested_test.cpp")); err != nil {
2829
t.Fatal(err)
2930
}
3031
defer os.Remove(libFileName)

examples/window/main_windows.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,7 @@ func main() {
146146
}
147147

148148
func wndProc(hwnd HWND, msg uint32, wparam, lparam uintptr) uintptr {
149-
switch msg {
150-
case WM_DESTROY:
149+
if msg == WM_DESTROY {
151150
PostQuitMessage(0)
152151
}
153152
return DefWindowProc(hwnd, msg, wparam, lparam)

func.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,13 @@ func RegisterFunc(fptr any, cfn uintptr) {
175175
if arg.Size() == 0 {
176176
continue
177177
}
178-
addInt := func(u uintptr) {
178+
addInt := func(uintptr) {
179179
ints++
180180
}
181-
addFloat := func(u uintptr) {
181+
addFloat := func(uintptr) {
182182
floats++
183183
}
184-
addStack := func(u uintptr) {
184+
addStack := func(uintptr) {
185185
stack++
186186
}
187187
_ = addStruct(reflect.New(arg).Elem(), &ints, &floats, &stack, addInt, addFloat, addStack, nil)
@@ -311,7 +311,8 @@ func RegisterFunc(fptr any, cfn uintptr) {
311311
syscall := thePool.Get().(*syscall15Args)
312312
defer thePool.Put(syscall)
313313

314-
if runtime.GOARCH == "loong64" {
314+
switch {
315+
case runtime.GOARCH == "loong64":
315316
*syscall = syscall15Args{
316317
cfn,
317318
sysargs[0], sysargs[1], sysargs[2], sysargs[3], sysargs[4], sysargs[5],
@@ -321,7 +322,7 @@ func RegisterFunc(fptr any, cfn uintptr) {
321322
0,
322323
}
323324
runtime_cgocall(syscall15XABI0, unsafe.Pointer(syscall))
324-
} else if runtime.GOARCH == "arm64" || runtime.GOOS != "windows" {
325+
case runtime.GOARCH == "arm64", runtime.GOOS != "windows":
325326
// Use the normal arm64 calling convention even on Windows
326327
*syscall = syscall15Args{
327328
cfn,
@@ -332,7 +333,7 @@ func RegisterFunc(fptr any, cfn uintptr) {
332333
arm64_r8,
333334
}
334335
runtime_cgocall(syscall15XABI0, unsafe.Pointer(syscall))
335-
} else {
336+
default:
336337
*syscall = syscall15Args{}
337338
// This is a fallback for Windows amd64, 386, and arm. Note this may not support floats
338339
syscall.a1, syscall.a2, _ = syscall_syscall15X(cfn, sysargs[0], sysargs[1], sysargs[2], sysargs[3], sysargs[4],
@@ -376,13 +377,12 @@ func RegisterFunc(fptr any, cfn uintptr) {
376377
default:
377378
panic("purego: unsupported return kind: " + outType.Kind().String())
378379
}
379-
if len(args) > 0 {
380-
// reuse args slice instead of allocating one when possible
381-
args[0] = v
382-
return args[:1]
383-
} else {
380+
if len(args) == 0 {
384381
return []reflect.Value{v}
385382
}
383+
// reuse args slice instead of allocating one when possible
384+
args[0] = v
385+
return args[:1]
386386
})
387387
fn.Set(v)
388388
}

func_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package purego_test
55

66
import (
7+
"context"
78
"errors"
89
"fmt"
910
"os/exec"
@@ -142,7 +143,7 @@ func TestABI(t *testing.T) {
142143
libFileName := filepath.Join(t.TempDir(), "abitest.so")
143144
t.Logf("Build %v", libFileName)
144145

145-
if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "abitest", "abi_test.c")); err != nil {
146+
if err := buildSharedLib(context.Background(), "CC", libFileName, filepath.Join("testdata", "abitest", "abi_test.c")); err != nil {
146147
t.Fatal(err)
147148
}
148149

@@ -199,8 +200,8 @@ func TestABI(t *testing.T) {
199200
}
200201
}
201202

202-
func buildSharedLib(compilerEnv, libFile string, sources ...string) error {
203-
out, err := exec.Command("go", "env", compilerEnv).Output()
203+
func buildSharedLib(ctx context.Context, compilerEnv, libFile string, sources ...string) error {
204+
out, err := exec.CommandContext(ctx, "go", "env", compilerEnv).Output()
204205
if err != nil {
205206
return fmt.Errorf("go env %s error: %w", compilerEnv, err)
206207
}
@@ -229,7 +230,7 @@ func buildSharedLib(compilerEnv, libFile string, sources ...string) error {
229230
}
230231
args = append(args, "-arch", arch)
231232
}
232-
cmd := exec.Command(compiler, append(args, sources...)...)
233+
cmd := exec.CommandContext(ctx, compiler, append(args, sources...)...)
233234
if out, err := cmd.CombinedOutput(); err != nil {
234235
return fmt.Errorf("compile lib: %w\n%q\n%s", err, cmd, string(out))
235236
}

internal/fakecgo/go_libinit.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,7 @@ func x_cgo_bindm(g unsafe.Pointer) {
4646
//go:norace
4747
func _cgo_try_pthread_create(thread *pthread_t, attr *pthread_attr_t, pfn unsafe.Pointer, arg *ThreadStart) int {
4848
var ts syscall.Timespec
49-
// tries needs to be the same type as syscall.Timespec.Nsec
50-
// but the fields are int32 on 32bit and int64 on 64bit.
51-
// tries is assigned to syscall.Timespec.Nsec in order to match its type.
52-
tries := ts.Nsec
49+
tries := ts.Nsec //nolint:ineffassign,staticcheck // tries needs to be the same type as syscall.Timespec.Nsec but the fields are int32 on 32bit and int64 on 64bit. tries is assigned to syscall.Timespec.Nsec in order to match its type.
5350
var err int
5451

5552
for tries = 0; tries < 20; tries++ {

internal/fakecgo/go_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func _cgo_sys_thread_start(ts *ThreadStart) {
1616
var size size_t
1717
var err int
1818

19-
//fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
19+
// fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
2020
sigfillset(&ign)
2121
pthread_sigmask(SIG_SETMASK, &ign, &oset)
2222

0 commit comments

Comments
 (0)