mirror of
https://github.com/golang/go
synced 2024-11-23 07:30:05 -07:00
cmd/go: use index to match packages in dependency modules
If we're trying to search in a module in the module cache, instead iterate over the packages in the index. Change-Id: Ia94cbe6e9690110c28b93dbb33810680e3010381 Reviewed-on: https://go-review.googlesource.com/c/go/+/403756 Reviewed-by: Michael Matloob <matloob@golang.org> Reviewed-by: Peter Weinberger <pjw@google.com> Run-TryBot: Michael Matloob <matloob@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
ea5d7cbc26
commit
11195c60e6
@ -210,7 +210,7 @@ func (mi *ModuleIndex) Packages() []string {
|
|||||||
|
|
||||||
// RelPath returns the path relative to the module's root.
|
// RelPath returns the path relative to the module's root.
|
||||||
func (mi *ModuleIndex) RelPath(path string) string {
|
func (mi *ModuleIndex) RelPath(path string) string {
|
||||||
return filepath.Clean(str.TrimFilePathPrefix(path, mi.modroot))
|
return str.TrimFilePathPrefix(path, mi.modroot)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImportPackage is the equivalent of build.Import given the information in ModuleIndex.
|
// ImportPackage is the equivalent of build.Import given the information in ModuleIndex.
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"cmd/go/internal/base"
|
"cmd/go/internal/base"
|
||||||
"cmd/go/internal/fsys"
|
"cmd/go/internal/fsys"
|
||||||
"cmd/go/internal/par"
|
"cmd/go/internal/par"
|
||||||
|
"cmd/go/internal/str"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -54,10 +55,10 @@ func indexModule(modroot string) ([]byte, error) {
|
|||||||
if !info.IsDir() {
|
if !info.IsDir() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
rel, err := filepath.Rel(modroot, path)
|
if !str.HasFilePathPrefix(path, modroot) {
|
||||||
if err != nil {
|
panic(fmt.Errorf("path %v in walk doesn't have modroot %v as prefix:", path, modroot))
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
rel := str.TrimFilePathPrefix(path, modroot)
|
||||||
packages = append(packages, importRaw(modroot, rel))
|
packages = append(packages, importRaw(modroot, rel))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -6,15 +6,18 @@ package modload
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"cmd/go/internal/cfg"
|
"cmd/go/internal/cfg"
|
||||||
"cmd/go/internal/fsys"
|
"cmd/go/internal/fsys"
|
||||||
"cmd/go/internal/imports"
|
"cmd/go/internal/imports"
|
||||||
|
"cmd/go/internal/modindex"
|
||||||
"cmd/go/internal/search"
|
"cmd/go/internal/search"
|
||||||
|
|
||||||
"golang.org/x/mod/module"
|
"golang.org/x/mod/module"
|
||||||
@ -165,6 +168,12 @@ func matchPackages(ctx context.Context, m *search.Match, tags map[string]bool, f
|
|||||||
}
|
}
|
||||||
modPrefix = mod.Path
|
modPrefix = mod.Path
|
||||||
}
|
}
|
||||||
|
if mi, err := modindex.Get(root); err == nil {
|
||||||
|
walkFromIndex(ctx, m, tags, root, mi, have, modPrefix)
|
||||||
|
continue
|
||||||
|
} else if !errors.Is(err, modindex.ErrNotIndexed) {
|
||||||
|
m.AddError(err)
|
||||||
|
}
|
||||||
|
|
||||||
prune := pruneVendor
|
prune := pruneVendor
|
||||||
if isLocal {
|
if isLocal {
|
||||||
@ -176,6 +185,60 @@ func matchPackages(ctx context.Context, m *search.Match, tags map[string]bool, f
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// walkFromIndex matches packages in a module using the module index. modroot
|
||||||
|
// is the module's root directory on disk, index is the ModuleIndex for the
|
||||||
|
// module, and importPathRoot is the module's path prefix.
|
||||||
|
func walkFromIndex(ctx context.Context, m *search.Match, tags map[string]bool, modroot string, index *modindex.ModuleIndex, have map[string]bool, importPathRoot string) {
|
||||||
|
isMatch := func(string) bool { return true }
|
||||||
|
treeCanMatch := func(string) bool { return true }
|
||||||
|
if !m.IsMeta() {
|
||||||
|
isMatch = search.MatchPattern(m.Pattern())
|
||||||
|
treeCanMatch = search.TreeCanMatchPattern(m.Pattern())
|
||||||
|
}
|
||||||
|
loopPackages:
|
||||||
|
for _, reldir := range index.Packages() {
|
||||||
|
// Avoid .foo, _foo, and testdata subdirectory trees.
|
||||||
|
p := reldir
|
||||||
|
for {
|
||||||
|
elem, rest, found := strings.Cut(p, string(filepath.Separator))
|
||||||
|
if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" {
|
||||||
|
continue loopPackages
|
||||||
|
}
|
||||||
|
if found && elem == "vendor" {
|
||||||
|
// Ignore this path if it contains the element "vendor" anywhere
|
||||||
|
// except for the last element (packages named vendor are allowed
|
||||||
|
// for historical reasons). Note that found is true when this
|
||||||
|
// isn't the last path element.
|
||||||
|
continue loopPackages
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
// Didn't find the separator, so we're considering the last element.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p = rest
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't use GOROOT/src.
|
||||||
|
if reldir == "" && importPathRoot == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
name := path.Join(importPathRoot, filepath.ToSlash(reldir))
|
||||||
|
if !treeCanMatch(name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !have[name] {
|
||||||
|
have[name] = true
|
||||||
|
if isMatch(name) {
|
||||||
|
if _, _, err := index.ScanDir(reldir, tags); err != imports.ErrNoGo {
|
||||||
|
m.Pkgs = append(m.Pkgs, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MatchInModule identifies the packages matching the given pattern within the
|
// MatchInModule identifies the packages matching the given pattern within the
|
||||||
// given module version, which does not need to be in the build list or module
|
// given module version, which does not need to be in the build list or module
|
||||||
// requirement graph.
|
// requirement graph.
|
||||||
|
Loading…
Reference in New Issue
Block a user