diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5a032bc..93d249c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,10 +1,8 @@ version: 2 updates: -- package-ecosystem: gomod - directory: "/" - schedule: - interval: daily - time: "10:00" - open-pull-requests-limit: 10 - reviewers: - - ryancurrah + - package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + time: "10:00" + open-pull-requests-limit: 10 diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 67af946..e9b4748 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -23,30 +23,28 @@ jobs: name: Build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - - uses: actions/setup-go@v5 - with: - go-version: stable + - uses: actions/setup-go@v6 + with: + go-version: stable - - name: Build - run: make build + - name: Build + run: make build - - name: golangci-lint - uses: golangci/golangci-lint-action@v6 - with: - version: latest + - name: golangci-lint + uses: golangci/golangci-lint-action@v9 - - name: Test - run: make test + - name: Test + run: make test - - name: Cover - run: make install-go-tools cover + - name: Cover + run: make install-go-tools cover - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5 - with: - files: ./coverage.xml - flags: unittests - name: codecov-umbrella - fail_ci_if_error: true + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v5 + with: + files: ./coverage.xml + flags: unittests + name: codecov-umbrella + fail_ci_if_error: true diff --git a/.github/workflows/snyk.yml b/.github/workflows/snyk.yml index cc4ecb9..0862daa 100644 --- a/.github/workflows/snyk.yml +++ b/.github/workflows/snyk.yml @@ -1,6 +1,10 @@ name: Snyk -on: push +on: + pull_request: + push: + branches: + - main permissions: actions: none @@ -18,9 +22,9 @@ jobs: security: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v5 - - name: Run Snyk to check for vulnerabilities - uses: snyk/actions/golang@master - env: - SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + - name: Run Snyk to check for vulnerabilities + uses: snyk/actions/golang@master + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} diff --git a/.golangci.yml b/.golangci.yml index b4d72b7..84fcaa4 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,8 +1,8 @@ -# See https://golangci-lint.run/usage/configuration/ +version: "2" + linters: - enable-all: true + default: all disable: - - tenv - lll - gomodguard - gochecknoglobals @@ -13,7 +13,6 @@ linters: - forbidigo - funlen - nlreturn - - gofumpt - nonamedreturns - cyclop - err113 @@ -21,3 +20,11 @@ linters: - tagliatelle - wrapcheck - mnd + - wsl + - noinlineerr + settings: + revive: + rules: + - name: package-comments + disabled: true + \ No newline at end of file diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 2238033..ee9ed28 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -140,7 +140,7 @@ func GetConfig(configFile string) (*gomodguard.Configuration, error) { return nil, fmt.Errorf("%w: %s %s", errFindingConfigFile, configFile, homeDirCfgFile) } - data, err := os.ReadFile(cfgFile) + data, err := os.ReadFile(filepath.Clean(cfgFile)) if err != nil { return nil, fmt.Errorf(errReadingConfigFile, err) } diff --git a/internal/cli/cli_test.go b/internal/cli/cli_test.go index ae3753e..8825e67 100644 --- a/internal/cli/cli_test.go +++ b/internal/cli/cli_test.go @@ -33,7 +33,11 @@ func TestCmdRun(t *testing.T) { func TestWriteCheckstyle(t *testing.T) { outFile, err := os.CreateTemp(t.TempDir(), "checkstyle-*.xml") require.NoError(t, err) - defer outFile.Close() + + defer func() { + err := outFile.Close() + require.NoError(t, err) + }() issues := []gomodguard.Issue{ { diff --git a/processor.go b/processor.go index 4d2fac4..cbfc3c9 100644 --- a/processor.go +++ b/processor.go @@ -9,6 +9,7 @@ import ( "go/token" "os" "os/exec" + "path/filepath" "regexp" "strings" @@ -72,7 +73,7 @@ func NewProcessor(config *Configuration) (*Processor, error) { // and lints them. func (p *Processor) ProcessFiles(filenames []string) (issues []Issue) { for _, filename := range filenames { - data, err := os.ReadFile(filename) + data, err := os.ReadFile(filepath.Clean(filename)) if err != nil { issues = append(issues, Issue{ FileName: filename, @@ -89,51 +90,6 @@ func (p *Processor) ProcessFiles(filenames []string) (issues []Issue) { return issues } -// process file imports and add lint error if blocked package is imported. -func (p *Processor) process(filename string, data []byte) (issues []Issue) { - fileSet := token.NewFileSet() - - file, err := parser.ParseFile(fileSet, filename, data, parser.ParseComments) - if err != nil { - issues = append(issues, Issue{ - FileName: filename, - LineNumber: 0, - Reason: fmt.Sprintf("invalid syntax, file cannot be linted (%s)", err.Error()), - }) - - return - } - - imports := file.Imports - for n := range imports { - importedPkg := strings.TrimSpace(strings.Trim(imports[n].Path.Value, "\"")) - - blockReasons := p.isBlockedPackageFromModFile(importedPkg) - if blockReasons == nil { - continue - } - - for _, blockReason := range blockReasons { - issues = append(issues, p.addError(fileSet, imports[n].Pos(), blockReason)) - } - } - - return issues -} - -// addError adds an error for the file and line number for the current token.Pos -// with the given reason. -func (p *Processor) addError(fileset *token.FileSet, pos token.Pos, reason string) Issue { - position := fileset.Position(pos) - - return Issue{ - FileName: position.Filename, - LineNumber: position.Line, - Position: position, - Reason: reason, - } -} - // SetBlockedModules determines and sets which modules are blocked by reading // the go.mod file of the module that is being linted. // @@ -212,6 +168,51 @@ func (p *Processor) SetBlockedModules() { //nolint:funlen p.blockedModulesFromModFile = blockedModules } +// process file imports and add lint error if blocked package is imported. +func (p *Processor) process(filename string, data []byte) (issues []Issue) { + fileSet := token.NewFileSet() + + file, err := parser.ParseFile(fileSet, filename, data, parser.ParseComments) + if err != nil { + issues = append(issues, Issue{ + FileName: filename, + LineNumber: 0, + Reason: fmt.Sprintf("invalid syntax, file cannot be linted (%s)", err.Error()), + }) + + return + } + + imports := file.Imports + for n := range imports { + importedPkg := strings.TrimSpace(strings.Trim(imports[n].Path.Value, "\"")) + + blockReasons := p.isBlockedPackageFromModFile(importedPkg) + if blockReasons == nil { + continue + } + + for _, blockReason := range blockReasons { + issues = append(issues, p.addError(fileSet, imports[n].Pos(), blockReason)) + } + } + + return issues +} + +// addError adds an error for the file and line number for the current token.Pos +// with the given reason. +func (p *Processor) addError(fileset *token.FileSet, pos token.Pos, reason string) Issue { + position := fileset.Position(pos) + + return Issue{ + FileName: position.Filename, + LineNumber: position.Line, + Position: position, + Reason: reason, + } +} + // isBlockedPackageFromModFile returns the block reason if the package is blocked. func (p *Processor) isBlockedPackageFromModFile(packageName string) []string { for blockedModuleName, blockReasons := range p.blockedModulesFromModFile { @@ -235,12 +236,12 @@ func (p *Processor) isBlockedPackageFromModFile(packageName string) []string { // If the "GOMOD" environment variable is set to "/dev/null", it returns an error indicating that the current working directory must have a go.mod file. // The function returns the contents of the go.mod file as a byte slice and any error encountered during the process. func loadGoModFile() ([]byte, error) { - cmd := exec.Command("go", "env", "-json") + cmd := exec.Command("go", "env", "-json") //nolint:noctx // Ack at some point might use os/exec.CommandContext. stdout, _ := cmd.StdoutPipe() _ = cmd.Start() if stdout == nil { - return os.ReadFile(goModFilename) + return os.ReadFile(filepath.Clean(goModFilename)) } buf := new(bytes.Buffer) diff --git a/processor_internal_test.go b/processor_internal_test.go index 2842655..171ad79 100644 --- a/processor_internal_test.go +++ b/processor_internal_test.go @@ -495,7 +495,7 @@ func TestProcessorSetBlockedModulesWithIndirectDependency(t *testing.T) { processor.SetBlockedModules() // Assert number of blocked modules - assert.Equal(t, len(tt.wantBlockedModules), len(processor.blockedModulesFromModFile)) + assert.Len(t, processor.blockedModulesFromModFile, len(tt.wantBlockedModules)) // Assert blocked modules and reasons for blockedModule, wantReasons := range tt.wantBlockedModules { diff --git a/processor_test.go b/processor_test.go index 7b08451..a9914c0 100644 --- a/processor_test.go +++ b/processor_test.go @@ -1,4 +1,3 @@ -//nolint:scopelint package gomodguard_test import ( @@ -25,17 +24,7 @@ func TestProcessorNewProcessor(t *testing.T) { } func TestProcessorProcessFiles(t *testing.T) { //nolint:funlen - backupWd, err := os.Getwd() - if err != nil { - t.Error(err) - } - - defer func() { _ = os.Chdir(backupWd) }() - - err = os.Chdir("_example/allOptions") - if err != nil { - t.Error(err) - } + t.Chdir("_example/allOptions") wd, err := os.Getwd() if err != nil {