Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 1 addition & 0 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ plugins:
show_contribution: true
show_line_count: true
show_email_address: true
add_co_authors: true
Copy link
Owner

Choose a reason for hiding this comment

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

false (this is the default)

Copy link
Owner

Choose a reason for hiding this comment

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

can you also add the documentation of the option lower down in this file?

href: "mailto:{email}"
count_empty_lines: true
fallback_to_empty: false
Expand Down
1 change: 1 addition & 0 deletions src/mkdocs_git_authors_plugin/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class GitAuthorsPluginConfig(Config):
show_contribution = config_options.Type(bool, default=False)
show_line_count = config_options.Type(bool, default=False)
show_email_address = config_options.Type(bool, default=True)
add_co_authors = config_options.Type(bool, default=False)
href = config_options.Type(str, default="mailto:{email}")
count_empty_lines = config_options.Type(bool, default=True)
fallback_to_empty = config_options.Type(bool, default=False)
Expand Down
15 changes: 14 additions & 1 deletion src/mkdocs_git_authors_plugin/git/commit.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import re
from typing import Union
from typing import Any, Union, List

from mkdocs_git_authors_plugin import util
from mkdocs_git_authors_plugin.git.repo import AbstractRepoObject, Repo
Expand All @@ -24,6 +24,7 @@ def __init__(
author_time: str,
author_tz: str,
summary: str,
co_authors: List[Any],
):
"""Initialize a commit from its SHA.

Expand All @@ -48,6 +49,7 @@ def __init__(
self._datetime = util.commit_datetime(author_time, author_tz)
self._datetime_string = util.commit_datetime_string(self._datetime)
self._summary = summary
self._co_authors = co_authors

def author(self):
"""
Expand All @@ -60,6 +62,17 @@ def author(self):
"""
return self._author

def co_authors(self):
"""
The commit's co-author.

Args:

Returns:
Co-Authors list
"""
return self._co_authors

def datetime(self, _type=str) -> Union[str, util.datetime]:
"""
The commit's commit time.
Expand Down
79 changes: 9 additions & 70 deletions src/mkdocs_git_authors_plugin/git/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,76 +198,15 @@ def _process_git_blame(self) -> None:
self.add_total_lines()
self.repo().add_total_lines()
# Process co-authors if present
self._process_git_log(commit_data.get("sha"), commit)

def _process_git_log(self, sha, commit) -> None:
"""
Execute git log and parse the results.

This retrieves [co-authors](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors) from comment.
Each line will be associated with a Commit object and counted
to its co-author's "account".
Whether empty lines are counted is determined by the
count_empty_lines configuration option.

git log -1 <sha> will produce output like the following
for each line in a file:

When a commit does not contain co-authors:
commit ca8b32b24af1ce97fb29c5139b2f80e0c2ad9d1c
Author: John Doe <[email protected]>
Date: Sun Dec 22 11:10:32 2019 +0100

add plugin skeleton

When a commit contains co-authors:
commit ca8b32b24af1ce97fb29c5139b2f80e0c2ad9d1c
Author: John Doe <[email protected]>
Date: Sun Dec 22 11:10:32 2019 +0100

add plugin skeleton

Co-authored-by: John Doe <[email protected]>
Co-authored-by: Rock Smith <[email protected]>

In this case we skip the original author as redundant using email address to detect it.

Args:
sha: the SHA of the commit to process
Returns:
--- (this method works through side effects)
"""

args = []
args.append("-1") # Only existing sha
args.append(sha)
cmd = GitCommand("log", args)
cmd.run()

lines = cmd.stdout()

# in case of empty, non-committed files, raise error
if len(lines) == 0:
raise GitCommandError

ignore_authors = self.repo().config("ignore_authors")
for line in lines:
if line.startswith("Author: "):
# skip author as already available in Commit object
continue

