Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -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
40 changes: 19 additions & 21 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
16 changes: 10 additions & 6 deletions .github/workflows/snyk.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: Snyk

on: push
on:
pull_request:
push:
branches:
- main

permissions:
actions: none
Expand All @@ -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 }}
15 changes: 11 additions & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# See https://golangci-lint.run/usage/configuration/
version: "2"

linters:
enable-all: true
default: all
disable:
- tenv
- lll
- gomodguard
- gochecknoglobals
Expand All @@ -13,11 +13,18 @@ linters:
- forbidigo
- funlen
- nlreturn
- gofumpt
- nonamedreturns
- cyclop
- err113
- perfsprint
- tagliatelle
- wrapcheck
- mnd
- wsl
- noinlineerr
settings:
revive:
rules:
- name: package-comments
disabled: true

2 changes: 1 addition & 1 deletion internal/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
6 changes: 5 additions & 1 deletion internal/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
{
Expand Down
97 changes: 49 additions & 48 deletions processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"go/token"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"

Expand Down Expand Up @@ -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,
Expand All @@ -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.
//
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion processor_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
13 changes: 1 addition & 12 deletions processor_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//nolint:scopelint
package gomodguard_test

import (
Expand All @@ -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 {
Expand Down
Loading