internal/frontend: delete legacy code

Legacy code is removed from internal/frontend.

For golang/go#39629

Change-Id: Ia445eb991c9afd0877e2a8da527099d3c898800a
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/258277
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/internal/frontend/details.go b/internal/frontend/details.go
index cf23898..dfba6c1 100644
--- a/internal/frontend/details.go
+++ b/internal/frontend/details.go
@@ -173,19 +173,12 @@
 	ctx := r.Context()
 
 	if info.isModule {
-		if experiment.IsActive(ctx, internal.ExperimentUseUnits) {
-			return s.serveModulePage(ctx, w, r, ds, um, info.requestedVersion)
-		}
-		return s.legacyServeModulePage(w, r, ds, info.fullPath, info.requestedVersion, info.resolvedVersion)
+		return s.serveModulePage(ctx, w, r, ds, um, info.requestedVersion)
 	}
-
-	if experiment.IsActive(ctx, internal.ExperimentUseUnits) {
-		if um.IsPackage() {
-			return s.servePackagePage(ctx, w, r, ds, um, info.requestedVersion)
-		}
-		return s.serveDirectoryPage(ctx, w, r, ds, um, info.requestedVersion)
+	if um.IsPackage() {
+		return s.servePackagePage(ctx, w, r, ds, um, info.requestedVersion)
 	}
-	return s.legacyServePackagePage(w, r, ds, info.fullPath, info.modulePath, info.requestedVersion, info.resolvedVersion)
+	return s.serveDirectoryPage(ctx, w, r, ds, um, info.requestedVersion)
 }
 
 type urlPathInfo struct {
diff --git a/internal/frontend/directory_test.go b/internal/frontend/directory_test.go
index 84c68dc..1ebebc1 100644
--- a/internal/frontend/directory_test.go
+++ b/internal/frontend/directory_test.go
@@ -132,30 +132,19 @@
 				got *Directory
 				err error
 			)
-			t.Run("use-directories", func(t *testing.T) {
-				um := &internal.UnitMeta{
-					Path:              tc.dirPath,
-					ModulePath:        tc.modulePath,
-					Version:           tc.version,
-					IsRedistributable: true,
-					CommitTime:        sample.CommitTime,
-					Licenses:          sample.LicenseMetadata,
-				}
-				got, err = fetchDirectoryDetails(ctx, testDB, um, tc.includeDirPath)
-				if err != nil {
-					t.Fatal(err)
-				}
-				checkDirectory(got, tc.dirPath, tc.wantModulePath, tc.wantVersion, tc.wantPkgSuffixes)
-			})
-			t.Run("legacy", func(t *testing.T) {
-				mi := sample.ModuleInfoReleaseType(tc.modulePath, tc.version)
-				got, err = legacyFetchDirectoryDetails(ctx, testDB,
-					tc.dirPath, mi, sample.LicenseMetadata, tc.includeDirPath)
-				if err != nil {
-					t.Fatal(err)
-				}
-				checkDirectory(got, tc.dirPath, tc.wantModulePath, tc.wantVersion, tc.wantPkgSuffixes)
-			})
+			um := &internal.UnitMeta{
+				Path:              tc.dirPath,
+				ModulePath:        tc.modulePath,
+				Version:           tc.version,
+				IsRedistributable: true,
+				CommitTime:        sample.CommitTime,
+				Licenses:          sample.LicenseMetadata,
+			}
+			got, err = fetchDirectoryDetails(ctx, testDB, um, tc.includeDirPath)
+			if err != nil {
+				t.Fatal(err)
+			}
+			checkDirectory(got, tc.dirPath, tc.wantModulePath, tc.wantVersion, tc.wantPkgSuffixes)
 		})
 	}
 }
diff --git a/internal/frontend/header_test.go b/internal/frontend/header_test.go
index 1a6ac08..f66e724 100644
--- a/internal/frontend/header_test.go
+++ b/internal/frontend/header_test.go
@@ -241,3 +241,15 @@
 		})
 	}
 }
