From 6dadabb319ae144cd3340e141d25535ebcc05bbc Mon Sep 17 00:00:00 2001 From: wwcchh0123 <1170142389@qq.com> Date: Mon, 2 Sep 2024 15:15:17 +0800 Subject: [PATCH] feat: new gomodcheck linter --- internal/linters/go/gomodcheck/gomodcheck.go | 81 ++++++++++++++++++++ main.go | 1 + 2 files changed, 82 insertions(+) create mode 100644 internal/linters/go/gomodcheck/gomodcheck.go diff --git a/internal/linters/go/gomodcheck/gomodcheck.go b/internal/linters/go/gomodcheck/gomodcheck.go new file mode 100644 index 00000000..cafac2c2 --- /dev/null +++ b/internal/linters/go/gomodcheck/gomodcheck.go @@ -0,0 +1,81 @@ +package gomodcheck + +import ( + "bufio" + "context" + "os" + "regexp" + + "path/filepath" + "strings" + + "github.com/qiniu/reviewbot/config" + "github.com/qiniu/reviewbot/internal/linters" + + "github.com/qiniu/x/xlog" +) + +var lintName = "gomodcheck" + +func init() { + linters.RegisterPullRequestHandler(lintName, goModCheckHandler) + linters.RegisterLinterLanguages(lintName, []string{".go", ".mod"}) +} + +func goModCheckHandler(ctx context.Context, a linters.Agent) error { + log := xlog.New(ctx.Value(config.EventGUIDKey).(string)) + parsedOutput, err := goModCheckOutput(log, a) + if err != nil { + log.Errorf("gomodchecks parse output failed: %v", err) + return err + } + return linters.Report(log, a, parsedOutput) + +} + +func goModCheckOutput(log *xlog.Logger, a linters.Agent) (map[string][]linters.LinterOutput, error) { + output := make(map[string][]linters.LinterOutput) + for _, file := range a.PullRequestChangedFiles { + if filepath.Ext(file.GetFilename()) != ".mod" { + continue + } + + replaceRegex := regexp.MustCompile(`^replace\s+([^\s]+)\s+=>\s+([^\s]+)`) + goModPath := filepath.Join(a.RepoDir, file.GetFilename()) + file, err := os.Open(goModPath) + if err != nil { + log.Errorf("Error opening %s: %s", goModPath, err) + continue + } + defer file.Close() + + scanner := bufio.NewScanner(file) + lineNumber := 0 + filename := strings.TrimPrefix(goModPath, a.RepoDir+"/") + msg := "It is not recommended to use `replace ../xxx` to specify dependency " + + for scanner.Scan() { + lineNumber++ + line := scanner.Text() + if matches := replaceRegex.FindStringSubmatch(line); len(matches) > 0 { + replacementPath := matches[2] + if strings.HasPrefix(replacementPath, "../") { + output[filename] = append(output[filename], linters.LinterOutput{ + File: filename, + Line: lineNumber, + Column: 1, + Message: msg, + }) + } + } + } + + if err := scanner.Err(); err != nil { + log.Errorf("Error reading go.mod: %s", err) + continue + } + + } + + return output, nil +} diff --git a/main.go b/main.go index 1e470dca..808ae289 100644 --- a/main.go +++ b/main.go @@ -40,6 +40,7 @@ import ( _ "github.com/qiniu/reviewbot/internal/linters/git-flow/commit-check" _ "github.com/qiniu/reviewbot/internal/linters/go/gofmt" _ "github.com/qiniu/reviewbot/internal/linters/go/golangci_lint" + _ "github.com/qiniu/reviewbot/internal/linters/go/gomodcheck" _ "github.com/qiniu/reviewbot/internal/linters/java/pmdcheck" _ "github.com/qiniu/reviewbot/internal/linters/java/stylecheck" _ "github.com/qiniu/reviewbot/internal/linters/lua/luacheck"