blob: edcf316fab8583e27c7f9c78113a4a7fdb2d3b77 [file] [log] [blame]
// Copyright 2019 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.
// Package fetch provides a way to fetch modules from a proxy.
package fetch
import (
"archive/zip"
"fmt"
"path"
"strings"
"golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/derrors"
)
// extractReadmesFromZip returns the file path and contents of all files from r
// that are README files.
func extractReadmesFromZip(modulePath, resolvedVersion string, r *zip.Reader) (_ []*internal.Readme, err error) {
defer derrors.Wrap(&err, "extractReadmesFromZip(ctx, %q, %q, r)", modulePath, resolvedVersion)
var readmes []*internal.Readme
for _, zipFile := range r.File {
if isReadme(zipFile.Name) {
if zipFile.UncompressedSize64 > MaxFileSize {
return nil, fmt.Errorf("file size %d exceeds max limit %d", zipFile.UncompressedSize64, MaxFileSize)
}
c, err := readZipFile(zipFile, MaxFileSize)
if err != nil {
return nil, err
}
readmes = append(readmes, &internal.Readme{
Filepath: strings.TrimPrefix(zipFile.Name, moduleVersionDir(modulePath, resolvedVersion)+"/"),
Contents: string(c),
})
}
}
return readmes, nil
}
var excludedReadmeExts = map[string]bool{".go": true, ".vendor": true}
// isReadme reports whether file is README or if the base name of file, with or
// without the extension, is equal to expectedFile. README.go files will return
// false. It is case insensitive. It operates on '/'-separated paths.
func isReadme(file string) bool {
const expectedFile = "README"
base := path.Base(file)
ext := path.Ext(base)
return !excludedReadmeExts[ext] && strings.EqualFold(strings.TrimSuffix(base, ext), expectedFile)
}