Skip to content

Instantly share code, notes, and snippets.

@thewtex
Created November 12, 2010 13:43
Show Gist options
  • Save thewtex/674093 to your computer and use it in GitHub Desktop.
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.
#!/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