56 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			56 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | package packages | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"fmt" | ||
|  | 	"os" | ||
|  | 	"sort" | ||
|  | ) | ||
|  | 
 | ||
|  | // Visit visits all the packages in the import graph whose roots are | ||
|  | // pkgs, calling the optional pre function the first time each package | ||
|  | // is encountered (preorder), and the optional post function after a | ||
|  | // package's dependencies have been visited (postorder). | ||
|  | // The boolean result of pre(pkg) determines whether | ||
|  | // the imports of package pkg are visited. | ||
|  | func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { | ||
|  | 	seen := make(map[*Package]bool) | ||
|  | 	var visit func(*Package) | ||
|  | 	visit = func(pkg *Package) { | ||
|  | 		if !seen[pkg] { | ||
|  | 			seen[pkg] = true | ||
|  | 
 | ||
|  | 			if pre == nil || pre(pkg) { | ||
|  | 				paths := make([]string, 0, len(pkg.Imports)) | ||
|  | 				for path := range pkg.Imports { | ||
|  | 					paths = append(paths, path) | ||
|  | 				} | ||
|  | 				sort.Strings(paths) // Imports is a map, this makes visit stable | ||
|  | 				for _, path := range paths { | ||
|  | 					visit(pkg.Imports[path]) | ||
|  | 				} | ||
|  | 			} | ||
|  | 
 | ||
|  | 			if post != nil { | ||
|  | 				post(pkg) | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | 	for _, pkg := range pkgs { | ||
|  | 		visit(pkg) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | // PrintErrors prints to os.Stderr the accumulated errors of all | ||
|  | // packages in the import graph rooted at pkgs, dependencies first. | ||
|  | // PrintErrors returns the number of errors printed. | ||
|  | func PrintErrors(pkgs []*Package) int { | ||
|  | 	var n int | ||
|  | 	Visit(pkgs, nil, func(pkg *Package) { | ||
|  | 		for _, err := range pkg.Errors { | ||
|  | 			fmt.Fprintln(os.Stderr, err) | ||
|  | 			n++ | ||
|  | 		} | ||
|  | 	}) | ||
|  | 	return n | ||
|  | } |