diff options
author | Jay Conrod <jayconrod@google.com> | 2019-11-01 18:37:53 -0400 |
---|---|---|
committer | Jay Conrod <jayconrod@google.com> | 2019-11-07 16:13:31 +0000 |
commit | 0bf2eb5d4d1ee166d7649258da61e4712a05f383 (patch) | |
tree | 124cb07d9fafeb42674449d92182b6f8fe67a510 /src/cmd/go/internal/modfetch/coderepo.go | |
parent | 947f8504d950648fc1a291925bce142ddfc3b4fa (diff) | |
download | go-0bf2eb5d4d1ee166d7649258da61e4712a05f383.tar.gz go-0bf2eb5d4d1ee166d7649258da61e4712a05f383.zip |
cmd/go/internal/modfetch: switch to golang.org/x/mod/zip
zip.Create is now used to filter and translate zip files from VCS tools.
zip.Unzip is now used instead of Unzip.
Fixes #35290
Change-Id: I4aa41b2e96bf147c09db43d1d189b8393cafb06f
Reviewed-on: https://go-review.googlesource.com/c/go/+/204917
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src/cmd/go/internal/modfetch/coderepo.go')
-rw-r--r-- | src/cmd/go/internal/modfetch/coderepo.go | 120 |
1 files changed, 38 insertions, 82 deletions
diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go index c1a24469ffa..03dd4b076d0 100644 --- a/src/cmd/go/internal/modfetch/coderepo.go +++ b/src/cmd/go/internal/modfetch/coderepo.go @@ -6,6 +6,7 @@ package modfetch import ( "archive/zip" + "bytes" "errors" "fmt" "io" @@ -21,6 +22,7 @@ import ( "golang.org/x/mod/modfile" "golang.org/x/mod/module" "golang.org/x/mod/semver" + modzip "golang.org/x/mod/zip" ) // A codeRepo implements modfetch.Repo using an underlying codehost.Repo. @@ -900,13 +902,12 @@ func (r *codeRepo) Zip(dst io.Writer, version string) error { return err } - zw := zip.NewWriter(dst) + var files []modzip.File if subdir != "" { subdir += "/" } haveLICENSE := false topPrefix := "" - haveGoMod := make(map[string]bool) for _, zf := range zr.File { if topPrefix == "" { i := strings.Index(zf.Name, "/") @@ -918,106 +919,61 @@ func (r *codeRepo) Zip(dst io.Writer, version string) error { if !strings.HasPrefix(zf.Name, topPrefix) { return fmt.Errorf("zip file contains more than one top-level directory") } - dir, file := path.Split(zf.Name) - if file == "go.mod" { - haveGoMod[dir] = true - } - } - root := topPrefix + subdir - inSubmodule := func(name string) bool { - for { - dir, _ := path.Split(name) - if len(dir) <= len(root) { - return false - } - if haveGoMod[dir] { - return true - } - name = dir[:len(dir)-1] - } - } - - for _, zf := range zr.File { - if !zf.FileInfo().Mode().IsRegular() { - // Skip symlinks (golang.org/issue/27093). - continue - } - - if topPrefix == "" { - i := strings.Index(zf.Name, "/") - if i < 0 { - return fmt.Errorf("missing top-level directory prefix") - } - topPrefix = zf.Name[:i+1] - } - if strings.HasSuffix(zf.Name, "/") { // drop directory dummy entries - continue - } - if !strings.HasPrefix(zf.Name, topPrefix) { - return fmt.Errorf("zip file contains more than one top-level directory") - } name := strings.TrimPrefix(zf.Name, topPrefix) if !strings.HasPrefix(name, subdir) { continue } - if name == ".hg_archival.txt" { - // Inserted by hg archive. - // Not correct to drop from other version control systems, but too bad. - continue - } name = strings.TrimPrefix(name, subdir) - if isVendoredPackage(name) { + if name == "" || strings.HasSuffix(name, "/") { continue } - if inSubmodule(zf.Name) { - continue - } - 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) - } + files = append(files, zipFile{name: name, f: zf}) if name == "LICENSE" { haveLICENSE = true } - size := int64(zf.UncompressedSize64) - if size < 0 || maxSize < size { - return fmt.Errorf("module source tree too big") - } - maxSize -= size - - rc, err := zf.Open() - if err != nil { - return err - } - w, err := zw.Create(r.modPrefix(version) + "/" + name) - if err != nil { - return err - } - lr := &io.LimitedReader{R: rc, N: size + 1} - if _, err := io.Copy(w, lr); err != nil { - return err - } - if lr.N <= 0 { - return fmt.Errorf("individual file too large") - } } if !haveLICENSE && subdir != "" { data, err := r.code.ReadFile(rev, "LICENSE", codehost.MaxLICENSE) if err == nil { - w, err := zw.Create(r.modPrefix(version) + "/LICENSE") - if err != nil { - return err - } - if _, err := w.Write(data); err != nil { - return err - } + files = append(files, dataFile{name: "LICENSE", data: data}) } } - return zw.Close() + return modzip.Create(dst, module.Version{Path: r.modPath, Version: version}, files) +} + +type zipFile struct { + name string + f *zip.File +} + +func (f zipFile) Path() string { return f.name } +func (f zipFile) Lstat() (os.FileInfo, error) { return f.f.FileInfo(), nil } +func (f zipFile) Open() (io.ReadCloser, error) { return f.f.Open() } + +type dataFile struct { + name string + data []byte +} + +func (f dataFile) Path() string { return f.name } +func (f dataFile) Lstat() (os.FileInfo, error) { return dataFileInfo{f}, nil } +func (f dataFile) Open() (io.ReadCloser, error) { + return ioutil.NopCloser(bytes.NewReader(f.data)), nil } +type dataFileInfo struct { + f dataFile +} + +func (fi dataFileInfo) Name() string { return path.Base(fi.f.name) } +func (fi dataFileInfo) Size() int64 { return int64(len(fi.f.data)) } +func (fi dataFileInfo) Mode() os.FileMode { return 0644 } +func (fi dataFileInfo) ModTime() time.Time { return time.Time{} } +func (fi dataFileInfo) IsDir() bool { return false } +func (fi dataFileInfo) Sys() interface{} { return nil } + // hasPathPrefix reports whether the path s begins with the // elements in prefix. func hasPathPrefix(s, prefix string) bool { |