Index: hgreview.py |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/hgreview.py |
@@ -0,0 +1,80 @@ |
+import os |
+import re |
+import subprocess |
+import sys |
+import urllib |
+ |
+from mercurial import cmdutil, error |
+ |
+cmdtable = {} |
+command = cmdutil.command(cmdtable) |
+ |
+@command('review', |
Sebastian Noack
2016/03/10 12:31:05
Note that cmdutil isn't a standard library. IMO th
Wladimir Palant
2016/03/10 12:36:36
No, it isn't a standard library but it is document
Sebastian Noack
2016/03/10 12:44:28
I just realized that this is a Mercurial extension
|
+ [ |
+ ('i', 'issue', '', 'If given, adds a patch set to this review, otherwise create a new one.', 'ISSUE'), |
+ ('r', 'revision', '', 'Revision to diff against or a revision range to upload.', 'REV'), |
+ ('c', 'change', '', 'A single revision to upload.', 'REV'), |
+ ('t', 'title', '', 'New review subject or new patch set title.', 'TITLE'), |
+ ('m', 'message', '', 'New review description or new patch set message.', 'MESSAGE'), |
+ ('w', 'reviewers', '', 'Add reviewers (comma separated email addresses or @adblockplus.org user names).', 'REVIEWERS'), |
+ ('', 'cc', '', 'Add CC (comma separated email addresses or @adblockplus.org user names).', 'CC'), |
+ ('', 'private', None, 'Make the review restricted to reviewers and those CCed.'), |
+ ('y', 'assume_yes', None, 'Assume that the answer to yes/no questions is \'yes\'.'), |
+ ('', 'print_diffs', None, 'Print full diffs.'), |
+ ], '[options] [path...]') |
+def review(ui, repo, *paths, **opts): |
+ ''' |
+ Uploads a review to https://codereview.adblockplus.org/ or updates an |
+ existing review request. This will always send mails for new reviews, when |
+ updating a review mails will only be sent if a message is given. |
+ ''' |
+ args = ['--oauth2'] |
+ if ui.debugflag: |
+ args.append('--noisy') |
+ elif ui.verbose: |
+ args.append('--verbose') |
+ elif ui.quiet: |
+ args.append('--quiet') |
+ |
+ if opts.get('issue') or opts.get('message'): |
+ args.append('--send_mail') |
+ |
+ if opts.get('revision') and opts.get('change'): |
+ raise error.Abort('Ambiguous revision range, only one of --revision and --change can be specified.') |
+ if opts.get('change'): |
+ args.extend(['--rev', '{0}^:{0}'.format(opts['change'])]) |
+ elif opts.get('revision'): |
+ args.extend(['--rev', opts['revision']]) |
+ else: |
+ raise error.Abort('What should be reviewed? Either --revision or --change is required.') |
+ |
+ if not opts.get('title') and not opts.get('issue') and opts.get('change'): |
+ opts['title'] = repo[opts['change']].description() |
+ |
+ if not opts.get('issue') and not opts.get('reviewers'): |
+ raise error.Abort('Please specify --reviewers for your new review.') |
+ for opt in ('reviewers', 'cc'): |
+ if opts.get(opt): |
+ users = [u if '@' in u else u + '@adblockplus.org' |
+ for u in re.split(r'\s*,\s*', opts[opt])] |
+ opts[opt] = ','.join(users) |
+ |
+ for opt in ('issue', 'title', 'message', 'reviewers', 'cc'): |
+ if opts.get(opt, ''): |
+ args.extend(['--' + opt, opts[opt]]) |
+ |
+ for opt in ('private', 'assume_yes', 'print_diffs'): |
+ if opts.get(opt, False): |
+ args.append('--' + opt) |
+ |
+ args += paths |
Sebastian Noack
2016/03/10 12:31:05
Nit: Why not modifying args inline as above using
Wladimir Palant
2016/03/10 12:36:36
Done.
|
+ |
+ upload_path = ui.config('review', 'uploadtool_path', |
+ os.path.join('~', '.hgreview_upload.py')) |
+ upload_path = os.path.expanduser(upload_path) |
+ if not os.path.exists(upload_path): |
+ url = 'https://codereview.adblockplus.org/static/upload.py' |
+ ui.status('Downloading {0} to {1}.\n'.format(url, upload_path)) |
+ urllib.urlretrieve(url, upload_path) |
+ |
+ subprocess.call([sys.executable, upload_path] + args) |