72 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package packages
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
 | 
						|
	"golang.org/x/tools/go/packages"
 | 
						|
)
 | 
						|
 | 
						|
func ExtractErrors(pkg *packages.Package) []packages.Error {
 | 
						|
	errors := extractErrorsImpl(pkg, map[*packages.Package]bool{})
 | 
						|
	if len(errors) == 0 {
 | 
						|
		return errors
 | 
						|
	}
 | 
						|
 | 
						|
	seenErrors := map[string]bool{}
 | 
						|
	var uniqErrors []packages.Error
 | 
						|
	for _, err := range errors {
 | 
						|
		if seenErrors[err.Msg] {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		seenErrors[err.Msg] = true
 | 
						|
		uniqErrors = append(uniqErrors, err)
 | 
						|
	}
 | 
						|
 | 
						|
	if len(pkg.GoFiles) != 0 {
 | 
						|
		// errors were extracted from deps and have at leat one file in package
 | 
						|
		for i := range uniqErrors {
 | 
						|
			_, parseErr := ParseErrorPosition(uniqErrors[i].Pos)
 | 
						|
			if parseErr != nil {
 | 
						|
				// change pos to local file to properly process it by processors (properly read line etc)
 | 
						|
				uniqErrors[i].Msg = fmt.Sprintf("%s: %s", uniqErrors[i].Pos, uniqErrors[i].Msg)
 | 
						|
				uniqErrors[i].Pos = fmt.Sprintf("%s:1", pkg.GoFiles[0])
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		// some errors like "code in directory  expects import" don't have Pos, set it here
 | 
						|
		for i := range uniqErrors {
 | 
						|
			err := &uniqErrors[i]
 | 
						|
			if err.Pos == "" {
 | 
						|
				err.Pos = fmt.Sprintf("%s:1", pkg.GoFiles[0])
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return uniqErrors
 | 
						|
}
 | 
						|
 | 
						|
func extractErrorsImpl(pkg *packages.Package, seenPackages map[*packages.Package]bool) []packages.Error {
 | 
						|
	if seenPackages[pkg] {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	seenPackages[pkg] = true
 | 
						|
 | 
						|
	if !pkg.IllTyped { // otherwise it may take hours to traverse all deps many times
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	if len(pkg.Errors) != 0 {
 | 
						|
		return pkg.Errors
 | 
						|
	}
 | 
						|
 | 
						|
	var errors []packages.Error
 | 
						|
	for _, iPkg := range pkg.Imports {
 | 
						|
		iPkgErrors := extractErrorsImpl(iPkg, seenPackages)
 | 
						|
		if iPkgErrors != nil {
 | 
						|
			errors = append(errors, iPkgErrors...)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return errors
 | 
						|
}
 |