Skip to content

Commit 9682dac

Browse files
committed
Address review comments
Signed-off-by: Tushar Goel <[email protected]>
1 parent 02b9671 commit 9682dac

File tree

4 files changed

+144
-11
lines changed

4 files changed

+144
-11
lines changed

README.rst

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,41 @@ Fetch some package metadata and get a ``fetchcode.packagedcode_models.Package``
5959
>>> list(package.info('pkg:rubygems/files'))
6060
[Package(type='rubygems', namespace=None, name='files', version=None)]
6161

62+
Fetch a purl and get a ``fetchcode.fetch.Response`` object back::
63+
64+
>>> from fetchcode import fetch
65+
>>> f = fetch('pkg:swift/github.com/Alamofire/[email protected]')
66+
>>> f.location
67+
'/tmp/tmp_cm02xsg'
68+
>>> f.content_type
69+
'application/zip'
70+
>>> f.url
71+
'https://github.com/Alamofire/Alamofire/archive/5.4.3.zip'
72+
73+
Ecosystems supported for fetching a purl from fetchcode:
74+
75+
- alpm
76+
- apk
77+
- bitbucket
78+
- cargo
79+
- composer
80+
- conda
81+
- cpan
82+
- cran
83+
- deb
84+
- gem
85+
- generic
86+
- github
87+
- golang
88+
- hackage
89+
- hex
90+
- luarocks
91+
- maven
92+
- npm
93+
- nuget
94+
- pub
95+
- pypi
96+
- swift
6297

6398
License
6499
--------

src/fetchcode/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,7 @@ def get_url_scheme(url):
134134
"""
135135
Return the scheme of the given URL.
136136
"""
137-
url_parts = urlparse(url)
138-
scheme = url_parts.scheme
139-
return scheme
137+
return urlparse(url).scheme
140138

141139

142140
def fetch(url):

src/fetchcode/composer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ class Composer:
2626

2727
@classmethod
2828
def get_download_url(cls, purl):
29-
3029
"""
3130
Return the download URL for a Composer PURL.
3231
"""

tests/test_fetch.py

Lines changed: 108 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import pytest
2020

2121
from fetchcode import fetch
22+
from fetchcode import resolve_purl
23+
from fetchcode import resolve_url_from_purl
2224

2325

2426
@mock.patch("fetchcode.requests.get")
@@ -65,22 +67,121 @@ def test_fetch_with_scheme_not_present():
6567
assert "Not a supported/known scheme." == e_info
6668

6769

68-
@mock.patch("fetchcode.resolve_url_from_purl")
70+
@mock.patch("fetchcode._http_exists")
6971
@mock.patch("fetchcode.fetch_http")
70-
def test_fetch_purl(mock_fetch_http, mock_resolve):
72+
@mock.patch("fetchcode.pypi.fetch_json_response")
73+
def test_fetch_purl_with_fetchcode(mock_fetch_json_response, mock_fetch_http, mock_http_exists):
7174
mock_fetch_http.return_value = "mocked_purl_response"
72-
mock_resolve.return_value = ("http://resolved.com/file.tar.gz", "http")
75+
mock_http_exists.return_value = True
76+
mock_fetch_json_response.return_value = {
77+
"urls": [{"url": "https://example.com/sample-1.0.0.zip"}]
78+
}
7379

7480
response = fetch("pkg:pypi/[email protected]")
7581

7682
assert response == "mocked_purl_response"
77-
mock_resolve.assert_called_once()
83+
mock_http_exists.assert_called_once()
84+
mock_fetch_http.assert_called_once()
85+
86+
87+
@mock.patch("fetchcode._http_exists")
88+
@mock.patch("fetchcode.fetch_http")
89+
def test_fetch_purl_with_purl2url(mock_fetch_http, mock_http_exists):
90+
mock_fetch_http.return_value = "mocked_purl_response"
91+
mock_http_exists.return_value = True
92+
93+
response = fetch("pkg:alpm/[email protected]")
94+
95+
assert response == "mocked_purl_response"
96+
mock_http_exists.assert_called_once()
7897
mock_fetch_http.assert_called_once()
7998

8099

