Skip to content

Commit

Permalink
cmd/go/internal/modload: skip fetches of replaced modules in moduleInfo
Browse files Browse the repository at this point in the history
Fixes #27859

Change-Id: Ibb459cf41c3a8fe41bb008f60ef6cdd3437a37b1
Reviewed-on: https://go-review.googlesource.com/c/140860
Run-TryBot: Bryan C. Mills <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Russ Cox <[email protected]>
  • Loading branch information
Bryan C. Mills committed Oct 26, 2018
1 parent 160ee5d commit f8153fc
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 24 deletions.
50 changes: 27 additions & 23 deletions src/cmd/go/internal/modload/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,34 +145,38 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic {
}
}
}
if cfg.BuildMod == "vendor" {
m.Dir = filepath.Join(ModRoot, "vendor", m.Path)
}
}

complete(info)
if !fromBuildList {
complete(info)
return info
}

if fromBuildList {
if r := Replacement(m); r.Path != "" {
info.Replace = &modinfo.ModulePublic{
Path: r.Path,
Version: r.Version,
GoVersion: info.GoVersion,
}
if r.Version == "" {
if filepath.IsAbs(r.Path) {
info.Replace.Dir = r.Path
} else {
info.Replace.Dir = filepath.Join(ModRoot, r.Path)
}
}
complete(info.Replace)
info.Dir = info.Replace.Dir
info.GoMod = filepath.Join(info.Dir, "go.mod")
info.Error = nil // ignore error loading original module version (it has been replaced)
}
r := Replacement(m)
if r.Path == "" {
complete(info)
return info
}

// Don't hit the network to fill in extra data for replaced modules.
// The original resolved Version and Time don't matter enough to be
// worth the cost, and we're going to overwrite the GoMod and Dir from the
// replacement anyway. See https://golang.org/issue/27859.
info.Replace = &modinfo.ModulePublic{
Path: r.Path,
Version: r.Version,
GoVersion: info.GoVersion,
}
if r.Version == "" {
if filepath.IsAbs(r.Path) {
info.Replace.Dir = r.Path
} else {
info.Replace.Dir = filepath.Join(ModRoot, r.Path)
}
}
complete(info.Replace)
info.Dir = info.Replace.Dir
info.GoMod = filepath.Join(info.Dir, "go.mod")
return info
}

Expand Down
28 changes: 27 additions & 1 deletion src/cmd/go/testdata/script/mod_replace.txt
Original file line number Diff line number Diff line change
@@ -1,27 +1,41 @@
env GO111MODULE=on

cp go.mod go.mod.orig

# Make sure the test builds without replacement.
go build -o a1.exe .
exec ./a1.exe
stdout 'Don''t communicate by sharing memory'

# Modules can be replaced by local packages.
cp go.mod.orig go.mod
go mod edit -replace=rsc.io/quote/v3=./local/rsc.io/quote/v3
go build -o a2.exe .
exec ./a2.exe
stdout 'Concurrency is not parallelism.'

# The module path of the replacement doesn't need to match.
# (For example, it could be a long-running fork with its own import path.)
cp go.mod.orig go.mod
go mod edit -replace=rsc.io/quote/v3=./local/not-rsc.io/quote/v3
go build -o a3.exe .
exec ./a3.exe
stdout 'Clear is better than clever.'

# However, the same module can't be used as two different paths.
go mod edit -dropreplace=rsc.io/quote/v3 -replace=not-rsc.io/quote/[email protected]=rsc.io/quote/[email protected] -require=not-rsc.io/quote/[email protected]
cp go.mod.orig go.mod
go mod edit -replace=not-rsc.io/quote/[email protected]=rsc.io/quote/[email protected] -require=not-rsc.io/quote/[email protected]
! go build -o a4.exe .
stderr 'rsc.io/quote/[email protected] used for two different module paths \(not-rsc.io/quote/v3 and rsc.io/quote/v3\)'

# Modules that do not (yet) exist upstream can be replaced too.
cp go.mod.orig go.mod
go mod edit -require not-rsc.io/quote/[email protected] -replace=not-rsc.io/quote/v3=./local/rsc.io/quote/v3
go build -o a5.exe ./usenewmodule
! stderr 'finding not-rsc.io/quote/v3'
exec ./a5.exe
stdout 'Concurrency is not parallelism.'

-- go.mod --
module quoter

Expand All @@ -39,6 +53,18 @@ func main() {
fmt.Println(quote.GoV3())
}

-- usenewmodule/main.go --
package main

import (
"fmt"
"not-rsc.io/quote/v3"
)

func main() {
fmt.Println(quote.GoV3())
}

-- local/rsc.io/quote/v3/go.mod --
module rsc.io/quote/v3

Expand Down
39 changes: 39 additions & 0 deletions src/cmd/go/testdata/script/mod_vendor_replace.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
env GO111MODULE=on

# Before vendoring, we expect to see the original directory.
go list -f '{{.Version}} {{.Dir}}' -m rsc.io/quote/v3
stdout 'v3.0.0'
stdout '.*[/\\]not-rsc.io[/\\]quote[/\\]v3'

# Since all dependencies are replaced, 'go mod vendor' should not
# have to download anything from the network.
go mod vendor
! stderr 'downloading'
! stderr 'finding'

# After vendoring, we expect to see the replacement in the vendor directory,
# without attempting to look up the non-replaced version.
cmp vendor/rsc.io/quote/v3/quote.go local/not-rsc.io/quote/v3/quote.go

go list -mod=vendor -f '{{.Version}} {{.Dir}}' -m rsc.io/quote/v3
stdout 'v3.0.0'
stdout '.*[/\\]vendor[/\\]rsc.io[/\\]quote[/\\]v3'
! stderr 'finding'
! stderr 'lookup disabled'

-- go.mod --
module example.com/replace

require rsc.io/quote/v3 v3.0.0
replace rsc.io/quote/v3 => ./local/not-rsc.io/quote/v3

-- imports.go --
package replace

import _ "rsc.io/quote/v3"

-- local/not-rsc.io/quote/v3/go.mod --
module not-rsc.io/quote/v3

-- local/not-rsc.io/quote/v3/quote.go --
package quote

0 comments on commit f8153fc

Please sign in to comment.