Skip to content

Commit

Permalink
normalize path
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez committed Aug 24, 2022
1 parent 48deaeb commit 7f342cd
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 66 deletions.
16 changes: 0 additions & 16 deletions pkg/result/processors/utils.go → pkg/result/processors/issues.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package processors

import (
"path/filepath"
"regexp"
"strings"

"github.com/pkg/errors"

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

return retIssues
}

var separatorToReplace = regexp.QuoteMeta(string(filepath.Separator))

func normalizePathInRegex(path string) string {
if filepath.Separator == '/' {
return path
}

// This replacing should be safe because "/" are disallowed in Windows
// https://docs.microsoft.com/ru-ru/windows/win32/fileio/naming-a-file
return strings.ReplaceAll(path, "/", separatorToReplace)
}
4 changes: 2 additions & 2 deletions pkg/result/processors/path_prefixer.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package processors

import (
"path"
"path/filepath"

"github.com/golangci/golangci-lint/pkg/result"
)
Expand All @@ -27,7 +27,7 @@ func (*PathPrefixer) Name() string {
func (p *PathPrefixer) Process(issues []result.Issue) ([]result.Issue, error) {
if p.prefix != "" {
for i := range issues {
issues[i].Pos.Filename = path.Join(p.prefix, issues[i].Pos.Filename)
issues[i].Pos.Filename = filepath.Join(p.prefix, issues[i].Pos.Filename)
}
}
return issues, nil
Expand Down
32 changes: 24 additions & 8 deletions pkg/result/processors/path_prefixer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package processors

import (
"go/token"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/golangci/golangci-lint/pkg/result"
Expand All @@ -12,26 +14,40 @@ import (
func TestPathPrefixer_Process(t *testing.T) {
paths := func(ps ...string) (issues []result.Issue) {
for _, p := range ps {
issues = append(issues, result.Issue{Pos: token.Position{Filename: p}})
issues = append(issues, result.Issue{Pos: token.Position{Filename: filepath.FromSlash(p)}})
}
return
}

for _, tt := range []struct {
name, prefix string
issues, want []result.Issue
}{
{"empty prefix", "", paths("some/path", "cool"), paths("some/path", "cool")},
{"prefix", "ok", paths("some/path", "cool"), paths("ok/some/path", "ok/cool")},
{"prefix slashed", "ok/", paths("some/path", "cool"), paths("ok/some/path", "ok/cool")},
{
name: "empty prefix",
issues: paths("some/path", "cool"),
want: paths("some/path", "cool"),
},
{
name: "prefix",
prefix: "ok",
issues: paths("some/path", "cool"),
want: paths("ok/some/path", "ok/cool"),
},
{
name: "prefix slashed",
prefix: "ok/",
issues: paths("some/path", "cool"),
want: paths("ok/some/path", "ok/cool"),
},
} {
t.Run(tt.name, func(t *testing.T) {
r := require.New(t)

p := NewPathPrefixer(tt.prefix)

got, err := p.Process(tt.issues)
r.NoError(err, "prefixer should never error")
require.NoError(t, err)

r.Equal(got, tt.want)
assert.Equal(t, got, tt.want)
})
}
}
7 changes: 7 additions & 0 deletions pkg/result/processors/path_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build !windows

package processors

func normalizePathInRegex(path string) string {
return path
}
21 changes: 21 additions & 0 deletions pkg/result/processors/path_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//go:build windows

package processors

import (
"path/filepath"
"regexp"
"strings"
)

var separatorToReplace = regexp.QuoteMeta(string(filepath.Separator))

func normalizePathInRegex(path string) string {
if filepath.Separator == '/' {
return path
}

// This replacing should be safe because "/" are disallowed in Windows
// https://docs.microsoft.com/ru-ru/windows/win32/fileio/naming-a-file
return strings.ReplaceAll(path, "/", separatorToReplace)
}
9 changes: 4 additions & 5 deletions test/output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package test
import (
"fmt"
"os"
"path"
"path/filepath"
"testing"

Expand Down Expand Up @@ -50,11 +49,11 @@ func TestOutput_Stderr(t *testing.T) {
Runner().
Install().
Run().
ExpectHasIssue(expectedJSONOutput)
ExpectHasIssue(testshared.NormalizeFilePathInJSON(expectedJSONOutput))
}

func TestOutput_File(t *testing.T) {
resultPath := path.Join(t.TempDir(), "golangci_lint_test_result")
resultPath := filepath.Join(t.TempDir(), "golangci_lint_test_result")

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

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

b, err := os.ReadFile(resultPath)
require.NoError(t, err)
require.Contains(t, string(b), expectedJSONOutput)
require.Contains(t, string(b), testshared.NormalizeFilePathInJSON(expectedJSONOutput))
}

func TestOutput_Multiple(t *testing.T) {
Expand All @@ -94,5 +93,5 @@ func TestOutput_Multiple(t *testing.T) {
Run().
//nolint:misspell
ExpectHasIssue("testdata/misspell.go:6:38: `occured` is a misspelling of `occurred`").
ExpectOutputContains(expectedJSONOutput)
ExpectOutputContains(testshared.NormalizeFilePathInJSON(expectedJSONOutput))
}
16 changes: 2 additions & 14 deletions test/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package test

import (
"path/filepath"
"regexp"
"strings"
"testing"

Expand Down Expand Up @@ -46,7 +45,7 @@ func TestNotExistingDirRun(t *testing.T) {
Run().
ExpectExitCode(exitcodes.Failure).
ExpectOutputContains("cannot find package").
ExpectOutputContains("/testdata/no_such_dir")
ExpectOutputContains(testshared.NormalizeFileInString("/testdata/no_such_dir"))
}

func TestSymlinkLoop(t *testing.T) {
Expand Down Expand Up @@ -681,18 +680,7 @@ func TestPathPrefix(t *testing.T) {
WithTargetPath(testdataDir, "withtests").
Runner().
Run().
ExpectOutputRegexp(normalizePathInRegex(test.pattern))
ExpectOutputRegexp(test.pattern)
})
}
}

// FIXME(ldez) see utils.normalizePathInRegex(...) and maybe move into RunnerResult.ExpectOutputRegexp(...)
func normalizePathInRegex(path string) string {
if filepath.Separator == '/' {
return path
}

// This replacing should be safe because "/" are disallowed in Windows
// https://docs.microsoft.com/windows/win32/fileio/naming-a-file
return strings.ReplaceAll(path, "/", regexp.QuoteMeta(string(filepath.Separator)))
}
23 changes: 4 additions & 19 deletions test/testshared/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"sync"
"syscall"
Expand All @@ -18,14 +17,6 @@ import (
"github.com/golangci/golangci-lint/pkg/logutils"
)

func defaultBinaryName() string {
name := filepath.Join("..", "golangci-lint")
if runtime.GOOS == "windows" {
name += ".exe"
}
return name
}

type RunnerBuilder struct {
tb testing.TB
log logutils.Log
Expand Down Expand Up @@ -303,17 +294,17 @@ func (r *RunnerResult) ExpectExitCode(possibleCodes ...int) *RunnerResult {
}

// ExpectOutputRegexp can be called with either a string or compiled regexp
func (r *RunnerResult) ExpectOutputRegexp(s interface{}) *RunnerResult {
func (r *RunnerResult) ExpectOutputRegexp(s string) *RunnerResult {
r.tb.Helper()

assert.Regexp(r.tb, s, r.output, "exit code is %d", r.exitCode)
assert.Regexp(r.tb, normalizeFilePathInRegex(s), r.output, "exit code is %d", r.exitCode)
return r
}

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

assert.Contains(r.tb, r.output, s, "exit code is %d", r.exitCode)
assert.Contains(r.tb, r.output, normalizeFilePath(s), "exit code is %d", r.exitCode)
return r
}

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

assert.Equal(r.tb, s, r.output, "exit code is %d", r.exitCode)
assert.Equal(r.tb, normalizeFilePath(s), r.output, "exit code is %d", r.exitCode)
return r
}

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

return abs
}

func SkipOnWindows(tb testing.TB) {
if runtime.GOOS == "windows" {
tb.Skip("not supported on Windows")
}
}
2 changes: 0 additions & 2 deletions test/testshared/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package testshared

import (
"path/filepath"
"regexp"
"testing"

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

func TestRunnerResult_ExpectOutputRegexp(t *testing.T) {
r := &RunnerResult{tb: t, output: "this is an output"}
r.ExpectOutputRegexp(regexp.MustCompile(`an.+`))
r.ExpectOutputRegexp(`an.+`)
r.ExpectOutputRegexp("an")
}
31 changes: 31 additions & 0 deletions test/testshared/runner_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//go:build !windows

package testshared

import (
"path/filepath"
"testing"
)

func SkipOnWindows(_ testing.TB) {}

func NormalizeFilePathInJSON(in string) string {
return in
}

// NormalizeFileInString normalizes in quoted string.
func NormalizeFileInString(in string) string {
return in
}

func defaultBinaryName() string {
return filepath.Join("..", "golangci-lint")
}

func normalizeFilePath(in string) string {
return in
}

func normalizeFilePathInRegex(path string) string {
return path
}
48 changes: 48 additions & 0 deletions test/testshared/runner_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//go:build windows

package testshared

import (
"path/filepath"
"regexp"
"strings"
"testing"
)

func SkipOnWindows(tb testing.TB) {
tb.Skip("not supported on Windows")
}

func NormalizeFilePathInJSON(in string) string {
exp := regexp.MustCompile(`(?:^|\b)[\w-/.]+\.go`)

return exp.ReplaceAllStringFunc(in, func(s string) string {
return strings.ReplaceAll(s, "/", "\\\\")
})
}

func defaultBinaryName() string {
return filepath.Join("..", "golangci-lint.exe")
}

// NormalizeFileInString normalizes in quoted string, ie. `\\\\`.
func NormalizeFileInString(in string) string {
return strings.ReplaceAll(filepath.FromSlash(in), "\\", "\\\\")
}

func normalizeFilePath(in string) string {
exp := regexp.MustCompile(`(?:^|\b)[\w-/.]+\.go`)

return exp.ReplaceAllStringFunc(in, func(s string) string {
return strings.ReplaceAll(s, "/", "\\")
})
}

// normalizeFilePathInRegex normalizes path in regular expressions.
// FIXME(ldez) see utils.normalizeFilePathInRegex(...) and maybe move into RunnerResult.ExpectOutputRegexp(...)
// FIXME(ldez) use the same approach as normalizeFilePath and NormalizeFilePathInJSON.
func normalizeFilePathInRegex(path string) string {
// This replacing should be safe because "/" are disallowed in Windows
// https://docs.microsoft.com/windows/win32/fileio/naming-a-file
return strings.ReplaceAll(path, "/", regexp.QuoteMeta(string(filepath.Separator)))
}

0 comments on commit 7f342cd

Please sign in to comment.