Commit b8f42d74 authored by Russ Cox's avatar Russ Cox

cmd/go: move module cache from $GOPATH/src/mod to $GOPATH/pkg/mod

Using $GOPATH/src/mod confuses too many tools.
$GOPATH/pkg/mod seems better for now.
It's also next to dep's cache, $GOPATH/pkg/dep.
If we do eliminate GOPATH/pkg for holding .a files (#4719)
then we could still keep it around for pkg/mod.
(Or we could move the module cache again then.)

Fixes #26401.
Fixes #26635.

Change-Id: I18f7da216ed9f490eded3c00d837fb086ae5b6a4
Reviewed-on: https://go-review.googlesource.com/126755
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: 's avatarBryan C. Mills <bcmills@google.com>
Reviewed-by: 's avatarRob Pike <r@golang.org>
parent 27e546be
This diff is collapsed.
......@@ -153,10 +153,10 @@ func runClean(cmd *base.Command, args []string) {
}
if cleanModcache {
if modfetch.SrcMod == "" {
if modfetch.PkgMod == "" {
base.Fatalf("go clean -modcache: no module cache")
}
if err := removeAll(modfetch.SrcMod); err != nil {
if err := removeAll(modfetch.PkgMod); err != nil {
base.Errorf("go clean -modcache: %v", err)
}
}
......
......@@ -377,7 +377,7 @@ See https://golang.org/doc/code.html for an example.
GOPATH and Modules
When using modules, GOPATH is no longer used for resolving imports.
However, it is still used to store downloaded source code (in GOPATH/src/mod)
However, it is still used to store downloaded source code (in GOPATH/pkg/mod)
and compiled commands (in GOPATH/bin).
Internal Directories
......
......@@ -434,7 +434,7 @@ func LoadImport(path, srcDir string, parent *Package, stk *ImportStack, importPo
if strings.HasPrefix(path, "mod/") {
// Paths beginning with "mod/" might accidentally
// look in the module cache directory tree in $GOPATH/src/mod/.
// look in the module cache directory tree in $GOPATH/pkg/mod/.
// This prefix is owned by the Go core for possible use in the
// standard library (since it does not begin with a domain name),
// so it's OK to disallow entirely.
......
......@@ -39,7 +39,7 @@ func testMain(m *testing.M) int {
log.Fatal(err)
}
defer os.RemoveAll(dir)
modfetch.SrcMod = filepath.Join(dir, "src/mod")
modfetch.PkgMod = filepath.Join(dir, "pkg/mod")
codehost.WorkRoot = filepath.Join(dir, "codework")
return m.Run()
......
......@@ -22,17 +22,17 @@ import (
var QuietLookup bool // do not print about lookups
var SrcMod string // $GOPATH/src/mod; set by package modload
var PkgMod string // $GOPATH/pkg/mod; set by package modload
func cacheDir(path string) (string, error) {
if SrcMod == "" {
return "", fmt.Errorf("internal error: modfetch.SrcMod not set")
if PkgMod == "" {
return "", fmt.Errorf("internal error: modfetch.PkgMod not set")
}
enc, err := module.EncodePath(path)
if err != nil {
return "", err
}
return filepath.Join(SrcMod, "cache/download", enc, "/@v"), nil
return filepath.Join(PkgMod, "cache/download", enc, "/@v"), nil
}
func CachePath(m module.Version, suffix string) (string, error) {
......@@ -54,8 +54,8 @@ func CachePath(m module.Version, suffix string) (string, error) {
}
func DownloadDir(m module.Version) (string, error) {
if SrcMod == "" {
return "", fmt.Errorf("internal error: modfetch.SrcMod not set")
if PkgMod == "" {
return "", fmt.Errorf("internal error: modfetch.PkgMod not set")
}
enc, err := module.EncodePath(m.Path)
if err != nil {
......@@ -71,7 +71,7 @@ func DownloadDir(m module.Version) (string, error) {
if err != nil {
return "", err
}
return filepath.Join(SrcMod, enc+"@"+encVer), nil
return filepath.Join(PkgMod, enc+"@"+encVer), nil
}
// A cachingRepo is a cache around an underlying Repo,
......@@ -287,7 +287,7 @@ func readDiskStat(path, rev string) (file string, info *RevInfo, err error) {
// just to find out about a commit we already know about
// (and have cached under its pseudo-version).
func readDiskStatByHash(path, rev string) (file string, info *RevInfo, err error) {
if SrcMod == "" {
if PkgMod == "" {
// Do not download to current directory.
return "", nil, errNotCached
}
......
......@@ -28,9 +28,9 @@ var downloadCache par.Cache
// local download cache and returns the name of the directory
// corresponding to the root of the module's file tree.
func Download(mod module.Version) (dir string, err error) {
if SrcMod == "" {
if PkgMod == "" {
// Do not download to current directory.
return "", fmt.Errorf("missing modfetch.SrcMod")
return "", fmt.Errorf("missing modfetch.PkgMod")
}
// The par.Cache here avoids duplicate work but also
......@@ -53,7 +53,7 @@ func Download(mod module.Version) (dir string, err error) {
if _, err := os.Stat(zipfile); err == nil {
// Use it.
// This should only happen if the mod/cache directory is preinitialized
// or if src/mod/path was removed but not src/mod/cache/download.
// or if pkg/mod/path was removed but not pkg/mod/cache/download.
fmt.Fprintf(os.Stderr, "go: extracting %s %s\n", mod.Path, mod.Version)
} else {
if err := os.MkdirAll(filepath.Dir(zipfile), 0777); err != nil {
......@@ -200,7 +200,7 @@ func readGoSum(file string, data []byte) {
// checkSum checks the given module's checksum.
func checkSum(mod module.Version) {
if SrcMod == "" {
if PkgMod == "" {
// Do not use current directory.
return
}
......@@ -264,7 +264,7 @@ func checkOneSum(mod module.Version, h string) {
// Sum returns the checksum for the downloaded copy of the given module,
// if present in the download cache.
func Sum(mod module.Version) string {
if SrcMod == "" {
if PkgMod == "" {
// Do not use current directory.
return ""
}
......
......@@ -77,10 +77,10 @@ archive.
Even when downloading directly from version control systems,
the go command synthesizes explicit info, mod, and zip files
and stores them in its local cache, $GOPATH/src/mod/cache/download,
and stores them in its local cache, $GOPATH/pkg/mod/cache/download,
the same as if it had downloaded them directly from a proxy.
The cache layout is the same as the proxy URL space, so
serving $GOPATH/src/mod/cache/download at (or copying it to)
serving $GOPATH/pkg/mod/cache/download at (or copying it to)
https://example.com/proxy would let other users access those
cached module versions with GOPROXY=https://example.com/proxy.
`,
......
......@@ -50,7 +50,7 @@ GOPATH/src and itself contains a go.mod file or is below a directory
containing a go.mod file.
In module-aware mode, GOPATH no longer defines the meaning of imports
during a build, but it still stores downloaded dependencies (in GOPATH/src/mod)
during a build, but it still stores downloaded dependencies (in GOPATH/pkg/mod)
and installed commands (in GOPATH/bin, unless GOBIN is set).
Defining a module
......
......@@ -170,9 +170,9 @@ func Init() {
func init() {
load.ModInit = Init
// Set modfetch.SrcMod unconditionally, so that go clean -modcache can run even without modules enabled.
// Set modfetch.PkgMod unconditionally, so that go clean -modcache can run even without modules enabled.
if list := filepath.SplitList(cfg.BuildContext.GOPATH); len(list) > 0 && list[0] != "" {
modfetch.SrcMod = filepath.Join(list[0], "src/mod")
modfetch.PkgMod = filepath.Join(list[0], "pkg/mod")
}
}
......@@ -233,17 +233,17 @@ func InitMod() {
base.Fatalf("$GOPATH/go.mod exists but should not")
}
srcV := filepath.Join(list[0], "src/v")
srcMod := filepath.Join(list[0], "src/mod")
infoV, errV := os.Stat(srcV)
_, errMod := os.Stat(srcMod)
if errV == nil && infoV.IsDir() && errMod != nil && os.IsNotExist(errMod) {
os.Rename(srcV, srcMod)
oldSrcMod := filepath.Join(list[0], "src/mod")
pkgMod := filepath.Join(list[0], "pkg/mod")
infoOld, errOld := os.Stat(oldSrcMod)
_, errMod := os.Stat(pkgMod)
if errOld == nil && infoOld.IsDir() && errMod != nil && os.IsNotExist(errMod) {
os.Rename(oldSrcMod, pkgMod)
}
modfetch.SrcMod = srcMod
modfetch.PkgMod = pkgMod
modfetch.GoSumFile = filepath.Join(ModRoot, "go.sum")
codehost.WorkRoot = filepath.Join(srcMod, "cache/vcs")
codehost.WorkRoot = filepath.Join(pkgMod, "cache/vcs")
if CmdModInit {
// Running go mod init: do legacy module conversion
......
......@@ -29,7 +29,7 @@ func testMain(m *testing.M) int {
log.Fatal(err)
}
defer os.RemoveAll(dir)
modfetch.SrcMod = filepath.Join(dir, "src/mod")
modfetch.PkgMod = filepath.Join(dir, "pkg/mod")
codehost.WorkRoot = filepath.Join(dir, "codework")
return m.Run()
}
......
......@@ -97,13 +97,13 @@ func main() {
continue
}
path, vers, dir := f[0], f[1], f[2]
mod, err := ioutil.ReadFile(filepath.Join(gopath, "src/mod/cache/download", path, "@v", vers+".mod"))
mod, err := ioutil.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".mod"))
if err != nil {
log.Printf("%s: %v", arg, err)
exitCode = 1
continue
}
info, err := ioutil.ReadFile(filepath.Join(gopath, "src/mod/cache/download", path, "@v", vers+".info"))
info, err := ioutil.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".info"))
if err != nil {
log.Printf("%s: %v", arg, err)
exitCode = 1
......
......@@ -6,16 +6,16 @@ go mod edit -fmt
go list -mod=readonly
env GOPROXY=file:///nonexist
go list
grep v1.5.1 $GOPATH/src/mod/cache/download/rsc.io/quote/@v/list
grep v1.5.1 $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/list
# Use download cache as file:/// proxy.
[windows] stop # TODO: file://$WORK puts backslashes in the URL
env GOPATH=$WORK/gopath2
env GOPROXY=file:///nonexist
! go list
env GOPROXY=file://$WORK/gopath1/src/mod/cache/download
env GOPROXY=file://$WORK/gopath1/pkg/mod/cache/download
go list
grep v1.5.1 $GOPATH/src/mod/cache/download/rsc.io/quote/@v/list
grep v1.5.1 $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/list
-- $WORK/x/go.mod --
module x
......
# Test that GOPATH/src/mod is excluded
# Test that GOPATH/pkg/mod is excluded
env GO111MODULE=off
! go list mod/foo
stderr 'disallowed import path'
......
......@@ -10,12 +10,12 @@ go list -f '{{.Dir}}' rsc.io/quote
stdout '.*mod[\\/]rsc.io[\\/]quote@v1.5.2$'
# downloaded dependencies are read-only
exists -readonly $GOPATH/src/mod/rsc.io/quote@v1.5.2
exists -readonly $GOPATH/src/mod/rsc.io/quote@v1.5.2/buggy
exists -readonly $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
exists -readonly $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/buggy
# go clean -modcache can delete read-only dependencies
go clean -modcache
! exists $GOPATH/src/mod/rsc.io/quote@v1.5.2
! exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
# list {{.Dir}} shows replaced directories
cp go.mod2 go.mod
......
......@@ -9,14 +9,14 @@ go list -f '{{.ImportPath}}' $GOROOT/src/math
stdout ^math$
go list -f '{{.ImportPath}}' .
stdout ^x$
go list -f '{{.ImportPath}}' $GOPATH/src/mod/rsc.io/quote@v1.5.2
go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
stdout '^rsc.io/quote$'
go list -f '{{.ImportPath}}' $GOPATH/src/mod/rsc.io/sampler@v1.3.0
go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/sampler@v1.3.0
stdout '^rsc.io/sampler$'
go get rsc.io/sampler@v1.3.1
go list -f '{{.ImportPath}}' $GOPATH/src/mod/rsc.io/sampler@v1.3.1
go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/sampler@v1.3.1
stdout '^rsc.io/sampler$'
! go list -f '{{.ImportPath}}' $GOPATH/src/mod/rsc.io/sampler@v1.3.0
! go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/sampler@v1.3.0
stderr 'outside available modules'
-- go.mod --
......
......@@ -2,25 +2,25 @@ env GO111MODULE=on
# initial standalone module should use no downloaded modules
go list -deps -f {{.Dir}}
! stdout 'src[\\/]mod'
! stdout 'pkg[\\/]mod'
# v2 import should use a downloaded module
# both without an explicit go.mod entry ...
cp tmp/use_v2.go x.go
go list -deps -f {{.Dir}}
stdout 'src[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$'
stdout 'pkg[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$'
# ... and with one ...
cp tmp/use_v2.mod go.mod
go list -deps -f {{.Dir}}
stdout 'src[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$'
stdout 'pkg[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$'
# ... and even if there is a v2 module in a subdirectory.
mkdir v2
cp x.go v2/x.go
cp tmp/v2.mod v2/go.mod
go list -deps -f {{.Dir}}
stdout 'src[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$'
stdout 'pkg[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$'
-- go.mod --
module rsc.io/quote
......
......@@ -3,12 +3,12 @@ env GO111MODULE=on
# With good go.sum, verify succeeds by avoiding download.
cp go.sum.good go.sum
go mod verify
! exists $GOPATH/src/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip
# With bad go.sum, verify succeeds by avoiding download.
cp go.sum.bad go.sum
go mod verify
! exists $GOPATH/src/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip
# With bad go.sum, sync (which must download) fails.
# Even if the bad sum is in the old legacy go.modverify file.
......@@ -16,14 +16,14 @@ rm go.sum
cp go.sum.bad go.modverify
! go mod tidy
stderr 'checksum mismatch'
! exists $GOPATH/src/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip
# With good go.sum, sync works (and moves go.modverify to go.sum).
rm go.sum
cp go.sum.good go.modverify
go mod tidy
exists $GOPATH/src/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip
exists $GOPATH/src/mod/rsc.io/quote@v1.1.0/quote.go
exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip
exists $GOPATH/pkg/mod/rsc.io/quote@v1.1.0/quote.go
! exists go.modverify
# go.sum should have the new checksum for go.mod
......@@ -50,7 +50,7 @@ grep '^rsc.io/quote v1.1.0/go.mod ' go.sum
grep '^rsc.io/quote v1.1.0 ' go.sum
# sync should ignore missing ziphash; verify should not
rm $GOPATH/src/mod/cache/download/rsc.io/quote/@v/v1.1.0.ziphash
rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.ziphash
go mod tidy
! go mod verify
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment