Skip to content

Commit 7f342cd

Browse files
committed
normalize path
1 parent 48deaeb commit 7f342cd

11 files changed

+143
-66
lines changed

pkg/result/processors/utils.go renamed to 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

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//go:build !windows
2+
3+
package processors
4+
5+
func normalizePathInRegex(path string) string {
6+
return path
7+
}

pkg/result/processors/path_windows.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
func normalizePathInRegex(path string) string {
14+
if filepath.Separator == '/' {
15+
return path
16+
}
17+
18+
// This replacing should be safe because "/" are disallowed in Windows
19+
// https://docs.microsoft.com/ru-ru/windows/win32/fileio/naming-a-file
20+
return strings.ReplaceAll(path, "/", separatorToReplace)
21+
}

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

+2-14
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package test
22

33
import (
44
"path/filepath"
5-
"regexp"
65
"strings"
76
"testing"
87

@@ -46,7 +45,7 @@ func TestNotExistingDirRun(t *testing.T) {
4645
Run().
4746
ExpectExitCode(exitcodes.Failure).
4847
ExpectOutputContains("cannot find package").
49-
ExpectOutputContains("/testdata/no_such_dir")
48+
ExpectOutputContains(testshared.NormalizeFileInString("/testdata/no_such_dir"))
5049
}
5150

5251
func TestSymlinkLoop(t *testing.T) {
@@ -681,18 +680,7 @@ func TestPathPrefix(t *testing.T) {
681680
WithTargetPath(testdataDir, "withtests").
682681
Runner().
683682
Run().
684-
ExpectOutputRegexp(normalizePathInRegex(test.pattern))
683+
ExpectOutputRegexp(test.pattern)
685684
})
686685
}
687686
}
688-
689-
// FIXME(ldez) see utils.normalizePathInRegex(...) and maybe move into RunnerResult.ExpectOutputRegexp(...)
690-
func normalizePathInRegex(path string) string {
691-
if filepath.Separator == '/' {
692-
return path
693-
}
694-
695-
// This replacing should be safe because "/" are disallowed in Windows
696-
// https://docs.microsoft.com/windows/win32/fileio/naming-a-file
697-
return strings.ReplaceAll(path, "/", regexp.QuoteMeta(string(filepath.Separator)))
698-
}

test/testshared/runner.go

+4-19
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"os"
55
"os/exec"
66
"path/filepath"
7-
"runtime"
87
"strings"
98
"sync"
109
"syscall"
@@ -18,14 +17,6 @@ import (
1817
"github.com/golangci/golangci-lint/pkg/logutils"
1918
)
2019

