Anish Shah added the comment:
I have updated the patch.
> We do need proper error handling, still.
The problem is "err" variable has stdout of that process. So, even if we
change/push branch, it will be non-empty. Any idea how to solve this problem?
One more thing, if we create PR using API, it triggers GitHub webhooks. So, I'm
removing the part where we are storing the response in DB.
Also, I'm not sure how to add tests for this.
----------
title: Convert patches to GitHub Pull Request -> Convert patches to GitHub Pull
Request (depends on issue586)
_______________________________________________________
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue600>
_______________________________________________________
diff --git a/detectors/patches.py b/detectors/patches.py
index 18d3db4..9e2e01e 100644
--- a/detectors/patches.py
+++ b/detectors/patches.py
@@ -5,10 +5,97 @@
import posixpath
import identify_patch
+import os
+import subprocess
+import string
+import random
+import json
+import requests
+import tempfile
+import shutil
+import logging
patchtypes = ('.diff', '.patch')
sourcetypes = ('.diff', '.patch', '.py')
+
+class TemporaryDirectory(object):
+
+ def __enter__(self):
+ self.name = tempfile.mkdtemp()
+ return self.name
+
+ def __exit__(self, *args):
+ shutil.rmtree(self.name)
+
+
+def create_pull_request(db, head, base, issue_id, issue_title):
+ endpoint = 'https://api.github.com/repos/python/cpython/pulls'
+ access_token = os.environ['ACCESS_TOKEN']
+ headers = {'Authorization': 'token {}'.format(access_token)}
+ data = json.dumps({
+ "title": "{}".format(issue_title),
+ "body": "fixes issue bpo{}".format(issue_id),
+ "base": base, "head": head})
+ response = requests.post(endpoint, headers=headers, data=data)
+ if not response.ok:
+ logging.error(response.text, exc_info=True)
+ raise Exception('Error while creating pull request')
+ else:
+ response_body = response.json()
+ url = response_body['html_url']
+ state = response_body['state']
+ pr_id = db.pull_request.create(url=url, state=state)
+ issue_pr = db.issue.get(issue_id, 'pull_requests')
+ issue_pr.append(pr_id)
+ db.issue.set(issue_id, pull_requests=issue_pr)
+ db.commit()
+
+
+def git_command(command, path):
+ process = subprocess.Popen(command, cwd=path, shell=True,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = process.communicate()
+ # err takes stdout
+ # if err:
+ # raise Exception(err)
+
+
+def git_workflow(db, issue_id, file_id):
+ try:
+ path = os.environ['GIT_PATH']
+ versions = map(lambda id: (db.version.get(id, 'name'),
db.version.get(id, 'order')),
+ db.issue.get(issue_id, 'versions'))
+ title = db.issue.get(issue_id, 'title')
+ commit_msg = 'Fixes issue bpo{} : {}'.format(issue_id, title)
+ if len(versions) == 0:
+ parent_branch = "master"
+ else:
+ version = versions.pop()
+ if version[1] == 1:
+ parent_branch = "master"
+ else:
+ parent_branch = version[0].split()[1]
+ branch_name = ''.join([random.choice(string.ascii_letters) for i in
range(random.choice(range(10, 20)))])
+ with TemporaryDirectory() as temp_dir:
+ filepath = os.path.join(temp_dir, db.file.get(file_id, 'name'))
+ content = db.file.get(file_id, 'content')
+ with open(filepath, 'wb') as fp:
+ fp.write(content)
+ git_command("git checkout {}".format(parent_branch), path)
+ git_command("git checkout -b {}".format(branch_name), path)
+ git_command("git apply {}".format(filepath), path)
+ git_command("git add -A", path)
+ git_command("git commit -m \"{}\"".format(commit_msg), path)
+ git_command("git push origin {}".format(branch_name), path)
+ git_command("git checkout {}".format(parent_branch), path)
+ git_command("git branch -D {}".format(branch_name), path)
+ create_pull_request(db, branch_name, parent_branch, issue_id,
title)
+ except Exception, message:
+ logging.error(message, exc_info=True)
+ raise ValueError('Error!')
+
+
def ispatch(file, types):
return posixpath.splitext(file)[1] in types
@@ -26,6 +113,7 @@ def patches_keyword(db, cl, nodeid, newvalues):
for fileid in newfiles:
if ispatch(db.file.get(fileid, 'name'), patchtypes):
newpatch = True
+ git_workflow(db, nodeid, fileid)
break
if newpatch:
# Add the patch keyword if its not already there
diff --git a/initial_data.py b/initial_data.py
index dc0ed4f..a9eee3a 100644
--- a/initial_data.py
+++ b/initial_data.py
@@ -49,13 +49,12 @@ component.create(name="Windows", order="18")
component.create(name="XML", order="19")
version = db.getclass('version')
-version.create(name='Python 3.1', order='1')
-version.create(name='Python 3.0', order='2')
-version.create(name='Python 2.7', order='3')
-version.create(name='Python 2.6', order='4')
-version.create(name='Python 2.5', order='5')
-version.create(name='Python 2.4', order='6')
-version.create(name='3rd party', order='7')
+version.create(name='Python 3.6', order='1')
+version.create(name='Python 3.5', order='2')
+version.create(name='Python 3.4', order='3')
+version.create(name='Python 3.3', order='4')
+version.create(name='Python 3.2', order='5')
+version.create(name='Python 2.7', order='6')
severity = db.getclass('severity')
_______________________________________________
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/