internal: remove unit-meta-with-latest experiment
For golang/go#43265
Change-Id: I1d056a893fdff60744ff328ab9f4a1b6665b3e32
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/309709
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/internal/experiment.go b/internal/experiment.go
index 00c56c0..99939e6 100644
--- a/internal/experiment.go
+++ b/internal/experiment.go
@@ -9,7 +9,6 @@
ExperimentInsertSymbols = "insert-symbols"
ExperimentSymbolHistoryVersionsPage = "symbol-history-versions-page"
ExperimentSymbolHistoryMainPage = "symbol-history-main-page"
- ExperimentUnitMetaWithLatest = "unit-meta-with-latest"
)
// Experiments represents all of the active experiments in the codebase and
@@ -18,7 +17,6 @@
ExperimentInsertSymbols: "Insert data into symbols, package_symbols, and documentation_symbols.",
ExperimentSymbolHistoryVersionsPage: "Show package API history on the versions page.",
ExperimentSymbolHistoryMainPage: "Show package API history on the main unit page.",
- ExperimentUnitMetaWithLatest: "Use latest-version information for GetUnitMeta.",
}
// Experiment holds data associated with an experimental feature for frontend
diff --git a/internal/postgres/unit.go b/internal/postgres/unit.go
index 5cac3e2..ce98ec2 100644
--- a/internal/postgres/unit.go
+++ b/internal/postgres/unit.go
@@ -16,7 +16,6 @@
"golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/database"
"golang.org/x/pkgsite/internal/derrors"
- "golang.org/x/pkgsite/internal/experiment"
"golang.org/x/pkgsite/internal/middleware"
"golang.org/x/pkgsite/internal/stdlib"
"golang.org/x/pkgsite/internal/version"
@@ -39,19 +38,16 @@
defer derrors.WrapStack(&err, "DB.GetUnitMeta(ctx, %q, %q, %q)", fullPath, requestedModulePath, requestedVersion)
defer middleware.ElapsedStat(ctx, "GetUnitMeta")()
- if experiment.IsActive(ctx, internal.ExperimentUnitMetaWithLatest) {
- modulePath := requestedModulePath
- version := requestedVersion
- var lmv *internal.LatestModuleVersions
- if requestedVersion == internal.LatestVersion {
- modulePath, version, lmv, err = db.getLatestUnitVersion(ctx, fullPath, requestedModulePath)
- if err != nil {
- return nil, err
- }
+ modulePath := requestedModulePath
+ version := requestedVersion
+ var lmv *internal.LatestModuleVersions
+ if requestedVersion == internal.LatestVersion {
+ modulePath, version, lmv, err = db.getLatestUnitVersion(ctx, fullPath, requestedModulePath)
+ if err != nil {
+ return nil, err
}
- return db.getUnitMetaWithKnownLatestVersion(ctx, fullPath, modulePath, version, lmv)
}
- return db.legacyGetUnitMeta(ctx, fullPath, requestedModulePath, requestedVersion)
+ return db.getUnitMetaWithKnownLatestVersion(ctx, fullPath, modulePath, version, lmv)
}
func (db *DB) getUnitMetaWithKnownLatestVersion(ctx context.Context, fullPath, modulePath, version string, lmv *internal.LatestModuleVersions) (_ *internal.UnitMeta, err error) {
@@ -225,131 +221,6 @@
return modulePath, latestVersion, nil, nil
}
-func (db *DB) legacyGetUnitMeta(ctx context.Context, fullPath, requestedModulePath, requestedVersion string) (_ *internal.UnitMeta, err error) {
- defer derrors.WrapStack(&err, "DB.legacyGetUnitMeta(ctx, %q, %q, %q)", fullPath, requestedModulePath, requestedVersion)
-
- var (
- q string
- args []interface{}
- )
- q, args, err = getUnitMetaQuery(fullPath, requestedModulePath, requestedVersion).PlaceholderFormat(squirrel.Dollar).ToSql()
- if err != nil {
- return nil, fmt.Errorf("squirrel.ToSql: %v", err)
- }
- var (
- licenseTypes []string
- licensePaths []string
- um = internal.UnitMeta{Path: fullPath}
- )
- err = db.db.QueryRow(ctx, q, args...).Scan(
- &um.ModulePath,
- &um.Version,
- &um.CommitTime,
- jsonbScanner{&um.SourceInfo},
- &um.HasGoMod,
- &um.ModuleInfo.IsRedistributable,
- &um.Name,
- &um.IsRedistributable,
- pq.Array(&licenseTypes),
- pq.Array(&licensePaths))
- switch err {
- case sql.ErrNoRows:
- return nil, derrors.NotFound
- case nil:
- lics, err := zipLicenseMetadata(licenseTypes, licensePaths)
- if err != nil {
- return nil, err
- }
-
- if db.bypassLicenseCheck {
- um.IsRedistributable = true
- }
-
- um.Licenses = lics
- if err := populateLatestInfo(ctx, db, &um.ModuleInfo); err != nil {
- return nil, err
- }
- return &um, nil
- default:
- return nil, err
- }
-}
-
-func getUnitMetaQuery(fullPath, requestedModulePath, requestedVersion string) squirrel.SelectBuilder {
- query := squirrel.Select(
- "m.module_path",
- "m.version",
- "m.commit_time",
- "m.source_info",
- "m.has_go_mod",
- "m.redistributable",
- "u.name",
- "u.redistributable",
- "u.license_types",
- "u.license_paths",
- )
- if requestedVersion != internal.LatestVersion {
- query = query.From("modules m").
- Join("units u on u.module_id = m.id").
- Join("paths p ON p.id = u.path_id").Where(squirrel.Eq{"p.path": fullPath})
- if requestedModulePath != internal.UnknownModulePath {
- query = query.Where(squirrel.Eq{"m.module_path": requestedModulePath})
- }
- if internal.DefaultBranches[requestedVersion] {
- query = query.Join("version_map vm ON m.id = vm.module_id").Where("vm.requested_version = ? ", requestedVersion)
- } else if requestedVersion != internal.LatestVersion {
- query = query.Where(squirrel.Eq{"version": requestedVersion})
- }
- return orderByLatest(query).Limit(1)
- }
-
- // Use a nested select to fetch the latest version of the unit, then JOIN
- // on units to fetch other relevant information. This allows us to use the
- // index on units.id and paths.path to get the latest path. We can then
- // look up only the relevant information from the units table.
- nestedSelect := orderByLatest(squirrel.Select(
- "m.id",
- "m.module_path",
- "m.version",
- "m.commit_time",
- "m.source_info",
- "m.has_go_mod",
- "m.redistributable",
- "u.id AS unit_id",
- ).From("modules m").
- Join("units u ON u.module_id = m.id").
- Join("paths p ON p.id = u.path_id").
- Where(squirrel.Eq{"p.path": fullPath}))
- if requestedModulePath != internal.UnknownModulePath {
- nestedSelect = nestedSelect.Where(squirrel.Eq{"m.module_path": requestedModulePath})
- }
- nestedSelect = nestedSelect.Limit(1)
- return query.From("units u").JoinClause(nestedSelect.Prefix("JOIN (").Suffix(") m ON u.id = m.unit_id"))
-}
-
-// orderByLatest orders paths according to the go command.
-// Versions are ordered by:
-// (1) release (non-incompatible)
-// (2) prerelease (non-incompatible)
-// (3) release, incompatible
-// (4) prerelease, incompatible
-// (5) pseudo
-// They are then sorted based on semver, then decreasing module path length (so
-// that nested modules are preferred).
-func orderByLatest(q squirrel.SelectBuilder) squirrel.SelectBuilder {
- return q.OrderBy(
- `CASE
- WHEN m.version_type = 'release' AND NOT m.incompatible THEN 1
- WHEN m.version_type = 'prerelease' AND NOT m.incompatible THEN 2
- WHEN m.version_type = 'release' THEN 3
- WHEN m.version_type = 'prerelease' THEN 4
- ELSE 5
- END`,
- "m.series_path DESC",
- "m.sort_version DESC",
- ).PlaceholderFormat(squirrel.Dollar)
-}
-
// GetUnit returns a unit from the database, along with all of the data
// associated with that unit.
func (db *DB) GetUnit(ctx context.Context, um *internal.UnitMeta, fields internal.FieldSet) (_ *internal.Unit, err error) {
diff --git a/internal/postgres/unit_test.go b/internal/postgres/unit_test.go
index 37780f3..47de46d 100644
--- a/internal/postgres/unit_test.go
+++ b/internal/postgres/unit_test.go
@@ -26,12 +26,7 @@
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), testTimeout*2)
defer cancel()
- t.Run("legacy", func(t *testing.T) {
- testGetUnitMeta(t, ctx)
- })
- t.Run("latest", func(t *testing.T) {
- testGetUnitMeta(t, experiment.NewContext(ctx, internal.ExperimentUnitMetaWithLatest))
- })
+ testGetUnitMeta(t, ctx)
}
func testGetUnitMeta(t *testing.T, ctx context.Context) {
@@ -207,104 +202,6 @@
}
}
-func TestGetUnitMetaDiffs(t *testing.T) {
- // Demonstrate differences between legacy and latest-version GetUnitMeta
- // implementations.
-
- t.Parallel()
-
- type latest struct { // latest-version info
- module string
- version string // latest raw and cooked version
- goMod string // go.mod file contents after "module" line
- }
-
- modver := func(u *internal.UnitMeta) string { return u.ModulePath + "@" + u.Version }
-
- for _, test := range []struct {
- name string
- packages []string // mod@ver/pkg
- latests []latest
- path string
- wantLatest, wantLegacy string
- }{
- {
- name: "incompatible",
- // When there are incompatible versions and no go.mod at the latest
- // compatible version, the go command selects the highest
- // incompatible version, but legacy GetUnitMeta selects the highest
- // compatible version.
- packages: []string{
- "m.com@v1.0.0/a",
- "m.com@v2.0.0+incompatible/a",
- },
- latests: []latest{{"m.com", "v2.0.0+incompatible", ""}},
- path: "m.com/a",
- wantLatest: "m.com@v2.0.0+incompatible",
- wantLegacy: "m.com@v1.0.0",
- },
- {
- name: "shorter",
- // The go command prefers the longer path if both have latest-version information,
- // but legacy GetUnitMeta prefers the shorter path if it has a release version.
- packages: []string{
- "m.com@v1.0.0/a/b", // shorter path, release version
- "m.com/a@v1.0.0-pre/b", // longer path, pre-release version
- },
- latests: []latest{{"m.com", "v1.0.0", ""}, {"m.com/a", "v1.0.0-pre", ""}},
- path: "m.com/a/b",
- wantLatest: "m.com/a@v1.0.0-pre",
- wantLegacy: "m.com@v1.0.0",
- },
- {
- name: "retraction",
- // Legacy GetUnitMeta ignores retractions when picking the latest version.
- packages: []string{
- "m.com@v1.0.0/a",
- "m.com@v1.1.0/a", // latest, also retracted
- },
- latests: []latest{{"m.com", "v1.1.0", "retract v1.1.0"}},
- path: "m.com/a",
- wantLatest: "m.com@v1.0.0",
- wantLegacy: "m.com@v1.1.0",
- },
- } {
- t.Run(test.name, func(t *testing.T) {
- ctx := context.Background()
- testDB, release := acquire(t)
- defer release()
-
- for _, p := range test.packages {
- mod, ver, pkg := parseModuleVersionPackage(p)
- m := sample.Module(mod, ver, pkg)
- goMod := "module " + mod
- for _, l := range test.latests {
- if l.module == mod && l.version == ver {
- goMod += "\n" + l.goMod
- break
- }
- }
- MustInsertModuleGoMod(ctx, t, testDB, m, goMod)
- }
- gotLegacy, err := testDB.GetUnitMeta(ctx, test.path, internal.UnknownModulePath, internal.LatestVersion)
- if err != nil {
- t.Fatal(err)
- }
- if got := modver(gotLegacy); got != test.wantLegacy {
- t.Errorf("legacy: got %s, want %s", got, test.wantLegacy)
- }
- gotLatest, err := testDB.GetUnitMeta(experiment.NewContext(ctx, internal.ExperimentUnitMetaWithLatest),
- test.path, internal.UnknownModulePath, internal.LatestVersion)
- if err != nil {
- t.Fatal(err)
- }
- if got := modver(gotLatest); got != test.wantLatest {
- t.Errorf("latest: got %s, want %s", got, test.wantLatest)
- }
- })
- }
-}
-
func TestGetUnitMetaBypass(t *testing.T) {
t.Parallel()
testDB, release := acquire(t)
@@ -318,13 +215,13 @@
module, version, packageSuffix string
isMaster bool
}{
+ {"m.com", "v2.0.0+incompatible", "a", false},
+ {"m.com/b", "v2.0.0+incompatible", "a", true},
{"m.com", "v1.0.0", "a", false},
{"m.com", "v1.0.1", "dir/a", false},
{"m.com", "v1.1.0", "a/b", false},
{"m.com", "v1.2.0-pre", "a", true},
- {"m.com", "v2.0.0+incompatible", "a", false},
{"m.com/a", "v1.1.0", "b", false},
- {"m.com/b", "v2.0.0+incompatible", "a", true},
} {
m := sample.Module(testModule.module, testModule.version, testModule.packageSuffix)
makeModuleNonRedistributable(m)