81-
@mock.patch("fetchcode.get_url_scheme")
82-
def test_fetch_unsupported_scheme(mock_get_scheme):
83-
mock_get_scheme.return_value = "s3"
100+
@mock.patch("fetchcode.pypi.fetch_json_response")
101+
def test_fetch_invalid_purl(mock_fetch_json_response):
102+
mock_fetch_json_response.return_value = {}
84103

104+
with pytest.raises(Exception, match="No download URL found for invalid-package version 1.0.0"):
105+
fetch("pkg:pypi/[email protected]")
106+
107+
108+
@mock.patch("fetchcode.pypi.fetch_json_response")
109+
def test_fetch_invalid_purl(mock_fetch_json_response):
110+
mock_fetch_json_response.return_value = {}
111+
112+
with pytest.raises(Exception, match="No download URL found for invalid-package version 1.0.0"):
113+
fetch("pkg:pypi/[email protected]")
114+
115+
116+
def test_fetch_unsupported_scheme():
85117
with pytest.raises(Exception, match="Not a supported/known scheme"):
86118
fetch("s3://bucket/object")
119+
120+
121+
def test_resolve_url_from_purl_invalid():
122+
with pytest.raises(ValueError, match="Could not resolve PURL to a valid URL."):
123+
fetch("pkg:invalid/[email protected]")
124+
125+
126+
@mock.patch("fetchcode._http_exists")
127+
def test_resolve_url_from_purl_using_purl2url(mock_http_exists):
128+
mock_http_exists.return_value = True
129+
130+
url, _ = resolve_url_from_purl("pkg:swift/github.com/Alamofire/[email protected]")
131+
assert url == "https://github.com/Alamofire/Alamofire/archive/5.4.3.zip"
132+
mock_http_exists.assert_called_once_with(
133+
"https://github.com/Alamofire/Alamofire/archive/5.4.3.zip"
134+
)
135+
136+
137+
@mock.patch("fetchcode._http_exists")
138+
@mock.patch("fetchcode.pypi.fetch_json_response")
139+
def test_resolve_url_from_purl_using_fetchcode(mock_fetch_json_response, mock_http_exists):
140+
mock_http_exists.return_value = True
141+
mock_fetch_json_response.return_value = {
142+
"urls": [{"url": "https://example.com/sample-1.0.0.zip"}]
143+
}
144+
145+
url, _ = resolve_url_from_purl("pkg:pypi/[email protected]")
146+
assert url == "https://example.com/sample-1.0.0.zip"
147+
mock_http_exists.assert_called_once_with("https://example.com/sample-1.0.0.zip")
148+
149+
150+
def test_resolve_purl_invalid():
151+
assert resolve_purl("pkg:invalid/[email protected]") is None
152+
153+
154+
def test_resolve_purl_using_purl2url():
155+
url = resolve_purl("pkg:pub/[email protected]")
156+
assert url == "https://pub.dev/api/archives/http-0.13.3.tar.gz"
157+
158+
159+
@mock.patch("fetchcode._http_exists")
160+
def test_resolve_purl_using_purl2url_url_does_not_exists(mock_http_exists):
161+
mock_http_exists.return_value = False
162+
url = resolve_purl("pkg:pub/[email protected]")
163+
assert url is None
164+
165+
166+
@mock.patch("fetchcode._http_exists")
167+
@mock.patch("fetchcode.pypi.fetch_json_response")
168+
def test_resolve_purl_using_fetchcode(mock_fetch_json_response, mock_http_exists):
169+
mock_fetch_json_response.return_value = {
170+
"urls": [{"url": "https://example.com/sample-1.0.0.zip"}]
171+
}
172+
mock_http_exists.return_value = True
173+
url = resolve_purl("pkg:pypi/[email protected]")
174+
assert url == "https://example.com/sample-1.0.0.zip"
175+
176+
177+
@mock.patch("fetchcode._http_exists")
178+
@mock.patch("fetchcode.pypi.fetch_json_response")
179+
def test_resolve_purl_using_fetchcode_url_does_not_exists(
180+
mock_fetch_json_response, mock_http_exists
181+
):
182+
mock_fetch_json_response.return_value = {
183+
"urls": [{"url": "https://example.com/sample-1.0.0.zip"}]
184+
}
185+
mock_http_exists.return_value = False
186+
url = resolve_purl("pkg:pypi/[email protected]")
187+
assert url is None

0 commit comments

Comments
 (0)