21-
func defaultBinaryName() string {
22-
name := filepath.Join("..", "golangci-lint")
23-
if runtime.GOOS == "windows" {
24-
name += ".exe"
25-
}
26-
return name
27-
}
28-
2920
type RunnerBuilder struct {
3021
tb testing.TB
3122
log logutils.Log
@@ -303,17 +294,17 @@ func (r *RunnerResult) ExpectExitCode(possibleCodes ...int) *RunnerResult {
303294
}
304295

305296
// ExpectOutputRegexp can be called with either a string or compiled regexp
306-
func (r *RunnerResult) ExpectOutputRegexp(s interface{}) *RunnerResult {
297+
func (r *RunnerResult) ExpectOutputRegexp(s string) *RunnerResult {
307298
r.tb.Helper()
308299

309-
assert.Regexp(r.tb, s, r.output, "exit code is %d", r.exitCode)
300+
assert.Regexp(r.tb, normalizeFilePathInRegex(s), r.output, "exit code is %d", r.exitCode)
310301
return r
311302
}
312303

313304
func (r *RunnerResult) ExpectOutputContains(s string) *RunnerResult {
314305
r.tb.Helper()
315306

316-
assert.Contains(r.tb, r.output, s, "exit code is %d", r.exitCode)
307+
assert.Contains(r.tb, r.output, normalizeFilePath(s), "exit code is %d", r.exitCode)
317308
return r
318309
}
319310

@@ -327,7 +318,7 @@ func (r *RunnerResult) ExpectOutputNotContains(s string) *RunnerResult {
327318
func (r *RunnerResult) ExpectOutputEq(s string) *RunnerResult {
328319
r.tb.Helper()
329320

330-
assert.Equal(r.tb, s, r.output, "exit code is %d", r.exitCode)
321+
assert.Equal(r.tb, normalizeFilePath(s), r.output, "exit code is %d", r.exitCode)
331322
return r
332323
}
333324

@@ -356,9 +347,3 @@ func InstallGolangciLint(tb testing.TB) string {
356347

357348
return abs
358349
}
359-
360-
func SkipOnWindows(tb testing.TB) {
361-
if runtime.GOOS == "windows" {
362-
tb.Skip("not supported on Windows")
363-
}
364-
}

test/testshared/runner_test.go

-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package testshared
22

33
import (
44
"path/filepath"
5-
"regexp"
65
"testing"
76

87
"github.com/stretchr/testify/assert"
@@ -220,7 +219,6 @@ func TestRunnerResult_ExpectOutputNotContains(t *testing.T) {
220219

221220
func TestRunnerResult_ExpectOutputRegexp(t *testing.T) {
222221
r := &RunnerResult{tb: t, output: "this is an output"}
223-
r.ExpectOutputRegexp(regexp.MustCompile(`an.+`))
224222
r.ExpectOutputRegexp(`an.+`)
225223
r.ExpectOutputRegexp("an")
226224
}

test/testshared/runner_unix.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//go:build !windows
2+
3+
package testshared
4+
5+
import (
6+
"path/filepath"
7+
"testing"
8+
)
9+
10+
func SkipOnWindows(_ testing.TB) {}
11+
12+
func NormalizeFilePathInJSON(in string) string {
13+
return in
14+
}
15+
16+
// NormalizeFileInString normalizes in quoted string.
17+
func NormalizeFileInString(in string) string {
18+
return in
19+
}
20+
21+
func defaultBinaryName() string {
22+
return filepath.Join("..", "golangci-lint")
23+
}
24+
25+
func normalizeFilePath(in string) string {
26+
return in
27+
}
28+
29+
func normalizeFilePathInRegex(path string) string {
30+
return path
31+
}

test/testshared/runner_windows.go

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//go:build windows
2+
3+
package testshared
4+
5+
import (
6+
"path/filepath"
7+
"regexp"
8+
"strings"
9+
"testing"
10+
)
11+
12+
func SkipOnWindows(tb testing.TB) {
13+
tb.Skip("not supported on Windows")
14+
}
15+
16+
func NormalizeFilePathInJSON(in string) string {
17+
exp := regexp.MustCompile(`(?:^|\b)[\w-/.]+\.go`)
18+
19+
return exp.ReplaceAllStringFunc(in, func(s string) string {
20+
return strings.ReplaceAll(s, "/", "\\\\")
21+
})
22+
}
23+
24+
func defaultBinaryName() string {
25+
return filepath.Join("..", "golangci-lint.exe")
26+
}
27+
28+
// NormalizeFileInString normalizes in quoted string, ie. `\\\\`.
29+
func NormalizeFileInString(in string) string {
30+
return strings.ReplaceAll(filepath.FromSlash(in), "\\", "\\\\")
31+
}
32+
33+
func normalizeFilePath(in string) string {
34+
exp := regexp.MustCompile(`(?:^|\b)[\w-/.]+\.go`)
35+
36+
return exp.ReplaceAllStringFunc(in, func(s string) string {
37+
return strings.ReplaceAll(s, "/", "\\")
38+
})
39+
}
40+
41+
// normalizeFilePathInRegex normalizes path in regular expressions.
42+
// FIXME(ldez) see utils.normalizeFilePathInRegex(...) and maybe move into RunnerResult.ExpectOutputRegexp(...)
43+
// FIXME(ldez) use the same approach as normalizeFilePath and NormalizeFilePathInJSON.
44+
func normalizeFilePathInRegex(path string) string {
45+
// This replacing should be safe because "/" are disallowed in Windows
46+
// https://docs.microsoft.com/windows/win32/fileio/naming-a-file
47+
return strings.ReplaceAll(path, "/", regexp.QuoteMeta(string(filepath.Separator)))
48+
}

0 commit comments

Comments
 (0)