Skip to content

Commit 0cc1b8e

Browse files
authored
Run event loop in tasks and remove requests dependency. (#186)
1 parent 5da7e5c commit 0cc1b8e

File tree

5 files changed

+121
-109
lines changed

5 files changed

+121
-109
lines changed

dev-requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,3 @@
22
pytest==4.0.1
33
pytest-asyncio==0.9.0
44
pytest-aiohttp==0.3.0
5-
requests-mock==1.5.2

miss_islington/tasks.py

Lines changed: 76 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import celery
2+
import asyncio
23
import os
34
import subprocess
5+
import aiohttp
6+
from gidgethub import aiohttp as gh_aiohttp
7+
8+
import cachetools
49

510
from celery import bootsteps
611

@@ -14,6 +19,8 @@
1419
BROKER_URL=os.environ["REDIS_URL"], CELERY_RESULT_BACKEND=os.environ["REDIS_URL"]
1520
)
1621

22+
cache = cachetools.LRUCache(maxsize=500)
23+
1724

1825
@app.task()
1926
def setup_cpython_repo():
@@ -39,52 +46,78 @@ def setup_cpython_repo():
3946

4047
@app.task()
4148
def backport_task(commit_hash, branch, *, issue_number, created_by, merged_by):
42-
"""Backport a commit into a branch."""
43-
if not util.is_cpython_repo():
44-
# cd to cpython if we're not already in it
45-
if "cpython" in os.listdir("."):
46-
os.chdir("./cpython")
47-
else:
48-
print(f"pwd: {os.getcwd()}, listdir: {os.listdir('.')}")
49-
util.comment_on_pr(
50-
issue_number,
51-
f"""{util.get_participants(created_by, merged_by)}, Something is wrong... I can't backport for now.
52-
Please backport using [cherry_picker](https://pypi.org/project/cherry-picker/) on command line.
53-
```
54-
cherry_picker {commit_hash} {branch}
55-
```
56-
""",
57-
)
58-
util.assign_pr_to_core_dev(issue_number, merged_by)
59-
cp = cherry_picker.CherryPicker(
60-
"origin", commit_hash, [branch], prefix_commit=False
49+
loop = asyncio.get_event_loop()
50+
loop.run_until_complete(
51+
backport_task_asyncio(
52+
commit_hash,
53+
branch,
54+
issue_number=issue_number,
55+
created_by=created_by,
56+
merged_by=merged_by,
57+
)
6158
)
62-
try:
63-
cp.backport()
64-
except cherry_picker.BranchCheckoutException:
65-
util.comment_on_pr(
66-
issue_number,
67-
f"""Sorry {util.get_participants(created_by, merged_by)}, I had trouble checking out the `{branch}` backport branch.
68-
Please backport using [cherry_picker](https://pypi.org/project/cherry-picker/) on command line.
69-
```
70-
cherry_picker {commit_hash} {branch}
71-
```
72-
""",
59+
60+
61+
async def backport_task_asyncio(
62+
commit_hash, branch, *, issue_number, created_by, merged_by
63+
):
64+
"""Backport a commit into a branch."""
65+
66+
oauth_token = os.environ.get("GH_AUTH")
67+
async with aiohttp.ClientSession() as session:
68+
gh = gh_aiohttp.GitHubAPI(
69+
session, "python/cpython", oauth_token=oauth_token, cache=cache
7370
)
74-
util.assign_pr_to_core_dev(issue_number, merged_by)
75-
cp.abort_cherry_pick()
76-
except cherry_picker.CherryPickException:
77-
util.comment_on_pr(
78-
issue_number,
79-
f"""Sorry, {util.get_participants(created_by, merged_by)}, I could not cleanly backport this to `{branch}` due to a conflict.
80-
Please backport using [cherry_picker](https://pypi.org/project/cherry-picker/) on command line.
81-
```
82-
cherry_picker {commit_hash} {branch}
83-
```
84-
""",
71+
72+
if not util.is_cpython_repo():
73+
# cd to cpython if we're not already in it
74+
if "cpython" in os.listdir("."):
75+
os.chdir("./cpython")
76+
else:
77+
print(f"pwd: {os.getcwd()}, listdir: {os.listdir('.')}")
78+
79+
await util.comment_on_pr(
80+
gh,
81+
issue_number,
82+
f"""{util.get_participants(created_by, merged_by)}, Something is wrong... I can't backport for now.
83+
Please backport using [cherry_picker](https://pypi.org/project/cherry-picker/) on command line.
84+
```
85+
cherry_picker {commit_hash} {branch}
86+
```
87+
""",
88+
)
89+
await util.assign_pr_to_core_dev(gh, issue_number, merged_by)
90+
cp = cherry_picker.CherryPicker(
91+
"origin", commit_hash, [branch], prefix_commit=False
8592
)
86-
util.assign_pr_to_core_dev(issue_number, merged_by)
87-
cp.abort_cherry_pick()
93+
try:
94+
cp.backport()
95+
except cherry_picker.BranchCheckoutException:
96+
await util.comment_on_pr(
97+
gh,
98+
issue_number,
99+
f"""Sorry {util.get_participants(created_by, merged_by)}, I had trouble checking out the `{branch}` backport branch.
100+
Please backport using [cherry_picker](https://pypi.org/project/cherry-picker/) on command line.
101+
```
102+
cherry_picker {commit_hash} {branch}
103+
```
104+
""",
105+
)
106+
await util.assign_pr_to_core_dev(gh, issue_number, merged_by)
107+
cp.abort_cherry_pick()
108+
except cherry_picker.CherryPickException:
109+
await util.comment_on_pr(
110+
gh,
111+
issue_number,
112+
f"""Sorry, {util.get_participants(created_by, merged_by)}, I could not cleanly backport this to `{branch}` due to a conflict.
113+
Please backport using [cherry_picker](https://pypi.org/project/cherry-picker/) on command line.
114+
```
115+
cherry_picker {commit_hash} {branch}
116+
```
117+
""",
118+
)
119+
await util.assign_pr_to_core_dev(gh, issue_number, merged_by)
120+
cp.abort_cherry_pick()
88121

89122

90123
class InitRepoStep(bootsteps.StartStopStep):

miss_islington/util.py

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,31 @@
1-
import requests
2-
import os
31
import subprocess
42

53
import gidgethub
64

7-
from gidgethub import sansio
8-
95

106
AUTOMERGE_LABEL = ":robot: automerge"
117

128

13-
def comment_on_pr(issue_number, message):
9+
async def comment_on_pr(gh, issue_number, message):
1410
"""
1511
Leave a comment on a PR/Issue
1612
"""
17-
request_headers = sansio.create_headers(
18-
"miss-islington", oauth_token=os.getenv("GH_AUTH")
19-
)
20-
issue_comment_url = (
21-
f"https://api.github.com/repos/python/cpython/issues/{issue_number}/comments"
22-
)
13+
issue_comment_url = f"/repos/python/cpython/issues/{issue_number}/comments"
2314
data = {"body": message}
24-
response = requests.post(issue_comment_url, headers=request_headers, json=data)
25-
if response.status_code == requests.codes.created:
26-
print(f"Commented at {response.json()['html_url']}, message: {message}")
27-
else:
28-
print(response.status_code)
29-
print(response.text)
15+
response = await gh.post(issue_comment_url, data=data)
16+
print(f"Commented at {response['html_url']}, message: {message}")
3017
return response
3118

3219

33-
def assign_pr_to_core_dev(issue_number, coredev_login):
20+
async def assign_pr_to_core_dev(gh, issue_number, coredev_login):
3421
"""
3522
Assign the PR to a core dev. Should be done when miss-islington failed
3623
to backport.
3724
"""
38-
request_headers = sansio.create_headers(
39-
"miss-islington", oauth_token=os.getenv("GH_AUTH")
40-
)
41-
edit_issue_url = (
42-
f"https://api.github.com/repos/python/cpython/issues/{issue_number}"
43-
)
25+
26+
edit_issue_url = f"/repos/python/cpython/issues/{issue_number}"
4427
data = {"assignees": [coredev_login]}
45-
response = requests.patch(edit_issue_url, headers=request_headers, json=data)
46-
if response.status_code == requests.codes.created:
47-
print(f"Assigned PR {issue_number} to {coredev_login}")
48-
else:
49-
print(response.status_code)
50-
print(response.text)
51-
return response
28+
await gh.patch(edit_issue_url, data=data)
5229

5330

5431
async def leave_comment(gh, pr_number, message):

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@ cherry_picker==1.2.1
22
aiohttp==3.4.4
33
gidgethub==3.0.0
44
cachetools==3.0.0
5-
requests==2.21.0
65
redis==2.10.6
76
celery==4.2.1

tests/test_util.py

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99

1010

1111
class FakeGH:
12-
def __init__(self, *, getiter=None, getitem=None, post=None):
12+
def __init__(self, *, getiter=None, getitem=None, post=None, patch=None):
1313
self._getitem_return = getitem
1414
self._getiter_return = getiter
1515
self._post_return = post
16+
self._patch_return = patch
1617
self.getitem_url = None
1718
self.getiter_url = None
19+
self.patch_url = self.patch_data = None
1820
self.post_url = self.post_data = None
1921

2022
async def getitem(self, url):
@@ -31,6 +33,21 @@ async def getiter(self, url):
3133
for item in to_iterate:
3234
yield item
3335

36+
async def patch(self, url, *, data):
37+
self.patch_url = url
38+
self.patch_data = data
39+
return self._patch_return
40+
41+
async def post(self, url, *, data):
42+
self.post_url = url
43+
self.post_data = data
44+
print(type(self._post_return))
45+
if isinstance(self._post_return, Exception):
46+
print("raising")
47+
raise self._post_return
48+
else:
49+
return self._post_return
50+
3451

3552
def test_title_normalization():
3653
title = "abcd"
@@ -223,51 +240,38 @@ def test_pr_is_not_automerge():
223240
assert util.pr_is_automerge(labels) is False
224241

225242

226-
def test_comment_on_pr_success(requests_mock):
243+
async def test_comment_on_pr_success():
227244
issue_number = 100
228245
message = "Thanks for the PR!"
229-
post_url = (
230-
f"https://api.github.com/repos/python/cpython/issues/{issue_number}/comments"
231-
)
232-
requests_mock.post(
233-
post_url,
234-
json={
235-
"html_url": "https://github.com/python/cpython/pull/{issue_number}#issuecomment-401309376"
236-
},
237-
status_code=201,
246+
247+
gh = FakeGH(
248+
post={
249+
"html_url": f"https://github.com/python/cpython/pull/{issue_number}#issuecomment-401309376"
250+
}
238251
)
239-
response = util.comment_on_pr(issue_number, message)
240-
assert response.status_code == 201
252+
253+
await util.comment_on_pr(gh, issue_number, message)
254+
assert gh.post_url == f"/repos/python/cpython/issues/{issue_number}/comments"
255+
assert gh.post_data == {"body": message}
241256

242257

243-
def test_comment_on_pr_failure(requests_mock):
258+
async def test_comment_on_pr_failure():
244259
issue_number = 100
245260
message = "Thanks for the PR!"
246-
post_url = (
247-
f"https://api.github.com/repos/python/cpython/issues/{issue_number}/comments"
248-
)
249-
requests_mock.post(post_url, status_code=400)
250-
response = util.comment_on_pr(issue_number, message)
251-
assert response.status_code == 400
252-
261+
gh = FakeGH(post=gidgethub.BadRequest(status_code=http.HTTPStatus(400)))
253262

254-
def test_assign_pr_to_coredev_success(requests_mock):
263+
with pytest.raises(gidgethub.BadRequest):
264+
await util.comment_on_pr(gh, issue_number, message)
255265

256-
issue_number = 100
257-
coredev_login = "Mariatta"
258-
patch_url = f"https://api.github.com/repos/python/cpython/issues/{issue_number}"
259-
requests_mock.patch(patch_url, status_code=201)
260-
response = util.assign_pr_to_core_dev(issue_number, coredev_login)
261-
assert response.status_code == 201
262266

267+
async def test_assign_pr_to_coredev():
263268

264-
def test_assign_pr_to_coredev_failed(requests_mock):
265269
issue_number = 100
266270
coredev_login = "Mariatta"
267-
patch_url = f"https://api.github.com/repos/python/cpython/issues/{issue_number}"
268-
requests_mock.patch(patch_url, status_code=400)
269-
response = util.assign_pr_to_core_dev(issue_number, coredev_login)
270-
assert response.status_code == 400
271+
gh = FakeGH()
272+
273+
await util.assign_pr_to_core_dev(gh, issue_number, coredev_login)
274+
assert gh.patch_url == f"/repos/python/cpython/issues/{issue_number}"
271275

272276

273277
async def test_get_pr_for_commit():

0 commit comments

Comments
 (0)