1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
13 // Visit visits all the packages in the import graph whose roots are
14 // pkgs, calling the optional pre function the first time each package
15 // is encountered (preorder), and the optional post function after a
16 // package's dependencies have been visited (postorder).
17 // The boolean result of pre(pkg) determines whether
18 // the imports of package pkg are visited.
19 func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
20 seen := make(map[*Package]bool)
21 var visit func(*Package)
22 visit = func(pkg *Package) {
26 if pre == nil || pre(pkg) {
27 paths := make([]string, 0, len(pkg.Imports))
28 for path := range pkg.Imports {
29 paths = append(paths, path)
31 sort.Strings(paths) // Imports is a map, this makes visit stable
32 for _, path := range paths {
33 visit(pkg.Imports[path])
42 for _, pkg := range pkgs {
47 // PrintErrors prints to os.Stderr the accumulated errors of all
48 // packages in the import graph rooted at pkgs, dependencies first.
49 // PrintErrors returns the number of errors printed.
50 func PrintErrors(pkgs []*Package) int {
52 Visit(pkgs, nil, func(pkg *Package) {
53 for _, err := range pkg.Errors {
54 fmt.Fprintln(os.Stderr, err)