+
+// packageMetaFromLegacyPackage returns a PackageMeta based on data from a
+// LegacyPackage.
+func packageMetaFromLegacyPackage(pkg *internal.LegacyPackage) *internal.PackageMeta {
+	return &internal.PackageMeta{
+		Path:              pkg.Path,
+		IsRedistributable: pkg.IsRedistributable,
+		Name:              pkg.Name,
+		Synopsis:          pkg.Synopsis,
+		Licenses:          pkg.Licenses,
+	}
+}
diff --git a/internal/frontend/legacy_details.go b/internal/frontend/legacy_details.go
deleted file mode 100644
index 211d930..0000000
--- a/internal/frontend/legacy_details.go
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package frontend
-
-import (
-	"context"
-	"errors"
-	"fmt"
-
-	"golang.org/x/pkgsite/internal"
-	"golang.org/x/pkgsite/internal/derrors"
-	"golang.org/x/pkgsite/internal/licenses"
-	"golang.org/x/pkgsite/internal/stdlib"
-)
-
-// legacyFetchDocumentationDetails returns a DocumentationDetails constructed
-// from pkg.
-func legacyFetchDocumentationDetails(pkg *internal.LegacyVersionedPackage) *DocumentationDetails {
-	return &DocumentationDetails{
-		GOOS:          pkg.GOOS,
-		GOARCH:        pkg.GOARCH,
-		Documentation: pkg.DocumentationHTML,
-	}
-}
-
-// legacyFetchPackageOverviewDetails uses data for the given package to return
-// an OverviewDetails.
-func legacyFetchPackageOverviewDetails(ctx context.Context, pkg *internal.LegacyVersionedPackage, versionedLinks bool) (*OverviewDetails, error) {
-	od, err := constructOverviewDetails(ctx, &pkg.ModuleInfo, &internal.Readme{Filepath: pkg.LegacyReadmeFilePath, Contents: pkg.LegacyReadmeContents},
-		pkg.LegacyPackage.IsRedistributable, versionedLinks)
-	if err != nil {
-		return nil, err
-	}
-	od.PackageSourceURL = pkg.SourceInfo.DirectoryURL(internal.Suffix(pkg.Path, pkg.ModulePath))
-	if !pkg.LegacyPackage.IsRedistributable {
-		od.Redistributable = false
-	}
-	return od, nil
-}
-
-// legacyFetchDirectoryDetails fetches data for the directory specified by path and
-// version from the database and returns a Directory.
-//
-// includeDirPath indicates whether a package is included if its import path is
-// the same as dirPath.
-// This argument is needed because on the module "Packages" tab, we want to
-// display all packages in the module, even if the import path is the same as
-// the module path. However, on the package and directory view's
-// "Subdirectories" tab, we do not want to include packages whose import paths
-// are the same as the dirPath.
-func legacyFetchDirectoryDetails(ctx context.Context, ds internal.DataSource, dirPath string, mi *internal.ModuleInfo,
-	licmetas []*licenses.Metadata, includeDirPath bool) (_ *Directory, err error) {
-	defer derrors.Wrap(&err, "legacyfetchDirectoryDetails(%q, %q, %q, %v)", dirPath, mi.ModulePath, mi.Version, licmetas)
-
-	if includeDirPath && dirPath != mi.ModulePath && dirPath != stdlib.ModulePath {
-		return nil, fmt.Errorf("includeDirPath can only be set to true if dirPath = modulePath: %w", derrors.InvalidArgument)
-	}
-
-	if dirPath == stdlib.ModulePath {
-		pkgs, err := ds.LegacyGetPackagesInModule(ctx, stdlib.ModulePath, mi.Version)
-		if err != nil {
-			return nil, err
-		}
-		return legacyCreateDirectory(&internal.LegacyDirectory{
-			LegacyModuleInfo: internal.LegacyModuleInfo{ModuleInfo: *mi},
-			Path:             dirPath,
-			Packages:         pkgs,
-		}, licmetas, includeDirPath)
-	}
-
-	dbDir, err := ds.LegacyGetDirectory(ctx, dirPath, mi.ModulePath, mi.Version, internal.AllFields)
-	if errors.Is(err, derrors.NotFound) {
-		return legacyCreateDirectory(&internal.LegacyDirectory{
-			LegacyModuleInfo: internal.LegacyModuleInfo{ModuleInfo: *mi},
-			Path:             dirPath,
-			Packages:         nil,
-		}, licmetas, includeDirPath)
-	}
-	if err != nil {
-		return nil, err
-	}
-	return legacyCreateDirectory(dbDir, licmetas, includeDirPath)
-}
-
-// legacyFetchPackageVersionsDetails builds a version hierarchy for all module
-// versions containing a package path with v1 import path matching the given v1 path.
-func legacyFetchPackageVersionsDetails(ctx context.Context, ds internal.DataSource, pkgPath, v1Path, modulePath string) (*VersionsDetails, error) {
-	versions, err := ds.LegacyGetTaggedVersionsForPackageSeries(ctx, pkgPath)
-	if err != nil {
-		return nil, err
-	}
-	// If no tagged versions for the package series are found, fetch the
-	// pseudo-versions instead.
-	if len(versions) == 0 {
-		versions, err = ds.LegacyGetPsuedoVersionsForPackageSeries(ctx, pkgPath)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	linkify := func(mi *internal.ModuleInfo) string {
-		// Here we have only version information, but need to construct the full
-		// import path of the package corresponding to this version.
-		var versionPath string
-		if mi.ModulePath == stdlib.ModulePath {
-			versionPath = pkgPath
-		} else {
-			versionPath = pathInVersion(v1Path, mi)
-		}
-		return constructPackageURL(versionPath, mi.ModulePath, linkVersion(mi.Version, mi.ModulePath))
-	}
-	return buildVersionDetails(modulePath, versions, linkify), nil
-}
-
-// legacyFetchPackageLicensesDetails fetches license data for the package version specified by
-// path and version from the database and returns a LicensesDetails.
-func legacyFetchPackageLicensesDetails(ctx context.Context, ds internal.DataSource, pkgPath, modulePath, resolvedVersion string) (*LicensesDetails, error) {
-	dsLicenses, err := ds.LegacyGetPackageLicenses(ctx, pkgPath, modulePath, resolvedVersion)
-	if err != nil {
-		return nil, err
-	}
-	return &LicensesDetails{Licenses: transformLicenses(modulePath, resolvedVersion, dsLicenses)}, nil
-}
diff --git a/internal/frontend/legacy_directory.go b/internal/frontend/legacy_directory.go
deleted file mode 100644
index 0bf18d6..0000000
--- a/internal/frontend/legacy_directory.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package frontend
-
-import (
-	"context"
-	"fmt"
-	"net/http"
-
-	"golang.org/x/pkgsite/internal"
-	"golang.org/x/pkgsite/internal/derrors"
-	"golang.org/x/pkgsite/internal/licenses"
-)
-
-func (s *Server) legacyServeDirectoryPage(ctx context.Context, w http.ResponseWriter, r *http.Request, ds internal.DataSource, dbDir *internal.LegacyDirectory, requestedVersion string) (err error) {
-	defer derrors.Wrap(&err, "legacyServeDirectoryPage for %s@%s", dbDir.Path, requestedVersion)
-	tab := r.FormValue("tab")
-	settings, ok := directoryTabLookup[tab]
-	if tab == "" || !ok || settings.Disabled {
-		tab = tabSubdirectories
-		settings = directoryTabLookup[tab]
-	}
-	licenses, err := ds.LegacyGetModuleLicenses(ctx, dbDir.ModulePath, dbDir.Version)
-	if err != nil {
-		return err
-	}
-	header, err := legacyCreateDirectory(dbDir, licensesToMetadatas(licenses), false)
-	if err != nil {
-		return err
-	}
-	if requestedVersion == internal.LatestVersion {
-		header.URL = constructDirectoryURL(dbDir.Path, dbDir.ModulePath, internal.LatestVersion)
-	}
-
-	details, err := legacyFetchDetailsForDirectory(r, tab, dbDir, licenses)
-	if err != nil {
-		return err
-	}
-	page := &DetailsPage{
-		basePage:       s.newBasePage(r, fmt.Sprintf("%s directory", dbDir.Path)),
-		Name:           dbDir.Path,
-		Settings:       settings,
-		Header:         header,
-		Breadcrumb:     breadcrumbPath(dbDir.Path, dbDir.ModulePath, linkVersion(dbDir.Version, dbDir.ModulePath)),
-		Details:        details,
-		CanShowDetails: true,
-		Tabs:           directoryTabSettings,
-		PageType:       pageTypeDirectory,
-		CanonicalURLPath: constructPackageURL(
-			dbDir.Path,
-			dbDir.ModulePath,
-			linkVersion(dbDir.Version, dbDir.ModulePath),
-		),
-	}
-	s.servePage(ctx, w, settings.TemplateName, page)
-	return nil
-}
-
-// legacyCreateDirectory constructs a *Directory for the given dirPath.
-func legacyCreateDirectory(dbDir *internal.LegacyDirectory, licmetas []*licenses.Metadata, includeDirPath bool) (_ *Directory, err error) {
-	defer derrors.Wrap(&err, "legacyCreateDirectory(%q, %q, %t)", dbDir.Path, dbDir.Version, includeDirPath)
-	var packages []*internal.PackageMeta
-	for _, pkg := range dbDir.Packages {
-		newPkg := packageMetaFromLegacyPackage(pkg)
-		packages = append(packages, newPkg)
-	}
-	return createDirectory(dbDir.Path, &dbDir.ModuleInfo, packages, nil, licmetas, includeDirPath)
-}
diff --git a/internal/frontend/legacy_module.go b/internal/frontend/legacy_module.go
deleted file mode 100644
index 89aa03f..0000000
--- a/internal/frontend/legacy_module.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package frontend
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"net/http"
-
-	"golang.org/x/pkgsite/internal"
-	"golang.org/x/pkgsite/internal/derrors"
-	"golang.org/x/pkgsite/internal/log"
-	"golang.org/x/pkgsite/internal/stdlib"
-)
-
-// legacyServeModulePage serves details pages for the module specified by modulePath
-// and version.
-func (s *Server) legacyServeModulePage(w http.ResponseWriter, r *http.Request, ds internal.DataSource, modulePath, requestedVersion, resolvedVersion string) error {
-	// This function handles top level behavior related to the existence of the
-	// requested modulePath@version:
-	// TODO: fix
-	//   1. If the module version exists, serve it.
-	//   2. else if we got any unexpected error, serve a server error
-	//   3. else if the error is NotFound, serve the directory page
-	//   3. else, we didn't find the module so there are two cases:
-	//     a. We don't know anything about this module: just serve a 404
-	//     b. We have valid versions for this module path, but `version` isn't
-	//        one of them. Serve a 404 but recommend the other versions.
-	ctx := r.Context()
-	mi, err := ds.LegacyGetModuleInfo(ctx, modulePath, resolvedVersion)
-	if err == nil {
-		readme := &internal.Readme{Filepath: mi.LegacyReadmeFilePath, Contents: mi.LegacyReadmeContents}
-		return s.legacyServeModulePageWithModule(ctx, w, r, ds, &mi.ModuleInfo, readme, requestedVersion)
-	}
-	if !errors.Is(err, derrors.NotFound) {
-		return err
-	}
-	if requestedVersion != internal.LatestVersion {
-		_, err = ds.LegacyGetModuleInfo(ctx, modulePath, internal.LatestVersion)
-		if err == nil {
-			return legacyPathFoundAtLatestError("module", modulePath, displayVersion(requestedVersion, modulePath))
-		}
-		if !errors.Is(err, derrors.NotFound) {
-			log.Errorf(ctx, "error checking for latest module: %v", err)
-		}
-	}
-	return pathNotFoundError(modulePath, requestedVersion)
-}
-
-func (s *Server) legacyServeModulePageWithModule(ctx context.Context, w http.ResponseWriter, r *http.Request, ds internal.DataSource,
-	mi *internal.ModuleInfo, readme *internal.Readme, requestedVersion string) error {
-	licenses, err := ds.LegacyGetLicenses(ctx, mi.ModulePath, mi.ModulePath, mi.Version)
-	if err != nil {
-		return err
-	}
-	modHeader := createModule(mi, licensesToMetadatas(licenses), requestedVersion == internal.LatestVersion)
-	tab := r.FormValue("tab")
-	settings, ok := moduleTabLookup[tab]
-	if !ok {
-		tab = tabOverview
-		settings = moduleTabLookup[tabOverview]
-	}
-	canShowDetails := modHeader.IsRedistributable || settings.AlwaysShowDetails
-	var details interface{}
-	if canShowDetails {
-		var err error
-		details, err = legacyFetchDetailsForModule(r, tab, ds, mi, licenses, readme)
-		if err != nil {
-			return fmt.Errorf("error fetching page for %q: %v", tab, err)
-		}
-	}
-	pageType := pageTypeModule
-	if mi.ModulePath == stdlib.ModulePath {
-		pageType = pageTypeStdLib
-	}
-
-	page := &DetailsPage{
-		basePage:       s.newBasePage(r, moduleHTMLTitle(mi.ModulePath)),
-		Name:           mi.ModulePath,
-		Settings:       settings,
-		Header:         modHeader,
-		Breadcrumb:     breadcrumbPath(modHeader.ModulePath, modHeader.ModulePath, modHeader.LinkVersion),
-		Details:        details,
-		CanShowDetails: canShowDetails,
-		Tabs:           moduleTabSettings,
-		PageType:       pageType,
-		CanonicalURLPath: constructModuleURL(
-			mi.ModulePath,
-			linkVersion(mi.Version, mi.ModulePath),
-		),
-	}
-	s.servePage(ctx, w, settings.TemplateName, page)
-	return nil
-}
diff --git a/internal/frontend/legacy_package.go b/internal/frontend/legacy_package.go
deleted file mode 100644
index 04bb5e9..0000000
--- a/internal/frontend/legacy_package.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package frontend
-
-import (
-	"errors"
-	"fmt"
-	"net/http"
-	"strings"
-
-	"github.com/google/safehtml/template"
-	"golang.org/x/pkgsite/internal"
-	"golang.org/x/pkgsite/internal/derrors"
-	"golang.org/x/pkgsite/internal/log"
-)
-
-// legacyServePackagePage serves details pages for the package with import path
-// pkgPath, in the module specified by modulePath and version.
-func (s *Server) legacyServePackagePage(w http.ResponseWriter, r *http.Request, ds internal.DataSource, pkgPath, modulePath, requestedVersion, resolvedVersion string) (err error) {
-	ctx := r.Context()
-
-	// This function handles top level behavior related to the existence of the
-	// requested pkgPath@version.
-	//   1. If a package exists at this version, serve it.
-	//   2. If there is a directory at this version, serve it.
-	//   3. If there is another version that contains this package path: serve a
-	//      404 and suggest these versions.
-	//   4. Just serve a 404
-	pkg, err := ds.LegacyGetPackage(ctx, pkgPath, modulePath, resolvedVersion)
-	if err == nil {
-		return s.legacyServePackagePageWithPackage(w, r, ds, pkg, requestedVersion)
-	}
-	if !errors.Is(err, derrors.NotFound) {
-		return err
-	}
-	if requestedVersion == internal.LatestVersion {
-		// If we've already checked the latest version, then we know that this path
-		// is not a package at any version, so just skip ahead and serve the
-		// directory page.
-		dbDir, err := ds.LegacyGetDirectory(ctx, pkgPath, modulePath, resolvedVersion, internal.AllFields)
-		if err != nil {
-			if errors.Is(err, derrors.NotFound) {
-				return pathNotFoundError(pkgPath, requestedVersion)
-			}
-			return err
-		}
-		return s.legacyServeDirectoryPage(ctx, w, r, ds, dbDir, requestedVersion)
-	}
-	dir, err := ds.LegacyGetDirectory(ctx, pkgPath, modulePath, resolvedVersion, internal.AllFields)
-	if err == nil {
-		return s.legacyServeDirectoryPage(ctx, w, r, ds, dir, requestedVersion)
-	}
-	if !errors.Is(err, derrors.NotFound) {
-		// The only error we expect is NotFound, so serve an 500 here, otherwise
-		// whatever response we resolve below might be inconsistent or misleading.
-		return fmt.Errorf("checking for directory: %v", err)
-	}
-	_, err = ds.LegacyGetPackage(ctx, pkgPath, modulePath, internal.LatestVersion)
-	if err == nil {
-		return legacyPathFoundAtLatestError("package", pkgPath, requestedVersion)
-	}
-	if !errors.Is(err, derrors.NotFound) {
-		// Unlike the error handling for LegacyGetDirectory above, we don't serve an
-		// InternalServerError here. The reasoning for this is that regardless of
-		// the result of LegacyGetPackage(..., "latest"), we're going to serve a NotFound
-		// response code. So the semantics of the endpoint are the same whether or
-		// not we get an unexpected error from GetPackage -- we just don't serve a
-		// more informative error response.
-		log.Errorf(ctx, "error checking for latest package: %v", err)
-		return nil
-	}
-	return pathNotFoundError(pkgPath, requestedVersion)
-}
-
-func (s *Server) legacyServePackagePageWithPackage(w http.ResponseWriter, r *http.Request, ds internal.DataSource, pkg *internal.LegacyVersionedPackage, requestedVersion string) (err error) {
-	defer func() {
-		if _, ok := err.(*serverError); !ok {
-			derrors.Wrap(&err, "legacyServePackagePageWithPackage(w, r, %q, %q, %q)", pkg.Path, pkg.ModulePath, requestedVersion)
-		}
-	}()
-	pkgHeader, err := createPackage(
-		packageMetaFromLegacyPackage(&pkg.LegacyPackage),
-		&pkg.ModuleInfo,
-		requestedVersion == internal.LatestVersion)
-	if err != nil {
-		return fmt.Errorf("creating package header for %s@%s: %v", pkg.Path, pkg.Version, err)
-	}
-
-	settings, err := packageSettings(r.FormValue("tab"))
-	if err != nil {
-		http.Redirect(w, r, r.URL.Path, http.StatusFound)
-		return nil
-	}
-	canShowDetails := pkg.LegacyPackage.IsRedistributable || settings.AlwaysShowDetails
-
-	var details interface{}
-	if canShowDetails {
-		var err error
-		details, err = legacyFetchDetailsForPackage(r, settings.Name, ds, pkg)
-		if err != nil {
-			return fmt.Errorf("fetching page for %q: %v", settings.Name, err)
-		}
-	}
-
-	var (
-		pageType = pageTypePackage
-		pageName = pkg.Name
-	)
-	if pkg.Name == "main" {
-		pageName = effectiveName(pkg.Path, pkg.Name)
-		pageType = pageTypeCommand
-	}
-	page := &DetailsPage{
-		basePage: s.newBasePage(r, packageHTMLTitle(pkg.Path, pkg.Name)),
-		Name:     pageName,
-		Settings: *settings,
-		Header:   pkgHeader,
-		Breadcrumb: breadcrumbPath(pkgHeader.Path, pkgHeader.Module.ModulePath,
-			pkgHeader.Module.LinkVersion),
-		Details:        details,
-		CanShowDetails: canShowDetails,
-		Tabs:           packageTabSettings,
-		PageType:       pageType,
-		CanonicalURLPath: constructPackageURL(
-			pkg.Path,
-			pkg.ModulePath,
-			linkVersion(pkg.Version, pkg.ModulePath),
-		),
-	}
-	page.basePage.AllowWideContent = settings.Name == tabDoc
-	s.servePage(r.Context(), w, settings.TemplateName, page)
-	return nil
-}
-
-// packageMetaFromLegacyPackage returns a PackageMeta based on data from a
-// LegacyPackage.
-func packageMetaFromLegacyPackage(pkg *internal.LegacyPackage) *internal.PackageMeta {
-	return &internal.PackageMeta{
-		Path:              pkg.Path,
-		IsRedistributable: pkg.IsRedistributable,
-		Name:              pkg.Name,
-		Synopsis:          pkg.Synopsis,
-		Licenses:          pkg.Licenses,
-	}
-}
-
-// legacyPathFoundAtLatestError returns an error page when the fullPath exists, but
-// the version that is requested does not.
-func legacyPathFoundAtLatestError(pathType, fullPath, requestedVersion string) error {
-	return &serverError{
-		status: http.StatusNotFound,
-		epage: &errorPage{
-			messageTemplate: template.MakeTrustedTemplate(`
-				<h3 class="Error-message">{{.TType}} {{.Path}}@{{.Version}} is not available.</h3>
-				<p class="Error-message">
-				  There are other versions of this {{.Type}} that are! To view them,
-				  <a href="/{{.Path}}?tab=versions">click here</a>.
-				</p>`),
-			MessageData: struct{ TType, Type, Path, Version string }{
-				strings.Title(pathType), pathType, fullPath, displayVersion(requestedVersion, fullPath)},
-		},
-	}
-}
diff --git a/internal/frontend/legacy_tabs.go b/internal/frontend/legacy_tabs.go
deleted file mode 100644
index cf2e2cf..0000000
--- a/internal/frontend/legacy_tabs.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package frontend
-
-import (
-	"fmt"
-	"net/http"
-
-	"golang.org/x/pkgsite/internal"
-	"golang.org/x/pkgsite/internal/licenses"
-	"golang.org/x/pkgsite/internal/postgres"
-)
-
-// legacyFetchDetailsForModule returns tab details by delegating to the correct detail
-// handler.
-func legacyFetchDetailsForModule(r *http.Request, tab string, ds internal.DataSource, mi *internal.ModuleInfo, licenses []*licenses.License, readme *internal.Readme) (interface{}, error) {
-	ctx := r.Context()
-	switch tab {
-	case "packages":
-		return legacyFetchDirectoryDetails(ctx, ds, mi.ModulePath, mi, licensesToMetadatas(licenses), true)
-	case tabLicenses:
-		return &LicensesDetails{Licenses: transformLicenses(mi.ModulePath, mi.Version, licenses)}, nil
-	case tabVersions:
-		return fetchModuleVersionsDetails(ctx, ds, mi.ModulePath)
-	case tabOverview:
-		return constructOverviewDetails(ctx, mi, readme, mi.IsRedistributable, urlIsVersioned(r.URL))
-	}
-	return nil, fmt.Errorf("BUG: unable to fetch details: unknown tab %q", tab)
-}
-
-// legacyFetchDetailsForDirectory returns tab details by delegating to the correct
-// detail handler.
-func legacyFetchDetailsForDirectory(r *http.Request, tab string, dir *internal.LegacyDirectory, licenses []*licenses.License) (interface{}, error) {
-	switch tab {
-	case tabOverview:
-		readme := &internal.Readme{Filepath: dir.LegacyReadmeFilePath, Contents: dir.LegacyReadmeContents}
-		return constructOverviewDetails(r.Context(), &dir.ModuleInfo, readme, dir.LegacyModuleInfo.IsRedistributable, urlIsVersioned(r.URL))
-	case tabSubdirectories:
-		// Ideally we would just use fetchDirectoryDetails here so that it
-		// follows the same code path as fetchDetailsForModule and
-		// fetchDetailsForPackage. However, since we already have the directory
-		// and licenses info, it doesn't make sense to call
-		// postgres.GetUnit again.
-		return legacyCreateDirectory(dir, licensesToMetadatas(licenses), false)
-	case tabLicenses:
-		return &LicensesDetails{Licenses: transformLicenses(dir.ModulePath, dir.Version, licenses)}, nil
-	}
-	return nil, fmt.Errorf("BUG: unable to fetch details: unknown tab %q", tab)
-}
-
-// legacyFetchDetailsForPackage returns tab details by delegating to the correct detail
-// handler.
-func legacyFetchDetailsForPackage(r *http.Request, tab string, ds internal.DataSource, pkg *internal.LegacyVersionedPackage) (interface{}, error) {
-	ctx := r.Context()
-	switch tab {
-	case tabDoc:
-		return legacyFetchDocumentationDetails(pkg), nil
-	case tabVersions:
-		return legacyFetchPackageVersionsDetails(ctx, ds, pkg.Path, pkg.V1Path, pkg.ModulePath)
-	case tabSubdirectories:
-		return legacyFetchDirectoryDetails(ctx, ds, pkg.Path, &pkg.ModuleInfo, pkg.Licenses, false)
-	case tabImports:
-		return fetchImportsDetails(ctx, ds, pkg.Path, pkg.ModulePath, pkg.Version)
-	case tabImportedBy:
-		db, ok := ds.(*postgres.DB)
-		if !ok {
-			// The proxydatasource does not support the imported by page.
-			return nil, proxydatasourceNotSupportedErr()
-		}
-		return fetchImportedByDetails(ctx, db, pkg.Path, pkg.ModulePath)
-	case tabLicenses:
-		return legacyFetchPackageLicensesDetails(ctx, ds, pkg.Path, pkg.ModulePath, pkg.Version)
-	case tabOverview:
-		return legacyFetchPackageOverviewDetails(ctx, pkg, urlIsVersioned(r.URL))
-	}
-	return nil, fmt.Errorf("BUG: unable to fetch details: unknown tab %q", tab)
-}
diff --git a/internal/frontend/license.go b/internal/frontend/license.go
index 7fcf377..7dfeff7 100644
--- a/internal/frontend/license.go
+++ b/internal/frontend/license.go
@@ -103,12 +103,3 @@
 	}
 	return ids
 }