result = re.search(r"Co-authored-by: (.*) <(.*)>", line)
if result is not None and result.group(1) != "" and result.group(2) != "":
# Extract co-authors from the commit
co_author = self.repo().author(result.group(1), result.group(2))
if (
co_author.email() not in ignore_authors
and co_author.email() != commit.author().email()
):
# Create the co-author
if co_author not in self._authors:
self._authors.append(co_author)
co_author.add_lines(self, commit)
for co_author in commit.co_authors():
# Create the co-author
if (
co_author.email() not in ignore_authors
and co_author.email() != commit.author().email()
):
if co_author not in self._authors:
self._authors.append(co_author)
co_author.add_lines(self, commit)

def path(self) -> Path:
"""
Expand Down
72 changes: 70 additions & 2 deletions src/mkdocs_git_authors_plugin/git/repo.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import re
from pathlib import Path
from typing import Any, Union
from typing import Any, Union, List

from mkdocs_git_authors_plugin.git.command import GitCommand

from mkdocs_git_authors_plugin.git.command import GitCommandError


class Repo(object):
"""
Expand Down Expand Up @@ -49,7 +52,7 @@ def author(self, name, email: str):
self._authors[email] = Author(self, name, email)
return self._authors[email]

def get_authors(self) -> list:
def get_authors(self) -> List[Any]:
"""
Sorted list of authors in the repository.

Expand Down Expand Up @@ -113,9 +116,74 @@ def get_commit(self, sha: str, **kwargs) -> Union[Any, None]:
if not self._commits.get(sha):
from .commit import Commit

if self.config("add_co_authors"):
kwargs["co_authors"] = self._get_co_authors(sha)
else:
kwargs["co_authors"] = []
self._commits[sha] = Commit(self, sha, **kwargs)
return self._commits.get(sha)

def _get_co_authors(self, sha) -> List[Any]:
"""
Execute git log and parse the results.

This retrieves [co-authors](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors) from comment.
Each line will be associated with a Commit object and counted
to its co-author's "account".
Whether empty lines are counted is determined by the
count_empty_lines configuration option.

git log -1 <sha> will produce output like the following
for each line in a file:

When a commit does not contain co-authors:
commit ca8b32b24af1ce97fb29c5139b2f80e0c2ad9d1c
Author: John Doe <[email protected]>
Date: Sun Dec 22 11:10:32 2019 +0100

add plugin skeleton

When a commit contains co-authors:
commit ca8b32b24af1ce97fb29c5139b2f80e0c2ad9d1c
Author: John Doe <[email protected]>
Date: Sun Dec 22 11:10:32 2019 +0100

add plugin skeleton

Co-authored-by: John Doe <[email protected]>
Co-authored-by: Rock Smith <[email protected]>

In this case we skip the original author as redundant using email address to detect it.

Args:
sha: the SHA of the commit to process
author_email: email of the author
Returns:
List of co-authors excluding commit author
"""
args = ["-1", sha]
cmd = GitCommand("log", args)
cmd.run()

lines = cmd.stdout()

# in case of empty, non-committed files, raise error
if len(lines) == 0:
raise GitCommandError
co_authors = []

for line in lines:
if line.startswith("Author: "):
# skip author as already available in Commit object
continue

result = re.search(r"Co-authored-by: (.*) <(.*)>", line)
if result is not None and result.group(1) != "" and result.group(2) != "":
# Extract co-authors from the commit
co_author = self.author(result.group(1), result.group(2))
co_authors.append(co_author)
return co_authors

def page(self, path):
"""
Return the (cached) Page object for given path.
Expand Down
9 changes: 9 additions & 0 deletions tests/basic_setup/mkdocs_add_co_authors.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
site_name: test gitauthors_plugin
use_directory_urls: true

plugins:
- search
- git-authors:
add_co_authors: true
ignore_authors:
- '[email protected]'
2 changes: 1 addition & 1 deletion tests/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def test_ignore_authors_working(tmp_path) -> None:


def test_co_authors_working(tmp_path) -> None:
result = build_docs_setup("tests/basic_setup/mkdocs_ignore_authors.yml", tmp_path)
result = build_docs_setup("tests/basic_setup/mkdocs_add_co_authors.yml", tmp_path)
assert (
result.exit_code == 0
), f"'mkdocs build' command failed. Error: {result.stdout}"
Expand Down