Skip to content

Commit

Permalink
Support GitHub Release Asset Downloads
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=246162
rdar://100859270

Reviewed by Jonathan Bedard.

* Tools/Scripts/libraries/webkitcorepy/setup.py: version bump
* Tools/Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py: version bump
* Tools/Scripts/libraries/webkitcorepy/webkitcorepy/mocks/requests_.py:
(Response.fromJson): expose `status_code` optional argument
* Tools/Scripts/libraries/webkitscmpy/setup.py: version bump
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: version bump
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/remote/git_hub.py:
(GitHub._commits_response): Use Response.fromJson when mocking 404 response with JSON text
(GitHub._commit_response): Use Response.fromJson when mocking 404 response with JSON text
(GitHub._compare_response): Use Response.fromJson when mocking 404 response with JSON text
(GitHub.request):Use Response.fromJson when mocking 404 response with JSON text
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/git_hub.py:
Added optional `stream` argument to `GitHub.request()`. Implemented `GitHub.download_release_assets()`

Canonical link: https://commits.webkit.org/255283@main
  • Loading branch information
roynos committed Oct 7, 2022
1 parent a903a71 commit 755130c
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Tools/Scripts/libraries/webkitcorepy/setup.py
Expand Up @@ -30,7 +30,7 @@ def readme():

