Skip to content

Commit 31611c1

Browse files
committed
internal/postgres: ensure good version not later than cooked
The good latest version of a module should never be later than the cooked latest version. If it is, then pkgsite will show a different version than the go command will download. One way this can happen is if a module retracts all tagged versions, and pseudo-versions were built on top of some of them. For example, initially it could have versions v0.1.0 v0.1.0-DATE-HASH (a pseudo-version) Then v0.1.0 is retracted and a new pseudo-version appears at head: v0.1.0 (retracted) v0.1.0-DATE-HASH v0.0.0-DATE-HASH (head of default branch) The go command will get the v0.0.0 version, but technically the v0.1.0 is later. For golang/go#43265 Change-Id: I8ff30de4eb2dcdf108205de99af93d2f31772cff Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/318069 Trust: Jonathan Amsterdam <[email protected]> Run-TryBot: Jonathan Amsterdam <[email protected]> Reviewed-by: Julie Qiu <[email protected]>
1 parent bb873d2 commit 31611c1

File tree

4 files changed

+44
-9
lines changed

4 files changed

+44
-9
lines changed

internal/postgres/search_test.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -787,15 +787,19 @@ func TestUpsertSearchDocument(t *testing.T) {
787787
return sd
788788
}
789789

790-
insertModule := func(version string, gomod bool) {
790+
insertModule := func(version string, gomod, latest bool) {
791791
m := sample.Module(sample.ModulePath, version, "A")
792792
m.HasGoMod = gomod
793793
m.Packages()[0].Documentation[0].Synopsis = "syn-" + version
794-
MustInsertModule(ctx, t, testDB, m)
794+
if latest {
795+
MustInsertModule(ctx, t, testDB, m)
796+
} else {
797+
MustInsertModuleNotLatest(ctx, t, testDB, m)
798+
}
795799
}
796800

797801
const v1 = "v1.0.0"
798-
insertModule(v1, false)
802+
insertModule(v1, false, true)
799803
sd1 := getSearchDocument()
800804
if sd1.version != v1 {
801805
t.Fatalf("got %s, want %s", sd1.version, v1)
@@ -804,22 +808,22 @@ func TestUpsertSearchDocument(t *testing.T) {
804808
// Since the latest compatible version has no go.mod file, this incompatible version
805809
// is the latest.
806810
const vInc = "v2.0.0+incompatible"
807-
insertModule(vInc, false)
811+
insertModule(vInc, false, true)
808812
sdInc := getSearchDocument()
809813
if sdInc.version != vInc {
810814
t.Fatalf("got %s, want %s", sdInc.version, vInc)
811815
}
812816

813817
// Inserting an older module doesn't change anything.
814-
insertModule("v0.5.0", true)
818+
insertModule("v0.5.0", true, false)
815819
sdOlder := getSearchDocument()
816820
if diff := cmp.Diff(sdInc, sdOlder, cmp.AllowUnexported(searchDocument{})); diff != "" {
817821
t.Fatalf("mismatch (-want, +got):\n%s", diff)
818822
}
819823

820824
// A later compatible version with a go.mod file. This becomes the new latest version.
821825
const v15 = "v1.5.2"
822-
insertModule(v15, true)
826+
insertModule(v15, true, true)
823827
sdNewer := getSearchDocument()
824828
if sdNewer.version != v15 {
825829
t.Fatalf("got %s, want %s", sdNewer.version, v15)

internal/postgres/test_helper.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,17 +202,25 @@ func RunDBTestsInParallel(dbBaseName string, numDBs int, m *testing.M, acquirep
202202
// MustInsertModule inserts m into db, calling t.Fatal on error.
203203
// It also updates the latest-version information for m.
204204
func MustInsertModule(ctx context.Context, t *testing.T, db *DB, m *internal.Module) {
205-
MustInsertModuleGoMod(ctx, t, db, m, "")
205+
mustInsertModule(ctx, t, db, m, "", true)
206206
}
207207

208208
func MustInsertModuleGoMod(ctx context.Context, t *testing.T, db *DB, m *internal.Module, goMod string) {
209+
mustInsertModule(ctx, t, db, m, goMod, true)
210+
}
211+
212+
func MustInsertModuleNotLatest(ctx context.Context, t *testing.T, db *DB, m *internal.Module) {
213+
mustInsertModule(ctx, t, db, m, "", false)
214+
}
215+
216+
func mustInsertModule(ctx context.Context, t *testing.T, db *DB, m *internal.Module, goMod string, latest bool) {
209217
t.Helper()
210218
var lmv *internal.LatestModuleVersions
211219
if goMod == "-" {
212220
if err := db.UpdateLatestModuleVersionsStatus(ctx, m.ModulePath, 404); err != nil {
213221
t.Fatal(err)
214222
}
215-
} else {
223+
} else if latest {
216224
lmv = addLatest(ctx, t, db, m.ModulePath, m.Version, goMod)
217225
}
218226
if _, err := db.InsertModule(ctx, m, lmv); err != nil {

internal/postgres/unit.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,21 @@ func (db *DB) getLatestUnitVersion(ctx context.Context, fullPath, requestedModul
188188
if !version.IsIncompatible(lmv.CookedVersion) {
189189
unretractedVersions = version.RemoveIf(unretractedVersions, version.IsIncompatible)
190190
}
191+
// The good version should never be later than the cooked version.
192+
// https://golang.org/issue/43265 documents how that could happen:
193+
// 1. A pseudo-version is created off of a tagged version. In this case,
194+
// golang.zx2c4.com/[email protected].
195+
// 2. All tagged versions are retracted.
196+
// 3. A new pseudo-version is published. In this case, v0.0.0-20210506092213-60a26371f42f.
197+
// Technically, the first pseudo-version is higher than the second, so it
198+
// is the latest good version. But the proxy's latest endpoint returns
199+
// the second pseudo-version, so that is the cooked version (and what the
200+
// go command will download).
201+
if lmv.CookedVersion != "" {
202+
unretractedVersions = version.RemoveIf(unretractedVersions, func(v string) bool {
203+
return version.Later(v, lmv.CookedVersion)
204+
})
205+
}
191206
latestVersion = version.LatestOf(unretractedVersions)
192207
break
193208
}

internal/postgres/version.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,18 @@ func getLatestGoodVersion(ctx context.Context, tx *database.DB, modulePath strin
388388
if err != nil {
389389
return "", err
390390
}
391-
// Choose the latest good version from the unretracted versions.
391+
// Choose the latest good version from a filtered list of versions.
392392
if lmv != nil {
393+
// Remove retracted versions.
393394
vs = version.RemoveIf(vs, lmv.IsRetracted)
395+
// The good version should never be later than the cooked version.
396+
if lmv.CookedVersion != "" {
397+
vs = version.RemoveIf(vs, func(v string) bool {
398+
return version.Later(v, lmv.CookedVersion)
399+
})
400+
}
394401
}
402+
395403
return version.LatestOf(vs), nil
396404
}
397405

0 commit comments

Comments
 (0)