internal/imports: save scanned module cache results

Save the packages found when scanning of the module cache.
The computed package may have a different import path due
to replace directives, so this needs to be updated
when the moduleResolver is initialized again.

Change-Id: Ib575fcc59b814ff263b431362df3698839a282f6
Reviewed-on: https://go-review.googlesource.com/c/tools/+/186301
Run-TryBot: Suzy Mueller <suzmue@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Suzy Mueller 2019-07-16 17:37:05 -04:00
Родитель c81b74871b
Коммит 82a3ea8a50
3 изменённых файлов: 43 добавлений и 2 удалений

Просмотреть файл

@ -27,6 +27,8 @@ type ModuleResolver struct {
Main *ModuleJSON
ModsByModPath []*ModuleJSON // All modules, ordered by # of path components in module Path...
ModsByDir []*ModuleJSON // ...or Dir.
ModCachePkgs map[string]*pkg // Packages in the mod cache, keyed by absolute directory.
}
type ModuleJSON struct {
@ -87,6 +89,8 @@ func (r *ModuleResolver) init() error {
return count(j) < count(i) // descending order
})
r.ModCachePkgs = make(map[string]*pkg)
r.Initialized = true
return nil
}
@ -232,6 +236,15 @@ func (r *ModuleResolver) scan(_ references) ([]*pkg, error) {
dupCheck[dir] = true
absDir := dir
// Packages in the module cache are immutable. If we have
// already seen this package on a previous scan of the module
// cache, return that result.
if p, ok := r.ModCachePkgs[absDir]; ok {
result = append(result, p)
return
}
subdir := ""
if dir != root.Path {
subdir = dir[len(root.Path)+len("/"):]
@ -298,10 +311,18 @@ func (r *ModuleResolver) scan(_ references) ([]*pkg, error) {
dir = canonicalDir
}
result = append(result, &pkg{
res := &pkg{
importPathShort: VendorlessPath(importPath),
dir: dir,
})
}
switch root.Type {
case gopathwalk.RootModuleCache:
// Save the results of processing this directory.
r.ModCachePkgs[absDir] = res
}
result = append(result, res)
}, gopathwalk.Options{Debug: r.env.Debug, ModulesEnabled: true})
return result, nil
}

Просмотреть файл

@ -118,6 +118,25 @@ import _ "example.com"
mt.assertFound("example.com", "x")
}
// Tests that scanning the module cache > 1 time is able to find the same module.
func TestModMultipleScans(t *testing.T) {
mt := setup(t, `
-- go.mod --
module x
require example.com v1.0.0
-- x.go --
package x
import _ "example.com"
`, "")
defer mt.cleanup()
mt.assertScanFinds("example.com", "x")
mt.assertScanFinds("example.com", "x")
}
// Tests that -mod=vendor sort of works. Adapted from mod_getmode_vendor.txt.
func TestModeGetmodeVendor(t *testing.T) {
mt := setup(t, `

Просмотреть файл

@ -75,6 +75,7 @@ func Imports(ctx context.Context, view View, f GoFile, rng span.Range) ([]TextEd
resolver.Main = nil
resolver.ModsByModPath = nil
resolver.ModsByDir = nil
resolver.ModCachePkgs = nil
}
options := &imports.Options{
Env: view.ProcessEnv(ctx),