setup(
name='webkitcorepy',
version='0.13.15',
version='0.13.16',
description='Library containing various Python support classes and functions.',
long_description=readme(),
classifiers=[
Expand Down
Expand Up @@ -44,7 +44,7 @@
from webkitcorepy.editor import Editor
from webkitcorepy.file_lock import FileLock

version = Version(0, 13, 15)
version = Version(0, 13, 16)

from webkitcorepy.autoinstall import Package, AutoInstall
if sys.version_info > (3, 0):
Expand Down
Expand Up @@ -33,14 +33,14 @@ def fromText(data, url=None, headers=None):
return Response(text=data, url=url, headers=headers)

@staticmethod
def fromJson(data, url=None, headers=None):
def fromJson(data, url=None, headers=None, status_code=None):
assert isinstance(data, list) or isinstance(data, dict)

headers = headers or {}
if 'Content-Type' not in headers:
headers['Content-Type'] = 'text/json'

return Response(text=json.dumps(data), url=url, headers=headers)
return Response(text=json.dumps(data), url=url, headers=headers, status_code=status_code)

@staticmethod
def create404(url=None, headers=None):
Expand Down
2 changes: 1 addition & 1 deletion Tools/Scripts/libraries/webkitscmpy/setup.py
Expand Up @@ -29,7 +29,7 @@ def readme():

setup(
name='webkitscmpy',
version='5.6.14',
version='5.6.15',
description='Library designed to interact with git and svn repositories.',
long_description=readme(),
classifiers=[
Expand Down
Expand Up @@ -46,7 +46,7 @@ def _maybe_add_webkitcorepy_path():
"Please install webkitcorepy with `pip install webkitcorepy --extra-index-url <package index URL>`"
)

version = Version(5, 6, 14)
version = Version(5, 6, 15)

AutoInstall.register(Package('fasteners', Version(0, 15, 0)))
AutoInstall.register(Package('jinja2', Version(2, 11, 3)))
Expand Down
Expand Up @@ -146,10 +146,10 @@ def _commits_response(self, url, ref):

base = self.commit(ref)
if not base:
return mocks.Response(
status_code=404,
return mocks.Response.fromJson(
dict(message='No commit found for SHA: {}'.format(ref)),
url=url,
text=jsonlib.dumps(dict(message='No commit found for SHA: {}'.format(ref))),
status_code=404,
)

response = []
Expand Down Expand Up @@ -192,10 +192,10 @@ def _commit_response(self, url, ref):

commit = self.commit(ref)
if not commit:
return mocks.Response(
status_code=404,
return mocks.Response.fromJson(
dict(message='No commit found for SHA: {}'.format(ref)),
url=url,
text=jsonlib.dumps(dict(message='No commit found for SHA: {}'.format(ref))),
status_code=404,
)
return mocks.Response.fromJson({
'sha': commit.hash,
Expand All @@ -222,10 +222,10 @@ def _compare_response(self, url, ref_a, ref_b):
commit_a = self.commit(ref_a)
commit_b = self.commit(ref_b)
if not commit_a or not commit_b:
return mocks.Response(
status_code=404,
return mocks.Response.fromJson(
dict(message='Not found'),
url=url,
text=jsonlib.dumps(dict(message='Not found')),
status_code=404,
)

if commit_a.branch != self.default_branch or commit_b.branch == self.default_branch:
Expand Down Expand Up @@ -435,10 +435,11 @@ def request(self, method, url, data=None, params=None, auth=None, json=None, **k
return mocks.Response.fromJson({
key: value for key, value in candidate.items() if key not in ('requested_reviews', 'reviews')
}, url=url)
return mocks.Response(
status_code=404,
text=jsonlib.dumps(dict(message='Not found')),

return mocks.Response.fromJson(
dict(message='Not found'),
url=url,
status_code=404,
)

# Create/update pull-request
Expand Down
35 changes: 31 additions & 4 deletions Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/git_hub.py
Expand Up @@ -336,7 +336,7 @@ def credentials(self, required=True, validate=False, save_in_keyring=None):
def is_git(self):
return True

def request(self, path=None, params=None, headers=None, authenticated=None, paginate=True, json=None, method='GET', endpoint_url=None, files=None, data=None):
def request(self, path=None, params=None, headers=None, authenticated=None, paginate=True, json=None, method='GET', endpoint_url=None, files=None, data=None, stream=False):
headers = {key: value for key, value in headers.items()} if headers else dict()
headers['Accept'] = headers.get('Accept', self.ACCEPT_HEADER)

Expand All @@ -362,17 +362,22 @@ def request(self, path=None, params=None, headers=None, authenticated=None, pagi
name=self.name,
path='/{}'.format(path) if path else '',
)
response = self.session.request(method, url, params=params, json=json, headers=headers, auth=auth, files=files, data=data)
response = self.session.request(method, url, params=params, json=json, headers=headers, auth=auth, files=files, data=data, stream=stream)
is_json_response = response.headers.get('Content-Type', '').split(';')[0] in ['application/json', 'text/json']
if authenticated is None and not auth and response.status_code // 100 == 4:
return self.request(path=path, params=params, headers=headers, authenticated=True, paginate=paginate, json=json, method=method, endpoint_url=endpoint_url, files=files, data=data)
return self.request(path=path, params=params, headers=headers, authenticated=True, paginate=paginate, json=json, method=method, endpoint_url=endpoint_url, files=files, data=data, stream=stream)
if response.status_code not in [200, 201]:
sys.stderr.write("Request to '{}' returned status code '{}'\n".format(url, response.status_code))
message = response.json().get('message')
message = response.json().get('message') if is_json_response else ''
if message:
sys.stderr.write('Message: {}\n'.format(message))
if auth:
sys.stderr.write(Tracker.REFRESH_TOKEN_PROMPT)
return None

if not is_json_response:
return response

result = response.json()

while paginate and isinstance(response.json(), list) and len(response.json()) == params['per_page']:
Expand Down Expand Up @@ -738,3 +743,25 @@ def upload_release_asset(self, release_tag_name, source_filename, mime_type, ass
finally:
if not file_like_object:
file_object.close()

def download_release_assets(self, destination_directory, release_tag_name=None):
assert os.path.isdir(destination_directory), '`{destination_directory}` must be a directory'.format(destination_directory=destination_directory)
path = 'releases/tags/{release_tag_name}'.format(release_tag_name=release_tag_name) if release_tag_name else 'releases/latest'
release_info = self.request(path, authenticated=True, paginate=False)
release_assets = self.request(
'releases/{id}/assets'.format(id=release_info['id']),
authenticated=True,
paginate=False
)
headers = dict(Accept='application/octet-stream')
for asset_info in release_assets:
with self.request(
'releases/assets/{id}'.format(id=asset_info['id']),
headers=headers,
authenticated=True,
paginate=False,
stream=True
) as response:
with open(os.path.join(destination_directory, asset_info['name']), 'wb') as file_object:
for chunk in response.iter_content(chunk_size=10240):
file_object.write(chunk)

0 comments on commit 755130c

Please sign in to comment.