internal/datasource: factor out everything else
Move GetLatestInfo to the shared datasource.
Remove GetModuleInfo; it was unused.
For golang/go#47780
Change-Id: I94419458f219759f83c990124d31fcfbddbb4b8e
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/344951
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/datasource/datasource.go b/internal/datasource/datasource.go
index 25181ca..34e684a 100644
--- a/internal/datasource/datasource.go
+++ b/internal/datasource/datasource.go
@@ -11,16 +11,19 @@
"context"
"errors"
"fmt"
+ "strconv"
"strings"
"time"
lru "github.com/hashicorp/golang-lru"
+ "golang.org/x/mod/semver"
"golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/derrors"
"golang.org/x/pkgsite/internal/fetch"
"golang.org/x/pkgsite/internal/log"
"golang.org/x/pkgsite/internal/proxy"
"golang.org/x/pkgsite/internal/source"
+ "golang.org/x/pkgsite/internal/version"
)
// dataSource implements the internal.DataSource interface, by trying a list of
@@ -201,3 +204,74 @@
}
return nil
}
+
+// GetLatestInfo returns latest information for unitPath and modulePath.
+func (ds *dataSource) GetLatestInfo(ctx context.Context, unitPath, modulePath string, latestUnitMeta *internal.UnitMeta) (latest internal.LatestInfo, err error) {
+ defer derrors.Wrap(&err, "GetLatestInfo(ctx, %q, %q)", unitPath, modulePath)
+
+ if ds.prox == nil {
+ return internal.LatestInfo{}, nil
+ }
+
+ if latestUnitMeta == nil {
+ latestUnitMeta, err = ds.GetUnitMeta(ctx, unitPath, internal.UnknownModulePath, version.Latest)
+ if err != nil {
+ return latest, err
+ }
+ }
+ latest.MinorVersion = latestUnitMeta.Version
+ latest.MinorModulePath = latestUnitMeta.ModulePath
+
+ latest.MajorModulePath, latest.MajorUnitPath, err = ds.getLatestMajorVersion(ctx, unitPath, modulePath)
+ if err != nil {
+ return latest, err
+ }
+ // Do not try to discover whether the unit is in the latest minor version; assume it is.
+ latest.UnitExistsAtMinor = true
+ return latest, nil
+}
+
+// getLatestMajorVersion returns the latest module path and the full package path
+// of the latest version found in the proxy by iterating through vN versions.
+// This function does not attempt to find whether the full path exists
+// in the new major version.
+func (ds *dataSource) getLatestMajorVersion(ctx context.Context, fullPath, modulePath string) (_ string, _ string, err error) {
+ // We are checking if the full path is valid so that we can forward the error if not.
+ seriesPath := internal.SeriesPathForModule(modulePath)
+ info, err := ds.prox.Info(ctx, seriesPath, version.Latest)
+ if err != nil {
+ return "", "", err
+ }
+
+ // Converting version numbers to integers may cause an overflow, as version
+ // numbers need not fit into machine integers.
+ // While using Atoi is wrong, for it to fail, the version number must reach a
+ // value higher than at least 2^31, which is unlikely.
+ startVersion, err := strconv.Atoi(strings.TrimPrefix(semver.Major(info.Version), "v"))
+ if err != nil {
+ return "", "", err
+ }
+ startVersion++
+
+ // We start checking versions from "/v2" or higher, since v1 and v0 versions
+ // don't have a major version at the end of the modulepath.
+ if startVersion < 2 {
+ startVersion = 2
+ }
+
+ for v := startVersion; ; v++ {
+ query := fmt.Sprintf("%s/v%d", seriesPath, v)
+
+ _, err := ds.prox.Info(ctx, query, version.Latest)
+ if errors.Is(err, derrors.NotFound) {
+ if v == 2 {
+ return modulePath, fullPath, nil
+ }
+ latestModulePath := fmt.Sprintf("%s/v%d", seriesPath, v-1)
+ return latestModulePath, latestModulePath, nil
+ }
+ if err != nil {
+ return "", "", err
+ }
+ }
+}
diff --git a/internal/datasource/local.go b/internal/datasource/local.go
index 2315d33..feffa36 100644
--- a/internal/datasource/local.go
+++ b/internal/datasource/local.go
@@ -71,7 +71,7 @@
// GetLatestInfo is not implemented.
func (ds *LocalDataSource) GetLatestInfo(ctx context.Context, unitPath, modulePath string, latestUnitMeta *internal.UnitMeta) (internal.LatestInfo, error) {
- return internal.LatestInfo{}, nil
+ return ds.ds.GetLatestInfo(ctx, unitPath, modulePath, latestUnitMeta)
}
// GetNestedModules is not implemented.
diff --git a/internal/datasource/proxy.go b/internal/datasource/proxy.go
index f3d08dc..bafd6d5 100644
--- a/internal/datasource/proxy.go
+++ b/internal/datasource/proxy.go
@@ -6,19 +6,12 @@
import (
"context"
- "errors"
- "fmt"
- "strconv"
- "strings"
"time"
- "golang.org/x/mod/semver"
"golang.org/x/pkgsite/internal"
- "golang.org/x/pkgsite/internal/derrors"
"golang.org/x/pkgsite/internal/fetch"
"golang.org/x/pkgsite/internal/proxy"
"golang.org/x/pkgsite/internal/source"
- "golang.org/x/pkgsite/internal/version"
)
var _ internal.DataSource = (*ProxyDataSource)(nil)
@@ -54,67 +47,5 @@
// GetLatestInfo returns latest information for unitPath and modulePath.
func (ds *ProxyDataSource) GetLatestInfo(ctx context.Context, unitPath, modulePath string, latestUnitMeta *internal.UnitMeta) (latest internal.LatestInfo, err error) {
- defer derrors.Wrap(&err, "GetLatestInfo(ctx, %q, %q)", unitPath, modulePath)
-
- if latestUnitMeta == nil {
- latestUnitMeta, err = ds.GetUnitMeta(ctx, unitPath, internal.UnknownModulePath, version.Latest)
- if err != nil {
- return latest, err
- }
- }
- latest.MinorVersion = latestUnitMeta.Version
- latest.MinorModulePath = latestUnitMeta.ModulePath
-
- latest.MajorModulePath, latest.MajorUnitPath, err = ds.getLatestMajorVersion(ctx, unitPath, modulePath)
- if err != nil {
- return latest, err
- }
- // Do not try to discover whether the unit is in the latest minor version; assume it is.
- latest.UnitExistsAtMinor = true
- return latest, nil
-}
-
-// getLatestMajorVersion returns the latest module path and the full package path
-// of the latest version found in the proxy by iterating through vN versions.
-// This function does not attempt to find whether the full path exists
-// in the new major version.
-func (ds *ProxyDataSource) getLatestMajorVersion(ctx context.Context, fullPath, modulePath string) (_ string, _ string, err error) {
- // We are checking if the full path is valid so that we can forward the error if not.
- seriesPath := internal.SeriesPathForModule(modulePath)
- info, err := ds.ds.prox.Info(ctx, seriesPath, version.Latest)
- if err != nil {
- return "", "", err
- }
-
- // Converting version numbers to integers may cause an overflow, as version
- // numbers need not fit into machine integers.
- // While using Atoi is wrong, for it to fail, the version number must reach a
- // value higher than at least 2^31, which is unlikely.
- startVersion, err := strconv.Atoi(strings.TrimPrefix(semver.Major(info.Version), "v"))
- if err != nil {
- return "", "", err
- }
- startVersion++
-
- // We start checking versions from "/v2" or higher, since v1 and v0 versions
- // don't have a major version at the end of the modulepath.
- if startVersion < 2 {
- startVersion = 2
- }
-
- for v := startVersion; ; v++ {
- query := fmt.Sprintf("%s/v%d", seriesPath, v)
-
- _, err := ds.ds.prox.Info(ctx, query, version.Latest)
- if errors.Is(err, derrors.NotFound) {
- if v == 2 {
- return modulePath, fullPath, nil
- }
- latestModulePath := fmt.Sprintf("%s/v%d", seriesPath, v-1)
- return latestModulePath, latestModulePath, nil
- }
- if err != nil {
- return "", "", err
- }
- }
+ return ds.ds.GetLatestInfo(ctx, unitPath, modulePath, latestUnitMeta)
}
diff --git a/internal/datasource/proxy_details.go b/internal/datasource/proxy_details.go
index 3d01727..77f29fa 100644
--- a/internal/datasource/proxy_details.go
+++ b/internal/datasource/proxy_details.go
@@ -17,17 +17,6 @@
return ds.ds.GetUnit(ctx, um, field, bc)
}
-// GetModuleInfo returns the ModuleInfo as fetched from the proxy for module
-// version specified by modulePath and version.
-func (ds *ProxyDataSource) GetModuleInfo(ctx context.Context, modulePath, version string) (_ *internal.ModuleInfo, err error) {
- defer derrors.Wrap(&err, "GetModuleInfo(%q, %q)", modulePath, version)
- m, err := ds.ds.getModule(ctx, modulePath, version)
- if err != nil {
- return nil, err
- }
- return &m.ModuleInfo, nil
-}
-
func (ds *ProxyDataSource) GetUnitMeta(ctx context.Context, path, requestedModulePath, requestedVersion string) (_ *internal.UnitMeta, err error) {
return ds.ds.GetUnitMeta(ctx, path, requestedModulePath, requestedVersion)
}
diff --git a/internal/datasource/proxy_test.go b/internal/datasource/proxy_test.go
index 4fcd767..9730c66 100644
--- a/internal/datasource/proxy_test.go
+++ b/internal/datasource/proxy_test.go
@@ -66,64 +66,8 @@
GOARCH: "amd64",
}},
}
- cmpOpts = append([]cmp.Option{
- cmpopts.IgnoreFields(licenses.License{}, "Contents"),
- cmpopts.IgnoreFields(internal.ModuleInfo{}, "SourceInfo"),
- }, sample.LicenseCmpOpts...)
)
-func TestGetModuleInfo(t *testing.T) {
- ctx, ds, teardown := setup(t, false)
- defer teardown()
-
- modinfo := func(m, v string) *internal.ModuleInfo {
- t.Helper()
- mi, err := ds.GetModuleInfo(ctx, m, v)
- if err != nil {
- t.Fatal(err)
- }
- return mi
- }
-
- wantModuleInfo := internal.ModuleInfo{
- ModulePath: "example.com/basic",
- Version: "v1.1.0",
- CommitTime: time.Date(2019, 1, 30, 0, 0, 0, 0, time.UTC),
- IsRedistributable: true,
- HasGoMod: true,
- }
- got := modinfo("example.com/basic", "v1.1.0")
- if diff := cmp.Diff(&wantModuleInfo, got, cmpOpts...); diff != "" {
- t.Errorf("GetModuleInfo diff (-want +got):\n%s", diff)
- }
-
- // Get v1.0.0 of a deprecated module. The deprecation comment is in
- // the latest version, v1.1.0.
- got = modinfo("example.com/deprecated", "v1.0.0")
- if !got.Deprecated {
- t.Fatal("got not deprecated, want deprecated")
- }
- if want := "use something else"; got.DeprecationComment != want {
- t.Errorf("got %q, want %q", got.DeprecationComment, want)
- }
-
- // Get v1.0.0 of a module with retractions. It should not be marked
- // retracted, even though its own go.mod says it should be, because
- // the latest go.mod does not retract it.
- if modinfo("example.com/retractions", "v1.0.0").Retracted {
- t.Fatal("got retracted, wanted false")
- }
- // v1.1.0 of the module is retracted.
- got = modinfo("example.com/retractions", "v1.1.0")
- if !got.Retracted {
- t.Fatal("got retracted false, wanted true")
- }
- if want := "worse"; got.RetractionRationale != want {
- t.Errorf("got rationale %q, want %q", got.RetractionRationale, want)
- }
-
-}
-
func TestProxyGetUnitMeta(t *testing.T) {
ctx, ds, teardown := setup(t, false)
defer teardown()