aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/modfetch/coderepo.go
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2018-11-27 08:50:28 -0500
committerBryan C. Mills <bcmills@google.com>2018-11-29 18:18:51 +0000
commitba2e8f65ab36f145177419c56cc03adf67f0e167 (patch)
tree7d7ac889d63f59600f3e9bd37c0f89ae7df1c56f /src/cmd/go/internal/modfetch/coderepo.go
parentc124a919716fd54f9b16b83fa94f68b0c8fc4681 (diff)
downloadgo-ba2e8f65ab36f145177419c56cc03adf67f0e167.tar.gz
go-ba2e8f65ab36f145177419c56cc03adf67f0e167.zip
cmd/go/internal/modfetch: make Repo.Zip write to an io.Writer instead of a temporary file
This will be used to eliminate a redundant copy in CL 145178. (It also decouples two design points that were previously coupled: the destination of the zip output and the program logic to write that output.) Updates #26794 Change-Id: I6cfd5a33c162c0016a1b83a278003684560a3772 Reviewed-on: https://go-review.googlesource.com/c/151341 Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/cmd/go/internal/modfetch/coderepo.go')
-rw-r--r--src/cmd/go/internal/modfetch/coderepo.go67
1 files changed, 26 insertions, 41 deletions
diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go
index 9cf0e911508..737aade739b 100644
--- a/src/cmd/go/internal/modfetch/coderepo.go
+++ b/src/cmd/go/internal/modfetch/coderepo.go
@@ -407,25 +407,26 @@ func (r *codeRepo) modPrefix(rev string) string {
return r.modPath + "@" + rev
}
-func (r *codeRepo) Zip(version string, tmpdir string) (tmpfile string, err error) {
+func (r *codeRepo) Zip(dst io.Writer, version string) error {
rev, dir, _, err := r.findDir(version)
if err != nil {
- return "", err
+ return err
}
dl, actualDir, err := r.code.ReadZip(rev, dir, codehost.MaxZipFile)
if err != nil {
- return "", err
+ return err
}
+ defer dl.Close()
if actualDir != "" && !hasPathPrefix(dir, actualDir) {
- return "", fmt.Errorf("internal error: downloading %v %v: dir=%q but actualDir=%q", r.path, rev, dir, actualDir)
+ return fmt.Errorf("internal error: downloading %v %v: dir=%q but actualDir=%q", r.path, rev, dir, actualDir)
}
subdir := strings.Trim(strings.TrimPrefix(dir, actualDir), "/")
// Spool to local file.
- f, err := ioutil.TempFile(tmpdir, "go-codehost-")
+ f, err := ioutil.TempFile("", "go-codehost-")
if err != nil {
dl.Close()
- return "", err
+ return err
}
defer os.Remove(f.Name())
defer f.Close()
@@ -433,35 +434,24 @@ func (r *codeRepo) Zip(version string, tmpdir string) (tmpfile string, err error
lr := &io.LimitedReader{R: dl, N: maxSize + 1}
if _, err := io.Copy(f, lr); err != nil {
dl.Close()
- return "", err
+ return err
}
dl.Close()
if lr.N <= 0 {
- return "", fmt.Errorf("downloaded zip file too large")
+ return fmt.Errorf("downloaded zip file too large")
}
size := (maxSize + 1) - lr.N
if _, err := f.Seek(0, 0); err != nil {
- return "", err
+ return err
}
// Translate from zip file we have to zip file we want.
zr, err := zip.NewReader(f, size)
if err != nil {
- return "", err
- }
- f2, err := ioutil.TempFile(tmpdir, "go-codezip-")
- if err != nil {
- return "", err
+ return err
}
- zw := zip.NewWriter(f2)
- newName := f2.Name()
- defer func() {
- f2.Close()
- if err != nil {
- os.Remove(newName)
- }
- }()
+ zw := zip.NewWriter(dst)
if subdir != "" {
subdir += "/"
}
@@ -472,12 +462,12 @@ func (r *codeRepo) Zip(version string, tmpdir string) (tmpfile string, err error
if topPrefix == "" {
i := strings.Index(zf.Name, "/")
if i < 0 {
- return "", fmt.Errorf("missing top-level directory prefix")
+ return fmt.Errorf("missing top-level directory prefix")
}
topPrefix = zf.Name[:i+1]
}
if !strings.HasPrefix(zf.Name, topPrefix) {
- return "", fmt.Errorf("zip file contains more than one top-level directory")
+ return fmt.Errorf("zip file contains more than one top-level directory")
}
dir, file := path.Split(zf.Name)
if file == "go.mod" {
@@ -497,11 +487,12 @@ func (r *codeRepo) Zip(version string, tmpdir string) (tmpfile string, err error
name = dir[:len(dir)-1]
}
}
+
for _, zf := range zr.File {
if topPrefix == "" {
i := strings.Index(zf.Name, "/")
if i < 0 {
- return "", fmt.Errorf("missing top-level directory prefix")
+ return fmt.Errorf("missing top-level directory prefix")
}
topPrefix = zf.Name[:i+1]
}
@@ -509,7 +500,7 @@ func (r *codeRepo) Zip(version string, tmpdir string) (tmpfile string, err error
continue
}
if !strings.HasPrefix(zf.Name, topPrefix) {
- return "", fmt.Errorf("zip file contains more than one top-level directory")
+ return fmt.Errorf("zip file contains more than one top-level directory")
}
name := strings.TrimPrefix(zf.Name, topPrefix)
if !strings.HasPrefix(name, subdir) {
@@ -529,28 +520,28 @@ func (r *codeRepo) Zip(version string, tmpdir string) (tmpfile string, err error
}
base := path.Base(name)
if strings.ToLower(base) == "go.mod" && base != "go.mod" {
- return "", fmt.Errorf("zip file contains %s, want all lower-case go.mod", zf.Name)
+ return fmt.Errorf("zip file contains %s, want all lower-case go.mod", zf.Name)
}
if name == "LICENSE" {
haveLICENSE = true
}
- size := int64(zf.UncompressedSize)
+ size := int64(zf.UncompressedSize64)
if size < 0 || maxSize < size {
- return "", fmt.Errorf("module source tree too big")
+ return fmt.Errorf("module source tree too big")
}
maxSize -= size
rc, err := zf.Open()
if err != nil {
- return "", err
+ return err
}
w, err := zw.Create(r.modPrefix(version) + "/" + name)
lr := &io.LimitedReader{R: rc, N: size + 1}
if _, err := io.Copy(w, lr); err != nil {
- return "", err
+ return err
}
if lr.N <= 0 {
- return "", fmt.Errorf("individual file too large")
+ return fmt.Errorf("individual file too large")
}
}
@@ -559,21 +550,15 @@ func (r *codeRepo) Zip(version string, tmpdir string) (tmpfile string, err error
if err == nil {
w, err := zw.Create(r.modPrefix(version) + "/LICENSE")
if err != nil {
- return "", err
+ return err
}
if _, err := w.Write(data); err != nil {
- return "", err
+ return err
}
}
}
- if err := zw.Close(); err != nil {
- return "", err
- }
- if err := f2.Close(); err != nil {
- return "", err
- }
- return f2.Name(), nil
+ return zw.Close()
}
// hasPathPrefix reports whether the path s begins with the