github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/go/not-internal/modcmd/verify.go (about) 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. 4 5 package modcmd 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "io/ioutil" 12 "os" 13 14 "github.com/gagliardetto/golang-go/cmd/go/not-internal/base" 15 "github.com/gagliardetto/golang-go/cmd/go/not-internal/cfg" 16 "github.com/gagliardetto/golang-go/cmd/go/not-internal/modfetch" 17 "github.com/gagliardetto/golang-go/cmd/go/not-internal/modload" 18 "github.com/gagliardetto/golang-go/cmd/go/not-internal/work" 19 20 "golang.org/x/mod/module" 21 "golang.org/x/mod/sumdb/dirhash" 22 ) 23 24 var cmdVerify = &base.Command{ 25 UsageLine: "go mod verify", 26 Short: "verify dependencies have expected content", 27 Long: ` 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 33 non-zero status. 34 `, 35 Run: runVerify, 36 } 37 38 func init() { 39 work.AddModCommonFlags(cmdVerify) 40 } 41 42 func runVerify(cmd *base.Command, args []string) { 43 if len(args) != 0 { 44 // NOTE(rsc): Could take a module pattern. 45 base.Fatalf("go mod verify: verify takes no arguments") 46 } 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'") 51 } else { 52 base.Fatalf("go: cannot find main module; see 'go help modules'") 53 } 54 } 55 ok := true 56 for _, mod := range modload.LoadBuildList()[1:] { 57 ok = verifyMod(mod) && ok 58 } 59 if ok { 60 fmt.Printf("all modules verified\n") 61 } 62 } 63 64 func verifyMod(mod module.Version) bool { 65 ok := true 66 zip, zipErr := modfetch.CachePath(mod, "zip") 67 if zipErr == nil { 68 _, zipErr = os.Stat(zip) 69 } 70 dir, dirErr := modfetch.DownloadDir(mod) 71 data, err := ioutil.ReadFile(zip + "hash") 72 if err != nil { 73 if zipErr != nil && errors.Is(zipErr, os.ErrNotExist) && 74 dirErr != nil && errors.Is(dirErr, os.ErrNotExist) { 75 // Nothing downloaded yet. Nothing to verify. 76 return true 77 } 78 base.Errorf("%s %s: missing ziphash: %v", mod.Path, mod.Version, err) 79 return false 80 } 81 h := string(bytes.TrimSpace(data)) 82 83 if zipErr != nil && errors.Is(zipErr, os.ErrNotExist) { 84 // ok 85 } else { 86 hZ, err := dirhash.HashZip(zip, dirhash.DefaultHash) 87 if err != nil { 88 base.Errorf("%s %s: %v", mod.Path, mod.Version, err) 89 return false 90 } else if hZ != h { 91 base.Errorf("%s %s: zip has been modified (%v)", mod.Path, mod.Version, zip) 92 ok = false 93 } 94 } 95 if dirErr != nil && errors.Is(dirErr, os.ErrNotExist) { 96 // ok 97 } else { 98 hD, err := dirhash.HashDir(dir, mod.Path+"@"+mod.Version, dirhash.DefaultHash) 99 if err != nil { 100 101 base.Errorf("%s %s: %v", mod.Path, mod.Version, err) 102 return false 103 } 104 if hD != h { 105 base.Errorf("%s %s: dir has been modified (%v)", mod.Path, mod.Version, dir) 106 ok = false 107 } 108 } 109 return ok 110 }