gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/golang.org/x/tools/go/packages/visit.go (about) 1 package packages 2 3 import ( 4 "fmt" 5 "os" 6 "sort" 7 ) 8 9 // Visit visits all the packages in the import graph whose roots are 10 // pkgs, calling the optional pre function the first time each package 11 // is encountered (preorder), and the optional post function after a 12 // package's dependencies have been visited (postorder). 13 // The boolean result of pre(pkg) determines whether 14 // the imports of package pkg are visited. 15 func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { 16 seen := make(map[*Package]bool) 17 var visit func(*Package) 18 visit = func(pkg *Package) { 19 if !seen[pkg] { 20 seen[pkg] = true 21 22 if pre == nil || pre(pkg) { 23 paths := make([]string, 0, len(pkg.Imports)) 24 for path := range pkg.Imports { 25 paths = append(paths, path) 26 } 27 sort.Strings(paths) // Imports is a map, this makes visit stable 28 for _, path := range paths { 29 visit(pkg.Imports[path]) 30 } 31 } 32 33 if post != nil { 34 post(pkg) 35 } 36 } 37 } 38 for _, pkg := range pkgs { 39 visit(pkg) 40 } 41 } 42 43 // PrintErrors prints to os.Stderr the accumulated errors of all 44 // packages in the import graph rooted at pkgs, dependencies first. 45 // PrintErrors returns the number of errors printed. 46 func PrintErrors(pkgs []*Package) int { 47 var n int 48 Visit(pkgs, nil, func(pkg *Package) { 49 for _, err := range pkg.Errors { 50 fmt.Fprintln(os.Stderr, err) 51 n++ 52 } 53 }) 54 return n 55 }