Skip to content

Commit 3f3c89d

Browse files
committed
internal/datasource: consolidate
Merge ProxyDataSource and LocalDataSource into a single type, DataSource. Combine and simplify tests. For golang/go#47780 Change-Id: I3510fee3a3d786705a2306a6233b352e5af40076 Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/344952 Trust: Jonathan Amsterdam <[email protected]> Run-TryBot: Jonathan Amsterdam <[email protected]> TryBot-Result: kokoro <[email protected]> Reviewed-by: Julie Qiu <[email protected]>
1 parent ec70ff3 commit 3f3c89d

File tree

10 files changed

+598
-748
lines changed

10 files changed

+598
-748
lines changed

cmd/frontend/main.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"golang.org/x/pkgsite/internal/config"
2121
"golang.org/x/pkgsite/internal/datasource"
2222
"golang.org/x/pkgsite/internal/dcensus"
23+
"golang.org/x/pkgsite/internal/fetch"
2324
"golang.org/x/pkgsite/internal/frontend"
2425
"golang.org/x/pkgsite/internal/log"
2526
"golang.org/x/pkgsite/internal/middleware"
@@ -76,13 +77,13 @@ func main() {
7677
}
7778

7879
if *directProxy {
79-
var pds *datasource.ProxyDataSource
80-
if *bypassLicenseCheck {
81-
pds = datasource.NewBypassingLicenseCheck(proxyClient)
82-
} else {
83-
pds = datasource.NewProxy(proxyClient)
84-
}
85-
dsg = func(context.Context) internal.DataSource { return pds }
80+
ds := datasource.Options{
81+
Getters: []fetch.ModuleGetter{fetch.NewProxyModuleGetter(proxyClient)},
82+
ProxyClientForLatest: proxyClient,
83+
BypassLicenseCheck: *bypassLicenseCheck,
84+
SourceClient: source.NewClient(1 * time.Minute),
85+
}.New()
86+
dsg = func(context.Context) internal.DataSource { return ds }
8687
} else {
8788
db, err := cmdconfig.OpenDB(ctx, cfg, *bypassLicenseCheck)
8889
if err != nil {

cmd/pkgsite/main.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ func main() {
6868

6969
func newServer(ctx context.Context, paths []string, gopathMode bool) (*frontend.Server, error) {
7070
getters := buildGetters(ctx, paths, gopathMode)
71-
lds := datasource.NewLocal(getters, source.NewClient(time.Second))
71+
lds := datasource.Options{
72+
Getters: getters,
73+
SourceClient: source.NewClient(time.Second),
74+
BypassLicenseCheck: true,
75+
}.New()
7276
server, err := frontend.NewServer(frontend.ServerConfig{
7377
DataSourceGetter: func(context.Context) internal.DataSource { return lds },
7478
StaticPath: template.TrustedSourceFromFlag(flag.Lookup("static").Value),

internal/datasource/datasource.go

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,38 @@ import (
2626
"golang.org/x/pkgsite/internal/version"
2727
)
2828

29-
// dataSource implements the internal.DataSource interface, by trying a list of
29+
// DataSource implements the internal.DataSource interface, by trying a list of
3030
// fetch.ModuleGetters to fetch modules and caching the results.
31-
type dataSource struct {
32-
getters []fetch.ModuleGetter
33-
sourceClient *source.Client
34-
bypassLicenseCheck bool
35-
cache *lru.Cache
36-
prox *proxy.Client // used for latest-version info only
31+
type DataSource struct {
32+
opts Options
33+
cache *lru.Cache
34+
}
3735

36+
// Options are parameters for creating a new DataSource.
37+
type Options struct {
38+
// List of getters to try, in order.
39+
Getters []fetch.ModuleGetter
40+
// If set, this will be used for latest-version information. To fetch modules from the proxy,
41+
// include a ProxyModuleGetter in Getters.
42+
ProxyClientForLatest *proxy.Client
43+
SourceClient *source.Client
44+
BypassLicenseCheck bool
3845
}
3946

40-
func newDataSource(getters []fetch.ModuleGetter, sc *source.Client, bypassLicenseCheck bool, prox *proxy.Client) *dataSource {
47+
// New creates a new DataSource from the options.
48+
func (o Options) New() *DataSource {
4149
cache, err := lru.New(maxCachedModules)
4250
if err != nil {
43-
// Can only happen if size is bad.
51+
// Can only happen if size is bad, and we control it.
4452
panic(err)
4553
}
46-
return &dataSource{
47-
getters: getters,
48-
sourceClient: sc,
49-
bypassLicenseCheck: bypassLicenseCheck,
50-
cache: cache,
51-
prox: prox,
54+
opts := o
55+
// Copy getters slice so caller doesn't modify us.
56+
opts.Getters = make([]fetch.ModuleGetter, len(opts.Getters))
57+
copy(opts.Getters, o.Getters)
58+
return &DataSource{
59+
opts: opts,
60+
cache: cache,
5261
}
5362
}
5463

@@ -61,7 +70,7 @@ type cacheEntry struct {
6170
const maxCachedModules = 100
6271

6372
// cacheGet returns information from the cache if it is present, and (nil, nil) otherwise.
64-
func (ds *dataSource) cacheGet(path, version string) (*internal.Module, error) {
73+
func (ds *DataSource) cacheGet(path, version string) (*internal.Module, error) {
6574
// Look for an exact match first, then use LocalVersion, as for a
6675
// directory-based or GOPATH-mode module.
6776
for _, v := range []string{version, fetch.LocalVersion} {
@@ -74,13 +83,13 @@ func (ds *dataSource) cacheGet(path, version string) (*internal.Module, error) {
7483
}
7584

7685
// cachePut puts information into the cache.
77-
func (ds *dataSource) cachePut(path, version string, m *internal.Module, err error) {
86+
func (ds *DataSource) cachePut(path, version string, m *internal.Module, err error) {
7887
ds.cache.Add(internal.Modver{Path: path, Version: version}, cacheEntry{m, err})
7988
}
8089

8190
// getModule gets the module at the given path and version. It first checks the
8291
// cache, and if it isn't there it then tries to fetch it.
83-
func (ds *dataSource) getModule(ctx context.Context, modulePath, version string) (_ *internal.Module, err error) {
92+
func (ds *DataSource) getModule(ctx context.Context, modulePath, version string) (_ *internal.Module, err error) {
8493
defer derrors.Wrap(&err, "getModule(%q, %q)", modulePath, version)
8594

8695
mod, err := ds.cacheGet(modulePath, version)
@@ -92,10 +101,10 @@ func (ds *dataSource) getModule(ctx context.Context, modulePath, version string)
92101
// module. At worst some work will be duplicated, but if that turns out to
93102
// be a problem we could use golang.org/x/sync/singleflight.
94103
m, err := ds.fetch(ctx, modulePath, version)
95-
if m != nil && ds.prox != nil {
104+
if m != nil && ds.opts.ProxyClientForLatest != nil {
96105
// Use the go.mod file at the raw latest version to fill in deprecation
97106
// and retraction information.
98-
lmv, err2 := fetch.LatestModuleVersions(ctx, modulePath, ds.prox, nil)
107+
lmv, err2 := fetch.LatestModuleVersions(ctx, modulePath, ds.opts.ProxyClientForLatest, nil)
99108
if err2 != nil {
100109
err = err2
101110
} else {
@@ -112,18 +121,18 @@ func (ds *dataSource) getModule(ctx context.Context, modulePath, version string)
112121

113122
// fetch fetches a module using the configured ModuleGetters.
114123
// It tries each getter in turn until it finds one that has the module.
115-
func (ds *dataSource) fetch(ctx context.Context, modulePath, version string) (_ *internal.Module, err error) {
124+
func (ds *DataSource) fetch(ctx context.Context, modulePath, version string) (_ *internal.Module, err error) {
116125
log.Infof(ctx, "DataSource: fetching %s@%s", modulePath, version)
117126
start := time.Now()
118127
defer func() {
119128
log.Infof(ctx, "DataSource: fetched %s@%s in %s with error %v", modulePath, version, time.Since(start), err)
120129
}()
121-
for _, g := range ds.getters {
122-
fr := fetch.FetchModule(ctx, modulePath, version, g, ds.sourceClient)
130+
for _, g := range ds.opts.Getters {
131+
fr := fetch.FetchModule(ctx, modulePath, version, g, ds.opts.SourceClient)
123132
defer fr.Defer()
124133
if fr.Error == nil {
125134
m := fr.Module
126-
if ds.bypassLicenseCheck {
135+
if ds.opts.BypassLicenseCheck {
127136
m.IsRedistributable = true
128137
for _, unit := range m.Units {
129138
unit.IsRedistributable = true
@@ -142,7 +151,7 @@ func (ds *dataSource) fetch(ctx context.Context, modulePath, version string) (_
142151

143152
// findModule finds the module with longest module path containing the given
144153
// package path. It returns an error if no module is found.
145-
func (ds *dataSource) findModule(ctx context.Context, pkgPath, modulePath, version string) (_ *internal.Module, err error) {
154+
func (ds *DataSource) findModule(ctx context.Context, pkgPath, modulePath, version string) (_ *internal.Module, err error) {
146155
defer derrors.Wrap(&err, "findModule(%q, %q, %q)", pkgPath, modulePath, version)
147156

148157
if modulePath != internal.UnknownModulePath {
@@ -162,7 +171,7 @@ func (ds *dataSource) findModule(ctx context.Context, pkgPath, modulePath, versi
162171
}
163172

164173
// GetUnitMeta returns information about a path.
165-
func (ds *dataSource) GetUnitMeta(ctx context.Context, path, requestedModulePath, requestedVersion string) (_ *internal.UnitMeta, err error) {
174+
func (ds *DataSource) GetUnitMeta(ctx context.Context, path, requestedModulePath, requestedVersion string) (_ *internal.UnitMeta, err error) {
166175
defer derrors.Wrap(&err, "GetUnitMeta(%q, %q, %q)", path, requestedModulePath, requestedVersion)
167176

168177
module, err := ds.findModule(ctx, path, requestedModulePath, requestedVersion)
@@ -182,7 +191,7 @@ func (ds *dataSource) GetUnitMeta(ctx context.Context, path, requestedModulePath
182191

183192
// GetUnit returns information about a unit. Both the module path and package
184193
// path must be known.
185-
func (ds *dataSource) GetUnit(ctx context.Context, um *internal.UnitMeta, fields internal.FieldSet, bc internal.BuildContext) (_ *internal.Unit, err error) {
194+
func (ds *DataSource) GetUnit(ctx context.Context, um *internal.UnitMeta, fields internal.FieldSet, bc internal.BuildContext) (_ *internal.Unit, err error) {
186195
defer derrors.Wrap(&err, "GetUnit(%q, %q)", um.Path, um.ModulePath)
187196

188197
m, err := ds.getModule(ctx, um.ModulePath, um.Version)
@@ -206,10 +215,10 @@ func findUnit(m *internal.Module, path string) *internal.Unit {
206215
}
207216

208217
// GetLatestInfo returns latest information for unitPath and modulePath.
209-
func (ds *dataSource) GetLatestInfo(ctx context.Context, unitPath, modulePath string, latestUnitMeta *internal.UnitMeta) (latest internal.LatestInfo, err error) {
218+
func (ds *DataSource) GetLatestInfo(ctx context.Context, unitPath, modulePath string, latestUnitMeta *internal.UnitMeta) (latest internal.LatestInfo, err error) {
210219
defer derrors.Wrap(&err, "GetLatestInfo(ctx, %q, %q)", unitPath, modulePath)
211220

212-
if ds.prox == nil {
221+
if ds.opts.ProxyClientForLatest == nil {
213222
return internal.LatestInfo{}, nil
214223
}
215224

@@ -235,10 +244,10 @@ func (ds *dataSource) GetLatestInfo(ctx context.Context, unitPath, modulePath st
235244
// of the latest version found in the proxy by iterating through vN versions.
236245
// This function does not attempt to find whether the full path exists
237246
// in the new major version.
238-
func (ds *dataSource) getLatestMajorVersion(ctx context.Context, fullPath, modulePath string) (_ string, _ string, err error) {
247+
func (ds *DataSource) getLatestMajorVersion(ctx context.Context, fullPath, modulePath string) (_ string, _ string, err error) {
239248
// We are checking if the full path is valid so that we can forward the error if not.
240249
seriesPath := internal.SeriesPathForModule(modulePath)
241-
info, err := ds.prox.Info(ctx, seriesPath, version.Latest)
250+
info, err := ds.opts.ProxyClientForLatest.Info(ctx, seriesPath, version.Latest)
242251
if err != nil {
243252
return "", "", err
244253
}
@@ -262,7 +271,7 @@ func (ds *dataSource) getLatestMajorVersion(ctx context.Context, fullPath, modul
262271
for v := startVersion; ; v++ {
263272
query := fmt.Sprintf("%s/v%d", seriesPath, v)
264273

265-
_, err := ds.prox.Info(ctx, query, version.Latest)
274+
_, err := ds.opts.ProxyClientForLatest.Info(ctx, query, version.Latest)
266275
if errors.Is(err, derrors.NotFound) {
267276
if v == 2 {
268277
return modulePath, fullPath, nil
@@ -275,3 +284,13 @@ func (ds *dataSource) getLatestMajorVersion(ctx context.Context, fullPath, modul
275284
}
276285
}
277286
}
287+
288+
// GetNestedModules is not implemented.
289+
func (ds *DataSource) GetNestedModules(ctx context.Context, modulePath string) ([]*internal.ModuleInfo, error) {
290+
return nil, nil
291+
}
292+
293+
// GetModuleReadme is not implemented.
294+
func (*DataSource) GetModuleReadme(ctx context.Context, modulePath, resolvedVersion string) (*internal.Readme, error) {
295+
return nil, nil
296+
}

0 commit comments

Comments
 (0)