]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: move psuedo-version and version sorting to x/mod
authorJay Conrod <jayconrod@google.com>
Tue, 23 Mar 2021 21:03:46 +0000 (17:03 -0400)
committerJay Conrod <jayconrod@google.com>
Wed, 24 Mar 2021 13:54:14 +0000 (13:54 +0000)
Fixes #44969

Change-Id: I01e7b1cf73f0f506aa805bbfe4a9ccaed3d44efe
Reviewed-on: https://go-review.googlesource.com/c/go/+/304229
Trust: Jay Conrod <jayconrod@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
13 files changed:
src/cmd/go.mod
src/cmd/go.sum
src/cmd/go/internal/modfetch/cache.go
src/cmd/go/internal/modfetch/coderepo.go
src/cmd/go/internal/modfetch/proxy.go
src/cmd/go/internal/modfetch/pseudo_test.go [deleted file]
src/cmd/go/internal/modfetch/repo.go
src/cmd/go/internal/modload/import.go
src/cmd/go/internal/modload/query.go
src/cmd/go/proxy_test.go
src/cmd/vendor/golang.org/x/mod/module/pseudo.go [moved from src/cmd/go/internal/modfetch/pseudo.go with 95% similarity]
src/cmd/vendor/golang.org/x/mod/semver/semver.go
src/cmd/vendor/modules.txt

