Skip to content

Commit

Permalink
Calculate and output new contributor boolean
Browse files Browse the repository at this point in the history
Signed-off-by: Zack Koppert <[email protected]>
  • Loading branch information
zkoppert committed Oct 10, 2023
1 parent 55a6567 commit c54afce
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 8 deletions.
15 changes: 14 additions & 1 deletion contributor_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# [
# {
# "username" : "zkoppert",
# "new_contributor" : "False",
# "avatar_url" : "https://avatars.githubusercontent.com/u/29484535?v=4",
# "contribution_count" : "1261",
# "commit_url" : "https://github.com/github/contributors/commits?author=zkoppert&since=2023-10-01&until=2023-10-05"
Expand All @@ -17,9 +18,13 @@ def __new__(cls, *args, **kwargs): # pylint: disable=unused-argument
"""Create a new contributor_stats object"""
return super().__new__(cls)

def __init__(self, username, avatar_url, contribution_count, commit_url):
def __init__(
self, username, new_contributor, avatar_url, contribution_count, commit_url
):
"""Initialize the contributor_stats object"""
new_contributor = False
self.username = username
self.new_contributor = new_contributor
self.avatar_url = avatar_url
self.contribution_count = contribution_count
self.commit_url = commit_url
Expand All @@ -28,6 +33,14 @@ def __repr__(self) -> str:
"""Return the representation of the contributor_stats object"""
return (
f"contributor_stats(username={self.username}, "
f"new_contributor={self.new_contributor}, "
f"avatar_url={self.avatar_url}, "
f"contribution_count={self.contribution_count}, commit_url={self.commit_url})"
)


def is_new_contributor(username: str, returning_contributors: list) -> bool:
"""Check if the contributor is new or returning"""
if username in returning_contributors:
return True
return False
31 changes: 30 additions & 1 deletion contributors.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,25 @@ def main():
github_connection,
)

# Check for new contributor if user provided start_date and end_date
if start_date and end_date:
## get the list of contributors from before start_date so we can see if contributors after start_date are new or returning
returning_contributors = get_all_contributors(
organization,
repository,
start_date="2008-02-29", # GitHub was founded on 2008-02-29
end_date=start_date,
github_connection=github_connection,
)
for contributor in contributors:
for user in contributor:
user.new_contributor = contributor_stats.is_new_contributor(
user.username, returning_contributors
)

# Output the contributors information
print(contributors)
markdown.write_to_markdown(contributors, "contributors.md")
markdown.write_to_markdown(contributors, "contributors.md", start_date, end_date)
# write_to_json(contributors)