-
-// licensesToMetadatas converts a slice of Licenses to a slice of Metadatas.
-func licensesToMetadatas(lics []*licenses.License) []*licenses.Metadata {
-	var ms []*licenses.Metadata
-	for _, l := range lics {
-		ms = append(ms, l.Metadata)
-	}
-	return ms
-}
diff --git a/internal/frontend/versions_test.go b/internal/frontend/versions_test.go
index e00fe95..9965ca9 100644
--- a/internal/frontend/versions_test.go
+++ b/internal/frontend/versions_test.go
@@ -264,24 +264,13 @@
 				}
 			}
 
-			t.Run("use-directories", func(t *testing.T) {
-				got, err := fetchVersionsDetails(ctx, testDB, tc.pkg.Path, tc.pkg.ModulePath)
-				if err != nil {
-					t.Fatalf("fetchVersionsDetails(ctx, db, %q, %q): %v", tc.pkg.Path, tc.pkg.ModulePath, err)
-				}
-				if diff := cmp.Diff(tc.wantDetails, got); diff != "" {
-					t.Errorf("mismatch (-want +got):\n%s", diff)
-				}
-			})
-			t.Run("no-experiments", func(t *testing.T) {
-				got, err := legacyFetchPackageVersionsDetails(ctx, testDB, tc.pkg.Path, tc.pkg.V1Path, tc.pkg.ModulePath)
-				if err != nil {
-					t.Fatalf("legacyFetchPackageVersionsDetails(ctx, db, %q, %q, %q): %v", tc.pkg.Path, tc.pkg.V1Path, tc.pkg.ModulePath, err)
-				}
-				if diff := cmp.Diff(tc.wantDetails, got); diff != "" {
-					t.Errorf("mismatch (-want +got):\n%s", diff)
-				}
-			})
+			got, err := fetchVersionsDetails(ctx, testDB, tc.pkg.Path, tc.pkg.ModulePath)
+			if err != nil {
+				t.Fatalf("fetchVersionsDetails(ctx, db, %q, %q): %v", tc.pkg.Path, tc.pkg.ModulePath, err)
+			}
+			if diff := cmp.Diff(tc.wantDetails, got); diff != "" {
+				t.Errorf("mismatch (-want +got):\n%s", diff)
+			}
 		})
 	}
 }