index d78fabe1962cbb3c68512352a4bc18661fb5cd96..9b080404330f1f06025951b79e40361bcdc020fa 100644 (file)
@@ -6,7 +6,7 @@ require (
        github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5
        golang.org/x/arch v0.0.0-20210308155006-05f8f0431f72
        golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
-       golang.org/x/mod v0.4.3-0.20210310185834-19d50cac98aa
+       golang.org/x/mod v0.4.3-0.20210323215154-1cc8812c1740
        golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 // indirect
        golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
        golang.org/x/tools v0.1.1-0.20210312185553-8e4f4c86593a
index 706230f4cf05b3dc18096ce66f494bb3763bcae2..391e99ca99ff6a047497da2f5f8762ccc719149f 100644 (file)
@@ -14,8 +14,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.3-0.20210310185834-19d50cac98aa h1:++oSKjoJSsXNHyhUdK1BtBKMAaMHER+GWyKN3319OZA=
-golang.org/x/mod v0.4.3-0.20210310185834-19d50cac98aa/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.3-0.20210323215154-1cc8812c1740 h1:UYbWz0ISU1ccVf+FK/BRuwA4LGw2SzoambF9r5ozR/E=
+golang.org/x/mod v0.4.3-0.20210323215154-1cc8812c1740/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
index 776def7cbca859d2c2c88ace030e2a2e74bc8c26..c1303502e5526c4ed354a2e7e384ff2924577834 100644 (file)
@@ -497,7 +497,7 @@ func readDiskStatByHash(path, rev string) (file string, info *RevInfo, err error
        for _, name := range names {
                if strings.HasSuffix(name, suffix) {
                        v := strings.TrimSuffix(name, ".info")
-                       if IsPseudoVersion(v) && semver.Compare(v, maxVersion) > 0 {
+                       if module.IsPseudoVersion(v) && semver.Compare(v, maxVersion) > 0 {
                                maxVersion = v
                                file, info, err = readDiskStat(path, strings.TrimSuffix(name, ".info"))
                        }
@@ -674,7 +674,7 @@ func rewriteVersionList(dir string) (err error) {
                        }
                }
        }
-       SortVersions(list)
+       semver.Sort(list)
 
        var buf bytes.Buffer
        for _, v := range list {
index 2dcbb99b18514ae3abd52e78a3406810fae83f3a..f817a045834e36fd19b769e9ce6c0c25e18e4d98 100644 (file)
@@ -159,7 +159,7 @@ func (r *codeRepo) Versions(prefix string) ([]string, error) {
                if r.codeDir != "" {
                        v = v[len(r.codeDir)+1:]
                }
-               if v == "" || v != module.CanonicalVersion(v) || IsPseudoVersion(v) {
+               if v == "" || v != module.CanonicalVersion(v) || module.IsPseudoVersion(v) {
                        continue
                }
 
@@ -172,8 +172,8 @@ func (r *codeRepo) Versions(prefix string) ([]string, error) {
 
                list = append(list, v)
        }
-       SortVersions(list)
-       SortVersions(incompatible)
+       semver.Sort(list)
+       semver.Sort(incompatible)
 
        return r.appendIncompatibleVersions(list, incompatible)
 }
@@ -385,7 +385,7 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
        if statVers != "" && statVers == module.CanonicalVersion(statVers) {
                info2.Version = statVers
 
-               if IsPseudoVersion(info2.Version) {
+               if module.IsPseudoVersion(info2.Version) {
                        if err := r.validatePseudoVersion(info, info2.Version); err != nil {
                                return nil, err
                        }
@@ -433,7 +433,7 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
                }
                trimmed := tag[len(tagPrefix):]
                // Tags that look like pseudo-versions would be confusing. Ignore them.
-               if IsPseudoVersion(tag) {
+               if module.IsPseudoVersion(tag) {
                        return "", false
                }
 
@@ -531,7 +531,7 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
                pseudoBase, _ = tagToVersion(tag) // empty if the tag is invalid
        }
 
-       info2.Version = PseudoVersion(r.pseudoMajor, pseudoBase, info.Time, info.Short)
+       info2.Version = module.PseudoVersion(r.pseudoMajor, pseudoBase, info.Time, info.Short)
        return checkGoMod()
 }
 
@@ -560,7 +560,7 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string)
                return err
        }
 
-       rev, err := PseudoVersionRev(version)
+       rev, err := module.PseudoVersionRev(version)
        if err != nil {
                return err
        }
@@ -575,12 +575,12 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string)
                }
        }
 
-       t, err := PseudoVersionTime(version)
+       t, err := module.PseudoVersionTime(version)
        if err != nil {
                return err
        }
        if !t.Equal(info.Time.Truncate(time.Second)) {
-               return fmt.Errorf("does not match version-control timestamp (expected %s)", info.Time.UTC().Format(pseudoVersionTimestampFormat))
+               return fmt.Errorf("does not match version-control timestamp (expected %s)", info.Time.UTC().Format(module.PseudoVersionTimestampFormat))
        }
 
        tagPrefix := ""
@@ -604,7 +604,7 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string)
        // not enforce that property when resolving existing pseudo-versions: we don't
        // know when the parent tags were added, and the highest-tagged parent may not
        // have existed when the pseudo-version was first resolved.
-       base, err := PseudoVersionBase(strings.TrimSuffix(version, "+incompatible"))
+       base, err := module.PseudoVersionBase(strings.TrimSuffix(version, "+incompatible"))
        if err != nil {
                return err
        }
@@ -661,7 +661,7 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string)
                if err != nil {
                        return err
                }
-               rev, err := PseudoVersionRev(version)
+               rev, err := module.PseudoVersionRev(version)
                if err != nil {
                        return fmt.Errorf("not a descendent of preceding tag (%s)", lastTag)
                }
