Skip to content

Instantly share code, notes, and snippets.

@eteq
Created February 6, 2012 08:23
Show Gist options
  • Save eteq/1750715 to your computer and use it in GitHub Desktop.
Save eteq/1750715 to your computer and use it in GitHub Desktop.
Python function/script to convert github issues to pull requests
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Requires python >=2.6
"""
Tool to convert github issues to pull requests by attaching code. Uses the
github v3 API. Defaults assumed for the `astropy <http://www.astropy.org>`_
project.
"""
from __future__ import print_function
def issue_to_pr(issuenum, srcbranch, repo='astropy', targetuser='astropy',
targetbranch='master', username=None, pw=None,
baseurl='https://api.github.com'):
"""
Attaches code to an issue, converting a regular issue into a pull request.
Parameters
----------
issuenum : int
The issue number (in `targetuser`/`repo`) onto which the code should be
attached.
srcbranch : str
The branch (in `username`/`repo`) the from which to attach the code.
After this is complete, further updates to this branch will be passed
on to the pull request.
repo : str
The name of the repository (the same-name repo should be present for
both `targetuser` and `username`).
targetuser : str
The name of the user/organization that has the issue.
targetbranch : str
The name of the branch (in `targetuser`/`repo`) that the pull request
should merge into.
username : str or None
The name of the user sourcing the pull request. If None, the caller
will be prompted for their name at the terminal.
pw : str or None
The password of the user sourcing the pull request. If None, the
caller will be prompted for their name at the terminal (text will be
hidden).
baseurl : str
The URL to use to access the github site (including protocol).
.. warning::
Be cautious supplying `pw` as a string - if you do this in an ipython
session, for example, it will be logged in the input history, revealing
your password in clear text. When in doubt, leave it as `None`,
as this will securely prompt you for your password.
Returns
-------
response : str
The json-decoded response from the github server.
error message : str, optional
If present, indicates github responded with an HTTP error.
"""
import urllib
import urllib2
import getpass
import json
if username is None:
username = raw_input('Username: ')
if pw is None:
pw = getpass.getpass()
data = {'issue': str(issuenum),
'head': username + ':' + srcbranch,
'base': targetbranch}
datajson = json.dumps(data)
suburl = 'repos/{user}/{repo}/pulls'.format(user=targetuser, repo=repo)
url = urllib.basejoin(baseurl, suburl)
req = urllib2.Request(url)
req.add_data(datajson)
_add_basic_auth_header(req, username, pw)
try:
response = urllib2.urlopen(req)
except urllib2.HTTPError, e:
print('HTTP Error', e)
res = e.fp.read()
return json.loads(res), str(e)
res = response.read()
return json.loads(res)
def _add_basic_auth_header(req, username, pw):
from base64 import b64encode
upwstr = username + ':' + pw
upwstrenc = b64encode(upwstr.encode('utf-8')).strip().decode('utf-8')
req.add_header('Authorization', 'Basic ' + upwstrenc)
if __name__ == '__main__':
import sys
if sys.version_info < (2,6):
print('issue2pr.py requires Python >=2.6, exiting')
sys.exit(-1)
import argparse
descr = 'Convert a github issue to a Pull Request by attaching code.'
parser = argparse.ArgumentParser(description=descr)
parser.add_argument('srcbranch', metavar='BRANCH', type=str, help='The '
'name of the branch in the source (user\'s) repository '
'that is to be pulled into the target.')
parser.add_argument('issuenum', metavar='ISSUE', type=int,
help='The issue number from the target repository')
parser.add_argument('--repo', metavar='REPO', type=str,
default='astropy', help='The name of the repository '
'of the issue and code. must have the same name for '
'both target and source (default: astropy)')
parser.add_argument('--targetuser', metavar='USER', type=str,
default='astropy', help='The name of the '
'user/organization the pull request should pull into '
'(default: astropy)')
parser.add_argument('--targbranch', metavar='BRANCH', type=str,
default='master', help='The branch name the pull '
'request should be pulled into (default: master)')
parser.add_argument('--baseurl', metavar='URL', type=str,
default='https://api.github.com', help='The base '
'URL for github (default: https://api.github.com)')
args = parser.parse_args()
targrepo = args.targetuser + '/' + args.repo
print('Converting issue', args.issuenum, 'of', targrepo, 'to pull request')
print('Will request to pull branch', args.srcbranch, 'of user\'s',
args.repo, 'repo to branch', args.targbranch, 'of ', targrepo)
issue_to_pr(args.issuenum, args.srcbranch, args.repo, args.targetuser,
args.targbranch, None, None, args.baseurl)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment