Skip to content

Commit bddc63a

Browse files
authored
dev: fix CI workflow for Windows (golangci#3134)
1 parent 890a826 commit bddc63a

25 files changed

+279
-76
lines changed

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
go.sum linguist-generated
2+
* text=auto eol=lf
3+
*.ps1 text eol=crlf

.github/workflows/pr.yml

+2-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ env:
99
GO_VERSION: 1.19
1010

1111
jobs:
12-
# Check if there any dirty change for go mod tidy
12+
# Check if there is any dirty change for go mod tidy
1313
go-mod:
1414
runs-on: ubuntu-latest
1515
steps:
@@ -41,8 +41,7 @@ jobs:
4141
# ex:
4242
# - 1.18beta1 -> 1.18.0-beta.1
4343
# - 1.18rc1 -> 1.18.0-rc.1
44-
# go-version: ${{ env.GO_VERSION }} # todo(ldez) uncomment after the next release v1.48.0
45-
go-version: 1.18
44+
go-version: ${{ env.GO_VERSION }}
4645
- name: lint
4746
uses: golangci/[email protected]
4847
with:
@@ -66,7 +65,6 @@ jobs:
6665
go-version: ${{ env.GO_VERSION }} # test only the latest go version to speed up CI
6766
- name: Run tests
6867
run: make.exe test
69-
continue-on-error: true
7068

7169
tests-on-macos:
7270
needs: golangci-lint # run after golangci-lint action to not produce duplicated errors

Makefile

+12-7
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,22 @@
44
# enable consistent Go 1.12/1.13 GOPROXY behavior.
55
export GOPROXY = https://proxy.golang.org
66

7+
BINARY = golangci-lint
8+
ifeq ($(OS),Windows_NT)
9+
BINARY := $(BINARY).exe
10+
endif
11+
712
# Build
813

9-
build: golangci-lint
14+
build: $(BINARY)
1015
.PHONY: build
1116

1217
build_race:
13-
go build -race -o golangci-lint ./cmd/golangci-lint
18+
go build -race -o $(BINARY) ./cmd/golangci-lint
1419
.PHONY: build_race
1520

1621
clean:
17-
rm -f golangci-lint
22+
rm -f $(BINARY)
1823
rm -f test/path
1924
rm -f tools/Dracula.itermcolors
2025
rm -f tools/goreleaser
@@ -25,7 +30,7 @@ clean:
2530
# Test
2631
test: export GOLANGCI_LINT_INSTALLED = true
2732
test: build
28-
GL_TEST_RUN=1 ./golangci-lint run -v
33+
GL_TEST_RUN=1 ./$(BINARY) run -v
2934
GL_TEST_RUN=1 go test -v -parallel 2 ./...
3035
.PHONY: test
3136

@@ -36,7 +41,7 @@ test_fix: build
3641
.PHONY: test_fix
3742

3843
test_race: build_race
39-
GL_TEST_RUN=1 ./golangci-lint run -v --timeout=5m
44+
GL_TEST_RUN=1 ./$(BINARY) run -v --timeout=5m
4045
.PHONY: test_race
4146

4247
test_linters:
@@ -67,7 +72,7 @@ snapshot: .goreleaser.yml tools/goreleaser
6772

6873
# Non-PHONY targets (real files)
6974

70-
golangci-lint: FORCE
75+
$(BINARY): FORCE
7176
go build -o $@ ./cmd/golangci-lint
7277

7378
tools/goreleaser: export GOFLAGS = -mod=readonly
@@ -87,7 +92,7 @@ tools/Dracula.itermcolors:
8792
assets/demo.svg: tools/svg-term tools/Dracula.itermcolors
8893
./tools/svg-term --cast=183662 --out assets/demo.svg --window --width 110 --height 30 --from 2000 --to 20000 --profile ./tools/Dracula.itermcolors --term iterm2
8994

90-
assets/github-action-config.json: FORCE golangci-lint
95+
assets/github-action-config.json: FORCE $(BINARY)
9196
# go run ./scripts/gen_github_action_config/main.go $@
9297
cd ./scripts/gen_github_action_config/; go run ./main.go ../../$@
9398

pkg/result/processors/utils.go pkg/result/processors/issues.go

-16
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package processors
22

33
import (
4-
"path/filepath"
5-
"regexp"
6-
"strings"
7-
84
"github.com/pkg/errors"
95

106
"github.com/golangci/golangci-lint/pkg/result"
@@ -48,15 +44,3 @@ func transformIssues(issues []result.Issue, transform func(i *result.Issue) *res
4844

4945
return retIssues
5046
}
51-
52-
var separatorToReplace = regexp.QuoteMeta(string(filepath.Separator))
53-
54-
func normalizePathInRegex(path string) string {
55-
if filepath.Separator == '/' {
56-
return path
57-
}
58-
59-
// This replacing should be safe because "/" are disallowed in Windows
60-
// https://docs.microsoft.com/ru-ru/windows/win32/fileio/naming-a-file
61-
return strings.ReplaceAll(path, "/", separatorToReplace)
62-
}

pkg/result/processors/path_prefixer.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package processors
22

33
import (
4-
"path"
4+
"path/filepath"
55

66
"github.com/golangci/golangci-lint/pkg/result"
77
)
@@ -27,7 +27,7 @@ func (*PathPrefixer) Name() string {
2727
func (p *PathPrefixer) Process(issues []result.Issue) ([]result.Issue, error) {
2828
if p.prefix != "" {
2929
for i := range issues {
30-
issues[i].Pos.Filename = path.Join(p.prefix, issues[i].Pos.Filename)
30+
issues[i].Pos.Filename = filepath.Join(p.prefix, issues[i].Pos.Filename)
3131
}
3232
}
3333
return issues, nil

pkg/result/processors/path_prefixer_test.go

+24-8
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package processors
22

33
import (
44
"go/token"
5+
"path/filepath"
56
"testing"
67

8+
"github.com/stretchr/testify/assert"
79
"github.com/stretchr/testify/require"
810

911
"github.com/golangci/golangci-lint/pkg/result"
@@ -12,26 +14,40 @@ import (
1214
func TestPathPrefixer_Process(t *testing.T) {
1315
paths := func(ps ...string) (issues []result.Issue) {
1416
for _, p := range ps {
15-
issues = append(issues, result.Issue{Pos: token.Position{Filename: p}})
17+
issues = append(issues, result.Issue{Pos: token.Position{Filename: filepath.FromSlash(p)}})
1618
}
1719
return
1820
}
21+
1922
for _, tt := range []struct {
2023
name, prefix string
2124
issues, want []result.Issue
2225
}{
23-
{"empty prefix", "", paths("some/path", "cool"), paths("some/path", "cool")},
24-
{"prefix", "ok", paths("some/path", "cool"), paths("ok/some/path", "ok/cool")},
25-
{"prefix slashed", "ok/", paths("some/path", "cool"), paths("ok/some/path", "ok/cool")},
26+
{
27+
name: "empty prefix",
28+
issues: paths("some/path", "cool"),
29+
want: paths("some/path", "cool"),
30+
},
31+
{
32+
name: "prefix",
33+
prefix: "ok",
34+
issues: paths("some/path", "cool"),
35+
want: paths("ok/some/path", "ok/cool"),
36+
},
37+
{
38+
name: "prefix slashed",
39+
prefix: "ok/",
40+
issues: paths("some/path", "cool"),
41+
want: paths("ok/some/path", "ok/cool"),
42+
},
2643
} {
2744
t.Run(tt.name, func(t *testing.T) {
28-
r := require.New(t)
29-
3045
p := NewPathPrefixer(tt.prefix)
46+
3147
got, err := p.Process(tt.issues)
32-
r.NoError(err, "prefixer should never error")
48+
require.NoError(t, err)
3349

34-
r.Equal(got, tt.want)
50+
assert.Equal(t, got, tt.want)
3551
})
3652
}
3753
}

pkg/result/processors/path_unix.go

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//go:build !windows
2+
3+
package processors
4+
5+
// normalizePathInRegex it's a noop function on Unix.
6+
func normalizePathInRegex(path string) string {
7+
return path
8+
}

pkg/result/processors/path_windows.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//go:build windows
2+
3+
package processors
4+
5+
import (
6+
"path/filepath"
7+
"regexp"
8+
"strings"
9+
)
10+
11+
var separatorToReplace = regexp.QuoteMeta(string(filepath.Separator))
12+
13+
// normalizePathInRegex normalizes path in regular expressions.
14+
// noop on Unix.
15+
// This replacing should be safe because "/" are disallowed in Windows
16+
// https://docs.microsoft.com/windows/win32/fileio/naming-a-file
17+
func normalizePathInRegex(path string) string {
18+
return strings.ReplaceAll(path, "/", separatorToReplace)
19+
}

pkg/result/processors/severity_rules.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ func createSeverityRules(rules []SeverityRule, prefix string) []severityRule {
4949
parsedRule.source = regexp.MustCompile(prefix + rule.Source)
5050
}
5151
if rule.Path != "" {
52-
parsedRule.path = regexp.MustCompile(rule.Path)
52+
path := normalizePathInRegex(rule.Path)
53+
parsedRule.path = regexp.MustCompile(path)
5354
}
5455
parsedRules = append(parsedRules, parsedRule)
5556
}

pkg/result/processors/skip_files_test.go

+9-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package processors
22

33
import (
44
"go/token"
5+
"path/filepath"
6+
"strings"
57
"testing"
68

79
"github.com/stretchr/testify/assert"
@@ -33,14 +35,15 @@ func TestSkipFiles(t *testing.T) {
3335

3436
processAssertEmpty(t, newTestSkipFiles(t, ".*"), newFileIssue("any.go"))
3537

36-
processAssertEmpty(t, newTestSkipFiles(t, "a/b/c.go"), newFileIssue("a/b/c.go"))
37-
processAssertSame(t, newTestSkipFiles(t, "a/b/c.go"), newFileIssue("a/b/d.go"))
38+
cleanPath := strings.ReplaceAll(filepath.FromSlash("a/b/c.go"), `\`, `\\`)
39+
processAssertEmpty(t, newTestSkipFiles(t, cleanPath), newFileIssue(filepath.FromSlash("a/b/c.go")))
40+
processAssertSame(t, newTestSkipFiles(t, cleanPath), newFileIssue(filepath.FromSlash("a/b/d.go")))
3841

39-
processAssertEmpty(t, newTestSkipFiles(t, ".*\\.pb\\.go"), newFileIssue("a/b.pb.go"))
40-
processAssertSame(t, newTestSkipFiles(t, ".*\\.pb\\.go"), newFileIssue("a/b.go"))
42+
processAssertEmpty(t, newTestSkipFiles(t, ".*\\.pb\\.go"), newFileIssue(filepath.FromSlash("a/b.pb.go")))
43+
processAssertSame(t, newTestSkipFiles(t, ".*\\.pb\\.go"), newFileIssue(filepath.FromSlash("a/b.go")))
4144

42-
processAssertEmpty(t, newTestSkipFiles(t, ".*\\.pb\\.go$"), newFileIssue("a/b.pb.go"))
43-
processAssertSame(t, newTestSkipFiles(t, ".*\\.pb\\.go$"), newFileIssue("a/b.go"))
45+
processAssertEmpty(t, newTestSkipFiles(t, ".*\\.pb\\.go$"), newFileIssue(filepath.FromSlash("a/b.pb.go")))
46+
processAssertSame(t, newTestSkipFiles(t, ".*\\.pb\\.go$"), newFileIssue(filepath.FromSlash("a/b.go")))
4447
}
4548

4649
func TestSkipFilesInvalidPattern(t *testing.T) {

test/fix_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
)
1313

1414
func TestFix(t *testing.T) {
15+
testshared.SkipOnWindows(t)
16+
1517
tmpDir := filepath.Join(testdataDir, "fix.tmp")
1618
_ = os.RemoveAll(tmpDir) // cleanup previous runs
1719

test/linters_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ func TestSourcesFromTestdata(t *testing.T) {
2222
}
2323

2424
func TestTypecheck(t *testing.T) {
25+
testshared.SkipOnWindows(t)
26+
2527
testSourcesFromDir(t, filepath.Join(testdataDir, "notcompiles"))
2628
}
2729

test/output_test.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package test
33
import (
44
"fmt"
55
"os"
6-
"path"
76
"path/filepath"
87
"testing"
98

@@ -50,11 +49,11 @@ func TestOutput_Stderr(t *testing.T) {
5049
Runner().
5150
Install().
5251
Run().
53-
ExpectHasIssue(expectedJSONOutput)
52+
ExpectHasIssue(testshared.NormalizeFilePathInJSON(expectedJSONOutput))
5453
}
5554

5655
func TestOutput_File(t *testing.T) {
57-
resultPath := path.Join(t.TempDir(), "golangci_lint_test_result")
56+
resultPath := filepath.Join(t.TempDir(), "golangci_lint_test_result")
5857

5958
sourcePath := filepath.Join(testdataDir, "misspell.go")
6059

@@ -74,7 +73,7 @@ func TestOutput_File(t *testing.T) {
7473

7574
b, err := os.ReadFile(resultPath)
7675
require.NoError(t, err)
77-
require.Contains(t, string(b), expectedJSONOutput)
76+
require.Contains(t, string(b), testshared.NormalizeFilePathInJSON(expectedJSONOutput))
7877
}
7978

8079
func TestOutput_Multiple(t *testing.T) {
@@ -94,5 +93,5 @@ func TestOutput_Multiple(t *testing.T) {
9493
Run().
9594
//nolint:misspell
9695
ExpectHasIssue("testdata/misspell.go:6:38: `occured` is a misspelling of `occurred`").
97-
ExpectOutputContains(expectedJSONOutput)
96+
ExpectOutputContains(testshared.NormalizeFilePathInJSON(expectedJSONOutput))
9897
}

test/run_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func TestNotExistingDirRun(t *testing.T) {
4545
Run().
4646
ExpectExitCode(exitcodes.Failure).
4747
ExpectOutputContains("cannot find package").
48-
ExpectOutputContains("/testdata/no_such_dir")
48+
ExpectOutputContains(testshared.NormalizeFileInString("/testdata/no_such_dir"))
4949
}
5050

5151
func TestSymlinkLoop(t *testing.T) {

test/testdata/depguard_ignore_file_rules.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build !windows
2+
13
//golangcitest:args -Edepguard
24
//golangcitest:config_path testdata/configs/depguard_ignore_file_rules.yml
35
//golangcitest:expected_exitcode 0

test/testdata/ifshort.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build !windows
2+
13
//golangcitest:args -Eifshort --internal-cmd-test
24
package testdata
35

test/testdata/tenv_go118.go

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//go:build go1.18
2-
// +build go1.18
32

43
//golangcitest:args -Etenv
54
package testdata

test/testdata/thelper_go118.go

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//go:build go1.18
2-
// +build go1.18
32

43
//golangcitest:args -Ethelper
54
package testdata

test/testshared/analysis.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func Analyze(t *testing.T, sourcePath string, rawData []byte) {
4646

4747
var reportData jsonResult
4848
err = json.Unmarshal(rawData, &reportData)
49-
require.NoError(t, err)
49+
require.NoError(t, err, string(rawData))
5050

5151
for _, issue := range reportData.Issues {
5252
checkMessage(t, want, issue.Pos, "diagnostic", issue.FromLinter, issue.Text)

0 commit comments

Comments
 (0)