Skip to content

Commit

Permalink
add skip files with the given glob patterns and add flags for configu…
Browse files Browse the repository at this point in the history
…re linter.
  • Loading branch information
ghostiam committed Oct 27, 2023
1 parent a24d332 commit 36b448d
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 21 deletions.
6 changes: 1 addition & 5 deletions cmd/protogetter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,5 @@ import (
)

func main() {
cfg := &protogetter.Config{
Mode: protogetter.StandaloneMode,
}

singlechecker.Main(protogetter.NewAnalyzer(cfg))
singlechecker.Main(protogetter.NewAnalyzer(nil))
}
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ module github.com/ghostiam/protogetter

go 1.19

require golang.org/x/tools v0.12.0
require (
github.com/gobwas/glob v0.2.3
github.com/jessevdk/go-flags v1.5.0
golang.org/x/tools v0.12.0
)

require (
golang.org/x/mod v0.12.0 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
Expand Down
91 changes: 76 additions & 15 deletions protogetter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ package protogetter

import (
"bytes"
"flag"
"fmt"
"go/ast"
"go/format"
"go/token"
"log"
"path/filepath"
"strings"

"github.com/gobwas/glob"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/ast/inspector"
)
Expand All @@ -23,31 +26,73 @@ const (
const msgFormat = "avoid direct access to proto field %s, use %s instead"

func NewAnalyzer(cfg *Config) *analysis.Analyzer {
if cfg == nil {
cfg = &Config{}
}

return &analysis.Analyzer{
Name: "protogetter",
Doc: "Reports direct reads from proto message fields when getters should be used",
Name: "protogetter",
Doc: "Reports direct reads from proto message fields when getters should be used",
Flags: flags(cfg),
Run: func(pass *analysis.Pass) (any, error) {
Run(pass, cfg)
return nil, nil
_, err := Run(pass, cfg)
return nil, err
},
}
}

func flags(opts *Config) flag.FlagSet {
fs := flag.NewFlagSet("protogetter", flag.ContinueOnError)

fs.Func("skip-generated-by", "skip files generated with the given prefixes", func(s string) error {
for _, prefix := range strings.Split(s, ",") {
opts.SkipGeneratedBy = append(opts.SkipGeneratedBy, prefix)
}
return nil
})
fs.Func("skip-files", "skip files with the given glob patterns", func(s string) error {
for _, pattern := range strings.Split(s, ",") {
opts.SkipFiles = append(opts.SkipFiles, pattern)
}
return nil
})

return *fs
}

type Config struct {
Mode Mode
SkipGeneratedBy []string
Mode Mode // Zero value is StandaloneMode.
SkipGeneratedBy []string `short:"g" long:"skip-generated-by" description:"Skip files generated with the given prefixes"`
SkipFiles []string `short:"f" long:"skip-files" description:"Skip files with the given glob patterns"`
}

func Run(pass *analysis.Pass, cfg *Config) []Issue {
// Always skip files generated by protoc-gen-go and protoc-gen-grpc-gateway.
skipGeneratedBy := []string{"protoc-gen-go", "protoc-gen-grpc-gateway"}
func Run(pass *analysis.Pass, cfg *Config) ([]Issue, error) {
skipGeneratedBy := make([]string, 0, len(cfg.SkipGeneratedBy)+3)
// Always skip files generated by protoc-gen-go, protoc-gen-go-grpc and protoc-gen-grpc-gateway.
skipGeneratedBy = append(skipGeneratedBy, "protoc-gen-go", "protoc-gen-go-grpc", "protoc-gen-grpc-gateway")
for _, s := range cfg.SkipGeneratedBy {
if strings.TrimSpace(s) == "" {
s = strings.TrimSpace(s)
if s == "" {
continue
}
skipGeneratedBy = append(skipGeneratedBy, s)
}

skipFilesGlobPatterns := make([]glob.Glob, 0, len(cfg.SkipFiles))
for _, s := range cfg.SkipFiles {
s = strings.TrimSpace(s)
if s == "" {
continue
}

compile, err := glob.Compile(s)
if err != nil {
return nil, fmt.Errorf("invalid glob pattern: %w", err)
}

skipFilesGlobPatterns = append(skipFilesGlobPatterns, compile)
}

nodeTypes := []ast.Node{
(*ast.AssignStmt)(nil),
(*ast.CallExpr)(nil),
Expand All @@ -56,14 +101,20 @@ func Run(pass *analysis.Pass, cfg *Config) []Issue {
(*ast.UnaryExpr)(nil),
}

// Skip protoc-generated files.
// Skip filtered files.
var files []*ast.File
for _, f := range pass.Files {
if !skipGeneratedFile(f, skipGeneratedBy) {
files = append(files, f)
if skipGeneratedFile(f, skipGeneratedBy) {
continue
}

// ast.Print(pass.Fset, f)
if skipFilesByGlob(pass.Fset.File(f.Pos()).Name(), skipFilesGlobPatterns) {
continue
}

files = append(files, f)

// ast.Print(pass.Fset, f)
}

ins := inspector.New(files)
Expand All @@ -85,7 +136,7 @@ func Run(pass *analysis.Pass, cfg *Config) []Issue {
}
})

return issues
return issues, nil
}

func analyse(pass *analysis.Pass, filter *PosFilter, n ast.Node) *Report {
Expand Down Expand Up @@ -196,6 +247,16 @@ func skipGeneratedFile(f *ast.File, prefixes []string) bool {
return false
}

func skipFilesByGlob(filename string, patterns []glob.Glob) bool {
for _, pattern := range patterns {
if pattern.Match(filename) || pattern.Match(filepath.Base(filename)) {
return true
}
}

return false
}

func formatNode(node ast.Node) string {
buf := new(bytes.Buffer)
if err := format.Node(buf, token.NewFileSet(), node); err != nil {
Expand Down

0 comments on commit 36b448d

Please sign in to comment.