diff options
author | Bryan C. Mills <bcmills@google.com> | 2018-11-27 08:50:28 -0500 |
---|---|---|
committer | Bryan C. Mills <bcmills@google.com> | 2018-11-29 18:18:51 +0000 |
commit | ba2e8f65ab36f145177419c56cc03adf67f0e167 (patch) | |
tree | 7d7ac889d63f59600f3e9bd37c0f89ae7df1c56f /src/cmd/go/internal/modfetch/coderepo.go | |
parent | c124a919716fd54f9b16b83fa94f68b0c8fc4681 (diff) | |
download | go-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.go | 67 |
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 |