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
 | |
| }
 | 
