github.com/gernest/nezuko@v0.1.2/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 "fmt" 10 "io/ioutil" 11 "os" 12 13 "github.com/gernest/nezuko/internal/base" 14 "github.com/gernest/nezuko/internal/dirhash" 15 "github.com/gernest/nezuko/internal/modfetch" 16 "github.com/gernest/nezuko/internal/modload" 17 "github.com/gernest/nezuko/internal/module" 18 ) 19 20 var cmdVerify = &base.Command{ 21 UsageLine: "z mod verify", 22 Short: "verify dependencies have expected content", 23 Long: ` 24 Verify checks that the dependencies of the current module, 25 which are stored in a local downloaded source cache, have not been 26 modified since being downloaded. If all the modules are unmodified, 27 verify prints "all modules verified." Otherwise it reports which 28 modules have been changed and causes 'z mod' to exit with a 29 non-zero status. 30 `, 31 Run: runVerify, 32 } 33 34 func runVerify(cmd *base.Command, args []string) { 35 if len(args) != 0 { 36 // NOTE(rsc): Could take a module pattern. 37 base.Fatalf("z mod verify: verify takes no arguments") 38 } 39 ok := true 40 for _, mod := range modload.LoadBuildList()[1:] { 41 ok = verifyMod(mod) && ok 42 } 43 if ok { 44 fmt.Printf("all modules verified\n") 45 } 46 } 47 48 func verifyMod(mod module.Version) bool { 49 ok := true 50 zip, zipErr := modfetch.CachePath(mod, "zip") 51 if zipErr == nil { 52 _, zipErr = os.Stat(zip) 53 } 54 dir, dirErr := modfetch.DownloadDir(mod) 55 if dirErr == nil { 56 _, dirErr = os.Stat(dir) 57 } 58 data, err := ioutil.ReadFile(zip + "hash") 59 if err != nil { 60 if zipErr != nil && os.IsNotExist(zipErr) && dirErr != nil && os.IsNotExist(dirErr) { 61 // Nothing downloaded yet. Nothing to verify. 62 return true 63 } 64 base.Errorf("%s %s: missing ziphash: %v", mod.Path, mod.Version, err) 65 return false 66 } 67 h := string(bytes.TrimSpace(data)) 68 69 if zipErr != nil && os.IsNotExist(zipErr) { 70 // ok 71 } else { 72 hZ, err := dirhash.HashZip(zip, dirhash.DefaultHash) 73 if err != nil { 74 base.Errorf("%s %s: %v", mod.Path, mod.Version, err) 75 return false 76 } else if hZ != h { 77 base.Errorf("%s %s: zip has been modified (%v)", mod.Path, mod.Version, zip) 78 ok = false 79 } 80 } 81 if dirErr != nil && os.IsNotExist(dirErr) { 82 // ok 83 } else { 84 hD, err := dirhash.HashDir(dir, mod.Path+"@"+mod.Version, dirhash.DefaultHash) 85 if err != nil { 86 87 base.Errorf("%s %s: %v", mod.Path, mod.Version, err) 88 return false 89 } 90 if hD != h { 91 base.Errorf("%s %s: dir has been modified (%v)", mod.Path, mod.Version, dir) 92 ok = false 93 } 94 } 95 return ok 96 }