Skip to content

Commit bfbb217

Browse files
committed
Mimic git-quick-stats suggestReviewers()
* Adjust the previous function to mimic what suggestReviewers() does when you execute it in git-quick-stats. This matches the output of the bash version when run side-by-side. Also, renamed the function to look more similar to the original bash function. Updated test cases as appropriate Note that it does not handle the adjustable options such as $_since, $_until, etc yet. * Added .toml file to prepare for dist building and pip distribution
1 parent 465bfdb commit bfbb217

File tree

5 files changed

+73
-27
lines changed

5 files changed

+73
-27
lines changed

git_py_stats/interactive_mode.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def handle_interactive_mode() -> None:
2929
'19': lambda: list_cmds.git_commits_per_hour(input("Enter author name: ")),
3030
'20': list_cmds.git_commits_per_timezone,
3131
'21': lambda: list_cmds.git_commits_per_timezone(input("Enter author name: ")),
32-
'22': suggest_cmds.code_reviewers,
32+
'22': suggest_cmds.suggest_reviewers,
3333
}
3434

3535
while True:

git_py_stats/non_interactive_mode.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def handle_non_interactive_mode(args) -> None:
3434
'commits_by_author_by_hour': lambda: list_cmds.git_commits_per_hour(args.commits_by_author_by_hour),
3535
'commits_by_timezone': list_cmds.git_commits_per_timezone,
3636
'commits_by_author_by_timezone': lambda: list_cmds.git_commits_per_timezone(args.commits_by_author_by_timezone),
37-
'suggest_reviewers': suggest_cmds.code_reviewers,
37+
'suggest_reviewers': suggest_cmds.suggest_reviewers,
3838
}
3939

4040
# Call the appropriate function based on the command-line argument

git_py_stats/suggest_cmds.py

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,73 @@
1-
"""
2-
Functions related to the 'Suggest' section.
3-
"""
4-
5-
from collections import Counter
1+
import subprocess
2+
from collections import defaultdict
63

74
from git_py_stats.git_operations import run_git_command
85

9-
10-
def code_reviewers() -> None:
6+
def suggest_reviewers() -> None:
117
"""
128
Suggests potential code reviewers based on commit history.
139
"""
14-
cmd = ['git', 'log', '--format=%ae', '--no-merges']
15-
output = run_git_command(cmd)
16-
17-
if output:
18-
emails = output.split('\n')
19-
counter = Counter(emails)
20-
reviewers = [email for email, count in counter.items()]
21-
22-
if reviewers:
10+
11+
# Construct the git log command with all options. Original command is:
12+
# git -c log.showSignature=false log --use-mailmap $_merges "$_since" "$_until" \
13+
# --pretty=%aN $_log_options $_pathspec | head -n 100 | sort | uniq -c \
14+
# | sort -nr
15+
# Then some LC_ALL portion which is currently not important
16+
# Then pipe it all into column -t -s
17+
#
18+
# For now, let's just hardcode some of this stuff
19+
cmd = ['git', '-c', 'log.showSignature=false', 'log', '--use-mailmap', '--no-merges', '--pretty=%aN']
20+
21+
try:
22+
# Execute the git command and get the output
23+
output = run_git_command(cmd)
24+
25+
# Check if output is empty
26+
if not output:
27+
print('No data available.')
28+
return
29+
30+
# Split the output into lines (each line is a commit author)
31+
lines = output.splitlines()
32+
33+
# Mimic "head -n 100"
34+
head_lines = lines[:100]
35+
36+
# Mimic "sort"
37+
sorted_lines = sorted(head_lines)
38+
39+
# Mimic "uniq -c"
40+
counted_authors = []
41+
current_author = None
42+
current_count = 0
43+
44+
# Iterate over sorted lines and count consecutive duplicates
45+
for author in sorted_lines:
46+
if author == current_author:
47+
current_count += 1
48+
else:
49+
if current_author is not None:
50+
counted_authors.append((current_count, current_author))
51+
current_author = author
52+
current_count = 1
53+
54+
# Append the last counted author
55+
if current_author is not None:
56+
counted_authors.append((current_count, current_author))
57+
58+
# Sort by count descending, and by name ascending
59+
sorted_authors = sorted(counted_authors, key=lambda x: (-x[0], x[1]))
60+
61+
# Print results similar to "column -t -s"
62+
if sorted_authors:
2363
print("Suggested code reviewers based on git history:")
24-
for reviewer in reviewers:
25-
print(reviewer)
64+
for count, author in sorted_authors:
65+
# Pad output with 7 to match original code's behavior
66+
# TODO: Bit of a magic number we can remove later
67+
print(f"{count:7} {author}")
2668
else:
27-
print('No potential reviewers found. Consider using a larger dataset.')
28-
else:
29-
print('No data available.')
69+
print("No potential reviewers found.")
70+
71+
except subprocess.CalledProcessError as e:
72+
print(f"Error executing git command: {e}")
3073

git_py_stats/tests/test_suggest_cmds.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ class TestSuggestCmds(unittest.TestCase):
1111

1212
# Don't print to stdout
1313
@patch('git_py_stats.suggest_cmds.print')
14-
def test_code_reviewers(self, mock_print) -> None:
14+
def test_suggest_reviewers(self, mock_print) -> None:
1515
"""
16-
Test case for code_reviewers in suggest_cmds
16+
Test case for suggest_reviewers in suggest_cmds
1717
18-
Checks if `code_reviewers` executes without errors, and it uses
18+
Checks if `suggest_reviewers` executes without errors, and it uses
1919
`unittest.mock.patch` to mock the print function to prevent actual
2020
output during testing.
2121
2222
Verifies that the function returns `None` and calls the print function
2323
at least once, indicating that some output was generated.
2424
"""
2525

26-
result = suggest_cmds.code_reviewers()
26+
result = suggest_cmds.suggest_reviewers()
2727
self.assertIsNone(result)
2828
mock_print.assert_called()
2929

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[build-system]
2+
requires = ["setuptools>=61.0"]
3+
build-backend = "setuptools.build_meta"

0 commit comments

Comments
 (0)