Created
November 12, 2010 13:43
-
-
Save thewtex/674093 to your computer and use it in GitHub Desktop.
Add authors of the files that were changed as reviewers to a Gerrit submission.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
info = """Add reviewers to a Gerrit change. | |
Authors of files that were edited are nominated as potential reviewers. | |
*Caveats* | |
- Should be executed from the root of the repository. | |
- Should be executed while checked out on the topic branch to be pushed to | |
Gerrit. | |
- Should be executed when ready to perform the initial Gerrit push. | |
""" | |
import subprocess | |
import sys | |
def get_authors(): | |
p = subprocess.Popen("git log --follow --format='%aN*%aE' -- $(git diff-index --name-only \ | |
master) | sort | uniq", shell=True, stdout=subprocess.PIPE, | |
universal_newlines=True) | |
p.wait() | |
authors = p.stdout.readlines() | |
# remove the newline and split | |
authors = [ a.rstrip().split( '*' ) for a in authors ] | |
p = subprocess.Popen( "git config user.name", shell=True, | |
stdout=subprocess.PIPE, universal_newlines=True ) | |
p.wait() | |
myname = p.stdout.readline().rstrip() | |
p = subprocess.Popen( "git config user.email", shell=True, | |
stdout=subprocess.PIPE, universal_newlines=True ) | |
p.wait() | |
myemail = p.stdout.readline()[:-1].rstrip() | |
try: | |
authors.remove( [myname, myemail] ) | |
except ValueError: | |
pass | |
author_dict = {} | |
for a in authors: | |
author_dict[a[1]] = a[0] | |
return author_dict | |
class ReviewerSelector( object ): | |
def __init__( self, reviewers ): | |
self.reviewers = reviewers | |
self._count_reviewers_changes() | |
request_review = {} | |
for r in reviewers.keys(): | |
if self.reviewer_changes[r] > 1: | |
request_review[r] = True | |
else: | |
request_review[r] = False | |
self.request_review = request_review | |
def run( self ): | |
e = 1 | |
while e: | |
self._select_reviewers() | |
e = self._push_to_gerrit() | |
if e == 0: | |
print( 'Gerrit push success!' ) | |
else: | |
print( 'Gerrit push failure!' ) | |
def _count_reviewers_changes( self ): | |
reviewer_changes = {} | |
for email, name in self.reviewers.items(): | |
p = subprocess.Popen('git log --author="' + name + '" --follow --oneline \ | |
--numstat --since="5 years ago" -- $(git diff-index --name-only \ | |
master)', shell=True, stdout=subprocess.PIPE, | |
universal_newlines=True) | |
p.wait() | |
lines = p.stdout.readlines() | |
lines = lines[1::2] | |
count = 0 | |
for l in lines: | |
ls = l.split() | |
count += int( ls[0] ) + int( ls[1] ) | |
reviewer_changes[email] = count | |
self.reviewer_changes = reviewer_changes | |
sorted_reviewers = sorted( reviewer_changes.items(), key=lambda rc: rc[1] ) | |
reviewer_order = {} | |
for i,r in enumerate( sorted_reviewers ): | |
reviewer_order[i] = r[0] | |
self.reviewer_order = reviewer_order | |
def _print_potential_reviewers( self ): | |
print( '\n%s %s %-20s %-30s %s\n' % ('A', 'B', | |
'C', 'D', 'E') ) | |
for i in range( len( self.reviewers ) ): | |
r = self.reviewer_order[i] | |
if self.request_review[r]: | |
will_review='*' | |
else: | |
will_review=' ' | |
print( '%s [%2d] %-20s %-30s %d' % (will_review, i, | |
self.reviewers[r], r, self.reviewer_changes[r]) ) | |
print( "\nA = Will request review\nB = Number for toggling\nC = Name\nD = Email\nE = Line count of changes in edited files over the past 5 years\n" ) | |
def _select_reviewers( self ): | |
making_changes = True | |
while making_changes: | |
self._print_potential_reviewers() | |
sys.stdout.write( 'q=quit a=select_all n=select_none nums=toggle nothing=push: ' ) | |
sys.stdout.flush() | |
user_input = sys.stdin.readline().rstrip() | |
if user_input == '': | |
making_changes = False | |
elif user_input == 'q': | |
sys.exit(0) | |
elif user_input == 'a': | |
for r in self.reviewers.keys(): | |
self.request_review[r] = True | |
elif user_input == 'n': | |
for r in self.reviewers.keys(): | |
self.request_review[r] = False | |
else: | |
indices = [ int(x) for x in user_input.split() ] | |
for i in indices: | |
self.request_review[self.reviewer_order[i]] = not self.request_review[self.reviewer_order[i]] | |
def _push_to_gerrit( self ): | |
push_cmd = 'git push --receive-pack=\'git receive-pack' | |
for r in self.reviewers: | |
if self.request_review[r]: | |
push_cmd += ' --reviewer ' + r | |
push_cmd += "' gerrit HEAD:refs/for/master/$(git symbolic-ref HEAD | sed -e 's|^refs/heads/||')" | |
e = subprocess.call( push_cmd, shell=True ) | |
return e | |
def main(): | |
authors = get_authors() | |
reviewer_selector = ReviewerSelector( authors ) | |
reviewer_selector.run() | |
if __name__ == '__main__': | |
if len( sys.argv ) > 1: | |
if sys.argv[1] == '-h' or sys.argv[1] == '--help': | |
print( info ) | |
sys.exit( 0 ) | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment