@@ -23,7 +23,8 @@ import (
23
23
// ModuleResolver implements resolver for modules using the go command as little
24
24
// as feasible.
25
25
type ModuleResolver struct {
26
- env * ProcessEnv
26
+ env * ProcessEnv
27
+ moduleCacheDir string
27
28
28
29
Initialized bool
29
30
Main * ModuleJSON
@@ -116,7 +117,7 @@ func (r *ModuleResolver) findPackage(importPath string) (*ModuleJSON, string) {
116
117
}
117
118
pathInModule := importPath [len (m .Path ):]
118
119
pkgDir := filepath .Join (m .Dir , pathInModule )
119
- if dirIsNestedModule (pkgDir , m ) {
120
+ if r . dirIsNestedModule (pkgDir , m ) {
120
121
continue
121
122
}
122
123
@@ -155,7 +156,7 @@ func (r *ModuleResolver) findModuleByDir(dir string) *ModuleJSON {
155
156
continue
156
157
}
157
158
158
- if dirIsNestedModule (dir , m ) {
159
+ if r . dirIsNestedModule (dir , m ) {
159
160
continue
160
161
}
161
162
@@ -166,18 +167,28 @@ func (r *ModuleResolver) findModuleByDir(dir string) *ModuleJSON {
166
167
167
168
// dirIsNestedModule reports if dir is contained in a nested module underneath
168
169
// mod, not actually in mod.
169
- func dirIsNestedModule (dir string , mod * ModuleJSON ) bool {
170
+ func ( r * ModuleResolver ) dirIsNestedModule (dir string , mod * ModuleJSON ) bool {
170
171
if ! strings .HasPrefix (dir , mod .Dir ) {
171
172
return false
172
173
}
173
- mf := findModFile (dir )
174
+ if r .dirInModuleCache (dir ) {
175
+ // Nested modules in the module cache are pruned,
176
+ // so it cannot be a nested module.
177
+ return false
178
+ }
179
+ mf := r .findModFile (dir )
174
180
if mf == "" {
175
181
return false
176
182
}
177
183
return filepath .Dir (mf ) != mod .Dir
178
184
}
179
185
180
- func findModFile (dir string ) string {
186
+ func (r * ModuleResolver ) findModFile (dir string ) string {
187
+ if r .dirInModuleCache (dir ) {
188
+ matches := modCacheRegexp .FindStringSubmatch (dir )
189
+ index := strings .Index (dir , matches [1 ]+ "@" + matches [2 ])
190
+ return filepath .Join (dir [:index ], matches [1 ]+ "@" + matches [2 ], "go.mod" )
191
+ }
181
192
for {
182
193
f := filepath .Join (dir , "go.mod" )
183
194
info , err := os .Stat (f )
@@ -192,6 +203,13 @@ func findModFile(dir string) string {
192
203
}
193
204
}
194
205
206
+ func (r * ModuleResolver ) dirInModuleCache (dir string ) bool {
207
+ if r .moduleCacheDir == "" {
208
+ return false
209
+ }
210
+ return strings .HasPrefix (dir , r .moduleCacheDir )
211
+ }
212
+
195
213
func (r * ModuleResolver ) loadPackageNames (importPaths []string , srcDir string ) (map [string ]string , error ) {
196
214
if err := r .init (); err != nil {
197
215
return nil , err
@@ -223,9 +241,10 @@ func (r *ModuleResolver) scan(_ references) ([]*pkg, error) {
223
241
if r .Main != nil {
224
242
roots = append (roots , gopathwalk.Root {r .Main .Dir , gopathwalk .RootCurrentModule })
225
243
}
226
- for _ , p := range filepath . SplitList ( r . env . GOPATH ) {
227
- roots = append ( roots , gopathwalk. Root { filepath .Join (p , "/pkg/mod" ), gopathwalk . RootModuleCache } )
244
+ if r . moduleCacheDir == "" {
245
+ r . moduleCacheDir = filepath .Join (filepath . SplitList ( r . env . GOPATH )[ 0 ] , "/pkg/mod" )
228
246
}
247
+ roots = append (roots , gopathwalk.Root {r .moduleCacheDir , gopathwalk .RootModuleCache })
229
248
230
249
// Walk replace targets, just in case they're not in any of the above.
231
250
for _ , mod := range r .ModsByModPath {
@@ -359,15 +378,7 @@ func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) (di
359
378
}
360
379
361
380
// Check that this package is not obviously impossible to import.
362
- var modFile string
363
- switch root .Type {
364
- case gopathwalk .RootModuleCache :
365
- matches := modCacheRegexp .FindStringSubmatch (subdir )
366
- index := strings .Index (dir , matches [1 ]+ "@" + matches [2 ])
367
- modFile = filepath .Join (dir [:index ], matches [1 ]+ "@" + matches [2 ], "go.mod" )
368
- default :
369
- modFile = findModFile (dir )
370
- }
381
+ modFile := r .findModFile (dir )
371
382
372
383
var needsReplace bool
373
384
modBytes , err := ioutil .ReadFile (modFile )
0 commit comments