@@ -26,29 +26,38 @@ import (
26
26
"golang.org/x/pkgsite/internal/version"
27
27
)
28
28
29
- // dataSource implements the internal.DataSource interface, by trying a list of
29
+ // DataSource implements the internal.DataSource interface, by trying a list of
30
30
// 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
+ }
37
35
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
38
45
}
39
46
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 {
41
49
cache , err := lru .New (maxCachedModules )
42
50
if err != nil {
43
- // Can only happen if size is bad.
51
+ // Can only happen if size is bad, and we control it .
44
52
panic (err )
45
53
}
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 ,
52
61
}
53
62
}
54
63
@@ -61,7 +70,7 @@ type cacheEntry struct {
61
70
const maxCachedModules = 100
62
71
63
72
// 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 ) {
65
74
// Look for an exact match first, then use LocalVersion, as for a
66
75
// directory-based or GOPATH-mode module.
67
76
for _ , v := range []string {version , fetch .LocalVersion } {
@@ -74,13 +83,13 @@ func (ds *dataSource) cacheGet(path, version string) (*internal.Module, error) {
74
83
}
75
84
76
85
// 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 ) {
78
87
ds .cache .Add (internal.Modver {Path : path , Version : version }, cacheEntry {m , err })
79
88
}
80
89
81
90
// getModule gets the module at the given path and version. It first checks the
82
91
// 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 ) {
84
93
defer derrors .Wrap (& err , "getModule(%q, %q)" , modulePath , version )
85
94
86
95
mod , err := ds .cacheGet (modulePath , version )
@@ -92,10 +101,10 @@ func (ds *dataSource) getModule(ctx context.Context, modulePath, version string)
92
101
// module. At worst some work will be duplicated, but if that turns out to
93
102
// be a problem we could use golang.org/x/sync/singleflight.
94
103
m , err := ds .fetch (ctx , modulePath , version )
95
- if m != nil && ds .prox != nil {
104
+ if m != nil && ds .opts . ProxyClientForLatest != nil {
96
105
// Use the go.mod file at the raw latest version to fill in deprecation
97
106
// and retraction information.
98
- lmv , err2 := fetch .LatestModuleVersions (ctx , modulePath , ds .prox , nil )
107
+ lmv , err2 := fetch .LatestModuleVersions (ctx , modulePath , ds .opts . ProxyClientForLatest , nil )
99
108
if err2 != nil {
100
109
err = err2
101
110
} else {
@@ -112,18 +121,18 @@ func (ds *dataSource) getModule(ctx context.Context, modulePath, version string)
112
121
113
122
// fetch fetches a module using the configured ModuleGetters.
114
123
// 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 ) {
116
125
log .Infof (ctx , "DataSource: fetching %s@%s" , modulePath , version )
117
126
start := time .Now ()
118
127
defer func () {
119
128
log .Infof (ctx , "DataSource: fetched %s@%s in %s with error %v" , modulePath , version , time .Since (start ), err )
120
129
}()
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 )
123
132
defer fr .Defer ()
124
133
if fr .Error == nil {
125
134
m := fr .Module
126
- if ds .bypassLicenseCheck {
135
+ if ds .opts . BypassLicenseCheck {
127
136
m .IsRedistributable = true
128
137
for _ , unit := range m .Units {
129
138
unit .IsRedistributable = true
@@ -142,7 +151,7 @@ func (ds *dataSource) fetch(ctx context.Context, modulePath, version string) (_
142
151
143
152
// findModule finds the module with longest module path containing the given
144
153
// 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 ) {
146
155
defer derrors .Wrap (& err , "findModule(%q, %q, %q)" , pkgPath , modulePath , version )
147
156
148
157
if modulePath != internal .UnknownModulePath {
@@ -162,7 +171,7 @@ func (ds *dataSource) findModule(ctx context.Context, pkgPath, modulePath, versi
162
171
}
163
172
164
173
// 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 ) {
166
175
defer derrors .Wrap (& err , "GetUnitMeta(%q, %q, %q)" , path , requestedModulePath , requestedVersion )
167
176
168
177
module , err := ds .findModule (ctx , path , requestedModulePath , requestedVersion )
@@ -182,7 +191,7 @@ func (ds *dataSource) GetUnitMeta(ctx context.Context, path, requestedModulePath
182
191
183
192
// GetUnit returns information about a unit. Both the module path and package
184
193
// 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 ) {
186
195
defer derrors .Wrap (& err , "GetUnit(%q, %q)" , um .Path , um .ModulePath )
187
196
188
197
m , err := ds .getModule (ctx , um .ModulePath , um .Version )
@@ -206,10 +215,10 @@ func findUnit(m *internal.Module, path string) *internal.Unit {
206
215
}
207
216
208
217
// 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 ) {
210
219
defer derrors .Wrap (& err , "GetLatestInfo(ctx, %q, %q)" , unitPath , modulePath )
211
220
212
- if ds .prox == nil {
221
+ if ds .opts . ProxyClientForLatest == nil {
213
222
return internal.LatestInfo {}, nil
214
223
}
215
224
@@ -235,10 +244,10 @@ func (ds *dataSource) GetLatestInfo(ctx context.Context, unitPath, modulePath st
235
244
// of the latest version found in the proxy by iterating through vN versions.
236
245
// This function does not attempt to find whether the full path exists
237
246
// 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 ) {
239
248
// We are checking if the full path is valid so that we can forward the error if not.
240
249
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 )
242
251
if err != nil {
243
252
return "" , "" , err
244
253
}
@@ -262,7 +271,7 @@ func (ds *dataSource) getLatestMajorVersion(ctx context.Context, fullPath, modul
262
271
for v := startVersion ; ; v ++ {
263
272
query := fmt .Sprintf ("%s/v%d" , seriesPath , v )
264
273
265
- _ , err := ds .prox .Info (ctx , query , version .Latest )
274
+ _ , err := ds .opts . ProxyClientForLatest .Info (ctx , query , version .Latest )
266
275
if errors .Is (err , derrors .NotFound ) {
267
276
if v == 2 {
268
277
return modulePath , fullPath , nil
@@ -275,3 +284,13 @@ func (ds *dataSource) getLatestMajorVersion(ctx context.Context, fullPath, modul
275
284
}
276
285
}
277
286
}
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