github.com/wgliang/gometalinter@v2.0.6-0.20180523041418-a75adcf7cb0e+incompatible/_linters/src/mvdan.cc/lint/cmd/metalint/main.go (about) 1 // Copyright (c) 2017, Daniel Martà <mvdan@mvdan.cc> 2 // See LICENSE for licensing information 3 4 package main // import "mvdan.cc/lint/cmd/metalint" 5 6 import ( 7 "flag" 8 "fmt" 9 "os" 10 "strings" 11 12 "golang.org/x/tools/go/loader" 13 "golang.org/x/tools/go/ssa" 14 "golang.org/x/tools/go/ssa/ssautil" 15 16 "mvdan.cc/lint" 17 18 "github.com/kisielk/gotool" 19 20 interfacer "mvdan.cc/interfacer/check" 21 unparam "mvdan.cc/unparam/check" 22 ) 23 24 var tests = flag.Bool("tests", false, "include tests") 25 26 func main() { 27 flag.Parse() 28 if err := runLinters(flag.Args()...); err != nil { 29 fmt.Fprintln(os.Stderr, err) 30 os.Exit(1) 31 } 32 } 33 34 var linters = [...]struct { 35 name string 36 checker lint.Checker 37 }{ 38 {"unparam", &unparam.Checker{}}, 39 {"interfacer", &interfacer.Checker{}}, 40 } 41 42 type metaChecker struct { 43 wd string 44 45 lprog *loader.Program 46 prog *ssa.Program 47 } 48 49 func runLinters(args ...string) error { 50 paths := gotool.ImportPaths(args) 51 wd, err := os.Getwd() 52 if err != nil { 53 return err 54 } 55 c := &metaChecker{wd: wd} 56 var conf loader.Config 57 if _, err := conf.FromArgs(paths, *tests); err != nil { 58 return err 59 } 60 if c.lprog, err = conf.Load(); err != nil { 61 return err 62 } 63 for _, l := range linters { 64 l.checker.Program(c.lprog) 65 if ssaChecker, ok := l.checker.(lint.WithSSA); ok { 66 if c.prog == nil { 67 c.prog = ssautil.CreateProgram(c.lprog, 0) 68 c.prog.Build() 69 } 70 ssaChecker.ProgramSSA(c.prog) 71 } 72 issues, err := l.checker.Check() 73 if err != nil { 74 return err 75 } 76 c.printIssues(l.name, issues) 77 } 78 return nil 79 } 80 81 func (c *metaChecker) printIssues(name string, issues []lint.Issue) { 82 for _, issue := range issues { 83 fpos := c.lprog.Fset.Position(issue.Pos()).String() 84 if strings.HasPrefix(fpos, c.wd) { 85 fpos = fpos[len(c.wd)+1:] 86 } 87 fmt.Printf("%s: %s (%s)\n", fpos, issue.Message(), name) 88 } 89 }