зеркало из https://github.com/golang/pkgsite.git
256 строки
7.7 KiB
Go
256 строки
7.7 KiB
Go
// 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 internal
|
|
|
|
import (
|
|
"errors"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"golang.org/x/mod/module"
|
|
"golang.org/x/pkgsite/internal/derrors"
|
|
"golang.org/x/pkgsite/internal/licenses"
|
|
"golang.org/x/pkgsite/internal/source"
|
|
"golang.org/x/pkgsite/internal/stdlib"
|
|
)
|
|
|
|
const (
|
|
// LatestVersion signifies the latest available version in requests to the
|
|
// proxy client.
|
|
LatestVersion = "latest"
|
|
|
|
// MainVersion represents the main branch.
|
|
MainVersion = "main"
|
|
|
|
// MasterVersion represents the master branch.
|
|
MasterVersion = "master"
|
|
|
|
// UnknownModulePath signifies that the module path for a given package
|
|
// path is ambiguous or not known. This is because requests to the
|
|
// frontend can come in the form of <import-path>[@<version>], and it is
|
|
// not clear which part of the import-path is the module path.
|
|
UnknownModulePath = "unknownModulePath"
|
|
)
|
|
|
|
// DefaultBranches are default branches that are supported by pkgsite.
|
|
var DefaultBranches = map[string]bool{
|
|
MainVersion: true,
|
|
MasterVersion: true,
|
|
}
|
|
|
|
// ModuleInfo holds metadata associated with a module.
|
|
type ModuleInfo struct {
|
|
ModulePath string
|
|
Version string
|
|
CommitTime time.Time
|
|
IsRedistributable bool
|
|
// HasGoMod describes whether the module zip has a go.mod file.
|
|
HasGoMod bool
|
|
SourceInfo *source.Info
|
|
|
|
// Deprecated describes whether the module is deprecated.
|
|
Deprecated bool
|
|
// DeprecationComment is the comment describing the deprecation, if any.
|
|
DeprecationComment string
|
|
// Retracted describes whether the module version is retracted.
|
|
Retracted bool
|
|
// RetractionRationale is the reason for the retraction, if any.
|
|
RetractionRationale string
|
|
}
|
|
|
|
// VersionMap holds metadata associated with module queries for a version.
|
|
type VersionMap struct {
|
|
ModulePath string
|
|
RequestedVersion string
|
|
ResolvedVersion string
|
|
GoModPath string
|
|
Status int
|
|
Error string
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
// SeriesPath returns the series path for the module.
|
|
//
|
|
// A series is a group of modules that share the same base path and are assumed
|
|
// to be major-version variants.
|
|
//
|
|
// The series path is the module path without the version. For most modules,
|
|
// this will be the module path for all module versions with major version 0 or
|
|
// 1. For gopkg.in modules, the series path does not correspond to any module
|
|
// version.
|
|
//
|
|
// Examples:
|
|
// The module paths "a/b" and "a/b/v2" both have series path "a/b".
|
|
// The module paths "gopkg.in/yaml.v1" and "gopkg.in/yaml.v2" both have series
|
|
// path "gopkg.in/yaml".
|
|
func (v *ModuleInfo) SeriesPath() string {
|
|
return SeriesPathForModule(v.ModulePath)
|
|
}
|
|
|
|
// SeriesPathForModule returns the series path for the provided modulePath.
|
|
func SeriesPathForModule(modulePath string) string {
|
|
seriesPath, _, _ := module.SplitPathVersion(modulePath)
|
|
return seriesPath
|
|
}
|
|
|
|
// MajorVersionForModule returns the final "vN" from the module path, if any.
|
|
// It returns the empty string if the module path is malformed.
|
|
// Examples:
|
|
//
|
|
// "m.com" => ""
|
|
// "m.com/v2" => "v2"
|
|
// "gpkg.in/m.v1 = "v1"
|
|
func MajorVersionForModule(modulePath string) string {
|
|
_, v, _ := module.SplitPathVersion(modulePath)
|
|
return strings.TrimLeft(v, "/.")
|
|
}
|
|
|
|
// SeriesPathAndMajorVersion splits modulePath into a series path and a
|
|
// numeric major version.
|
|
// If the path doesn't have a "vN" suffix, it returns 1.
|
|
// If the module path is invalid, it returns ("", 0).
|
|
func SeriesPathAndMajorVersion(modulePath string) (string, int) {
|
|
seriesPath, v, ok := module.SplitPathVersion(modulePath)
|
|
if !ok {
|
|
return "", 0
|
|
}
|
|
if v == "" {
|
|
return seriesPath, 1
|
|
}
|
|
// First two characters are either ".v" or "/v".
|
|
n, err := strconv.Atoi(v[2:])
|
|
if err != nil {
|
|
return "", 0
|
|
}
|
|
return seriesPath, n
|
|
}
|
|
|
|
// Suffix returns the suffix of the fullPath. It assumes that basePath is a
|
|
// prefix of fullPath. If fullPath and basePath are the same, the empty string
|
|
// is returned.
|
|
func Suffix(fullPath, basePath string) string {
|
|
return strings.TrimPrefix(strings.TrimPrefix(fullPath, basePath), "/")
|
|
}
|
|
|
|
// V1Path returns the path for version 1 of the package whose import path
|
|
// is fullPath. If modulePath is the standard library, then V1Path returns
|
|
// fullPath.
|
|
func V1Path(fullPath, modulePath string) string {
|
|
if modulePath == stdlib.ModulePath {
|
|
return fullPath
|
|
}
|
|
return path.Join(SeriesPathForModule(modulePath), Suffix(fullPath, modulePath))
|
|
}
|
|
|
|
// A Module is a specific, reproducible build of a module.
|
|
type Module struct {
|
|
ModuleInfo
|
|
// Licenses holds all licenses within this module version, including those
|
|
// that may be contained in nested subdirectories.
|
|
Licenses []*licenses.License
|
|
Units []*Unit
|
|
}
|
|
|
|
// Packages returns all of the units for a module that are packages.
|
|
func (m *Module) Packages() []*Unit {
|
|
var pkgs []*Unit
|
|
for _, u := range m.Units {
|
|
if u.IsPackage() {
|
|
pkgs = append(pkgs, u)
|
|
}
|
|
}
|
|
return pkgs
|
|
}
|
|
|
|
// IndexVersion holds the version information returned by the module index.
|
|
type IndexVersion struct {
|
|
Path string
|
|
Version string
|
|
Timestamp time.Time
|
|
}
|
|
|
|
// ModuleVersionState holds a worker module version state.
|
|
type ModuleVersionState struct {
|
|
ModulePath string
|
|
Version string
|
|
|
|
// IndexTimestamp is the timestamp received from the Index for this version,
|
|
// which should correspond to the time this version was committed to the
|
|
// Index.
|
|
//
|
|
// This may be nil if the request only came via frontend fetch, or the
|
|
// status is not a 2xx status.
|
|
IndexTimestamp *time.Time
|
|
|
|
// CreatedAt is the time this version was originally inserted into the
|
|
// module version state table.
|
|
CreatedAt time.Time
|
|
|
|
// Status is the most recent HTTP status code received from the Fetch service
|
|
// for this version, or nil if no request to the fetch service has been made.
|
|
Status int
|
|
// Error is the most recent HTTP response body received from the Fetch
|
|
// service, for a response with an unsuccessful status code. It is used for
|
|
// debugging only, and has no semantic significance.
|
|
Error string
|
|
// TryCount is the number of times a fetch of this version has been
|
|
// attempted.
|
|
TryCount int
|
|
// LastProcessedAt is the last time this version was updated with a result
|
|
// from the fetch service.
|
|
LastProcessedAt *time.Time
|
|
// NextProcessedAfter is the next time a fetch for this version should be
|
|
// attempted.
|
|
NextProcessedAfter time.Time
|
|
|
|
// AppVersion is the value of the GAE_VERSION environment variable, which is
|
|
// set by app engine. It is a timestamp in the format 20190709t112655 that
|
|
// is close to, but not the same as, the deployment time. For example, the
|
|
// deployment time for the above timestamp might be Jul 9, 2019, 11:29:59 AM.
|
|
AppVersion string
|
|
|
|
// HasGoMod says whether the zip file has a go.mod file.
|
|
HasGoMod bool
|
|
|
|
// GoModPath is the path declared in the go.mod file fetched from the proxy.
|
|
GoModPath string
|
|
|
|
// NumPackages it the number of packages that were processed as part of the
|
|
// module (regardless of whether the processing was successful).
|
|
NumPackages *int
|
|
}
|
|
|
|
// PackageVersionState holds a worker package version state. It is associated
|
|
// with a given module version state.
|
|
type PackageVersionState struct {
|
|
PackagePath string
|
|
ModulePath string
|
|
Version string
|
|
Status int
|
|
Error string
|
|
}
|
|
|
|
// A Modver holds a module path and version.
|
|
type Modver struct {
|
|
Path string
|
|
Version string
|
|
}
|
|
|
|
func (mv Modver) String() string {
|
|
return mv.Path + "@" + mv.Version
|
|
}
|
|
|
|
// ParseModver parses a string of the form M@V into a Modver.
|
|
func ParseModver(s string) (mv Modver, err error) {
|
|
defer derrors.Wrap(&err, "ParseModver(%q)", s)
|
|
parts := strings.Split(s, "@")
|
|
if len(parts) != 2 {
|
|
return mv, errors.New("should be module@version")
|
|
}
|
|
return Modver{Path: parts[0], Version: parts[1]}, nil
|
|
}
|