all: use golang.org/x/mod
Use the semver and module packages from golang.org/x/mod. Remove them
from internal/thirdparty.
We also rename Encode{Version,Path} to Escape{Version,Path} because
golang.org/x/module does that.
Fixes b/133841935.
Change-Id: I0e52c6dd7109fbd488a030c750cdc06736356868
Reviewed-on: https://team-review.git.corp.google.com/c/golang/discovery/+/619244
CI-Result: Cloud Build <devtools-proctor-result-processor@system.gserviceaccount.com>
Reviewed-by: Julie Qiu <julieqiu@google.com>
diff --git a/go.mod b/go.mod
index c88cc48..a7d6856 100644
--- a/go.mod
+++ b/go.mod
@@ -40,6 +40,7 @@
github.com/yuin/gopher-lua v0.0.0-20190514113301-1cd887cd7036 // indirect
go.opencensus.io v0.22.1
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392
+ golang.org/x/mod v0.1.0
golang.org/x/net v0.0.0-20191007182048-72f939374954
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
diff --git a/go.sum b/go.sum
index 4371a19..53c5e07 100644
--- a/go.sum
+++ b/go.sum
@@ -349,6 +349,7 @@
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0 h1:sfUMP1Gu8qASkorDVjnMuvgJzwFbTZSeXFiGBYAVdl4=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
diff --git a/internal/discovery.go b/internal/discovery.go
index d90eca3..349b331 100644
--- a/internal/discovery.go
+++ b/internal/discovery.go
@@ -9,7 +9,7 @@
"golang.org/x/discovery/internal/license"
"golang.org/x/discovery/internal/source"
- "golang.org/x/discovery/internal/thirdparty/module"
+ "golang.org/x/mod/module"
"golang.org/x/discovery/internal/version"
)
diff --git a/internal/frontend/details.go b/internal/frontend/details.go
index e387d32..a2a9a03 100644
--- a/internal/frontend/details.go
+++ b/internal/frontend/details.go
@@ -16,8 +16,8 @@
"golang.org/x/discovery/internal/license"
"golang.org/x/discovery/internal/log"
"golang.org/x/discovery/internal/stdlib"
- "golang.org/x/discovery/internal/thirdparty/module"
- "golang.org/x/discovery/internal/thirdparty/semver"
+ "golang.org/x/mod/module"
+ "golang.org/x/mod/semver"
"golang.org/x/xerrors"
)
diff --git a/internal/frontend/header.go b/internal/frontend/header.go
index 720f3fd..ee58b03 100644
--- a/internal/frontend/header.go
+++ b/internal/frontend/header.go
@@ -16,7 +16,7 @@
"golang.org/x/discovery/internal/license"
"golang.org/x/discovery/internal/middleware"
"golang.org/x/discovery/internal/stdlib"
- "golang.org/x/discovery/internal/thirdparty/module"
+ "golang.org/x/mod/module"
)
// Package contains information for an individual package.
diff --git a/internal/frontend/stdlib.go b/internal/frontend/stdlib.go
index ef3758b..e3a51c6 100644
--- a/internal/frontend/stdlib.go
+++ b/internal/frontend/stdlib.go
@@ -13,7 +13,7 @@
"golang.org/x/discovery/internal/derrors"
"golang.org/x/discovery/internal/log"
"golang.org/x/discovery/internal/stdlib"
- "golang.org/x/discovery/internal/thirdparty/module"
+ "golang.org/x/mod/module"
)
// handleStdLib handles a request for a stdlib package or module.
diff --git a/internal/frontend/versions.go b/internal/frontend/versions.go
index 047148f..940cd1f 100644
--- a/internal/frontend/versions.go
+++ b/internal/frontend/versions.go
@@ -14,8 +14,8 @@
"golang.org/x/discovery/internal"
"golang.org/x/discovery/internal/log"
"golang.org/x/discovery/internal/stdlib"
- "golang.org/x/discovery/internal/thirdparty/module"
- "golang.org/x/discovery/internal/thirdparty/semver"
+ "golang.org/x/mod/module"
+ "golang.org/x/mod/semver"
"golang.org/x/discovery/internal/version"
)
diff --git a/internal/license/detect.go b/internal/license/detect.go
index b2b7d25..ba128fe 100644
--- a/internal/license/detect.go
+++ b/internal/license/detect.go
@@ -14,7 +14,7 @@
"github.com/google/licensecheck"
"golang.org/x/discovery/internal/derrors"
- "golang.org/x/discovery/internal/thirdparty/module"
+ "golang.org/x/mod/module"
)
const (
diff --git a/internal/postgres/insert_version.go b/internal/postgres/insert_version.go
index 5a40e67..745737d 100644
--- a/internal/postgres/insert_version.go
+++ b/internal/postgres/insert_version.go
@@ -19,8 +19,8 @@
"golang.org/x/discovery/internal/database"
"golang.org/x/discovery/internal/derrors"
"golang.org/x/discovery/internal/stdlib"
- "golang.org/x/discovery/internal/thirdparty/module"
- "golang.org/x/discovery/internal/thirdparty/semver"
+ "golang.org/x/mod/module"
+ "golang.org/x/mod/semver"
"golang.org/x/discovery/internal/version"
"golang.org/x/xerrors"
)
diff --git a/internal/proxy/client.go b/internal/proxy/client.go
index 1581511..3f6350f 100644
--- a/internal/proxy/client.go
+++ b/internal/proxy/client.go
@@ -22,7 +22,7 @@
"go.opencensus.io/plugin/ochttp"
"golang.org/x/discovery/internal"
"golang.org/x/discovery/internal/derrors"
- "golang.org/x/discovery/internal/thirdparty/module"
+ "golang.org/x/mod/module"
"golang.org/x/net/context/ctxhttp"
"golang.org/x/xerrors"
)
@@ -62,7 +62,7 @@
// transforms that data into a *VersionInfo.
func (c *Client) GetInfo(ctx context.Context, modulePath, version string) (_ *VersionInfo, err error) {
defer derrors.Wrap(&err, "proxy.Client.GetInfo(%q, %q)", modulePath, version)
- u, err := c.encodedURL(modulePath, version, "info")
+ u, err := c.escapedURL(modulePath, version, "info")
if err != nil {
return nil, err
}
@@ -90,7 +90,7 @@
if err != nil {
return nil, err
}
- u, err := c.encodedURL(requestedPath, info.Version, "zip")
+ u, err := c.escapedURL(requestedPath, info.Version, "zip")
if err != nil {
return nil, err
}
@@ -113,15 +113,15 @@
return zipReader, nil
}
-func (c *Client) encodedURL(modulePath, version, suffix string) (_ string, err error) {
+func (c *Client) escapedURL(modulePath, version, suffix string) (_ string, err error) {
defer func() {
- derrors.Wrap(&err, "Client.encodedURL(%q, %q, %q)", modulePath, version, suffix)
+ derrors.Wrap(&err, "Client.escapedURL(%q, %q, %q)", modulePath, version, suffix)
}()
if suffix != "info" && suffix != "zip" {
return "", errors.New(`suffix must be "info" or "zip"`)
}
- encodedPath, err := module.EncodePath(modulePath)
+ escapedPath, err := module.EscapePath(modulePath)
if err != nil {
return "", xerrors.Errorf("path: %v: %w", err, derrors.InvalidArgument)
}
@@ -129,23 +129,23 @@
if suffix != "info" {
return "", fmt.Errorf("cannot ask for latest with suffix %q", suffix)
}
- return fmt.Sprintf("%s/%s/@latest", c.url, encodedPath), nil
+ return fmt.Sprintf("%s/%s/@latest", c.url, escapedPath), nil
}
- encodedVersion, err := module.EncodeVersion(version)
+ escapedVersion, err := module.EscapeVersion(version)
if err != nil {
return "", xerrors.Errorf("version: %v: %w", err, derrors.InvalidArgument)
}
- return fmt.Sprintf("%s/%s/@v/%s.%s", c.url, encodedPath, encodedVersion, suffix), nil
+ return fmt.Sprintf("%s/%s/@v/%s.%s", c.url, escapedPath, escapedVersion, suffix), nil
}
// ListVersions makes a request to $GOPROXY/<path>/@v/list and returns the
// resulting version strings.
func (c *Client) ListVersions(ctx context.Context, modulePath string) ([]string, error) {
- encodedPath, err := module.EncodePath(modulePath)
+ escapedPath, err := module.EscapePath(modulePath)
if err != nil {
- return nil, xerrors.Errorf("module.EncodePath(%q): %w", modulePath, derrors.InvalidArgument)
+ return nil, xerrors.Errorf("module.EscapePath(%q): %w", modulePath, derrors.InvalidArgument)
}
- u := fmt.Sprintf("%s/%s/@v/list", c.url, encodedPath)
+ u := fmt.Sprintf("%s/%s/@v/list", c.url, escapedPath)
var versions []string
collect := func(body io.Reader) error {
scanner := bufio.NewScanner(body)
diff --git a/internal/proxy/client_test.go b/internal/proxy/client_test.go
index e58da52..a226cd4 100644
--- a/internal/proxy/client_test.go
+++ b/internal/proxy/client_test.go
@@ -227,7 +227,7 @@
"", // only "info" or "zip"
},
} {
- got, err := c.encodedURL(test.path, test.version, test.suffix)
+ got, err := c.escapedURL(test.path, test.version, test.suffix)
if got != test.want || (err != nil) != (test.want == "") {
t.Errorf("%s, %s, %s: got (%q, %v), want %q", test.path, test.version, test.suffix, got, err, test.want)
}
diff --git a/internal/proxy/test_helper.go b/internal/proxy/test_helper.go
index 9434b8b..c8fe25d 100644
--- a/internal/proxy/test_helper.go
+++ b/internal/proxy/test_helper.go
@@ -19,7 +19,7 @@
"time"
"golang.org/x/discovery/internal/testing/testhelper"
- "golang.org/x/discovery/internal/thirdparty/semver"
+ "golang.org/x/mod/semver"
)
// TestVersion represents a module version to host in the fake proxy.
diff --git a/internal/proxydatasource/datasource.go b/internal/proxydatasource/datasource.go
index 4c9e274..8765084 100644
--- a/internal/proxydatasource/datasource.go
+++ b/internal/proxydatasource/datasource.go
@@ -18,7 +18,7 @@
"golang.org/x/discovery/internal/etl"
"golang.org/x/discovery/internal/license"
"golang.org/x/discovery/internal/proxy"
- "golang.org/x/discovery/internal/thirdparty/semver"
+ "golang.org/x/mod/semver"
"golang.org/x/discovery/internal/version"
"golang.org/x/xerrors"
)
diff --git a/internal/stdlib/stdlib.go b/internal/stdlib/stdlib.go
index 15dabc9..9b9adb0 100644
--- a/internal/stdlib/stdlib.go
+++ b/internal/stdlib/stdlib.go
@@ -23,7 +23,7 @@
"golang.org/x/discovery/internal/derrors"
"golang.org/x/discovery/internal/testing/testhelper"
- "golang.org/x/discovery/internal/thirdparty/semver"
+ "golang.org/x/mod/semver"
"gopkg.in/src-d/go-billy.v4/osfs"
"gopkg.in/src-d/go-git.v4"
diff --git a/internal/stdlib/stdlib_test.go b/internal/stdlib/stdlib_test.go
index a116cba..5ceda9c 100644
--- a/internal/stdlib/stdlib_test.go
+++ b/internal/stdlib/stdlib_test.go
@@ -9,7 +9,7 @@
"strings"
"testing"
- "golang.org/x/discovery/internal/thirdparty/semver"
+ "golang.org/x/mod/semver"
)
func TestTagForVersion(t *testing.T) {
diff --git a/internal/thirdparty/modfile/rule.go b/internal/thirdparty/modfile/rule.go
index f0b3093..9d3fba2 100644
--- a/internal/thirdparty/modfile/rule.go
+++ b/internal/thirdparty/modfile/rule.go
@@ -19,8 +19,8 @@
"strings"
"unicode"
- "golang.org/x/discovery/internal/thirdparty/module"
- "golang.org/x/discovery/internal/thirdparty/semver"
+ "golang.org/x/mod/module"
+ "golang.org/x/mod/semver"
)
// A File is the parsed, interpreted form of a go.mod file.
diff --git a/internal/thirdparty/module/module.go b/internal/thirdparty/module/module.go
deleted file mode 100644
index 8e11496..0000000
--- a/internal/thirdparty/module/module.go
+++ /dev/null
@@ -1,544 +0,0 @@
-// DO NOT EDIT. This file was copied from
-// https://go.googlesource.com/go/+/db7e7469/src/cmd/go/internal/module.
-// generated by internal/thirdparty/download.go -pkg=module
-
-// Copyright 2018 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 module defines the module.Version type
-// along with support code.
-package module
-
-// IMPORTANT NOTE
-//
-// This file essentially defines the set of valid import paths for the go command.
-// There are many subtle considerations, including Unicode ambiguity,
-// security, network, and file system representations.
-//
-// This file also defines the set of valid module path and version combinations,
-// another topic with many subtle considerations.
-//
-// Changes to the semantics in this file require approval from rsc.
-
-import (
- "fmt"
- "sort"
- "strings"
- "unicode"
- "unicode/utf8"
-
- "golang.org/x/discovery/internal/thirdparty/semver"
-)
-
-// A Version is defined by a module path and version pair.
-type Version struct {
- Path string
-
- // Version is usually a semantic version in canonical form.
- // There are two exceptions to this general rule.
- // First, the top-level target of a build has no specific version
- // and uses Version = "".
- // Second, during MVS calculations the version "none" is used
- // to represent the decision to take no version of a given module.
- Version string `json:",omitempty"`
-}
-
-// Check checks that a given module path, version pair is valid.
-// In addition to the path being a valid module path
-// and the version being a valid semantic version,
-// the two must correspond.
-// For example, the path "yaml/v2" only corresponds to
-// semantic versions beginning with "v2.".
-func Check(path, version string) error {
- if err := CheckPath(path); err != nil {
- return err
- }
- if !semver.IsValid(version) {
- return fmt.Errorf("malformed semantic version %v", version)
- }
- _, pathMajor, _ := SplitPathVersion(path)
- if !MatchPathMajor(version, pathMajor) {
- if pathMajor == "" {
- pathMajor = "v0 or v1"
- }
- if pathMajor[0] == '.' { // .v1
- pathMajor = pathMajor[1:]
- }
- return fmt.Errorf("mismatched module path %v and version %v (want %v)", path, version, pathMajor)
- }
- return nil
-}
-
-// firstPathOK reports whether r can appear in the first element of a module path.
-// The first element of the path must be an LDH domain name, at least for now.
-// To avoid case ambiguity, the domain name must be entirely lower case.
-func firstPathOK(r rune) bool {
- return r == '-' || r == '.' ||
- '0' <= r && r <= '9' ||
- 'a' <= r && r <= 'z'
-}
-
-// pathOK reports whether r can appear in an import path element.
-// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: + - . _ and ~.
-// This matches what "go get" has historically recognized in import paths.
-// TODO(rsc): We would like to allow Unicode letters, but that requires additional
-// care in the safe encoding (see note below).
-func pathOK(r rune) bool {
- if r < utf8.RuneSelf {
- return r == '+' || r == '-' || r == '.' || r == '_' || r == '~' ||
- '0' <= r && r <= '9' ||
- 'A' <= r && r <= 'Z' ||
- 'a' <= r && r <= 'z'
- }
- return false
-}
-
-// fileNameOK reports whether r can appear in a file name.
-// For now we allow all Unicode letters but otherwise limit to pathOK plus a few more punctuation characters.
-// If we expand the set of allowed characters here, we have to
-// work harder at detecting potential case-folding and normalization collisions.
-// See note about "safe encoding" below.
-func fileNameOK(r rune) bool {
- if r < utf8.RuneSelf {
- // Entire set of ASCII punctuation, from which we remove characters:
- // ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
- // We disallow some shell special characters: " ' * < > ? ` |
- // (Note that some of those are disallowed by the Windows file system as well.)
- // We also disallow path separators / : and \ (fileNameOK is only called on path element characters).
- // We allow spaces (U+0020) in file names.
- const allowed = "!#$%&()+,-.=@[]^_{}~ "
- if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' {
- return true
- }
- for i := 0; i < len(allowed); i++ {
- if rune(allowed[i]) == r {
- return true
- }
- }
- return false
- }
- // It may be OK to add more ASCII punctuation here, but only carefully.
- // For example Windows disallows < > \, and macOS disallows :, so we must not allow those.
- return unicode.IsLetter(r)
-}
-
-// CheckPath checks that a module path is valid.
-func CheckPath(path string) error {
- if err := checkPath(path, false); err != nil {
- return fmt.Errorf("malformed module path %q: %v", path, err)
- }
- i := strings.Index(path, "/")
- if i < 0 {
- i = len(path)
- }
- if i == 0 {
- return fmt.Errorf("malformed module path %q: leading slash", path)
- }
- if !strings.Contains(path[:i], ".") {
- return fmt.Errorf("malformed module path %q: missing dot in first path element", path)
- }
- if path[0] == '-' {
- return fmt.Errorf("malformed module path %q: leading dash in first path element", path)
- }
- for _, r := range path[:i] {
- if !firstPathOK(r) {
- return fmt.Errorf("malformed module path %q: invalid char %q in first path element", path, r)
- }
- }
- if _, _, ok := SplitPathVersion(path); !ok {
- return fmt.Errorf("malformed module path %q: invalid version", path)
- }
- return nil
-}
-
-// CheckImportPath checks that an import path is valid.
-func CheckImportPath(path string) error {
- if err := checkPath(path, false); err != nil {
- return fmt.Errorf("malformed import path %q: %v", path, err)
- }
- return nil
-}
-
-// checkPath checks that a general path is valid.
-// It returns an error describing why but not mentioning path.
-// Because these checks apply to both module paths and import paths,
-// the caller is expected to add the "malformed ___ path %q: " prefix.
-// fileName indicates whether the final element of the path is a file name
-// (as opposed to a directory name).
-func checkPath(path string, fileName bool) error {
- if !utf8.ValidString(path) {
- return fmt.Errorf("invalid UTF-8")
- }
- if path == "" {
- return fmt.Errorf("empty string")
- }
- if strings.Contains(path, "..") {
- return fmt.Errorf("double dot")
- }
- if strings.Contains(path, "//") {
- return fmt.Errorf("double slash")
- }
- if path[len(path)-1] == '/' {
- return fmt.Errorf("trailing slash")
- }
- elemStart := 0
- for i, r := range path {
- if r == '/' {
- if err := checkElem(path[elemStart:i], fileName); err != nil {
- return err
- }
- elemStart = i + 1
- }
- }
- if err := checkElem(path[elemStart:], fileName); err != nil {
- return err
- }
- return nil
-}
-
-// checkElem checks whether an individual path element is valid.
-// fileName indicates whether the element is a file name (not a directory name).
-func checkElem(elem string, fileName bool) error {
- if elem == "" {
- return fmt.Errorf("empty path element")
- }
- if strings.Count(elem, ".") == len(elem) {
- return fmt.Errorf("invalid path element %q", elem)
- }
- if elem[0] == '.' && !fileName {
- return fmt.Errorf("leading dot in path element")
- }
- if elem[len(elem)-1] == '.' {
- return fmt.Errorf("trailing dot in path element")
- }
- charOK := pathOK
- if fileName {
- charOK = fileNameOK
- }
- for _, r := range elem {
- if !charOK(r) {
- return fmt.Errorf("invalid char %q", r)
- }
- }
-
- // Windows disallows a bunch of path elements, sadly.
- // See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file
- short := elem
- if i := strings.Index(short, "."); i >= 0 {
- short = short[:i]
- }
- for _, bad := range badWindowsNames {
- if strings.EqualFold(bad, short) {
- return fmt.Errorf("%q disallowed as path element component on Windows", short)
- }
- }
- return nil
-}
-
-// CheckFilePath checks whether a slash-separated file path is valid.
-func CheckFilePath(path string) error {
- if err := checkPath(path, true); err != nil {
- return fmt.Errorf("malformed file path %q: %v", path, err)
- }
- return nil
-}
-
-// badWindowsNames are the reserved file path elements on Windows.
-// See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file
-var badWindowsNames = []string{
- "CON",
- "PRN",
- "AUX",
- "NUL",
- "COM1",
- "COM2",
- "COM3",
- "COM4",
- "COM5",
- "COM6",
- "COM7",
- "COM8",
- "COM9",
- "LPT1",
- "LPT2",
- "LPT3",
- "LPT4",
- "LPT5",
- "LPT6",
- "LPT7",
- "LPT8",
- "LPT9",
-}
-
-// SplitPathVersion returns prefix and major version such that prefix+pathMajor == path
-// and version is either empty or "/vN" for N >= 2.
-// As a special case, gopkg.in paths are recognized directly;
-// they require ".vN" instead of "/vN", and for all N, not just N >= 2.
-func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) {
- if strings.HasPrefix(path, "gopkg.in/") {
- return splitGopkgIn(path)
- }
-
- i := len(path)
- dot := false
- for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9' || path[i-1] == '.') {
- if path[i-1] == '.' {
- dot = true
- }
- i--
- }
- if i <= 1 || i == len(path) || path[i-1] != 'v' || path[i-2] != '/' {
- return path, "", true
- }
- prefix, pathMajor = path[:i-2], path[i-2:]
- if dot || len(pathMajor) <= 2 || pathMajor[2] == '0' || pathMajor == "/v1" {
- return path, "", false
- }
- return prefix, pathMajor, true
-}
-
-// splitGopkgIn is like SplitPathVersion but only for gopkg.in paths.
-func splitGopkgIn(path string) (prefix, pathMajor string, ok bool) {
- if !strings.HasPrefix(path, "gopkg.in/") {
- return path, "", false
- }
- i := len(path)
- if strings.HasSuffix(path, "-unstable") {
- i -= len("-unstable")
- }
- for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9') {
- i--
- }
- if i <= 1 || path[i-1] != 'v' || path[i-2] != '.' {
- // All gopkg.in paths must end in vN for some N.
- return path, "", false
- }
- prefix, pathMajor = path[:i-2], path[i-2:]
- if len(pathMajor) <= 2 || pathMajor[2] == '0' && pathMajor != ".v0" {
- return path, "", false
- }
- return prefix, pathMajor, true
-}
-
-// MatchPathMajor reports whether the semantic version v
-// matches the path major version pathMajor.
-func MatchPathMajor(v, pathMajor string) bool {
- if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") {
- pathMajor = strings.TrimSuffix(pathMajor, "-unstable")
- }
- if strings.HasPrefix(v, "v0.0.0-") && pathMajor == ".v1" {
- // Allow old bug in pseudo-versions that generated v0.0.0- pseudoversion for gopkg .v1.
- // For example, gopkg.in/yaml.v2@v2.2.1's go.mod requires gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405.
- return true
- }
- m := semver.Major(v)
- if pathMajor == "" {
- return m == "v0" || m == "v1" || semver.Build(v) == "+incompatible"
- }
- return (pathMajor[0] == '/' || pathMajor[0] == '.') && m == pathMajor[1:]
-}
-
-// CanonicalVersion returns the canonical form of the version string v.
-// It is the same as semver.Canonical(v) except that it preserves the special build suffix "+incompatible".
-func CanonicalVersion(v string) string {
- cv := semver.Canonical(v)
- if semver.Build(v) == "+incompatible" {
- cv += "+incompatible"
- }
- return cv
-}
-
-// Sort sorts the list by Path, breaking ties by comparing Versions.
-func Sort(list []Version) {
- sort.Slice(list, func(i, j int) bool {
- mi := list[i]
- mj := list[j]
- if mi.Path != mj.Path {
- return mi.Path < mj.Path
- }
- // To help go.sum formatting, allow version/file.
- // Compare semver prefix by semver rules,
- // file by string order.
- vi := mi.Version
- vj := mj.Version
- var fi, fj string
- if k := strings.Index(vi, "/"); k >= 0 {
- vi, fi = vi[:k], vi[k:]
- }
- if k := strings.Index(vj, "/"); k >= 0 {
- vj, fj = vj[:k], vj[k:]
- }
- if vi != vj {
- return semver.Compare(vi, vj) < 0
- }
- return fi < fj
- })
-}
-
-// Safe encodings
-//
-// Module paths appear as substrings of file system paths
-// (in the download cache) and of web server URLs in the proxy protocol.
-// In general we cannot rely on file systems to be case-sensitive,
-// nor can we rely on web servers, since they read from file systems.
-// That is, we cannot rely on the file system to keep rsc.io/QUOTE
-// and rsc.io/quote separate. Windows and macOS don't.
-// Instead, we must never require two different casings of a file path.
-// Because we want the download cache to match the proxy protocol,
-// and because we want the proxy protocol to be possible to serve
-// from a tree of static files (which might be stored on a case-insensitive
-// file system), the proxy protocol must never require two different casings
-// of a URL path either.
-//
-// One possibility would be to make the safe encoding be the lowercase
-// hexadecimal encoding of the actual path bytes. This would avoid ever
-// needing different casings of a file path, but it would be fairly illegible
-// to most programmers when those paths appeared in the file system
-// (including in file paths in compiler errors and stack traces)
-// in web server logs, and so on. Instead, we want a safe encoding that
-// leaves most paths unaltered.
-//
-// The safe encoding is this:
-// replace every uppercase letter with an exclamation mark
-// followed by the letter's lowercase equivalent.
-//
-// For example,
-// github.com/Azure/azure-sdk-for-go -> github.com/!azure/azure-sdk-for-go.
-// github.com/GoogleCloudPlatform/cloudsql-proxy -> github.com/!google!cloud!platform/cloudsql-proxy
-// github.com/Sirupsen/logrus -> github.com/!sirupsen/logrus.
-//
-// Import paths that avoid upper-case letters are left unchanged.
-// Note that because import paths are ASCII-only and avoid various
-// problematic punctuation (like : < and >), the safe encoding is also ASCII-only
-// and avoids the same problematic punctuation.
-//
-// Import paths have never allowed exclamation marks, so there is no
-// need to define how to encode a literal !.
-//
-// Although paths are disallowed from using Unicode (see pathOK above),
-// the eventual plan is to allow Unicode letters as well, to assume that
-// file systems and URLs are Unicode-safe (storing UTF-8), and apply
-// the !-for-uppercase convention. Note however that not all runes that
-// are different but case-fold equivalent are an upper/lower pair.
-// For example, U+004B ('K'), U+006B ('k'), and U+212A ('K' for Kelvin)
-// are considered to case-fold to each other. When we do add Unicode
-// letters, we must not assume that upper/lower are the only case-equivalent pairs.
-// Perhaps the Kelvin symbol would be disallowed entirely, for example.
-// Or perhaps it would encode as "!!k", or perhaps as "(212A)".
-//
-// Also, it would be nice to allow Unicode marks as well as letters,
-// but marks include combining marks, and then we must deal not
-// only with case folding but also normalization: both U+00E9 ('é')
-// and U+0065 U+0301 ('e' followed by combining acute accent)
-// look the same on the page and are treated by some file systems
-// as the same path. If we do allow Unicode marks in paths, there
-// must be some kind of normalization to allow only one canonical
-// encoding of any character used in an import path.
-
-// EncodePath returns the safe encoding of the given module path.
-// It fails if the module path is invalid.
-func EncodePath(path string) (encoding string, err error) {
- if err := CheckPath(path); err != nil {
- return "", err
- }
-
- return encodeString(path)
-}
-
-// EncodeVersion returns the safe encoding of the given module version.
-// Versions are allowed to be in non-semver form but must be valid file names
-// and not contain exclamation marks.
-func EncodeVersion(v string) (encoding string, err error) {
- if err := checkElem(v, true); err != nil || strings.Contains(v, "!") {
- return "", fmt.Errorf("disallowed version string %q", v)
- }
- return encodeString(v)
-}
-
-func encodeString(s string) (encoding string, err error) {
- haveUpper := false
- for _, r := range s {
- if r == '!' || r >= utf8.RuneSelf {
- // This should be disallowed by CheckPath, but diagnose anyway.
- // The correctness of the encoding loop below depends on it.
- return "", fmt.Errorf("internal error: inconsistency in EncodePath")
- }
- if 'A' <= r && r <= 'Z' {
- haveUpper = true
- }
- }
-
- if !haveUpper {
- return s, nil
- }
-
- var buf []byte
- for _, r := range s {
- if 'A' <= r && r <= 'Z' {
- buf = append(buf, '!', byte(r+'a'-'A'))
- } else {
- buf = append(buf, byte(r))
- }
- }
- return string(buf), nil
-}
-
-// DecodePath returns the module path of the given safe encoding.
-// It fails if the encoding is invalid or encodes an invalid path.
-func DecodePath(encoding string) (path string, err error) {
- path, ok := decodeString(encoding)
- if !ok {
- return "", fmt.Errorf("invalid module path encoding %q", encoding)
- }
- if err := CheckPath(path); err != nil {
- return "", fmt.Errorf("invalid module path encoding %q: %v", encoding, err)
- }
- return path, nil
-}
-
-// DecodeVersion returns the version string for the given safe encoding.
-// It fails if the encoding is invalid or encodes an invalid version.
-// Versions are allowed to be in non-semver form but must be valid file names
-// and not contain exclamation marks.
-func DecodeVersion(encoding string) (v string, err error) {
- v, ok := decodeString(encoding)
- if !ok {
- return "", fmt.Errorf("invalid version encoding %q", encoding)
- }
- if err := checkElem(v, true); err != nil {
- return "", fmt.Errorf("disallowed version string %q", v)
- }
- return v, nil
-}
-
-func decodeString(encoding string) (string, bool) {
- var buf []byte
-
- bang := false
- for _, r := range encoding {
- if r >= utf8.RuneSelf {
- return "", false
- }
- if bang {
- bang = false
- if r < 'a' || 'z' < r {
- return "", false
- }
- buf = append(buf, byte(r+'A'-'a'))
- continue
- }
- if r == '!' {
- bang = true
- continue
- }
- if 'A' <= r && r <= 'Z' {
- return "", false
- }
- buf = append(buf, byte(r))
- }
- if bang {
- return "", false
- }
- return string(buf), true
-}
diff --git a/internal/thirdparty/module/module_test.go b/internal/thirdparty/module/module_test.go
deleted file mode 100644
index 13057a9..0000000
--- a/internal/thirdparty/module/module_test.go
+++ /dev/null
@@ -1,323 +0,0 @@
-// DO NOT EDIT. This file was copied from
-// https://go.googlesource.com/go/+/db7e7469/src/cmd/go/internal/module.
-// generated by internal/thirdparty/download.go -pkg=module
-
-// Copyright 2018 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 module
-
-import "testing"
-
-var checkTests = []struct {
- path string
- version string
- ok bool
-}{
- {"rsc.io/quote", "0.1.0", false},
- {"rsc io/quote", "v1.0.0", false},
-
- {"github.com/go-yaml/yaml", "v0.8.0", true},
- {"github.com/go-yaml/yaml", "v1.0.0", true},
- {"github.com/go-yaml/yaml", "v2.0.0", false},
- {"github.com/go-yaml/yaml", "v2.1.5", false},
- {"github.com/go-yaml/yaml", "v3.0.0", false},
-
- {"github.com/go-yaml/yaml/v2", "v1.0.0", false},
- {"github.com/go-yaml/yaml/v2", "v2.0.0", true},
- {"github.com/go-yaml/yaml/v2", "v2.1.5", true},
- {"github.com/go-yaml/yaml/v2", "v3.0.0", false},
-
- {"gopkg.in/yaml.v0", "v0.8.0", true},
- {"gopkg.in/yaml.v0", "v1.0.0", false},
- {"gopkg.in/yaml.v0", "v2.0.0", false},
- {"gopkg.in/yaml.v0", "v2.1.5", false},
- {"gopkg.in/yaml.v0", "v3.0.0", false},
-
- {"gopkg.in/yaml.v1", "v0.8.0", false},
- {"gopkg.in/yaml.v1", "v1.0.0", true},
- {"gopkg.in/yaml.v1", "v2.0.0", false},
- {"gopkg.in/yaml.v1", "v2.1.5", false},
- {"gopkg.in/yaml.v1", "v3.0.0", false},
-
- // For gopkg.in, .v1 means v1 only (not v0).
- // But early versions of vgo still generated v0 pseudo-versions for it.
- // Even though now we'd generate those as v1 pseudo-versions,
- // we accept the old pseudo-versions to avoid breaking existing go.mod files.
- // For example gopkg.in/yaml.v2@v2.2.1's go.mod requires check.v1 at a v0 pseudo-version.
- {"gopkg.in/check.v1", "v0.0.0", false},
- {"gopkg.in/check.v1", "v0.0.0-20160102150405-abcdef123456", true},
-
- {"gopkg.in/yaml.v2", "v1.0.0", false},
- {"gopkg.in/yaml.v2", "v2.0.0", true},
- {"gopkg.in/yaml.v2", "v2.1.5", true},
- {"gopkg.in/yaml.v2", "v3.0.0", false},
-
- {"rsc.io/quote", "v17.0.0", false},
- {"rsc.io/quote", "v17.0.0+incompatible", true},
-}
-
-func TestCheck(t *testing.T) {
- for _, tt := range checkTests {
- err := Check(tt.path, tt.version)
- if tt.ok && err != nil {
- t.Errorf("Check(%q, %q) = %v, wanted nil error", tt.path, tt.version, err)
- } else if !tt.ok && err == nil {
- t.Errorf("Check(%q, %q) succeeded, wanted error", tt.path, tt.version)
- }
- }
-}
-
-var checkPathTests = []struct {
- path string
- ok bool
- importOK bool
- fileOK bool
-}{
- {"x.y/z", true, true, true},
- {"x.y", true, true, true},
-
- {"", false, false, false},
- {"x.y/\xFFz", false, false, false},
- {"/x.y/z", false, false, false},
- {"x./z", false, false, false},
- {".x/z", false, false, true},
- {"-x/z", false, true, true},
- {"x..y/z", false, false, false},
- {"x.y/z/../../w", false, false, false},
- {"x.y//z", false, false, false},
- {"x.y/z//w", false, false, false},
- {"x.y/z/", false, false, false},
-
- {"x.y/z/v0", false, true, true},
- {"x.y/z/v1", false, true, true},
- {"x.y/z/v2", true, true, true},
- {"x.y/z/v2.0", false, true, true},
- {"X.y/z", false, true, true},
-
- {"!x.y/z", false, false, true},
- {"_x.y/z", false, true, true},
- {"x.y!/z", false, false, true},
- {"x.y\"/z", false, false, false},
- {"x.y#/z", false, false, true},
- {"x.y$/z", false, false, true},
- {"x.y%/z", false, false, true},
- {"x.y&/z", false, false, true},
- {"x.y'/z", false, false, false},
- {"x.y(/z", false, false, true},
- {"x.y)/z", false, false, true},
- {"x.y*/z", false, false, false},
- {"x.y+/z", false, true, true},
- {"x.y,/z", false, false, true},
- {"x.y-/z", true, true, true},
- {"x.y./zt", false, false, false},
- {"x.y:/z", false, false, false},
- {"x.y;/z", false, false, false},
- {"x.y</z", false, false, false},
- {"x.y=/z", false, false, true},
- {"x.y>/z", false, false, false},
- {"x.y?/z", false, false, false},
- {"x.y@/z", false, false, true},
- {"x.y[/z", false, false, true},
- {"x.y\\/z", false, false, false},
- {"x.y]/z", false, false, true},
- {"x.y^/z", false, false, true},
- {"x.y_/z", false, true, true},
- {"x.y`/z", false, false, false},
- {"x.y{/z", false, false, true},
- {"x.y}/z", false, false, true},
- {"x.y~/z", false, true, true},
- {"x.y/z!", false, false, true},
- {"x.y/z\"", false, false, false},
- {"x.y/z#", false, false, true},
- {"x.y/z$", false, false, true},
- {"x.y/z%", false, false, true},
- {"x.y/z&", false, false, true},
- {"x.y/z'", false, false, false},
- {"x.y/z(", false, false, true},
- {"x.y/z)", false, false, true},
- {"x.y/z*", false, false, false},
- {"x.y/z+", true, true, true},
- {"x.y/z,", false, false, true},
- {"x.y/z-", true, true, true},
- {"x.y/z.t", true, true, true},
- {"x.y/z/t", true, true, true},
- {"x.y/z:", false, false, false},
- {"x.y/z;", false, false, false},
- {"x.y/z<", false, false, false},
- {"x.y/z=", false, false, true},
- {"x.y/z>", false, false, false},
- {"x.y/z?", false, false, false},
- {"x.y/z@", false, false, true},
- {"x.y/z[", false, false, true},
- {"x.y/z\\", false, false, false},
- {"x.y/z]", false, false, true},
- {"x.y/z^", false, false, true},
- {"x.y/z_", true, true, true},
- {"x.y/z`", false, false, false},
- {"x.y/z{", false, false, true},
- {"x.y/z}", false, false, true},
- {"x.y/z~", true, true, true},
- {"x.y/x.foo", true, true, true},
- {"x.y/aux.foo", false, false, false},
- {"x.y/prn", false, false, false},
- {"x.y/prn2", true, true, true},
- {"x.y/com", true, true, true},
- {"x.y/com1", false, false, false},
- {"x.y/com1.txt", false, false, false},
- {"x.y/calm1", true, true, true},
- {"github.com/!123/logrus", false, false, true},
-
- // TODO: CL 41822 allowed Unicode letters in old "go get"
- // without due consideration of the implications, and only on github.com (!).
- // For now, we disallow non-ASCII characters in module mode,
- // in both module paths and general import paths,
- // until we can get the implications right.
- // When we do, we'll enable them everywhere, not just for GitHub.
- {"github.com/user/unicode/испытание", false, false, true},
-
- {"../x", false, false, false},
- {"./y", false, false, false},
- {"x:y", false, false, false},
- {`\temp\foo`, false, false, false},
- {".gitignore", false, false, true},
- {".github/ISSUE_TEMPLATE", false, false, true},
- {"x☺y", false, false, false},
-}
-
-func TestCheckPath(t *testing.T) {
- for _, tt := range checkPathTests {
- err := CheckPath(tt.path)
- if tt.ok && err != nil {
- t.Errorf("CheckPath(%q) = %v, wanted nil error", tt.path, err)
- } else if !tt.ok && err == nil {
- t.Errorf("CheckPath(%q) succeeded, wanted error", tt.path)
- }
-
- err = CheckImportPath(tt.path)
- if tt.importOK && err != nil {
- t.Errorf("CheckImportPath(%q) = %v, wanted nil error", tt.path, err)
- } else if !tt.importOK && err == nil {
- t.Errorf("CheckImportPath(%q) succeeded, wanted error", tt.path)
- }
-
- err = CheckFilePath(tt.path)
- if tt.fileOK && err != nil {
- t.Errorf("CheckFilePath(%q) = %v, wanted nil error", tt.path, err)
- } else if !tt.fileOK && err == nil {
- t.Errorf("CheckFilePath(%q) succeeded, wanted error", tt.path)
- }
- }
-}
-
-var splitPathVersionTests = []struct {
- pathPrefix string
- version string
-}{
- {"x.y/z", ""},
- {"x.y/z", "/v2"},
- {"x.y/z", "/v3"},
- {"x.y/v", ""},
- {"gopkg.in/yaml", ".v0"},
- {"gopkg.in/yaml", ".v1"},
- {"gopkg.in/yaml", ".v2"},
- {"gopkg.in/yaml", ".v3"},
-}
-
-func TestSplitPathVersion(t *testing.T) {
- for _, tt := range splitPathVersionTests {
- pathPrefix, version, ok := SplitPathVersion(tt.pathPrefix + tt.version)
- if pathPrefix != tt.pathPrefix || version != tt.version || !ok {
- t.Errorf("SplitPathVersion(%q) = %q, %q, %v, want %q, %q, true", tt.pathPrefix+tt.version, pathPrefix, version, ok, tt.pathPrefix, tt.version)
- }
- }
-
- for _, tt := range checkPathTests {
- pathPrefix, version, ok := SplitPathVersion(tt.path)
- if pathPrefix+version != tt.path {
- t.Errorf("SplitPathVersion(%q) = %q, %q, %v, doesn't add to input", tt.path, pathPrefix, version, ok)
- }
- }
-}
-
-var encodeTests = []struct {
- path string
- enc string // empty means same as path
-}{
- {path: "ascii.com/abcdefghijklmnopqrstuvwxyz.-+/~_0123456789"},
- {path: "github.com/GoogleCloudPlatform/omega", enc: "github.com/!google!cloud!platform/omega"},
-}
-
-func TestEncodePath(t *testing.T) {
- // Check invalid paths.
- for _, tt := range checkPathTests {
- if !tt.ok {
- _, err := EncodePath(tt.path)
- if err == nil {
- t.Errorf("EncodePath(%q): succeeded, want error (invalid path)", tt.path)
- }
- }
- }
-
- // Check encodings.
- for _, tt := range encodeTests {
- enc, err := EncodePath(tt.path)
- if err != nil {
- t.Errorf("EncodePath(%q): unexpected error: %v", tt.path, err)
- continue
- }
- want := tt.enc
- if want == "" {
- want = tt.path
- }
- if enc != want {
- t.Errorf("EncodePath(%q) = %q, want %q", tt.path, enc, want)
- }
- }
-}
-
-var badDecode = []string{
- "github.com/GoogleCloudPlatform/omega",
- "github.com/!google!cloud!platform!/omega",
- "github.com/!0google!cloud!platform/omega",
- "github.com/!_google!cloud!platform/omega",
- "github.com/!!google!cloud!platform/omega",
- "",
-}
-
-func TestDecodePath(t *testing.T) {
- // Check invalid decodings.
- for _, bad := range badDecode {
- _, err := DecodePath(bad)
- if err == nil {
- t.Errorf("DecodePath(%q): succeeded, want error (invalid decoding)", bad)
- }
- }
-
- // Check invalid paths (or maybe decodings).
- for _, tt := range checkPathTests {
- if !tt.ok {
- path, err := DecodePath(tt.path)
- if err == nil {
- t.Errorf("DecodePath(%q) = %q, want error (invalid path)", tt.path, path)
- }
- }
- }
-
- // Check encodings.
- for _, tt := range encodeTests {
- enc := tt.enc
- if enc == "" {
- enc = tt.path
- }
- path, err := DecodePath(enc)
- if err != nil {
- t.Errorf("DecodePath(%q): unexpected error: %v", enc, err)
- continue
- }
- if path != tt.path {
- t.Errorf("DecodePath(%q) = %q, want %q", enc, path, tt.path)
- }
- }
-}
diff --git a/internal/thirdparty/semver/semver.go b/internal/thirdparty/semver/semver.go
deleted file mode 100644
index 456653f..0000000
--- a/internal/thirdparty/semver/semver.go
+++ /dev/null
@@ -1,392 +0,0 @@
-// DO NOT EDIT. This file was copied from
-// https://go.googlesource.com/go/+/6249ea2f/src/cmd/go/internal/semver.
-// generated by internal/thirdparty/download.go -pkg=semver
-
-// Copyright 2018 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 semver implements comparison of semantic version strings.
-// In this package, semantic version strings must begin with a leading "v",
-// as in "v1.0.0".
-//
-// The general form of a semantic version string accepted by this package is
-//
-// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]
-//
-// where square brackets indicate optional parts of the syntax;
-// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros;
-// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers
-// using only alphanumeric characters and hyphens; and
-// all-numeric PRERELEASE identifiers must not have leading zeros.
-//
-// This package follows Semantic Versioning 2.0.0 (see semver.org)
-// with two exceptions. First, it requires the "v" prefix. Second, it recognizes
-// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes)
-// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
-package semver
-
-// parsed returns the parsed form of a semantic version string.
-type parsed struct {
- major string
- minor string
- patch string
- short string
- prerelease string
- build string
- err string
-}
-
-// IsValid reports whether v is a valid semantic version string.
-func IsValid(v string) bool {
- _, ok := parse(v)
- return ok
-}
-
-// Canonical returns the canonical formatting of the semantic version v.
-// It fills in any missing .MINOR or .PATCH and discards build metadata.
-// Two semantic versions compare equal only if their canonical formattings
-// are identical strings.
-// The canonical invalid semantic version is the empty string.
-func Canonical(v string) string {
- p, ok := parse(v)
- if !ok {
- return ""
- }
- if p.build != "" {
- return v[:len(v)-len(p.build)]
- }
- if p.short != "" {
- return v + p.short
- }
- return v
-}
-
-// Major returns the major version prefix of the semantic version v.
-// For example, Major("v2.1.0") == "v2".
-// If v is an invalid semantic version string, Major returns the empty string.
-func Major(v string) string {
- pv, ok := parse(v)
- if !ok {
- return ""
- }
- return v[:1+len(pv.major)]
-}
-
-// MajorMinor returns the major.minor version prefix of the semantic version v.
-// For example, MajorMinor("v2.1.0") == "v2.1".
-// If v is an invalid semantic version string, MajorMinor returns the empty string.
-func MajorMinor(v string) string {
- pv, ok := parse(v)
- if !ok {
- return ""
- }
- i := 1 + len(pv.major)
- if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor {
- return v[:j]
- }
- return v[:i] + "." + pv.minor
-}
-
-// Prerelease returns the prerelease suffix of the semantic version v.
-// For example, Prerelease("v2.1.0-pre+meta") == "-pre".
-// If v is an invalid semantic version string, Prerelease returns the empty string.
-func Prerelease(v string) string {
- pv, ok := parse(v)
- if !ok {
- return ""
- }
- return pv.prerelease
-}
-
-// Build returns the build suffix of the semantic version v.
-// For example, Build("v2.1.0+meta") == "+meta".
-// If v is an invalid semantic version string, Build returns the empty string.
-func Build(v string) string {
- pv, ok := parse(v)
- if !ok {
- return ""
- }
- return pv.build
-}
-
-// Compare returns an integer comparing two versions according to
-// according to semantic version precedence.
-// The result will be 0 if v == w, -1 if v < w, or +1 if v > w.
-//
-// An invalid semantic version string is considered less than a valid one.
-// All invalid semantic version strings compare equal to each other.
-func Compare(v, w string) int {
- pv, ok1 := parse(v)
- pw, ok2 := parse(w)
- if !ok1 && !ok2 {
- return 0
- }
- if !ok1 {
- return -1
- }
- if !ok2 {
- return +1
- }
- if c := compareInt(pv.major, pw.major); c != 0 {
- return c
- }
- if c := compareInt(pv.minor, pw.minor); c != 0 {
- return c
- }
- if c := compareInt(pv.patch, pw.patch); c != 0 {
- return c
- }
- return comparePrerelease(pv.prerelease, pw.prerelease)
-}
-
-// Max canonicalizes its arguments and then returns the version string
-// that compares greater.
-func Max(v, w string) string {
- v = Canonical(v)
- w = Canonical(w)
- if Compare(v, w) > 0 {
- return v
- }
- return w
-}
-
-func parse(v string) (p parsed, ok bool) {
- if v == "" || v[0] != 'v' {
- p.err = "missing v prefix"
- return
- }
- p.major, v, ok = parseInt(v[1:])
- if !ok {
- p.err = "bad major version"
- return
- }
- if v == "" {
- p.minor = "0"
- p.patch = "0"
- p.short = ".0.0"
- return
- }
- if v[0] != '.' {
- p.err = "bad minor prefix"
- ok = false
- return
- }
- p.minor, v, ok = parseInt(v[1:])
- if !ok {
- p.err = "bad minor version"
- return
- }
- if v == "" {
- p.patch = "0"
- p.short = ".0"
- return
- }
- if v[0] != '.' {
- p.err = "bad patch prefix"
- ok = false
- return
- }
- p.patch, v, ok = parseInt(v[1:])
- if !ok {
- p.err = "bad patch version"
- return
- }
- if len(v) > 0 && v[0] == '-' {
- p.prerelease, v, ok = parsePrerelease(v)
- if !ok {
- p.err = "bad prerelease"
- return
- }
- }
- if len(v) > 0 && v[0] == '+' {
- p.build, v, ok = parseBuild(v)
- if !ok {
- p.err = "bad build"
- return
- }
- }
- if v != "" {
- p.err = "junk on end"
- ok = false
- return
- }
- ok = true
- return
-}
-
-func parseInt(v string) (t, rest string, ok bool) {
- if v == "" {
- return
- }
- if v[0] < '0' || '9' < v[0] {
- return
- }
- i := 1
- for i < len(v) && '0' <= v[i] && v[i] <= '9' {
- i++
- }
- if v[0] == '0' && i != 1 {
- return
- }
- return v[:i], v[i:], true
-}
-
-func parsePrerelease(v string) (t, rest string, ok bool) {
- // "A pre-release version MAY be denoted by appending a hyphen and
- // a series of dot separated identifiers immediately following the patch version.
- // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
- // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes."
- if v == "" || v[0] != '-' {
- return
- }
- i := 1
- start := 1
- for i < len(v) && v[i] != '+' {
- if !isIdentChar(v[i]) && v[i] != '.' {
- return
- }
- if v[i] == '.' {
- if start == i || isBadNum(v[start:i]) {
- return
- }
- start = i + 1
- }
- i++
- }
- if start == i || isBadNum(v[start:i]) {
- return
- }
- return v[:i], v[i:], true
-}
-
-func parseBuild(v string) (t, rest string, ok bool) {
- if v == "" || v[0] != '+' {
- return
- }
- i := 1
- start := 1
- for i < len(v) {
- if !isIdentChar(v[i]) && v[i] != '.' {
- return
- }
- if v[i] == '.' {
- if start == i {
- return
- }
- start = i + 1
- }
- i++
- }
- if start == i {
- return
- }
- return v[:i], v[i:], true
-}
-
-func isIdentChar(c byte) bool {
- return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-'
-}
-
-func isBadNum(v string) bool {
- i := 0
- for i < len(v) && '0' <= v[i] && v[i] <= '9' {
- i++
- }
- return i == len(v) && i > 1 && v[0] == '0'
-}
-
-func isNum(v string) bool {
- i := 0
- for i < len(v) && '0' <= v[i] && v[i] <= '9' {
- i++
- }
- return i == len(v)
-}
-
-func compareInt(x, y string) int {
- if x == y {
- return 0
- }
- if len(x) < len(y) {
- return -1
- }
- if len(x) > len(y) {
- return +1
- }
- if x < y {
- return -1
- } else {
- return +1
- }
-}
-
-func comparePrerelease(x, y string) int {
- // "When major, minor, and patch are equal, a pre-release version has
- // lower precedence than a normal version.
- // Example: 1.0.0-alpha < 1.0.0.
- // Precedence for two pre-release versions with the same major, minor,
- // and patch version MUST be determined by comparing each dot separated
- // identifier from left to right until a difference is found as follows:
- // identifiers consisting of only digits are compared numerically and
- // identifiers with letters or hyphens are compared lexically in ASCII
- // sort order. Numeric identifiers always have lower precedence than
- // non-numeric identifiers. A larger set of pre-release fields has a
- // higher precedence than a smaller set, if all of the preceding
- // identifiers are equal.
- // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta <
- // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0."
- if x == y {
- return 0
- }
- if x == "" {
- return +1
- }
- if y == "" {
- return -1
- }
- for x != "" && y != "" {
- x = x[1:] // skip - or .
- y = y[1:] // skip - or .
- var dx, dy string
- dx, x = nextIdent(x)
- dy, y = nextIdent(y)
- if dx != dy {
- ix := isNum(dx)
- iy := isNum(dy)
- if ix != iy {
- if ix {
- return -1
- } else {
- return +1
- }
- }
- if ix {
- if len(dx) < len(dy) {
- return -1
- }
- if len(dx) > len(dy) {
- return +1
- }
- }
- if dx < dy {
- return -1
- } else {
- return +1
- }
- }
- }
- if x == "" {
- return -1
- } else {
- return +1
- }
-}
-
-func nextIdent(x string) (dx, rest string) {
- i := 0
- for i < len(x) && x[i] != '.' {
- i++
- }
- return x[:i], x[i:]
-}
diff --git a/internal/thirdparty/semver/semver_test.go b/internal/thirdparty/semver/semver_test.go
deleted file mode 100644
index 2ef22ab..0000000
--- a/internal/thirdparty/semver/semver_test.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// DO NOT EDIT. This file was copied from
-// https://go.googlesource.com/go/+/6249ea2f/src/cmd/go/internal/semver.
-// generated by internal/thirdparty/download.go -pkg=semver
-
-// Copyright 2018 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 semver
-
-import (
- "strings"
- "testing"
-)
-
-var tests = []struct {
- in string
- out string
-}{
- {"bad", ""},
- {"v1-alpha.beta.gamma", ""},
- {"v1-pre", ""},
- {"v1+meta", ""},
- {"v1-pre+meta", ""},
- {"v1.2-pre", ""},
- {"v1.2+meta", ""},
- {"v1.2-pre+meta", ""},
- {"v1.0.0-alpha", "v1.0.0-alpha"},
- {"v1.0.0-alpha.1", "v1.0.0-alpha.1"},
- {"v1.0.0-alpha.beta", "v1.0.0-alpha.beta"},
- {"v1.0.0-beta", "v1.0.0-beta"},
- {"v1.0.0-beta.2", "v1.0.0-beta.2"},
- {"v1.0.0-beta.11", "v1.0.0-beta.11"},
- {"v1.0.0-rc.1", "v1.0.0-rc.1"},
- {"v1", "v1.0.0"},
- {"v1.0", "v1.0.0"},
- {"v1.0.0", "v1.0.0"},
- {"v1.2", "v1.2.0"},
- {"v1.2.0", "v1.2.0"},
- {"v1.2.3-456", "v1.2.3-456"},
- {"v1.2.3-456.789", "v1.2.3-456.789"},
- {"v1.2.3-456-789", "v1.2.3-456-789"},
- {"v1.2.3-456a", "v1.2.3-456a"},
- {"v1.2.3-pre", "v1.2.3-pre"},
- {"v1.2.3-pre+meta", "v1.2.3-pre"},
- {"v1.2.3-pre.1", "v1.2.3-pre.1"},
- {"v1.2.3-zzz", "v1.2.3-zzz"},
- {"v1.2.3", "v1.2.3"},
- {"v1.2.3+meta", "v1.2.3"},
- {"v1.2.3+meta-pre", "v1.2.3"},
- {"v1.2.3+meta-pre.sha.256a", "v1.2.3"},
-}
-
-func TestIsValid(t *testing.T) {
- for _, tt := range tests {
- ok := IsValid(tt.in)
- if ok != (tt.out != "") {
- t.Errorf("IsValid(%q) = %v, want %v", tt.in, ok, !ok)
- }
- }
-}
-
-func TestCanonical(t *testing.T) {
- for _, tt := range tests {
- out := Canonical(tt.in)
- if out != tt.out {
- t.Errorf("Canonical(%q) = %q, want %q", tt.in, out, tt.out)
- }
- }
-}
-
-func TestMajor(t *testing.T) {
- for _, tt := range tests {
- out := Major(tt.in)
- want := ""
- if i := strings.Index(tt.out, "."); i >= 0 {
- want = tt.out[:i]
- }
- if out != want {
- t.Errorf("Major(%q) = %q, want %q", tt.in, out, want)
- }
- }
-}
-
-func TestMajorMinor(t *testing.T) {
- for _, tt := range tests {
- out := MajorMinor(tt.in)
- var want string
- if tt.out != "" {
- want = tt.in
- if i := strings.Index(want, "+"); i >= 0 {
- want = want[:i]
- }
- if i := strings.Index(want, "-"); i >= 0 {
- want = want[:i]
- }
- switch strings.Count(want, ".") {
- case 0:
- want += ".0"
- case 1:
- // ok
- case 2:
- want = want[:strings.LastIndex(want, ".")]
- }
- }
- if out != want {
- t.Errorf("MajorMinor(%q) = %q, want %q", tt.in, out, want)
- }
- }
-}
-
-func TestPrerelease(t *testing.T) {
- for _, tt := range tests {
- pre := Prerelease(tt.in)
- var want string
- if tt.out != "" {
- if i := strings.Index(tt.out, "-"); i >= 0 {
- want = tt.out[i:]
- }
- }
- if pre != want {
- t.Errorf("Prerelease(%q) = %q, want %q", tt.in, pre, want)
- }
- }
-}
-
-func TestBuild(t *testing.T) {
- for _, tt := range tests {
- build := Build(tt.in)
- var want string
- if tt.out != "" {
- if i := strings.Index(tt.in, "+"); i >= 0 {
- want = tt.in[i:]
- }
- }
- if build != want {
- t.Errorf("Build(%q) = %q, want %q", tt.in, build, want)
- }
- }
-}
-
-func TestCompare(t *testing.T) {
- for i, ti := range tests {
- for j, tj := range tests {
- cmp := Compare(ti.in, tj.in)
- var want int
- if ti.out == tj.out {
- want = 0
- } else if i < j {
- want = -1
- } else {
- want = +1
- }
- if cmp != want {
- t.Errorf("Compare(%q, %q) = %d, want %d", ti.in, tj.in, cmp, want)
- }
- }
- }
-}
-
-func TestMax(t *testing.T) {
- for i, ti := range tests {
- for j, tj := range tests {
- max := Max(ti.in, tj.in)
- want := Canonical(ti.in)
- if i < j {
- want = Canonical(tj.in)
- }
- if max != want {
- t.Errorf("Max(%q, %q) = %q, want %q", ti.in, tj.in, max, want)
- }
- }
- }
-}
-
-var (
- v1 = "v1.0.0+metadata-dash"
- v2 = "v1.0.0+metadata-dash1"
-)
-
-func BenchmarkCompare(b *testing.B) {
- for i := 0; i < b.N; i++ {
- if Compare(v1, v2) != 0 {
- b.Fatalf("bad compare")
- }
- }
-}
diff --git a/internal/version/version.go b/internal/version/version.go
index 4cd4770..201b291 100644
--- a/internal/version/version.go
+++ b/internal/version/version.go
@@ -10,7 +10,7 @@
"regexp"
"strings"
- "golang.org/x/discovery/internal/thirdparty/semver"
+ "golang.org/x/mod/semver"
)
// Type defines the version types a module can have.
diff --git a/internal/version/version_test.go b/internal/version/version_test.go
index 92ceab6..ac7546c 100644
--- a/internal/version/version_test.go
+++ b/internal/version/version_test.go
@@ -7,7 +7,7 @@
import (
"testing"
- "golang.org/x/discovery/internal/thirdparty/semver"
+ "golang.org/x/mod/semver"
)
func TestForSorting(t *testing.T) {