github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/go/testdata/addmod.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 // +build ignore 6 7 // Addmod adds a module as a txtar archive to the testdata/mod directory. 8 // 9 // Usage: 10 // 11 // go run addmod.go path@version... 12 // 13 // It should only be used for very small modules - we do not want to check 14 // very large files into testdata/mod. 15 // 16 // It is acceptable to edit the archive afterward to remove or shorten files. 17 // See mod/README for more information. 18 // 19 package main 20 21 import ( 22 "bytes" 23 "flag" 24 "fmt" 25 "io/ioutil" 26 "log" 27 "os" 28 "os/exec" 29 "path/filepath" 30 "strings" 31 32 "github.com/gagliardetto/golang-go/cmd/go/not-internal/txtar" 33 ) 34 35 func usage() { 36 fmt.Fprintf(os.Stderr, "usage: go run addmod.go path@version...\n") 37 os.Exit(2) 38 } 39 40 var tmpdir string 41 42 func fatalf(format string, args ...interface{}) { 43 os.RemoveAll(tmpdir) 44 log.Fatalf(format, args...) 45 } 46 47 const goCmd = "go" 48 49 func main() { 50 flag.Usage = usage 51 flag.Parse() 52 if flag.NArg() == 0 { 53 usage() 54 } 55 56 log.SetPrefix("addmod: ") 57 log.SetFlags(0) 58 59 var err error 60 tmpdir, err = ioutil.TempDir("", "addmod-") 61 if err != nil { 62 log.Fatal(err) 63 } 64 65 run := func(command string, args ...string) string { 66 cmd := exec.Command(command, args...) 67 cmd.Dir = tmpdir 68 var stderr bytes.Buffer 69 cmd.Stderr = &stderr 70 out, err := cmd.Output() 71 if err != nil { 72 fatalf("%s %s: %v\n%s", command, strings.Join(args, " "), err, stderr.Bytes()) 73 } 74 return string(out) 75 } 76 77 gopath := strings.TrimSpace(run("go", "env", "GOPATH")) 78 if gopath == "" { 79 fatalf("cannot find GOPATH") 80 } 81 82 exitCode := 0 83 for _, arg := range flag.Args() { 84 if err := ioutil.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte("module m\n"), 0666); err != nil { 85 fatalf("%v", err) 86 } 87 run(goCmd, "get", "-d", arg) 88 path := arg 89 if i := strings.Index(path, "@"); i >= 0 { 90 path = path[:i] 91 } 92 out := run(goCmd, "list", "-m", "-f={{.Path}} {{.Version}} {{.Dir}}", path) 93 f := strings.Fields(out) 94 if len(f) != 3 { 95 log.Printf("go list -m %s: unexpected output %q", arg, out) 96 exitCode = 1 97 continue 98 } 99 path, vers, dir := f[0], f[1], f[2] 100 mod, err := ioutil.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".mod")) 101 if err != nil { 102 log.Printf("%s: %v", arg, err) 103 exitCode = 1 104 continue 105 } 106 info, err := ioutil.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".info")) 107 if err != nil { 108 log.Printf("%s: %v", arg, err) 109 exitCode = 1 110 continue 111 } 112 113 a := new(txtar.Archive) 114 title := arg 115 if !strings.Contains(arg, "@") { 116 title += "@" + vers 117 } 118 a.Comment = []byte(fmt.Sprintf("module %s\n\n", title)) 119 a.Files = []txtar.File{ 120 {Name: ".mod", Data: mod}, 121 {Name: ".info", Data: info}, 122 } 123 dir = filepath.Clean(dir) 124 err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { 125 if !info.Mode().IsRegular() { 126 return nil 127 } 128 name := info.Name() 129 if name == "go.mod" || strings.HasSuffix(name, ".go") { 130 data, err := ioutil.ReadFile(path) 131 if err != nil { 132 return err 133 } 134 a.Files = append(a.Files, txtar.File{Name: strings.TrimPrefix(path, dir+string(filepath.Separator)), Data: data}) 135 } 136 return nil 137 }) 138 if err != nil { 139 log.Printf("%s: %v", arg, err) 140 exitCode = 1 141 continue 142 } 143 144 data := txtar.Format(a) 145 target := filepath.Join("mod", strings.ReplaceAll(path, "/", "_")+"_"+vers+".txt") 146 if err := ioutil.WriteFile(target, data, 0666); err != nil { 147 log.Printf("%s: %v", arg, err) 148 exitCode = 1 149 continue 150 } 151 } 152 os.RemoveAll(tmpdir) 153 os.Exit(exitCode) 154 }