Expand Down Expand Up @@ -68,6 +84,18 @@ def get_contributors(
if "[bot]" in user.login:
continue

# Check if user has commits in the date range
if start_date and end_date:
user_commits = repo.commits(
author=user.login, since=start_date, until=end_date
)

# If the user has no commits in the date range, skip them
try:
next(user_commits)
except StopIteration:
continue

# Store the contributor information in a ContributorStats object
if start_date and end_date:
commit_url = f"https://github.com/{repo.full_name}/commits?author={user.login}&since={start_date}&until={end_date}"
Expand All @@ -77,6 +105,7 @@ def get_contributors(
)
contributor = contributor_stats.ContributorStats(
user.login,
False,
user.avatar_url,
user.contributions_count,
commit_url,
Expand Down
17 changes: 13 additions & 4 deletions markdown.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
"""This module contains the functions needed to write the output to markdown files."""


def write_to_markdown(collaborators, filename):
def write_to_markdown(collaborators, filename, start_date, end_date):
"""
This function writes a list of collaborators to a markdown file in table format.
Each collaborator is represented as a dictionary with keys 'username', 'contribution_count', and 'commits'.
Each collaborator is represented as a dictionary with keys 'username', 'contribution_count', 'new_contributor', and 'commits'.
Args:
collaborators (list): A list of dictionaries, where each dictionary represents a collaborator.
Each dictionary should have the keys 'username', 'contribution_count', and 'commits'.
filename (str): The path of the markdown file to which the table will be written.
"""
headers = "| Username | Contribution Count | Commits |\n| --- | --- | --- |\n"
if start_date and end_date:
headers = "| Username | Contribution Count | New Contributor | Commits |\n| --- | --- | --- | --- |\n"
else:
headers = "| Username | Contribution Count | Commits |\n| --- | --- | --- |\n"

table = headers

for repo in collaborators:
for collaborator in repo:
username = collaborator.username
contribution_count = collaborator.contribution_count
commit_url = collaborator.commit_url
new_contributor = collaborator.new_contributor

if start_date and end_date:
row = f"| {username} | {contribution_count} | {new_contributor} | {commit_url} |\n"
else:
row = f"| {username} | {contribution_count} | {commit_url} |\n"

row = f"| {username} | {contribution_count} | {commit_url} |\n"
table += row

with open(filename, "w", encoding="utf-8") as markdown_file:
Expand Down
2 changes: 2 additions & 0 deletions test_contributor_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def setUp(self):
"""
self.contributor = ContributorStats(
"zkoppert",
False,
"https://avatars.githubusercontent.com/u/29484535?v=4",
"1261",
"commit_url5",
Expand All @@ -25,6 +26,7 @@ def test_init(self):
Test the __init__ method of the ContributorStats class.
"""
self.assertEqual(self.contributor.username, "zkoppert")
self.assertEqual(self.contributor.new_contributor, False)
self.assertEqual(
self.contributor.avatar_url,
"https://avatars.githubusercontent.com/u/29484535?v=4",
Expand Down
31 changes: 31 additions & 0 deletions test_contributors.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def test_get_contributors(self, mock_contributor_stats):

mock_contributor_stats.assert_called_once_with(
"user",
False,
"https://avatars.githubusercontent.com/u/12345678?v=4",
"100",
"https://github.com/owner/repo/commits?author=user&since=2022-01-01&until=2022-12-31",
Expand Down Expand Up @@ -97,6 +98,36 @@ def test_get_all_contributors_with_repository(self, mock_get_contributors):
"repo", "2022-01-01", "2022-12-31"
)

@patch("contributors.contributor_stats.ContributorStats")
def test_get_contributors_skip_users_with_no_commits(self, mock_contributor_stats):
"""
Test the get_contributors function skips users with no commits in the date range.
"""
mock_repo = MagicMock()
mock_user = MagicMock()
mock_user.login = "user"
mock_user.avatar_url = "https://avatars.githubusercontent.com/u/12345678?v=4"
mock_user.contributions_count = "100"
mock_user2 = MagicMock()
mock_user2.login = "user2"
mock_user2.avatar_url = "https://avatars.githubusercontent.com/u/12345679?v=4"
mock_user2.contributions_count = "102"

mock_repo.contributors.return_value = [mock_user]
mock_repo.full_name = "owner/repo"
mock_repo.get_commits.side_effect = StopIteration

get_contributors(mock_repo, "2022-01-01", "2022-12-31")

# Note that only user is returned and user2 is not returned here because there were no commits in the date range
mock_contributor_stats.assert_called_once_with(
"user",
False,
"https://avatars.githubusercontent.com/u/12345678?v=4",
"100",
"https://github.com/owner/repo/commits?author=user&since=2022-01-01&until=2022-12-31",
)


if __name__ == "__main__":
unittest.main()
8 changes: 6 additions & 2 deletions test_markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,33 @@ def test_write_to_markdown(self, mock_file):
"""
person1 = contributor_stats.ContributorStats(
"user1",
False,
"url",
100,
"commit url",
)
person2 = contributor_stats.ContributorStats(
"user2",
False,
"url2",
200,
"commit url2",
)
# Set person2 as a new contributor since this cannot be set on initiatization of the object
person2.new_contributor = True
collaborators = [
[
person1,
person2,
]
]

write_to_markdown(collaborators, "filename")
write_to_markdown(collaborators, "filename", "2023-01-01", "2023-01-02")

mock_file.assert_called_once_with("filename", "w", encoding="utf-8")
mock_file().write.assert_any_call("# Contributors\n\n")
mock_file().write.assert_any_call(
"| Username | Contribution Count | Commits |\n| --- | --- | --- |\n| user1 | 100 | commit url |\n| user2 | 200 | commit url2 |\n"
"| Username | Contribution Count | New Contributor | Commits |\n| --- | --- | --- | --- |\n| user1 | 100 | False | commit url |\n| user2 | 200 | True | commit url2 |\n"
)


Expand Down

0 comments on commit c54afce

Please sign in to comment.