Skip to content

Commit

Permalink
fix: ignore autogen files
Browse files Browse the repository at this point in the history
  • Loading branch information
Rodge0 committed Nov 30, 2021
1 parent 8417f0f commit b408292
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 67 deletions.
141 changes: 76 additions & 65 deletions analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,107 +2,118 @@ package samealias

import (
"bufio"
"fmt"
"flag"
"go/ast"
"go/token"
"os"
"strconv"
"strings"

"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
)

var imports = map[string]string{}

var Analyzer = &analysis.Analyzer{
Name: "samealias",
Doc: "check different aliases for same package",
Run: run,

Requires: []*analysis.Analyzer{inspect.Analyzer},
type aliaspath struct {
alias string
position token.Position
}

func run(pass *analysis.Pass) (interface{}, error) {
filename := pass.Fset.Position(pass.Files[0].Pos()).Filename
var imports = map[string]aliaspath{}

res, err := isAutogenFile(filename)
//nolint:gochecknoglobals
var flagSet flag.FlagSet

if err != nil {
panic(err)
} else if !res {
inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
inspect.Preorder([]ast.Node{(*ast.ImportSpec)(nil)}, func(n ast.Node) {
visitImportSpecNode(n.(*ast.ImportSpec), pass)
})
fmt.Println(filename, "not autogen file, need process")
} else {
fmt.Println(filename, "autogen file, no need process")
}
//nolint:gochecknoglobals
var (
skipAutogens bool
)

return nil, nil
//nolint:gochecknoinits
func init() {
flagSet.BoolVar(&skipAutogens, "skipAutogens", false, "should the linter execute on autogen files as well")
}

func visitImportSpecNode(node *ast.ImportSpec, pass *analysis.Pass) {
if node.Name == nil {
return
func NewAnalyzer() *analysis.Analyzer {
return &analysis.Analyzer{
Name: "samealias",
Doc: "check different aliases for same package",
Run: run,
Flags: flagSet,
}
}

alias := ""
if node.Name != nil {
alias = node.Name.String()
}
func run(pass *analysis.Pass) (interface{}, error) {

if alias == "." {
return // Dot aliases are generally used in tests, so ignore.
}
for _, file := range pass.Files {
filename := pass.Fset.Position((file.Pos())).Filename
if skipAutogens && isAutogenFile(filename) {
continue
}
ast.Inspect(file, func(node ast.Node) bool {
f, ok := node.(*ast.ImportSpec)
if !ok {
if node == nil {
return true
}
return true
}

if strings.HasPrefix(alias, "_") {
return // Used by go test and for auto-includes, not a conflict.
}
if f.Name == nil {
return true
}

path, err := strconv.Unquote(node.Path.Value)
if err != nil {
pass.Reportf(node.Pos(), "import not quoted")
}
alias := ""
if f.Name != nil {
alias = f.Name.String()
}

if alias != "" {
val, ok := imports[path]
if ok {
if val != alias {
message := fmt.Sprintf("package %q have different alias, %q, %q", path, alias, val)

pass.Report(analysis.Diagnostic{
Pos: node.Pos(),
End: node.End(),
Message: message,
SuggestedFixes: []analysis.SuggestedFix{{
Message: "Use same alias or do not use alias",
}},
})
if alias == "." {
return true // Dot aliases are generally used in tests, so ignore.
}
} else {
imports[path] = alias
}
if strings.HasPrefix(alias, "_") {
return true // Used by go test and for auto-includes, not a conflict.
}

path, err := strconv.Unquote(f.Path.Value)
if err != nil {
pass.Reportf(f.Pos(), "import not quoted")
}

if alias != "" {
val, ok := imports[path]
if ok {
if val.alias != alias {
pass.Reportf(f.Pos(), "package %q have alias %q, conflict with %q in %q", path, alias, val.alias, val.position)
}
} else {
imports[path] = aliaspath{alias: alias, position: pass.Fset.Position(f.Pos())}
}
}

return true
})
}

return nil, nil
}

func isAutogenFile(path string) (bool, error) {
// autogen files containe "do not edit" before package key word
func isAutogenFile(path string) bool {
file, err := os.Open(path)
if err != nil {
return false, err
return false
}
defer file.Close()

scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines := strings.ToUpper(scanner.Text())
if strings.Contains(lines, "PACKAGE") {
return false, scanner.Err()
return false
}
if strings.Contains(lines, "DO NOT EDIT") {
return true, scanner.Err()
return true
}
}
return false, scanner.Err()

return false
}
2 changes: 1 addition & 1 deletion cmd/samealias/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ import (
)

func main() {
singlechecker.Main(samealias.Analyzer)
singlechecker.Main(samealias.NewAnalyzer())
}
2 changes: 1 addition & 1 deletion plugin/samealias.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type analyzerPlugin struct{}
// This must be implemented
func (*analyzerPlugin) GetAnalyzers() []*analysis.Analyzer {
return []*analysis.Analyzer{
linters.Analyzer,
linters.NewAnalyzer(),
}
}

Expand Down

0 comments on commit b408292

Please sign in to comment.