Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions reviewers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from collections import defaultdict
import operator
import os
import re


def prompt_for_user():
while True:
try:
user_input = input("\nName or email (case insensitive): ")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Since we're just checking the prefix of the name (or email), not sure if we should mention that here.

except (KeyboardInterrupt, EOFError):
return None
clean_input = user_input.strip().lower()
if clean_input != "":
return clean_input


if __name__ == "__main__":
print("Utility to help generate 'Reviewers' string for Pull Requests. Use Ctrl+D or Ctrl+C to exit")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both Ctrl+C and Ctrl+D print the selected reviewers? If not, we should mention that.

Either way, I think we should mention that they need to Ctrl+D to print the selected reviewers.


stream = os.popen("git log | grep Reviewers")
Comment thread
mumrah marked this conversation as resolved.
lines = stream.readlines()
all_reviewers = defaultdict(int)
for line in lines:
stripped = line.strip().lstrip("Reviewers: ")
reviewers = stripped.split(",")
for reviewer in reviewers:
all_reviewers[reviewer.strip()] += 1
parsed_reviewers = []

for item in all_reviewers.items():
m = re.match("(?P<name>.*)\s<(?P<email>.*)>", item[0])
if m is not None and len(m.groups()) == 2:
if item[1] > 2:
parsed_reviewers.append((m.group("name"), m.group("email"), item[1]))

selected_reviewers = []
while True:
if len(selected_reviewers) != 0:
print(f"Reviewers so far: {selected_reviewers}")
user_input = prompt_for_user()
if user_input is None:
break
candidates = []
for reviewer, email, count in parsed_reviewers:
if reviewer.lower().startswith(user_input) or email.lower().startswith(user_input):
candidates.append((reviewer, email, count))
if len(candidates) == 10:
break
if len(candidates) == 0:
continue

print("\nPossible matches (in order of most recent):")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention that the number in the parenthesis is the number of occurrences? How about something like:

        print("\nMatches order by most recent (the number in the parenthesis is the number of occurrences):")

or we can change the formatting to something like:

Name <email> (reviews=123)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention we only list top 10 candidates?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@showuon the zip + range(10) has the effect of only showing the top 10

for i, candidate in zip(range(10), candidates):
print(f"[{i+1}] {candidate[0]} {candidate[1]} ({candidate[2]})")
Comment thread
mumrah marked this conversation as resolved.

try:
selection_input = input("\nMake a selection: ")
selected_candidate = candidates[int(selection_input)-1]
selected_reviewers.append(selected_candidate)
except (EOFError, KeyboardInterrupt):
break
except (ValueError, IndexError):
print("Invalid selection")
continue

if len(selected_reviewers) != 0:
out = "\n\nReviewers: "
out += ", ".join([f"{name} <{email}>" for name, email, _ in selected_reviewers])
out += "\n"
print(out)