Skip to content

Commit

Permalink
feat: go list all pkgs and cache them to improve build speed
Browse files Browse the repository at this point in the history
  • Loading branch information
LiusCraft committed Feb 23, 2024
1 parent 517ed22 commit ea2344b
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions packages/imp.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@ import (
"go/types"
"os"
"os/exec"
"strings"
"sync"

"golang.org/x/tools/go/gcexportdata"
)

// pkgPath Caches
var (
packageCacheMap = map[string]string{}
mutex sync.Mutex
)

// ----------------------------------------------------------------------------

type Importer struct {
Expand All @@ -40,6 +47,9 @@ func NewImporter(fset *token.FileSet, workDir ...string) *Importer {
if len(workDir) > 0 {
dir = workDir[0]
}
if len(packageCacheMap) == 0 {
goListExportCache(".", "")
}
if fset == nil {
fset = token.NewFileSet()
}
Expand Down Expand Up @@ -96,6 +106,11 @@ func (p *Importer) loadByExport(expfile string, pkgPath string) (ret *types.Pack
// FindExport lookups export file (.a) of a package by its pkgPath.
// It returns empty if pkgPath not found.
func FindExport(dir, pkgPath string) (expfile string, err error) {
pkgFilePath := goListExportCache(dir, pkgPath)
if len(pkgFilePath) > 0 {
return pkgFilePath, nil
}

data, err := golistExport(dir, pkgPath)
if err != nil {
return
Expand All @@ -104,6 +119,35 @@ func FindExport(dir, pkgPath string) (expfile string, err error) {
return
}

// https://github.com/goplus/gop/issues/1710
// Not fully optimized
// Retrieve all imports in the specified directory and cache them
func goListExportCache(dir, pkg string) string {
var stdout, stderr bytes.Buffer
cmd := exec.Command("go", "list", "-f", "{{.ImportPath}},{{.Export}}", "-export", "all")
cmd.Stdout = &stdout
cmd.Stderr = &stderr
cmd.Dir = dir
mutex.Lock()
if len(packageCacheMap[pkg]) > 0 {
mutex.Unlock()
return packageCacheMap[pkg]
}
err := cmd.Run()
mutex.Unlock()
if err == nil {
ret := stdout.String()
for _, v := range strings.Split(ret, "\n") {
s := strings.Split(v, ",")
if len(s) != 2 {
continue
}
packageCacheMap[s[0]] = s[1]
}
}
return packageCacheMap[pkg]
}

func golistExport(dir, pkgPath string) (ret []byte, err error) {
var stdout, stderr bytes.Buffer
cmd := exec.Command("go", "list", "-f={{.Export}}", "-export", pkgPath)
Expand Down

0 comments on commit ea2344b

Please sign in to comment.