diff --git a/tools/check_sources.py b/tools/check_sources.py old mode 100755 new mode 100644 diff --git a/tools/gh_api.py b/tools/gh_api.py index cb14a4c..d68bcc8 100644 --- a/tools/gh_api.py +++ b/tools/gh_api.py @@ -5,14 +5,12 @@ try: except NameError: pass -import os import re import sys import requests import getpass import json -from pathlib import Path try: import requests_cache @@ -82,28 +80,6 @@ def get_auth_token(): def make_auth_header(): return {'Authorization': 'token ' + get_auth_token()} -def post_issue_comment(project, num, body): - url = 'https://api.github.com/repos/{project}/issues/{num}/comments'.format(project=project, num=num) - payload = json.dumps({'body': body}) - requests.post(url, data=payload, headers=make_auth_header()) - -def post_gist(content, description='', filename='file', auth=False): - """Post some text to a Gist, and return the URL.""" - post_data = json.dumps({ - "description": description, - "public": True, - "files": { - filename: { - "content": content - } - } - }).encode('utf-8') - - headers = make_auth_header() if auth else {} - response = requests.post("https://api.github.com/gists", data=post_data, headers=headers) - response.raise_for_status() - response_data = json.loads(response.text) - return response_data['html_url'] def get_pull_request(project, num, auth=False): """get pull request info by number @@ -118,15 +94,6 @@ def get_pull_request(project, num, auth=False): response.raise_for_status() return json.loads(response.text, object_hook=Obj) -def get_pull_request_files(project, num, auth=False): - """get list of files in a pull request""" - url = "https://api.github.com/repos/{project}/pulls/{num}/files".format(project=project, num=num) - if auth: - header = make_auth_header() - else: - header = None - return get_paged_request(url, headers=header) - element_pat = re.compile(r'<(.+?)>') rel_pat = re.compile(r'rel=[\'"](\w+)[\'"]') @@ -149,17 +116,6 @@ def get_paged_request(url, headers=None, **params): break return results -def get_pulls_list(project, auth=False, **params): - """get pull request list""" - params.setdefault("state", "closed") - url = "https://api.github.com/repos/{project}/pulls".format(project=project) - if auth: - headers = make_auth_header() - else: - headers = None - pages = get_paged_request(url, headers=headers, **params) - return pages - def get_issues_list(project, auth=False, **params): """get issues list""" params.setdefault("state", "closed") @@ -205,100 +161,3 @@ def get_authors(pr): authors.append("%s <%s>" % (author['name'], author['email'])) return authors -# encode_multipart_formdata is from urllib3.filepost -# The only change is to iter_fields, to enforce S3's required key ordering - -def iter_fields(fields): - fields = fields.copy() - for key in ('key', 'acl', 'Filename', 'success_action_status', 'AWSAccessKeyId', - 'Policy', 'Signature', 'Content-Type', 'file'): - yield (key, fields.pop(key)) - for (k,v) in fields.items(): - yield k,v - -def encode_multipart_formdata(fields, boundary=None): - """ - Encode a dictionary of ``fields`` using the multipart/form-data mime format. - - :param fields: - Dictionary of fields or list of (key, value) field tuples. The key is - treated as the field name, and the value as the body of the form-data - bytes. If the value is a tuple of two elements, then the first element - is treated as the filename of the form-data section. - - Field names and filenames must be unicode. - - :param boundary: - If not specified, then a random boundary will be generated using - :func:`mimetools.choose_boundary`. - """ - # copy requests imports in here: - from io import BytesIO - from requests.packages.urllib3.filepost import ( - choose_boundary, six, writer, b, get_content_type - ) - body = BytesIO() - if boundary is None: - boundary = choose_boundary() - - for fieldname, value in iter_fields(fields): - body.write(b('--%s\r\n' % (boundary))) - - if isinstance(value, tuple): - filename, data = value - writer(body).write('Content-Disposition: form-data; name="%s"; ' - 'filename="%s"\r\n' % (fieldname, filename)) - body.write(b('Content-Type: %s\r\n\r\n' % - (get_content_type(filename)))) - else: - data = value - writer(body).write('Content-Disposition: form-data; name="%s"\r\n' - % (fieldname)) - body.write(b'Content-Type: text/plain\r\n\r\n') - - if isinstance(data, int): - data = str(data) # Backwards compatibility - if isinstance(data, six.text_type): - writer(body).write(data) - else: - body.write(data) - - body.write(b'\r\n') - - body.write(b('--%s--\r\n' % (boundary))) - - content_type = b('multipart/form-data; boundary=%s' % boundary) - - return body.getvalue(), content_type - - -def post_download(project, filename, name=None, description=""): - """Upload a file to the GitHub downloads area""" - if name is None: - name = Path(filename).name - with open(filename, 'rb') as f: - filedata = f.read() - - url = "https://api.github.com/repos/{project}/downloads".format(project=project) - - payload = json.dumps(dict(name=name, size=len(filedata), - description=description)) - response = requests.post(url, data=payload, headers=make_auth_header()) - response.raise_for_status() - reply = json.loads(response.content) - s3_url = reply['s3_url'] - - fields = dict( - key=reply['path'], - acl=reply['acl'], - success_action_status=201, - Filename=reply['name'], - AWSAccessKeyId=reply['accesskeyid'], - Policy=reply['policy'], - Signature=reply['signature'], - file=(reply['name'], filedata), - ) - fields['Content-Type'] = reply['mime_type'] - data, content_type = encode_multipart_formdata(fields) - s3r = requests.post(s3_url, data=data, headers={'Content-Type': content_type}) - return s3r diff --git a/tools/git-mpr.py b/tools/git-mpr.py deleted file mode 100755 index ef32c02..0000000 --- a/tools/git-mpr.py +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -Usage: - git-mpr [-h] [-l | -a] [pr-number [pr-number ...]] - -Type `git mpr -h` for details. -""" - - -import io, os -import argparse -from subprocess import check_call, CalledProcessError - -import gh_api - -ipy_repository = 'git://github.com/ipython/ipython.git' -gh_project = "ipython/ipython" -not_merged = {} - -def merge_branch(repo, branch ): - """try to merge the givent branch into the current one - - If something does not goes smoothly, merge is aborted - - Returns True if merge successful, False otherwise - """ - # Delete the branch first - try : - check_call(['git', 'pull', repo, branch], stdin=io.open(os.devnull)) - except CalledProcessError : - check_call(['git', 'merge', '--abort']) - return False - return True - - -def git_new_branch(name): - """Create a new branch with the given name and check it out. - """ - check_call(['git', 'checkout', '-b', name]) - - -def merge_pr(num): - """ try to merge the branch of PR `num` into current branch - """ - # Get Github authorisation first, so that the user is prompted straight away - # if their login is needed. - - pr = gh_api.get_pull_request(gh_project, num) - repo = pr['head']['repo']['clone_url'] - - - branch = pr['head']['ref'] - mergeable = merge_branch(repo=repo, - branch=branch, - ) - if not mergeable : - cmd = "git pull "+repo+" "+branch - not_merged[str(num)] = cmd - print("==============================================================================") - print("Something went wrong merging this branch, you can try it manually by running :") - print(cmd) - print("==============================================================================") - - -def main(*args): - parser = argparse.ArgumentParser( - description=""" - Merge one or more github pull requests by their number. If any - one pull request can't be merged as is, its merge is ignored - and the process continues with the next ones (if any). - """ - ) - - grp = parser.add_mutually_exclusive_group() - grp.add_argument( - '-l', - '--list', - action='store_const', - const=True, - help='list PR, their number and their mergeability') - grp.add_argument('-a', - '--merge-all', - action='store_const', - const=True , - help='try to merge as many PR as possible, one by one') - parser.add_argument('merge', - type=int, - help="The pull request numbers", - nargs='*', - metavar='pr-number') - args = parser.parse_args() - - if(args.list): - pr_list = gh_api.get_pulls_list(gh_project) - for pr in pr_list : - mergeable = gh_api.get_pull_request(gh_project, pr['number'])['mergeable'] - - ismgb = u"√" if mergeable else " " - print(u"* #{number} [{ismgb}]: {title}".format( - number=pr['number'], - title=pr['title'], - ismgb=ismgb)) - - if(args.merge_all): - branch_name = 'merge-' + '-'.join(str(pr['number']) for pr in pr_list) - git_new_branch(branch_name) - pr_list = gh_api.get_pulls_list(gh_project) - for pr in pr_list : - merge_pr(pr['number']) - - - elif args.merge: - branch_name = 'merge-' + '-'.join(map(str, args.merge)) - git_new_branch(branch_name) - for num in args.merge : - merge_pr(num) - - if not_merged : - print('*************************************************************************************') - print('The following branch has not been merged automatically, consider doing it by hand :') - for num, cmd in not_merged.items() : - print( "PR {num}: {cmd}".format(num=num, cmd=cmd)) - print('*************************************************************************************') - -if __name__ == '__main__': - main() diff --git a/tools/git-mrb b/tools/git-mrb deleted file mode 100755 index c1e3d82..0000000 --- a/tools/git-mrb +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python -"""git-mrb: merge remote branch. - -git mrb [remote:branch OR remote-branch] [onto] [upstream] - -remote must be locally available, and branch must exist in that remote. - -If 'onto' branch isn't given, default is 'master'. - -If 'upstream' repository isn't given, default is 'origin'. - -You can separate the remote and branch spec with either a : or a -. -""" -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from subprocess import check_call -import sys - -#----------------------------------------------------------------------------- -# Functions -#----------------------------------------------------------------------------- - -def sh(cmd): - cmd = cmd.format(**shvars) - print '$', cmd - check_call(cmd, shell=True) - -#----------------------------------------------------------------------------- -# Main Script -#----------------------------------------------------------------------------- - -argv = sys.argv[1:] -narg = len(argv) - -try: - branch_spec = argv[0] - sep = ':' if ':' in branch_spec else '-' - remote, branch = branch_spec.split(':', 1) - if not branch: - raise ValueError('Branch spec %s invalid, branch not found' % - branch_spec) -except: - import traceback as tb - tb.print_exc() - print __doc__ - sys.exit(1) - -onto = argv[1] if narg >= 2 else 'master' -upstream = argv[1] if narg == 3 else 'origin' - -# Git doesn't like ':' in branch names. -if sep == ':': - branch_spec = branch_spec.replace(':', '-') - -# Global used by sh -shvars = dict(remote=remote, branch_spec=branch_spec, branch=branch, - onto=onto, upstream=upstream) - -# Start git calls. -sh('git fetch {remote}') -sh('git checkout -b {branch_spec} {onto}') -sh('git merge {remote}/{branch}') - -print """ -************************************************************* - Run test suite. If tests pass, run the following to merge: - -git checkout {onto} -git merge {branch_spec} -git push {upstream} {onto} - -************************************************************* -""".format(**shvars) - -ans = raw_input("Revert to master and delete temporary branch? [Y/n]: ") -if ans.strip().lower() in ('', 'y', 'yes'): - sh('git checkout {onto}') - sh('git branch -D {branch_spec}') diff --git a/tools/github_stats.py b/tools/github_stats.py old mode 100755 new mode 100644 index b5976b0..f1a44fa --- a/tools/github_stats.py +++ b/tools/github_stats.py @@ -10,7 +10,6 @@ To generate a report for IPython 2.0, run: #----------------------------------------------------------------------------- -import codecs import sys from argparse import ArgumentParser diff --git a/tools/make_tarball.py b/tools/make_tarball.py old mode 100755 new mode 100644 diff --git a/tools/mknbindex.py b/tools/mknbindex.py deleted file mode 100755 index 2489f7c..0000000 --- a/tools/mknbindex.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python -"""Simple script to auto-generate the index of notebooks in a given directory. -""" - -import glob -import urllib - -notebooks = sorted(glob.glob('*.ipynb')) - -tpl = ( '* [{0}](http://nbviewer.ipython.org/url/github.com/ipython/ipython/' - 'raw/master/examples/notebooks/{1})' ) - -idx = [ -"""# A collection of Notebooks for using IPython effectively - -The following notebooks showcase multiple aspects of IPython, from its basic -use to more advanced scenarios. They introduce you to the use of the Notebook -and also cover aspects of IPython that are available in other clients, such as -the cell magics for multi-language integration or our extended display -protocol. - -For beginners, we recommend that you start with the 5-part series that -introduces the system, and later read others as the topics interest you. - -Once you are familiar with the notebook system, we encourage you to visit our -[gallery](https://github.com/ipython/ipython/wiki/A-gallery-of-interesting-IPython-Notebooks) -where you will find many more examples that cover areas from basic Python -programming to advanced topics in scientific computing. -"""] - -idx.extend(tpl.format(nb.replace('.ipynb',''), urllib.quote(nb)) - for nb in notebooks) - -with open('README.md', 'w') as f: - f.write('\n'.join(idx)) - f.write('\n') diff --git a/tools/release b/tools/release index 45fb7e4..29506ce 100755 --- a/tools/release +++ b/tools/release @@ -12,7 +12,6 @@ import sys from toollib import (get_ipdir, pjoin, cd, execfile, sh, archive, archive_user, archive_dir) -from gh_api import post_download # Get main ipython dir, this will raise if it doesn't pass some checks ipdir = get_ipdir() @@ -53,12 +52,6 @@ if 'upload' in sys.argv: # do not upload OS specific files like .DS_Store to_upload = glob('*.whl')+glob('*.tar.gz') - for fname in to_upload: - # TODO: update to GitHub releases API - continue - print('uploading %s to GitHub' % fname) - desc = "IPython %s source distribution" % version - post_download("ipython/ipython", fname, description=desc) # Make target dir if it doesn't exist print('1. Uploading IPython to archive.ipython.org') diff --git a/tools/update_whatsnew.py b/tools/update_whatsnew.py old mode 100755 new mode 100644