43
43
44
44
def info (url ):
45
45
"""
46
- Return data according to the `url` string
47
- `url` string can be purl too
46
+ Return package metadata for a URL or PURL.
47
+ Return None if there is no URL, or the URL or PURL is not supported.
48
48
"""
49
49
if url :
50
50
try :
@@ -86,13 +86,7 @@ def get_cargo_data_from_purl(purl):
86
86
crate = response .get ("crate" ) or {}
87
87
homepage_url = crate .get ("homepage" )
88
88
code_view_url = crate .get ("repository" )
89
- yield Package (
90
- homepage_url = homepage_url ,
91
- api_url = api_url ,
92
- code_view_url = code_view_url ,
93
- download_url = download_url ,
94
- ** purl .to_dict (),
95
- )
89
+
96
90
versions = response .get ("versions" , [])
97
91
for version in versions :
98
92
version_purl = PackageURL (type = purl .type , name = name , version = version .get ("num" ))
@@ -103,6 +97,9 @@ def get_cargo_data_from_purl(purl):
103
97
download_url = None
104
98
declared_license = version .get ("license" )
105
99
100
+ if purl .version and version_purl .version != purl .version :
101
+ continue
102
+
106
103
yield Package (
107
104
homepage_url = homepage_url ,
108
105
api_url = api_url ,
@@ -112,6 +109,9 @@ def get_cargo_data_from_purl(purl):
112
109
** version_purl .to_dict (),
113
110
)
114
111
112
+ if purl .version :
113
+ break
114
+
115
115
116
116
@router .route ("pkg:npm/.*" )
117
117
def get_npm_data_from_purl (purl ):
@@ -123,28 +123,17 @@ def get_npm_data_from_purl(purl):
123
123
name = purl .name
124
124
version = purl .version
125
125
api_url = f"{ base_path } /{ name } "
126
+
126
127
response = get_response (api_url )
127
128
vcs_data = response .get ("repository" ) or {}
128
129
bugs = response .get ("bugs" ) or {}
129
-
130
130
download_url = f"{ base_path } /{ name } /-/{ name } -{ version } .tgz" if version else None
131
131
vcs_url = vcs_data .get ("url" )
132
132
bug_tracking_url = bugs .get ("url" )
133
133
license = response .get ("license" )
134
134
homepage_url = response .get ("homepage" )
135
135
136
- yield Package (
137
- homepage_url = homepage_url ,
138
- api_url = api_url ,
139
- vcs_url = vcs_url ,
140
- bug_tracking_url = bug_tracking_url ,
141
- download_url = download_url ,
142
- declared_license = license ,
143
- ** purl .to_dict (),
144
- )
145
-
146
136
versions = response .get ("versions" , [])
147
- tags = []
148
137
for num in versions :
149
138
version = versions [num ]
150
139
version_purl = PackageURL (
@@ -153,11 +142,13 @@ def get_npm_data_from_purl(purl):
153
142
repository = version .get ("repository" ) or {}
154
143
bugs = response .get ("bugs" ) or {}
155
144
dist = version .get ("dist" ) or {}
156
- licenses = version .get ("licenses" ) or [{}]
157
145
vcs_url = repository .get ("url" )
158
146
download_url = dist .get ("tarball" )
159
147
bug_tracking_url = bugs .get ("url" )
160
- declared_license = licenses [0 ].get ("type" )
148
+ declared_license = license
149
+
150
+ if purl .version and version_purl .version != purl .version :
151
+ continue
161
152
162
153
yield Package (
163
154
homepage_url = homepage_url ,
@@ -169,6 +160,9 @@ def get_npm_data_from_purl(purl):
169
160
** version_purl .to_dict (),
170
161
)
171
162
163
+ if purl .version :
164
+ break
165
+
172
166
173
167
@router .route ("pkg:pypi/.*" )
174
168
def get_pypi_data_from_purl (purl ):
@@ -177,6 +171,7 @@ def get_pypi_data_from_purl(purl):
177
171
"""
178
172
purl = PackageURL .from_string (purl )
179
173
name = purl .name
174
+
180
175
base_path = "https://pypi.org/pypi"
181
176
api_url = f"{ base_path } /{ name } /json"
182
177
response = get_response (api_url )
@@ -187,19 +182,14 @@ def get_pypi_data_from_purl(purl):
187
182
project_urls = info .get ("project_urls" ) or {}
188
183
code_view_url = get_pypi_codeview_url (project_urls )
189
184
bug_tracking_url = get_pypi_bugtracker_url (project_urls )
190
- yield Package (
191
- homepage_url = homepage_url ,
192
- api_url = api_url ,
193
- bug_tracking_url = bug_tracking_url ,
194
- code_view_url = code_view_url ,
195
- declared_license = license ,
196
- ** purl .to_dict (),
197
- )
185
+
198
186
for num in releases :
199
187
version_purl = PackageURL (type = purl .type , name = name , version = num )
200
188
release = releases .get (num ) or [{}]
201
189
release = release [0 ]
202
190
download_url = release .get ("url" )
191
+ if purl .version and version_purl .version != purl .version :
192
+ continue
203
193
yield Package (
204
194
homepage_url = homepage_url ,
205
195
api_url = api_url ,
@@ -210,6 +200,9 @@ def get_pypi_data_from_purl(purl):
210
200
** version_purl .to_dict (),
211
201
)
212
202
203
+ if purl .version :
204
+ break
205
+
213
206
214
207
@router .route ("pkg:github/.*" )
215
208
def get_github_data_from_purl (purl ):
@@ -296,19 +289,15 @@ def get_bitbucket_data_from_purl(purl):
296
289
bitbucket_url = "https://bitbucket.org"
297
290
bug_tracking_url = f"{ bitbucket_url } /{ namespace } /{ name } /issues"
298
291
code_view_url = f"{ bitbucket_url } /{ namespace } /{ name } "
299
- yield Package (
300
- api_url = api_url ,
301
- bug_tracking_url = bug_tracking_url ,
302
- code_view_url = code_view_url ,
303
- ** purl .to_dict (),
304
- )
292
+
305
293
links = response .get ("links" ) or {}
306
294
tags_url = links .get ("tags" ) or {}
307
295
tags_url = tags_url .get ("href" )
308
296
if not tags_url :
309
297
return []
310
298
tags_data = get_response (tags_url )
311
299
tags = tags_data .get ("values" ) or {}
300
+
312
301
for tag in tags :
313
302
version = tag .get ("name" ) or ""
314
303
version_purl = PackageURL (
@@ -318,6 +307,10 @@ def get_bitbucket_data_from_purl(purl):
318
307
f"{ base_path } /{ namespace } /{ name } /downloads/{ name } -{ version } .tar.gz"
319
308
)
320
309
code_view_url = f"{ bitbucket_url } /{ namespace } /{ name } /src/{ version } "
310
+
311
+ if purl .version and version_purl .version != purl .version :
312
+ continue
313
+
321
314
yield Package (
322
315
api_url = api_url ,
323
316
bug_tracking_url = bug_tracking_url ,
@@ -326,6 +319,9 @@ def get_bitbucket_data_from_purl(purl):
326
319
** version_purl .to_dict (),
327
320
)
328
321
322
+ if purl .version :
323
+ break
324
+
329
325
330
326
@router .route ("pkg:rubygems/.*" )
331
327
def get_rubygems_data_from_purl (purl ):
@@ -334,22 +330,38 @@ def get_rubygems_data_from_purl(purl):
334
330
"""
335
331
purl = PackageURL .from_string (purl )
336
332
name = purl .name
337
- api_url = f"https://rubygems.org/api/v1/gems/{ name } .json"
338
- response = get_response (api_url )
339
- declared_license = response .get ("licenses" ) or None
340
- homepage_url = response .get ("homepage_uri" )
341
- code_view_url = response .get ("source_code_uri" )
342
- bug_tracking_url = response .get ("bug_tracker_uri" )
343
- download_url = response .get ("gem_uri" )
344
- yield Package (
345
- homepage_url = homepage_url ,
346
- api_url = api_url ,
347
- bug_tracking_url = bug_tracking_url ,
348
- code_view_url = code_view_url ,
349
- declared_license = declared_license ,
350
- download_url = download_url ,
351
- ** purl .to_dict (),
352
- )
333
+ all_versions_url = f"https://rubygems.org/api/v1/versions/{ name } .json"
334
+ all_versions = get_response (all_versions_url )
335
+
336
+ for vers in all_versions :
337
+ version_purl = PackageURL (type = purl .type , name = name , version = vers .get ("number" ))
338
+
339
+ if purl .version and version_purl .version != purl .version :
340
+ continue
341
+
342
+ number = vers .get ("number" )
343
+ version_api = f"https://rubygems.org/api/v2/rubygems/{ name } /versions/{ number } .json"
344
+ version_api_response = get_response (version_api )
345
+ declared_license = version_api_response .get ("licenses" ) or None
346
+ homepage_url = version_api_response .get ("homepage_uri" )
347
+ code_view_url = version_api_response .get ("source_code_uri" )
348
+ bug_tracking_url = version_api_response .get ("bug_tracker_uri" )
349
+ download_url = version_api_response .get ("gem_uri" )
350
+ repository_homepage_url = version_api_response .get ("project_uri" )
351
+
352
+ yield Package (
353
+ homepage_url = homepage_url ,
354
+ api_url = version_api ,
355
+ bug_tracking_url = bug_tracking_url ,
356
+ code_view_url = code_view_url ,
357
+ declared_license = declared_license ,
358
+ download_url = download_url ,
359
+ repository_homepage_url = repository_homepage_url ,
360
+ ** version_purl .to_dict (),
361
+ )
362
+
363
+ if purl .version :
364
+ break
353
365
354
366
355
367
@router .route ("pkg:gnu/.*" )
@@ -378,7 +390,8 @@ def get_cocoapods_data_from_purl(purl):
378
390
data_list = get_cocoapod_tags (spec , name )
379
391
380
392
for tag in data_list :
381
- if purl .version and tag != purl .version :
393
+ version_purl = PackageURL (type = purl .type , name = name , version = tag )
394
+ if purl .version and version_purl .version != purl .version :
382
395
continue
383
396
384
397
gh_repo_owner = None
@@ -394,7 +407,7 @@ def get_cocoapods_data_from_purl(purl):
394
407
gh_repo_name = podspec_homepage_split [- 1 ]
395
408
396
409
tag_pkg = construct_cocoapods_package (
397
- purl ,
410
+ version_purl ,
398
411
name ,
399
412
hashed_path ,
400
413
cocoapods_org_url ,
0 commit comments