diff options
Diffstat (limited to '')
-rw-r--r-- | src/cmd/go/testdata/addmod.go | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/cmd/go/testdata/addmod.go b/src/cmd/go/testdata/addmod.go new file mode 100644 index 0000000..09fc8e7 --- /dev/null +++ b/src/cmd/go/testdata/addmod.go @@ -0,0 +1,154 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// Addmod adds a module as a txtar archive to the testdata/mod directory. +// +// Usage: +// +// go run addmod.go path@version... +// +// It should only be used for very small modules - we do not want to check +// very large files into testdata/mod. +// +// It is acceptable to edit the archive afterward to remove or shorten files. +// See mod/README for more information. +// +package main + +import ( + "bytes" + "flag" + "fmt" + "io/fs" + "log" + "os" + exec "internal/execabs" + "path/filepath" + "strings" + + "cmd/go/internal/txtar" +) + +func usage() { + fmt.Fprintf(os.Stderr, "usage: go run addmod.go path@version...\n") + os.Exit(2) +} + +var tmpdir string + +func fatalf(format string, args ...interface{}) { + os.RemoveAll(tmpdir) + log.Fatalf(format, args...) +} + +const goCmd = "go" + +func main() { + flag.Usage = usage + flag.Parse() + if flag.NArg() == 0 { + usage() + } + + log.SetPrefix("addmod: ") + log.SetFlags(0) + + var err error + tmpdir, err = os.MkdirTemp("", "addmod-") + if err != nil { + log.Fatal(err) + } + + run := func(command string, args ...string) string { + cmd := exec.Command(command, args...) + cmd.Dir = tmpdir + var stderr bytes.Buffer + cmd.Stderr = &stderr + out, err := cmd.Output() + if err != nil { + fatalf("%s %s: %v\n%s", command, strings.Join(args, " "), err, stderr.Bytes()) + } + return string(out) + } + + gopath := strings.TrimSpace(run("go", "env", "GOPATH")) + if gopath == "" { + fatalf("cannot find GOPATH") + } + + exitCode := 0 + for _, arg := range flag.Args() { + if err := os.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte("module m\n"), 0666); err != nil { + fatalf("%v", err) + } + run(goCmd, "get", "-d", arg) + path := arg + if i := strings.Index(path, "@"); i >= 0 { + path = path[:i] + } + out := run(goCmd, "list", "-m", "-f={{.Path}} {{.Version}} {{.Dir}}", path) + f := strings.Fields(out) + if len(f) != 3 { + log.Printf("go list -m %s: unexpected output %q", arg, out) + exitCode = 1 + continue + } + path, vers, dir := f[0], f[1], f[2] + mod, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".mod")) + if err != nil { + log.Printf("%s: %v", arg, err) + exitCode = 1 + continue + } + info, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".info")) + if err != nil { + log.Printf("%s: %v", arg, err) + exitCode = 1 + continue + } + + a := new(txtar.Archive) + title := arg + if !strings.Contains(arg, "@") { + title += "@" + vers + } + a.Comment = []byte(fmt.Sprintf("module %s\n\n", title)) + a.Files = []txtar.File{ + {Name: ".mod", Data: mod}, + {Name: ".info", Data: info}, + } + dir = filepath.Clean(dir) + err = filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { + if !info.Type().IsRegular() { + return nil + } + name := info.Name() + if name == "go.mod" || strings.HasSuffix(name, ".go") { + data, err := os.ReadFile(path) + if err != nil { + return err + } + a.Files = append(a.Files, txtar.File{Name: strings.TrimPrefix(path, dir+string(filepath.Separator)), Data: data}) + } + return nil + }) + if err != nil { + log.Printf("%s: %v", arg, err) + exitCode = 1 + continue + } + + data := txtar.Format(a) + target := filepath.Join("mod", strings.ReplaceAll(path, "/", "_")+"_"+vers+".txt") + if err := os.WriteFile(target, data, 0666); err != nil { + log.Printf("%s: %v", arg, err) + exitCode = 1 + continue + } + } + os.RemoveAll(tmpdir) + os.Exit(exitCode) +} |