@@ -672,8 +672,8 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string)
 
 func (r *codeRepo) revToRev(rev string) string {
        if semver.IsValid(rev) {
-               if IsPseudoVersion(rev) {
-                       r, _ := PseudoVersionRev(rev)
+               if module.IsPseudoVersion(rev) {
+                       r, _ := module.PseudoVersionRev(rev)
                        return r
                }
                if semver.Build(rev) == "+incompatible" {
@@ -843,7 +843,7 @@ func (r *codeRepo) GoMod(version string) (data []byte, err error) {
                return nil, fmt.Errorf("version %s is not canonical", version)
        }
 
-       if IsPseudoVersion(version) {
+       if module.IsPseudoVersion(version) {
                // findDir ignores the metadata encoded in a pseudo-version,
                // only using the revision at the end.
                // Invoke Stat to verify the metadata explicitly so we don't return
@@ -942,7 +942,7 @@ func (r *codeRepo) Zip(dst io.Writer, version string) error {
                return fmt.Errorf("version %s is not canonical", version)
        }
 
-       if IsPseudoVersion(version) {
+       if module.IsPseudoVersion(version) {
                // findDir ignores the metadata encoded in a pseudo-version,
                // only using the revision at the end.
                // Invoke Stat to verify the metadata explicitly so we don't return
index 6c86d8d786d94a161f509a66fffcfbc9bb00189c..31d453c8074e6a52b4b9fe7009ef9ef79aba70e3 100644 (file)
@@ -228,7 +228,7 @@ func (p *proxyRepo) versionError(version string, err error) error {
                        Path: p.path,
                        Err: &module.InvalidVersionError{
                                Version: version,
-                               Pseudo:  IsPseudoVersion(version),
+                               Pseudo:  module.IsPseudoVersion(version),
                                Err:     err,
                        },
                }
@@ -276,11 +276,11 @@ func (p *proxyRepo) Versions(prefix string) ([]string, error) {
        var list []string
        for _, line := range strings.Split(string(data), "\n") {
                f := strings.Fields(line)
-               if len(f) >= 1 && semver.IsValid(f[0]) && strings.HasPrefix(f[0], prefix) && !IsPseudoVersion(f[0]) {
+               if len(f) >= 1 && semver.IsValid(f[0]) && strings.HasPrefix(f[0], prefix) && !module.IsPseudoVersion(f[0]) {
                        list = append(list, f[0])
                }
        }
-       SortVersions(list)
+       semver.Sort(list)
        return list, nil
 }
 
@@ -307,8 +307,8 @@ func (p *proxyRepo) latest() (*RevInfo, error) {
                        )
                        if len(f) >= 2 {
                                ft, _ = time.Parse(time.RFC3339, f[1])
-                       } else if IsPseudoVersion(f[0]) {
-                               ft, _ = PseudoVersionTime(f[0])
+                       } else if module.IsPseudoVersion(f[0]) {
+                               ft, _ = module.PseudoVersionTime(f[0])
                                ftIsFromPseudo = true
                        } else {
                                // Repo.Latest promises that this method is only called where there are
diff --git a/src/cmd/go/internal/modfetch/pseudo_test.go b/src/cmd/go/internal/modfetch/pseudo_test.go
deleted file mode 100644 (file)
index 4483f8e..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-// 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 modfetch
-
-import (
-       "testing"
-       "time"
-)
-
-var pseudoTests = []struct {
-       major   string
-       older   string
-       version string
-}{
-       {"", "", "v0.0.0-20060102150405-hash"},
-       {"v0", "", "v0.0.0-20060102150405-hash"},
-       {"v1", "", "v1.0.0-20060102150405-hash"},
-       {"v2", "", "v2.0.0-20060102150405-hash"},
-       {"unused", "v0.0.0", "v0.0.1-0.20060102150405-hash"},
-       {"unused", "v1.2.3", "v1.2.4-0.20060102150405-hash"},
-       {"unused", "v1.2.99999999999999999", "v1.2.100000000000000000-0.20060102150405-hash"},
-       {"unused", "v1.2.3-pre", "v1.2.3-pre.0.20060102150405-hash"},
-       {"unused", "v1.3.0-pre", "v1.3.0-pre.0.20060102150405-hash"},
-       {"unused", "v0.0.0--", "v0.0.0--.0.20060102150405-hash"},
-       {"unused", "v1.0.0+metadata", "v1.0.1-0.20060102150405-hash+metadata"},
-       {"unused", "v2.0.0+incompatible", "v2.0.1-0.20060102150405-hash+incompatible"},
-       {"unused", "v2.3.0-pre+incompatible", "v2.3.0-pre.0.20060102150405-hash+incompatible"},
-}
-
-var pseudoTime = time.Date(2006, 1, 2, 15, 4, 5, 0, time.UTC)
-
-func TestPseudoVersion(t *testing.T) {
-       for _, tt := range pseudoTests {
-               v := PseudoVersion(tt.major, tt.older, pseudoTime, "hash")
-               if v != tt.version {
-                       t.Errorf("PseudoVersion(%q, %q, ...) = %v, want %v", tt.major, tt.older, v, tt.version)
-               }
-       }
-}
-
-func TestIsPseudoVersion(t *testing.T) {
-       for _, tt := range pseudoTests {
-               if !IsPseudoVersion(tt.version) {
-                       t.Errorf("IsPseudoVersion(%q) = false, want true", tt.version)
-               }
-               if IsPseudoVersion(tt.older) {
-                       t.Errorf("IsPseudoVersion(%q) = true, want false", tt.older)
-               }
-       }
-}
-
-func TestPseudoVersionTime(t *testing.T) {
-       for _, tt := range pseudoTests {
-               tm, err := PseudoVersionTime(tt.version)
-               if tm != pseudoTime || err != nil {
-                       t.Errorf("PseudoVersionTime(%q) = %v, %v, want %v, nil", tt.version, tm.Format(time.RFC3339), err, pseudoTime.Format(time.RFC3339))
-               }
-               tm, err = PseudoVersionTime(tt.older)
-               if tm != (time.Time{}) || err == nil {
-                       t.Errorf("PseudoVersionTime(%q) = %v, %v, want %v, error", tt.older, tm.Format(time.RFC3339), err, time.Time{}.Format(time.RFC3339))
-               }
-       }
-}
-
-func TestInvalidPseudoVersionTime(t *testing.T) {
-       const v = "---"
-       if _, err := PseudoVersionTime(v); err == nil {
-               t.Error("expected error, got nil instead")
-       }
-}
-
-func TestPseudoVersionRev(t *testing.T) {
-       for _, tt := range pseudoTests {
-               rev, err := PseudoVersionRev(tt.version)
-               if rev != "hash" || err != nil {
-                       t.Errorf("PseudoVersionRev(%q) = %q, %v, want %q, nil", tt.older, rev, err, "hash")
-               }
-               rev, err = PseudoVersionRev(tt.older)
-               if rev != "" || err == nil {
-                       t.Errorf("PseudoVersionRev(%q) = %q, %v, want %q, error", tt.older, rev, err, "")
-               }
-       }
-}
-
-func TestPseudoVersionBase(t *testing.T) {
-       for _, tt := range pseudoTests {
-               base, err := PseudoVersionBase(tt.version)
-               if err != nil {
-                       t.Errorf("PseudoVersionBase(%q): %v", tt.version, err)
-               } else if base != tt.older {
-                       t.Errorf("PseudoVersionBase(%q) = %q; want %q", tt.version, base, tt.older)
-               }
-       }
-}
-
-func TestInvalidPseudoVersionBase(t *testing.T) {
-       for _, in := range []string{
-               "v0.0.0",
-               "v0.0.0-",                                 // malformed: empty prerelease
-               "v0.0.0-0.20060102150405-hash",            // Z+1 == 0
-               "v0.1.0-0.20060102150405-hash",            // Z+1 == 0
-               "v1.0.0-0.20060102150405-hash",            // Z+1 == 0
-               "v0.0.0-20060102150405-hash+incompatible", // "+incompatible without base version
-               "v0.0.0-20060102150405-hash+metadata",     // other metadata without base version
-       } {
-               base, err := PseudoVersionBase(in)
-               if err == nil || base != "" {
-                       t.Errorf(`PseudoVersionBase(%q) = %q, %v; want "", error`, in, base, err)
-               }
-       }
-}
-
-func TestIncDecimal(t *testing.T) {
-       cases := []struct {
-               in, want string
-       }{
-               {"0", "1"},
-               {"1", "2"},
-               {"99", "100"},
-               {"100", "101"},
-               {"101", "102"},
-       }
-
-       for _, tc := range cases {
-               got := incDecimal(tc.in)
-               if got != tc.want {
-                       t.Fatalf("incDecimal(%q) = %q; want %q", tc.in, tc.want, got)
-               }
-       }
-}
-
-func TestDecDecimal(t *testing.T) {
-       cases := []struct {
-               in, want string
-       }{
-               {"", ""},
-               {"0", ""},
-               {"00", ""},
-               {"1", "0"},
-               {"2", "1"},
-               {"99", "98"},
-               {"100", "99"},
-               {"101", "100"},
-       }
-
-       for _, tc := range cases {
-               got := decDecimal(tc.in)
-               if got != tc.want {
-                       t.Fatalf("decDecimal(%q) = %q; want %q", tc.in, tc.want, got)
-               }
-       }
-}
index ed9a52267a64ad4935943efbe93ed749abca8d9b..46923cb7dcfe7c74b506f5b06a9fb9bbd75f7f22 100644 (file)
@@ -9,7 +9,6 @@ import (
        "io"
        "io/fs"
        "os"
-       "sort"
        "strconv"
        "time"
 
@@ -20,7 +19,6 @@ import (
        web "cmd/go/internal/web"
 
        "golang.org/x/mod/module"
-       "golang.org/x/mod/semver"
 )
 
 const traceRepo = false // trace all repo actions, for debugging
@@ -35,7 +33,7 @@ type Repo interface {
        // Pseudo-versions are not included.
        //
        // Versions should be returned sorted in semver order
-       // (implementations can use SortVersions).
+       // (implementations can use semver.Sort).
        //
        // Versions returns a non-nil error only if there was a problem
        // fetching the list of versions: it may return an empty list
@@ -346,16 +344,6 @@ func ImportRepoRev(path, rev string) (Repo, *RevInfo, error) {
        return repo, info, nil
 }
 
-func SortVersions(list []string) {
-       sort.Slice(list, func(i, j int) bool {
-               cmp := semver.Compare(list[i], list[j])
-               if cmp != 0 {
-                       return cmp < 0
-               }
-               return list[i] < list[j]
-       })
-}
-
 // A loggingRepo is a wrapper around an underlying Repo
 // that prints a log message at the start and end of each call.
 // It can be inserted when debugging.
index 995641c9f1f36d8a65192f6448e0c6f18c502fe4..31eb0c487466cbc28a68f781c2a2666976b125f7 100644 (file)
@@ -60,7 +60,7 @@ func (e *ImportMissingError) Error() string {
 
                if e.replaced.Path != "" {
                        suggestArg := e.replaced.Path
-                       if !modfetch.IsZeroPseudoVersion(e.replaced.Version) {
+                       if !module.IsZeroPseudoVersion(e.replaced.Version) {
                                suggestArg = e.replaced.String()
                        }
                        return fmt.Sprintf("module %s provides package %s and is replaced but not required; to add it:\n\tgo get %s", e.replaced.Path, e.Path, suggestArg)
@@ -344,9 +344,9 @@ func queryImport(ctx context.Context, path string) (module.Version, error) {
                                // used from within some other module, the user will be able to upgrade
                                // the requirement to any real version they choose.
                                if _, pathMajor, ok := module.SplitPathVersion(mp); ok && len(pathMajor) > 0 {
-                                       mv = modfetch.ZeroPseudoVersion(pathMajor[1:])
+                                       mv = module.ZeroPseudoVersion(pathMajor[1:])
                                } else {
-                                       mv = modfetch.ZeroPseudoVersion("v0")
+                                       mv = module.ZeroPseudoVersion("v0")
                                }
                        }
                        mods = append(mods, module.Version{Path: mp, Version: mv})
index 1707bd88edbd3a73809f1cf3571110213b026dca..6f6c6e8c98ddd16b79748010a476c3a832cfb351 100644 (file)
@@ -177,7 +177,7 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
                        return nil, err
                }
 
-               if (query == "upgrade" || query == "patch") && modfetch.IsPseudoVersion(current) && !rev.Time.IsZero() {
+               if (query == "upgrade" || query == "patch") && module.IsPseudoVersion(current) && !rev.Time.IsZero() {
                        // Don't allow "upgrade" or "patch" to move from a pseudo-version
                        // to a chronologically older version or pseudo-version.
                        //
@@ -196,7 +196,7 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
                        // newer but v1.1.0 is still an “upgrade”; or v1.0.2 might be a revert of
                        // an unsuccessful fix in v1.0.1, in which case the v1.0.2 commit may be
                        // older than the v1.0.1 commit despite the tag itself being newer.)
-                       currentTime, err := modfetch.PseudoVersionTime(current)
+                       currentTime, err := module.PseudoVersionTime(current)
                        if err == nil && rev.Time.Before(currentTime) {
                                if err := allowed(ctx, module.Version{Path: path, Version: current}); errors.Is(err, ErrDisallowed) {
                                        return nil, err
@@ -325,7 +325,7 @@ func newQueryMatcher(path string, query, current string, allowed AllowedFunc) (*
                if current == "" || current == "none" {
                        qm.mayUseLatest = true
                } else {
-                       qm.mayUseLatest = modfetch.IsPseudoVersion(current)
+                       qm.mayUseLatest = module.IsPseudoVersion(current)
                        qm.filter = func(mv string) bool { return semver.Compare(mv, current) >= 0 }
                }
 
@@ -336,7 +336,7 @@ func newQueryMatcher(path string, query, current string, allowed AllowedFunc) (*
                if current == "" {
                        qm.mayUseLatest = true
                } else {
-                       qm.mayUseLatest = modfetch.IsPseudoVersion(current)
+                       qm.mayUseLatest = module.IsPseudoVersion(current)
                        qm.prefix = semver.MajorMinor(current) + "."
                        qm.filter = func(mv string) bool { return semver.Compare(mv, current) >= 0 }
                }
@@ -1009,7 +1009,7 @@ func (rr *replacementRepo) Versions(prefix string) ([]string, error) {
        if index != nil && len(index.replace) > 0 {
                path := rr.ModulePath()
                for m, _ := range index.replace {
-                       if m.Path == path && strings.HasPrefix(m.Version, prefix) && m.Version != "" && !modfetch.IsPseudoVersion(m.Version) {
+                       if m.Path == path && strings.HasPrefix(m.Version, prefix) && m.Version != "" && !module.IsPseudoVersion(m.Version) {
                                versions = append(versions, m.Version)
                        }
                }
@@ -1066,9 +1066,9 @@ func (rr *replacementRepo) Latest() (*modfetch.RevInfo, error) {
                                // used from within some other module, the user will be able to upgrade
                                // the requirement to any real version they choose.
                                if _, pathMajor, ok := module.SplitPathVersion(path); ok && len(pathMajor) > 0 {
-                                       v = modfetch.PseudoVersion(pathMajor[1:], "", time.Time{}, "000000000000")
+                                       v = module.PseudoVersion(pathMajor[1:], "", time.Time{}, "000000000000")
                                } else {
-                                       v = modfetch.PseudoVersion("v0", "", time.Time{}, "000000000000")
+                                       v = module.PseudoVersion("v0", "", time.Time{}, "000000000000")
                                }
                        }
 
@@ -1083,9 +1083,9 @@ func (rr *replacementRepo) Latest() (*modfetch.RevInfo, error) {
 
 func (rr *replacementRepo) replacementStat(v string) (*modfetch.RevInfo, error) {
        rev := &modfetch.RevInfo{Version: v}
-       if modfetch.IsPseudoVersion(v) {
-               rev.Time, _ = modfetch.PseudoVersionTime(v)
-               rev.Short, _ = modfetch.PseudoVersionRev(v)
+       if module.IsPseudoVersion(v) {
+               rev.Time, _ = module.PseudoVersionTime(v)
+               rev.Short, _ = module.PseudoVersionRev(v)
        }
        return rev, nil
 }
index 7d8a97dd997fd0e478f8ecb96fa75119ccc06a2c..74bfecc08dbc6de1ca9768c536113eb878d7f3da 100644 (file)
@@ -23,7 +23,6 @@ import (
        "sync"
        "testing"
 
-       "cmd/go/internal/modfetch"
        "cmd/go/internal/modfetch/codehost"
        "cmd/go/internal/par"
        "cmd/go/internal/txtar"
@@ -229,7 +228,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) {
                        if m.Path != modPath {
                                continue
                        }
-                       if modfetch.IsPseudoVersion(m.Version) && (latestPseudo == "" || semver.Compare(latestPseudo, m.Version) > 0) {
+                       if module.IsPseudoVersion(m.Version) && (latestPseudo == "" || semver.Compare(latestPseudo, m.Version) > 0) {
                                latestPseudo = m.Version
                        } else if semver.Prerelease(m.Version) != "" && (latestPrerelease == "" || semver.Compare(latestPrerelease, m.Version) > 0) {
                                latestPrerelease = m.Version
@@ -282,7 +281,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) {
                                continue
                        }
                        found = true
-                       if !modfetch.IsPseudoVersion(m.Version) {
+                       if !module.IsPseudoVersion(m.Version) {
                                if err := module.Check(m.Path, m.Version); err == nil {
                                        fmt.Fprintf(w, "%s\n", m.Version)
                                }
@@ -315,7 +314,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) {
                for _, m := range modList {
                        if m.Path == path && semver.Compare(best, m.Version) < 0 {
                                var hash string
-                               if modfetch.IsPseudoVersion(m.Version) {
+                               if module.IsPseudoVersion(m.Version) {
                                        hash = m.Version[strings.LastIndex(m.Version, "-")+1:]
                                } else {
                                        hash = findHash(m)
similarity index 95%
rename from src/cmd/go/internal/modfetch/pseudo.go
rename to src/cmd/vendor/golang.org/x/mod/module/pseudo.go
index 93eb0fad961b6663dd2c21246ccfc0fe8d19dcfe..f04ad3788694fc9eb4764fb4d8546d2faa01f4f8 100644 (file)
@@ -32,7 +32,7 @@
 // If the most recent tagged version before the target commit is vX.Y.Z-pre or vX.Y.Z-pre+incompatible,
 // then the pseudo-version uses form (4) or (5), making it a slightly later prerelease.
 
-package modfetch
+package module
 
 import (
        "errors"
@@ -40,15 +40,13 @@ import (
        "strings"
        "time"
 
-       "internal/lazyregexp"
-
-       "golang.org/x/mod/module"
+       "golang.org/x/mod/internal/lazyregexp"
        "golang.org/x/mod/semver"
 )
 
 var pseudoVersionRE = lazyregexp.New(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$`)
 
-const pseudoVersionTimestampFormat = "20060102150405"
+const PseudoVersionTimestampFormat = "20060102150405"
 
 // PseudoVersion returns a pseudo-version for the given major version ("v1")
 // preexisting older tagged version ("" or "v1.2.3" or "v1.2.3-pre"), revision time,
@@ -57,7 +55,7 @@ func PseudoVersion(major, older string, t time.Time, rev string) string {
        if major == "" {
                major = "v0"
        }
-       segment := fmt.Sprintf("%s-%s", t.UTC().Format(pseudoVersionTimestampFormat), rev)
+       segment := fmt.Sprintf("%s-%s", t.UTC().Format(PseudoVersionTimestampFormat), rev)
        build := semver.Build(older)
        older = semver.Canonical(older)
        if older == "" {
@@ -142,7 +140,7 @@ func PseudoVersionTime(v string) (time.Time, error) {
        }
        t, err := time.Parse("20060102150405", timestamp)
        if err != nil {
-               return time.Time{}, &module.InvalidVersionError{
+               return time.Time{}, &InvalidVersionError{
                        Version: v,
                        Pseudo:  true,
                        Err:     fmt.Errorf("malformed time %q", timestamp),
@@ -180,7 +178,7 @@ func PseudoVersionBase(v string) (string, error) {
                        //
                        // There are a few such entries in the index generated by proxy.golang.org,
                        // but we believe those entries were generated by the proxy itself.
-                       return "", &module.InvalidVersionError{
+                       return "", &InvalidVersionError{
                                Version: v,
                                Pseudo:  true,
                                Err:     fmt.Errorf("lacks base version, but has build metadata %q", build),
@@ -208,7 +206,7 @@ func PseudoVersionBase(v string) (string, error) {
                        // treat them as equivalent to vX.0.0 (especially since the invalid
                        // pseudo-versions have lower precedence than the real ones). For now, we
                        // reject them.
-                       return "", &module.InvalidVersionError{
+                       return "", &InvalidVersionError{
                                Version: v,
                                Pseudo:  true,
                                Err:     fmt.Errorf("version before %s would have negative patch number", base),
@@ -230,7 +228,7 @@ var errPseudoSyntax = errors.New("syntax error")
 
 func parsePseudoVersion(v string) (base, timestamp, rev, build string, err error) {
        if !IsPseudoVersion(v) {
-               return "", "", "", "", &module.InvalidVersionError{
+               return "", "", "", "", &InvalidVersionError{
                        Version: v,
                        Pseudo:  true,
                        Err:     errPseudoSyntax,
index 4338f351774f86409b1b659f3e311e9bae1e354c..7be398f80d33e724ece45da019cb91132563c17b 100644 (file)
@@ -22,6 +22,8 @@
 // as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
 package semver
 
+import "sort"
+
 // parsed returns the parsed form of a semantic version string.
 type parsed struct {
        major      string
@@ -150,6 +152,24 @@ func Max(v, w string) string {
        return w
 }
 
+// ByVersion implements sort.Interface for sorting semantic version strings.
+type ByVersion []string
+
+func (vs ByVersion) Len() int      { return len(vs) }
+func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] }
+func (vs ByVersion) Less(i, j int) bool {
+       cmp := Compare(vs[i], vs[j])
+       if cmp != 0 {
+               return cmp < 0
+       }
+       return vs[i] < vs[j]
+}
+
+// Sort sorts a list of semantic version strings using ByVersion.
+func Sort(list []string) {
+       sort.Sort(ByVersion(list))
+}
+
 func parse(v string) (p parsed, ok bool) {
        if v == "" || v[0] != 'v' {
                p.err = "missing v prefix"
index 3dd50ccddbfca8222840f1ee51cecf0f336a6f80..6960ff1c7e2b7e8107bcc8202d9020ad9ad32cd8 100644 (file)
@@ -28,7 +28,7 @@ golang.org/x/arch/x86/x86asm
 golang.org/x/crypto/ed25519
 golang.org/x/crypto/ed25519/internal/edwards25519
 golang.org/x/crypto/ssh/terminal
-# golang.org/x/mod v0.4.3-0.20210310185834-19d50cac98aa
+# golang.org/x/mod v0.4.3-0.20210323215154-1cc8812c1740
 ## explicit
 golang.org/x/mod/internal/lazyregexp
 golang.org/x/mod/modfile