1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 "cmd/go/internal/base"
16 "cmd/go/internal/modfetch"
17 "cmd/go/internal/modload"
18 "cmd/go/internal/work"
20 "golang.org/x/mod/module"
21 "golang.org/x/mod/sumdb/dirhash"
24 var cmdVerify = &base.Command{
25 UsageLine: "go mod verify",
26 Short: "verify dependencies have expected content",
28 Verify checks that the dependencies of the current module,
29 which are stored in a local downloaded source cache, have not been
30 modified since being downloaded. If all the modules are unmodified,
31 verify prints "all modules verified." Otherwise it reports which
32 modules have been changed and causes 'go mod' to exit with a
39 work.AddModCommonFlags(cmdVerify)
42 func runVerify(cmd *base.Command, args []string) {
44 // NOTE(rsc): Could take a module pattern.
45 base.Fatalf("go mod verify: verify takes no arguments")
47 // Checks go mod expected behavior
48 if !modload.Enabled() || !modload.HasModRoot() {
49 if cfg.Getenv("GO111MODULE") == "off" {
50 base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'")
52 base.Fatalf("go: cannot find main module; see 'go help modules'")
56 for _, mod := range modload.LoadBuildList()[1:] {
57 ok = verifyMod(mod) && ok
60 fmt.Printf("all modules verified\n")
64 func verifyMod(mod module.Version) bool {
66 zip, zipErr := modfetch.CachePath(mod, "zip")
68 _, zipErr = os.Stat(zip)
70 dir, dirErr := modfetch.DownloadDir(mod)
71 data, err := ioutil.ReadFile(zip + "hash")
73 if zipErr != nil && errors.Is(zipErr, os.ErrNotExist) &&
74 dirErr != nil && errors.Is(dirErr, os.ErrNotExist) {
75 // Nothing downloaded yet. Nothing to verify.
78 base.Errorf("%s %s: missing ziphash: %v", mod.Path, mod.Version, err)
81 h := string(bytes.TrimSpace(data))
83 if zipErr != nil && errors.Is(zipErr, os.ErrNotExist) {
86 hZ, err := dirhash.HashZip(zip, dirhash.DefaultHash)
88 base.Errorf("%s %s: %v", mod.Path, mod.Version, err)
91 base.Errorf("%s %s: zip has been modified (%v)", mod.Path, mod.Version, zip)
95 if dirErr != nil && errors.Is(dirErr, os.ErrNotExist) {
98 hD, err := dirhash.HashDir(dir, mod.Path+"@"+mod.Version, dirhash.DefaultHash)
101 base.Errorf("%s %s: %v", mod.Path, mod.Version, err)
105 base.Errorf("%s %s: dir has been modified (%v)", mod.Path, mod.Version, dir)