Restore related GOPATH-mode go get functions
This commit is contained in:
@@ -604,6 +604,51 @@ func (sp *ImportStack) shorterThan(t []string) bool {
|
||||
// we return the same pointer each time.
|
||||
var packageCache = map[string]*Package{}
|
||||
|
||||
// ClearPackageCache clears the in-memory package cache and the preload caches.
|
||||
// It is only for use by GOPATH-based "go get".
|
||||
// TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
|
||||
func ClearPackageCache() {
|
||||
clear(packageCache)
|
||||
resolvedImportCache.Clear()
|
||||
packageDataCache.Clear()
|
||||
}
|
||||
|
||||
// ClearPackageCachePartial clears packages with the given import paths from the
|
||||
// in-memory package cache and the preload caches. It is only for use by
|
||||
// GOPATH-based "go get".
|
||||
// TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
|
||||
func ClearPackageCachePartial(args []string) {
|
||||
shouldDelete := make(map[string]bool)
|
||||
for _, arg := range args {
|
||||
shouldDelete[arg] = true
|
||||
if p := packageCache[arg]; p != nil {
|
||||
delete(packageCache, arg)
|
||||
}
|
||||
}
|
||||
resolvedImportCache.DeleteIf(func(key importSpec) bool {
|
||||
return shouldDelete[key.path]
|
||||
})
|
||||
packageDataCache.DeleteIf(func(key string) bool {
|
||||
return shouldDelete[key]
|
||||
})
|
||||
}
|
||||
|
||||
// ReloadPackageNoFlags is like LoadImport but makes sure
|
||||
// not to use the package cache.
|
||||
// It is only for use by GOPATH-based "go get".
|
||||
// TODO(rsc): When GOPATH-based "go get" is removed, delete this function.
|
||||
func ReloadPackageNoFlags(arg string, stk *ImportStack) *Package {
|
||||
p := packageCache[arg]
|
||||
if p != nil {
|
||||
delete(packageCache, arg)
|
||||
resolvedImportCache.DeleteIf(func(key importSpec) bool {
|
||||
return key.path == p.ImportPath
|
||||
})
|
||||
packageDataCache.Delete(p.ImportPath)
|
||||
}
|
||||
return LoadPackage(context.TODO(), PackageOpts{}, arg, base.Cwd(), stk, nil, 0)
|
||||
}
|
||||
|
||||
// dirToImportPath returns the pseudo-import path we use for a package
|
||||
// outside the Go path. It begins with _/ and then contains the full path
|
||||
// to the directory. If the package lives in c:\home\gopher\my\pkg then
|
||||
@@ -655,6 +700,20 @@ const (
|
||||
cmdlinePkgLiteral
|
||||
)
|
||||
|
||||
// LoadImport scans the directory named by path, which must be an import path,
|
||||
// but possibly a local import path (an absolute file system path or one beginning
|
||||
// with ./ or ../). A local relative path is interpreted relative to srcDir.
|
||||
// It returns a *Package describing the package found in that directory.
|
||||
// LoadImport does not set tool flags and should only be used by
|
||||
// this package, as part of a bigger load operation, and by GOPATH-based "go get".
|
||||
// TODO(rsc): When GOPATH-based "go get" is removed, unexport this function.
|
||||
// The returned PackageError, if any, describes why parent is not allowed
|
||||
// to import the named package, with the error referring to importPos.
|
||||
// The PackageError can only be non-nil when parent is not nil.
|
||||
func LoadImport(ctx context.Context, opts PackageOpts, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) (*Package, *PackageError) {
|
||||
return loadImport(ctx, opts, nil, path, srcDir, parent, stk, importPos, mode)
|
||||
}
|
||||
|
||||
// LoadPackage does Load import, but without a parent package load contezt
|
||||
func LoadPackage(ctx context.Context, opts PackageOpts, path, srcDir string, stk *ImportStack, importPos []token.Position, mode int) *Package {
|
||||
p, err := loadImport(ctx, opts, nil, path, srcDir, nil, stk, importPos, mode)
|
||||
|
||||
@@ -180,3 +180,41 @@ func (c *Cache[K, V]) Get(key K) (V, bool) {
|
||||
}
|
||||
return e.result, true
|
||||
}
|
||||
|
||||
// Clear removes all entries in the cache.
|
||||
//
|
||||
// Concurrent calls to Get may return old values. Concurrent calls to Do
|
||||
// may return old values or store results in entries that have been deleted.
|
||||
//
|
||||
// TODO(jayconrod): Delete this after the package cache clearing functions
|
||||
// in internal/load have been removed.
|
||||
func (c *Cache[K, V]) Clear() {
|
||||
c.m.Clear()
|
||||
}
|
||||
|
||||
// Delete removes an entry from the map. It is safe to call Delete for an
|
||||
// entry that does not exist. Delete will return quickly, even if the result
|
||||
// for a key is still being computed; the computation will finish, but the
|
||||
// result won't be accessible through the cache.
|
||||
//
|
||||
// TODO(jayconrod): Delete this after the package cache clearing functions
|
||||
// in internal/load have been removed.
|
||||
func (c *Cache[K, V]) Delete(key K) {
|
||||
c.m.Delete(key)
|
||||
}
|
||||
|
||||
// DeleteIf calls pred for each key in the map. If pred returns true for a key,
|
||||
// DeleteIf removes the corresponding entry. If the result for a key is
|
||||
// still being computed, DeleteIf will remove the entry without waiting for
|
||||
// the computation to finish. The result won't be accessible through the cache.
|
||||
//
|
||||
// TODO(jayconrod): Delete this after the package cache clearing functions
|
||||
// in internal/load have been removed.
|
||||
func (c *Cache[K, V]) DeleteIf(pred func(key K) bool) {
|
||||
c.m.Range(func(key, _ any) bool {
|
||||
if key := key.(K); pred(key) {
|
||||
c.Delete(key)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1013,11 +1013,11 @@ var defaultGOVCS = govcsConfig{
|
||||
{"public", []string{"git", "hg"}},
|
||||
}
|
||||
|
||||
// checkGOVCS checks whether the policy defined by the environment variable
|
||||
// CheckGOVCS checks whether the policy defined by the environment variable
|
||||
// GOVCS allows the given vcs command to be used with the given repository
|
||||
// root path. Note that root may not be a real package or module path; it's
|
||||
// the same as the root path in the go-import meta tag.
|
||||
func checkGOVCS(vcs *Cmd, root string) error {
|
||||
func CheckGOVCS(vcs *Cmd, root string) error {
|
||||
if vcs == vcsMod {
|
||||
// Direct module (proxy protocol) fetches don't
|
||||
// involve an external version control system
|
||||
@@ -1045,6 +1045,37 @@ func checkGOVCS(vcs *Cmd, root string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckNested checks for an incorrectly-nested VCS-inside-VCS
|
||||
// situation for dir, checking parents up until srcRoot.
|
||||
func CheckNested(vcs *Cmd, dir, srcRoot string) error {
|
||||
if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
|
||||
return fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
|
||||
}
|
||||
|
||||
otherDir := dir
|
||||
for len(otherDir) > len(srcRoot) {
|
||||
for _, otherVCS := range vcsList {
|
||||
if isVCSRoot(otherDir, otherVCS.RootNames) {
|
||||
// Allow expected vcs in original dir.
|
||||
if otherDir == dir && otherVCS == vcs {
|
||||
continue
|
||||
}
|
||||
// Otherwise, we have one VCS inside a different VCS.
|
||||
return fmt.Errorf("directory %q uses %s, but parent %q uses %s", dir, vcs.Cmd, otherDir, otherVCS.Cmd)
|
||||
}
|
||||
}
|
||||
// Move to parent.
|
||||
newDir := filepath.Dir(otherDir)
|
||||
if len(newDir) >= len(otherDir) {
|
||||
// Shouldn't happen, but just in case, stop.
|
||||
break
|
||||
}
|
||||
otherDir = newDir
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RepoRoot describes the repository root for a tree of source code.
|
||||
type RepoRoot struct {
|
||||
Repo string // repository URL, including scheme
|
||||
@@ -1160,7 +1191,7 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths
|
||||
if vcs == nil {
|
||||
return nil, fmt.Errorf("unknown version control system %q", match["vcs"])
|
||||
}
|
||||
if err := checkGOVCS(vcs, match["root"]); err != nil {
|
||||
if err := CheckGOVCS(vcs, match["root"]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var repoURL string
|
||||
@@ -1349,7 +1380,7 @@ func repoRootForImportDynamic(importPath string, mod ModuleMode, security web.Se
|
||||
}
|
||||
}
|
||||
|
||||
if err := checkGOVCS(vcs, mmi.Prefix); err != nil {
|
||||
if err := CheckGOVCS(vcs, mmi.Prefix); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user