mirror of https://github.com/golang/go.git
cmd/go: use workspace modules' go.sum files to check sums
By default, use workspace modules' go.sum files to check sums. Any missing sums will still be written to go.work.sum For #45713 Change-Id: I0f537602523dfec44d423c3c80c7ef396e1397b1 Reviewed-on: https://go-review.googlesource.com/c/go/+/359478 Trust: Michael Matloob <matloob@golang.org> Run-TryBot: Michael Matloob <matloob@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
parent
f9dcda3fd8
commit
1cd600301e
|
|
@ -384,7 +384,8 @@ func RemoveAll(dir string) error {
|
||||||
return robustio.RemoveAll(dir)
|
return robustio.RemoveAll(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
var GoSumFile string // path to go.sum; set by package modload
|
var GoSumFile string // path to go.sum; set by package modload
|
||||||
|
var WorkspaceGoSumFiles []string // path to module go.sums in workspace; set by package modload
|
||||||
|
|
||||||
type modSum struct {
|
type modSum struct {
|
||||||
mod module.Version
|
mod module.Version
|
||||||
|
|
@ -393,10 +394,11 @@ type modSum struct {
|
||||||
|
|
||||||
var goSum struct {
|
var goSum struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
m map[module.Version][]string // content of go.sum file
|
m map[module.Version][]string // content of go.sum file
|
||||||
status map[modSum]modSumStatus // state of sums in m
|
w map[string]map[module.Version][]string // sum file in workspace -> content of that sum file
|
||||||
overwrite bool // if true, overwrite go.sum without incorporating its contents
|
status map[modSum]modSumStatus // state of sums in m
|
||||||
enabled bool // whether to use go.sum at all
|
overwrite bool // if true, overwrite go.sum without incorporating its contents
|
||||||
|
enabled bool // whether to use go.sum at all
|
||||||
}
|
}
|
||||||
|
|
||||||
type modSumStatus struct {
|
type modSumStatus struct {
|
||||||
|
|
@ -417,23 +419,38 @@ func initGoSum() (bool, error) {
|
||||||
|
|
||||||
goSum.m = make(map[module.Version][]string)
|
goSum.m = make(map[module.Version][]string)
|
||||||
goSum.status = make(map[modSum]modSumStatus)
|
goSum.status = make(map[modSum]modSumStatus)
|
||||||
|
goSum.w = make(map[string]map[module.Version][]string)
|
||||||
|
|
||||||
|
for _, f := range WorkspaceGoSumFiles {
|
||||||
|
goSum.w[f] = make(map[module.Version][]string)
|
||||||
|
_, err := readGoSumFile(goSum.w[f], f)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled, err := readGoSumFile(goSum.m, GoSumFile)
|
||||||
|
goSum.enabled = enabled
|
||||||
|
return enabled, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func readGoSumFile(dst map[module.Version][]string, file string) (bool, error) {
|
||||||
var (
|
var (
|
||||||
data []byte
|
data []byte
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if actualSumFile, ok := fsys.OverlayPath(GoSumFile); ok {
|
if actualSumFile, ok := fsys.OverlayPath(file); ok {
|
||||||
// Don't lock go.sum if it's part of the overlay.
|
// Don't lock go.sum if it's part of the overlay.
|
||||||
// On Plan 9, locking requires chmod, and we don't want to modify any file
|
// On Plan 9, locking requires chmod, and we don't want to modify any file
|
||||||
// in the overlay. See #44700.
|
// in the overlay. See #44700.
|
||||||
data, err = os.ReadFile(actualSumFile)
|
data, err = os.ReadFile(actualSumFile)
|
||||||
} else {
|
} else {
|
||||||
data, err = lockedfile.Read(GoSumFile)
|
data, err = lockedfile.Read(file)
|
||||||
}
|
}
|
||||||
if err != nil && !os.IsNotExist(err) {
|
if err != nil && !os.IsNotExist(err) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
goSum.enabled = true
|
readGoSum(dst, file, data)
|
||||||
readGoSum(goSum.m, GoSumFile, data)
|
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
@ -485,6 +502,16 @@ func HaveSum(mod module.Version) bool {
|
||||||
if err != nil || !inited {
|
if err != nil || !inited {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
for _, goSums := range goSum.w {
|
||||||
|
for _, h := range goSums[mod] {
|
||||||
|
if !strings.HasPrefix(h, "h1:") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !goSum.status[modSum{mod, h}].dirty {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, h := range goSum.m[mod] {
|
for _, h := range goSum.m[mod] {
|
||||||
if !strings.HasPrefix(h, "h1:") {
|
if !strings.HasPrefix(h, "h1:") {
|
||||||
continue
|
continue
|
||||||
|
|
@ -602,15 +629,32 @@ func checkModSum(mod module.Version, h string) error {
|
||||||
// If it finds a conflicting pair instead, it calls base.Fatalf.
|
// If it finds a conflicting pair instead, it calls base.Fatalf.
|
||||||
// goSum.mu must be locked.
|
// goSum.mu must be locked.
|
||||||
func haveModSumLocked(mod module.Version, h string) bool {
|
func haveModSumLocked(mod module.Version, h string) bool {
|
||||||
|
sumFileName := "go.sum"
|
||||||
|
if strings.HasSuffix(GoSumFile, "go.work.sum") {
|
||||||
|
sumFileName = "go.work.sum"
|
||||||
|
}
|
||||||
for _, vh := range goSum.m[mod] {
|
for _, vh := range goSum.m[mod] {
|
||||||
if h == vh {
|
if h == vh {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(vh, "h1:") {
|
if strings.HasPrefix(vh, "h1:") {
|
||||||
base.Fatalf("verifying %s@%s: checksum mismatch\n\tdownloaded: %v\n\tgo.sum: %v"+goSumMismatch, mod.Path, mod.Version, h, vh)
|
base.Fatalf("verifying %s@%s: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+goSumMismatch, mod.Path, mod.Version, h, sumFileName, vh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
// Also check workspace sums.
|
||||||
|
foundMatch := false
|
||||||
|
// Check sums from all files in case there are conflicts between
|
||||||
|
// the files.
|
||||||
|
for goSumFile, goSums := range goSum.w {
|
||||||
|
for _, vh := range goSums[mod] {
|
||||||
|
if h == vh {
|
||||||
|
foundMatch = true
|
||||||
|
} else if strings.HasPrefix(vh, "h1:") {
|
||||||
|
base.Fatalf("verifying %s@%s: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+goSumMismatch, mod.Path, mod.Version, h, goSumFile, vh)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return foundMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
// addModSumLocked adds the pair mod,h to go.sum.
|
// addModSumLocked adds the pair mod,h to go.sum.
|
||||||
|
|
@ -749,7 +793,7 @@ Outer:
|
||||||
goSum.m = make(map[module.Version][]string, len(goSum.m))
|
goSum.m = make(map[module.Version][]string, len(goSum.m))
|
||||||
readGoSum(goSum.m, GoSumFile, data)
|
readGoSum(goSum.m, GoSumFile, data)
|
||||||
for ms, st := range goSum.status {
|
for ms, st := range goSum.status {
|
||||||
if st.used {
|
if st.used && !sumInWorkspaceModulesLocked(ms.mod) {
|
||||||
addModSumLocked(ms.mod, ms.sum)
|
addModSumLocked(ms.mod, ms.sum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -767,7 +811,7 @@ Outer:
|
||||||
sort.Strings(list)
|
sort.Strings(list)
|
||||||
for _, h := range list {
|
for _, h := range list {
|
||||||
st := goSum.status[modSum{m, h}]
|
st := goSum.status[modSum{m, h}]
|
||||||
if !st.dirty || (st.used && keep[m]) {
|
if (!st.dirty || (st.used && keep[m])) && !sumInWorkspaceModulesLocked(m) {
|
||||||
fmt.Fprintf(&buf, "%s %s %s\n", m.Path, m.Version, h)
|
fmt.Fprintf(&buf, "%s %s %s\n", m.Path, m.Version, h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -784,6 +828,15 @@ Outer:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sumInWorkspaceModulesLocked(m module.Version) bool {
|
||||||
|
for _, goSums := range goSum.w {
|
||||||
|
if _, ok := goSums[m]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// TrimGoSum trims go.sum to contain only the modules needed for reproducible
|
// TrimGoSum trims go.sum to contain only the modules needed for reproducible
|
||||||
// builds.
|
// builds.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -624,8 +624,10 @@ func LoadModFile(ctx context.Context) *Requirements {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
base.Fatalf("reading go.work: %v", err)
|
base.Fatalf("reading go.work: %v", err)
|
||||||
}
|
}
|
||||||
_ = TODOWorkspaces("Support falling back to individual module go.sum " +
|
for _, modRoot := range modRoots {
|
||||||
"files for sums not in the workspace sum file.")
|
sumFile := strings.TrimSuffix(modFilePath(modRoot), ".mod") + ".sum"
|
||||||
|
modfetch.WorkspaceGoSumFiles = append(modfetch.WorkspaceGoSumFiles, sumFile)
|
||||||
|
}
|
||||||
modfetch.GoSumFile = workFilePath + ".sum"
|
modfetch.GoSumFile = workFilePath + ".sum"
|
||||||
} else if modRoots == nil {
|
} else if modRoots == nil {
|
||||||
// We're in module mode, but not inside a module.
|
// We're in module mode, but not inside a module.
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekuf
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0=
|
rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0=
|
||||||
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
|
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
|
||||||
rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII=
|
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
|
||||||
-- go.work --
|
-- go.work --
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
|
|
@ -20,6 +18,9 @@ go 1.18
|
||||||
module example.com/hi
|
module example.com/hi
|
||||||
|
|
||||||
require "rsc.io/quote" v1.5.2
|
require "rsc.io/quote" v1.5.2
|
||||||
|
-- go.sum --
|
||||||
|
rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII=
|
||||||
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
-- main.go --
|
-- main.go --
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
# Test mismatched sums in go.sum files
|
||||||
|
|
||||||
|
! go run ./a
|
||||||
|
cmpenv stderr want-error
|
||||||
|
|
||||||
|
-- want-error --
|
||||||
|
verifying rsc.io/sampler@v1.3.0/go.mod: checksum mismatch
|
||||||
|
downloaded: h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
|
$WORK${/}gopath${/}src${/}a${/}go.sum: h1:U1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
|
|
||||||
|
SECURITY ERROR
|
||||||
|
This download does NOT match an earlier download recorded in go.sum.
|
||||||
|
The bits may have been replaced on the origin server, or an attacker may
|
||||||
|
have intercepted the download attempt.
|
||||||
|
|
||||||
|
For more information, see 'go help module-auth'.
|
||||||
|
-- go.work --
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
directory ./a
|
||||||
|
directory ./b
|
||||||
|
-- a/go.mod --
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
module example.com/hi
|
||||||
|
|
||||||
|
require "rsc.io/quote" v1.5.2
|
||||||
|
-- a/go.sum --
|
||||||
|
rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII=
|
||||||
|
rsc.io/sampler v1.3.0/go.mod h1:U1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
|
-- a/main.go --
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"rsc.io/quote"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(quote.Hello())
|
||||||
|
}
|
||||||
|
-- b/go.mod --
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
module example.com/hi
|
||||||
|
|
||||||
|
require "rsc.io/quote" v1.5.2
|
||||||
|
-- b/go.sum --
|
||||||
|
rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII=
|
||||||
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
|
-- b/main.go --
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"rsc.io/quote"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(quote.Hello())
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue