@@ -15,6 +15,63 @@ import (
15
15
"golang.org/x/mod/semver"
16
16
)
17
17
18
+ // Confirm that all specified versions of a package exist in a registry
19
+ func versionsExistInGeneric (
20
+ pkg string ,
21
+ versions []string ,
22
+ eco string ,
23
+ packageInstanceURL string ,
24
+ releasesPath string ,
25
+ versionsPath string ,
26
+ ) error {
27
+ resp , err := faulttolerant .Get (packageInstanceURL )
28
+ if err != nil {
29
+ return fmt .Errorf ("unable to validate package: %v" , err )
30
+ }
31
+ defer resp .Body .Close ()
32
+ if resp .StatusCode != http .StatusOK {
33
+ return fmt .Errorf ("unable to validate package: %q for %s" , resp .Status , packageInstanceURL )
34
+ }
35
+
36
+ // Parse the known versions from the JSON.
37
+ respJSON , err := io .ReadAll (resp .Body )
38
+ if err != nil {
39
+ return fmt .Errorf ("unable to retrieve JSON for %q: %v" , pkg , err )
40
+ }
41
+ // Fetch all known versions of package.
42
+ versionsInRepository := []string {}
43
+ releases := gjson .GetBytes (respJSON , releasesPath )
44
+ releases .ForEach (func (key , value gjson.Result ) bool {
45
+ versionsInRepository = append (versionsInRepository , value .Get (versionsPath ).String ())
46
+ return true // keep iterating.
47
+ })
48
+ // Determine which referenced versions are missing.
49
+ versionsMissing := []string {}
50
+ for _ , versionToCheckFor := range versions {
51
+ versionFound := false
52
+ vc , err := semantic .Parse (versionToCheckFor , "npm" )
53
+ if err != nil {
54
+ versionsMissing = append (versionsMissing , versionToCheckFor )
55
+ continue
56
+ }
57
+ for _ , pkgversion := range versionsInRepository {
58
+ if r , err := vc .CompareStr (pkgversion ); r == 0 && err == nil {
59
+ versionFound = true
60
+ break
61
+ }
62
+ }
63
+ if versionFound {
64
+ continue
65
+ }
66
+ versionsMissing = append (versionsMissing , versionToCheckFor )
67
+ }
68
+ if len (versionsMissing ) > 0 {
69
+ return & MissingVersionsError {Package : pkg , Ecosystem : eco , Missing : versionsMissing , Known : versionsInRepository }
70
+ }
71
+
72
+ return nil
73
+ }
74
+
18
75
// Confirm that all specified versions of a package exist in Go.
19
76
func versionsExistInGo (pkg string , versions []string ) error {
20
77
if pkg == "stdlib" || pkg == "toolchain" {
@@ -133,52 +190,12 @@ func goVersionsExist(versions []string) error {
133
190
func versionsExistInPackagist (pkg string , versions []string ) error {
134
191
packageInstanceURL := fmt .Sprintf ("%s/%s.json" , EcosystemBaseURLs ["Packagist" ], pkg )
135
192
136
- resp , err := faulttolerant .Get (packageInstanceURL )
137
- if err != nil {
138
- return fmt .Errorf ("unable to validate package: %v" , err )
139
- }
140
- defer resp .Body .Close ()
141
- if resp .StatusCode != http .StatusOK {
142
- return fmt .Errorf ("unable to validate package: %q for %s" , resp .Status , packageInstanceURL )
143
- }
144
-
145
- // Parse the known versions from the JSON.
146
- respJSON , err := io .ReadAll (resp .Body )
147
- if err != nil {
148
- return fmt .Errorf ("unable to retrieve JSON for %q: %v" , pkg , err )
149
- }
150
- // Fetch all known versions of package.
151
- versionsInRepository := []string {}
152
- releases := gjson .GetBytes (respJSON , fmt .Sprintf ("packages.%s" , pkg ))
153
- releases .ForEach (func (key , value gjson.Result ) bool {
154
- versionsInRepository = append (versionsInRepository , value .Get ("version" ).String ())
155
- return true // keep iterating.
156
- })
157
- // Determine which referenced versions are missing.
158
- versionsMissing := []string {}
159
- for _ , versionToCheckFor := range versions {
160
- versionFound := false
161
- vc , err := semantic .Parse (versionToCheckFor , "Packagist" )
162
- if err != nil {
163
- versionsMissing = append (versionsMissing , versionToCheckFor )
164
- continue
165
- }
166
- for _ , pkgversion := range versionsInRepository {
167
- if r , err := vc .CompareStr (pkgversion ); r == 0 && err == nil {
168
- versionFound = true
169
- break
170
- }
171
- }
172
- if versionFound {
173
- continue
174
- }
175
- versionsMissing = append (versionsMissing , versionToCheckFor )
176
- }
177
- if len (versionsMissing ) > 0 {
178
- return & MissingVersionsError {Package : pkg , Ecosystem : "Packagist" , Missing : versionsMissing , Known : versionsInRepository }
179
- }
180
-
181
- return nil
193
+ return versionsExistInGeneric (
194
+ pkg , versions ,
195
+ "Packagist" ,
196
+ packageInstanceURL ,
197
+ fmt .Sprintf ("packages.%s" , pkg ), "version" ,
198
+ )
182
199
}
183
200
184
201
// Confirm that all specified versions of a package exist in PyPI.
@@ -188,103 +205,22 @@ func versionsExistInPyPI(pkg string, versions []string) error {
188
205
pkgNormalized := strings .ToLower (pythonNormalizationRegex .ReplaceAllString (pkg , "-" ))
189
206
packageInstanceURL := fmt .Sprintf ("%s/%s/json" , EcosystemBaseURLs ["PyPI" ], pkgNormalized )
190
207
191
- // This 404's for non-existent packages.
192
- resp , err := faulttolerant .Get (packageInstanceURL )
193
- if err != nil {
194
- return fmt .Errorf ("unable to validate package: %v" , err )
195
- }
196
- defer resp .Body .Close ()
197
- if resp .StatusCode != http .StatusOK {
198
- return fmt .Errorf ("unable to validate package: %q for %s" , resp .Status , packageInstanceURL )
199
- }
200
-
201
- // Parse the known versions from the JSON.
202
- respJSON , err := io .ReadAll (resp .Body )
203
- if err != nil {
204
- return fmt .Errorf ("unable to retrieve JSON for %q: %v" , pkg , err )
205
- }
206
- // Fetch all known versions of package.
207
- versionsInPyPy := []string {}
208
- releases := gjson .GetBytes (respJSON , "releases.@keys" )
209
- releases .ForEach (func (key , value gjson.Result ) bool {
210
- versionsInPyPy = append (versionsInPyPy , value .String ())
211
- return true // keep iterating.
212
- })
213
- // Determine which referenced versions are missing.
214
- versionsMissing := []string {}
215
- for _ , versionToCheckFor := range versions {
216
- versionFound := false
217
- vc , err := semantic .Parse (versionToCheckFor , "PyPI" )
218
- if err != nil {
219
- versionsMissing = append (versionsMissing , versionToCheckFor )
220
- continue
221
- }
222
- for _ , pkgversion := range versionsInPyPy {
223
- if r , err := vc .CompareStr (pkgversion ); r == 0 && err == nil {
224
- versionFound = true
225
- break
226
- }
227
- }
228
- if versionFound {
229
- continue
230
- }
231
- versionsMissing = append (versionsMissing , versionToCheckFor )
232
- }
233
- if len (versionsMissing ) > 0 {
234
- return & MissingVersionsError {Package : pkg , Ecosystem : "PyPI" , Missing : versionsMissing , Known : versionsInPyPy }
235
- }
236
-
237
- return nil
208
+ return versionsExistInGeneric (
209
+ pkg , versions ,
210
+ "PyPI" ,
211
+ packageInstanceURL ,
212
+ "releases.@keys" , "@this" ,
213
+ )
238
214
}
239
215
240
216
// Confirm that all specified versions of a package exist in RubyGems.
241
217
func versionsExistInRubyGems (pkg string , versions []string ) error {
242
218
packageInstanceURL := fmt .Sprintf ("%s/versions/%s.json" , EcosystemBaseURLs ["RubyGems" ], pkg )
243
219
244
- resp , err := faulttolerant .Get (packageInstanceURL )
245
- if err != nil {
246
- return fmt .Errorf ("unable to validate package: %v" , err )
247
- }
248
- defer resp .Body .Close ()
249
- if resp .StatusCode != http .StatusOK {
250
- return fmt .Errorf ("unable to validate package: %q for %s" , resp .Status , packageInstanceURL )
251
- }
252
-
253
- // Parse the known versions from the JSON.
254
- respJSON , err := io .ReadAll (resp .Body )
255
- if err != nil {
256
- return fmt .Errorf ("unable to retrieve JSON for %q: %v" , pkg , err )
257
- }
258
- // Fetch all known versions of package.
259
- versionsInRepository := []string {}
260
- releases := gjson .GetBytes (respJSON , "@this" )
261
- releases .ForEach (func (key , value gjson.Result ) bool {
262
- versionsInRepository = append (versionsInRepository , value .Get ("number" ).String ())
263
- return true // keep iterating.
264
- })
265
- // Determine which referenced versions are missing.
266
- versionsMissing := []string {}
267
- for _ , versionToCheckFor := range versions {
268
- versionFound := false
269
- vc , err := semantic .Parse (versionToCheckFor , "RubyGems" )
270
- if err != nil {
271
- versionsMissing = append (versionsMissing , versionToCheckFor )
272
- continue
273
- }
274
- for _ , pkgversion := range versionsInRepository {
275
- if r , err := vc .CompareStr (pkgversion ); r == 0 && err == nil {
276
- versionFound = true
277
- break
278
- }
279
- }
280
- if versionFound {
281
- continue
282
- }
283
- versionsMissing = append (versionsMissing , versionToCheckFor )
284
- }
285
- if len (versionsMissing ) > 0 {
286
- return & MissingVersionsError {Package : pkg , Ecosystem : "RubyGems" , Missing : versionsMissing , Known : versionsInRepository }
287
- }
288
-
289
- return nil
220
+ return versionsExistInGeneric (
221
+ pkg , versions ,
222
+ "RubyGems" ,
223
+ packageInstanceURL ,
224
+ "@this" , "number" ,
225
+ )
290
226
}
0 commit comments