Skip to content

Commit 9277f8c

Browse files
TimiMakkonentimvink
authored andcommitted
Issue #90 | Sort page authors by page contribution, not site contribution
* fixes #90
1 parent 3c10d6a commit 9277f8c

File tree

2 files changed

+222
-5
lines changed

2 files changed

+222
-5
lines changed

src/mkdocs_git_authors_plugin/git/page.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22
import re
33
from pathlib import Path
4-
from typing import List
4+
from typing import Any, List
55

66
from mkdocs_git_authors_plugin.git.command import GitCommand, GitCommandError
77
from mkdocs_git_authors_plugin.git.repo import AbstractRepoObject, Repo
@@ -73,7 +73,7 @@ def get_authors(self) -> List[dict]:
7373
or repo.config("show_contribution")
7474
or repo.config("sort_authors_by") == "contribution"
7575
)
76-
self._authors = sorted(self._authors, key=repo._sort_key, reverse=reverse)
76+
self._authors = sorted(self._authors, key=self._sort_key, reverse=reverse)
7777
self._sorted = True
7878
author_threshold = repo.config("authorship_threshold_percent")
7979
if author_threshold > 0 and len(self._authors) > 1:
@@ -210,6 +210,26 @@ def path(self) -> Path:
210210
"""
211211
return self._path
212212

213+
def _sort_key(self, author) -> Any:
214+
"""
215+
Return a sort key for an author.
216+
217+
Args:
218+
author: an Author object
219+
220+
Returns:
221+
comparison key for the sorted() function,
222+
"""
223+
repo = self.repo()
224+
if (
225+
repo.config("show_line_count")
226+
or repo.config("show_contribution")
227+
or repo.config("sort_authors_by") == "contribution"
228+
):
229+
return getattr(author, "contribution")(self.path())
230+
else:
231+
return getattr(author, "name")()
232+
213233
def total_lines(self) -> int:
214234
"""
215235
Total number of lines in the markdown source file.

tests/test_util.py

Lines changed: 200 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,19 @@
3131
"show_contribution": False,
3232
"show_line_count": False,
3333
"show_email_address": True,
34+
"href": "mailto:{email}",
3435
"count_empty_lines": True,
35-
"sort_authors_by_name": True,
36-
"sort_reverse": False,
36+
"fallback_to_empty": False,
37+
"exclude": [],
38+
"ignore_commits": "",
39+
"ignore_authors": [],
40+
"enabled": True,
41+
"enabled_on_serve": True,
3742
"sort_authors_by": "name",
3843
"authorship_threshold_percent": 0,
39-
"ignore_authors": [],
44+
"strict": True,
45+
#"sort_authors_by_name": True,
46+
#"sort_reverse": False,
4047
}
4148

4249
#### Helpers ####
@@ -129,6 +136,16 @@ def setup_commit_history(testproject_path):
129136
return repo
130137

131138

139+
def commit_lines(r, file_name, author_name, author_email, num_of_lines=1):
140+
with open(file_name, "a") as the_file:
141+
for i in range(num_of_lines):
142+
the_file.write("Hello\n")
143+
144+
r.index.add([file_name])
145+
author = gitpython.Actor(author_name, author_email)
146+
r.index.commit("some commit", author=author)
147+
148+
132149
#### Tests ####
133150

134151

@@ -477,6 +494,186 @@ def test_mkdocs_in_git_subdir(tmp_path):
477494
os.chdir(cwd)
478495

479496

497+
def test_page_authors_summary(tmp_path):
498+
"""
499+
Builds a fake git project with some commits.
500+
501+
Args:
502+
tmp_path (PosixPath): Directory of a tempdir
503+
"""
504+
cwd = os.getcwd()
505+
os.chdir(str(tmp_path))
506+
507+
config = DEFAULT_CONFIG.copy()
508+
509+
# Create a git repo and file
510+
r = gitpython.Repo.init(tmp_path)
511+
file_name = str(tmp_path / "new-file")
512+
513+
# Initial commit
514+
commit_lines(r, file_name, "Tim", "[email protected]")
515+
516+
repo_instance = repo.Repo()
517+
repo_instance.set_config(config)
518+
page_instance = repo_instance.page(file_name)
519+
520+
authors_summary = util.page_authors_summary(page_instance, config)
521+
522+
assert authors_summary == "<span class='git-page-authors git-authors'>"\
523+
"<a href='mailto:[email protected]'>Tim</a>"\
524+
"</span>"
525+
526+
527+
# Now add a line to the file
528+
# From a second author with same email
529+
commit_lines(r, file_name, "Tim2", "[email protected]")
530+
531+
repo_instance = repo.Repo()
532+
repo_instance.set_config(config)
533+
page_instance = repo_instance.page(file_name)
534+
535+
authors_summary = util.page_authors_summary(page_instance, config)
536+
537+
assert authors_summary == "<span class='git-page-authors git-authors'>"\
538+
"<a href='mailto:[email protected]'>Tim</a>"\
539+
"</span>"
540+
541+
542+
# Then a third commit from a new author
543+
commit_lines(r, file_name, "John", "[email protected]")
544+
545+
repo_instance = repo.Repo()
546+
repo_instance.set_config(config)
547+
page_instance = repo_instance.page(file_name)
548+
549+
authors_summary = util.page_authors_summary(page_instance, config)
550+
551+
assert authors_summary == "<span class='git-page-authors git-authors'>"\
552+
"<a href='mailto:[email protected]'>John</a>, "\
553+
"<a href='mailto:[email protected]'>Tim</a>"\
554+
"</span>"
555+
556+
os.chdir(cwd)
557+
558+
559+
def test_page_authors_summary_showing_contribution(tmp_path):
560+
"""
561+
Builds a fake git project with some commits.
562+
563+
Args:
564+
tmp_path (PosixPath): Directory of a tempdir
565+
"""
566+
cwd = os.getcwd()
567+
os.chdir(str(tmp_path))
568+
569+
config = DEFAULT_CONFIG.copy()
570+
config["show_contribution"] = True
571+
572+
# Create a git repo and file
573+
r = gitpython.Repo.init(tmp_path)
574+
file_name = str(tmp_path / "new-file")
575+
576+
# Initial commit
577+
commit_lines(r, file_name, "Tim", "[email protected]")
578+
579+
repo_instance = repo.Repo()
580+
repo_instance.set_config(config)
581+
page_instance = repo_instance.page(file_name)
582+
583+
authors_summary = util.page_authors_summary(page_instance, config)
584+
585+
# Contribution is not shown if there is only single Author
586+
assert authors_summary == "<span class='git-page-authors git-authors'>"\
587+
"<a href='mailto:[email protected]'>Tim</a>"\
588+
"</span>"
589+
590+
591+
# Now add a line to the file
592+
# From a second author with same email
593+
commit_lines(r, file_name, "Tim2", "[email protected]")
594+
595+
repo_instance = repo.Repo()
596+
repo_instance.set_config(config)
597+
page_instance = repo_instance.page(file_name)
598+
599+
authors_summary = util.page_authors_summary(page_instance, config)
600+
601+
# Contribution is not shown if there is only single Author
602+
assert authors_summary == "<span class='git-page-authors git-authors'>"\
603+
"<a href='mailto:[email protected]'>Tim</a>"\
604+
"</span>"
605+
606+
607+
# Then a third commit from a new author
608+
commit_lines(r, file_name, "John", "[email protected]")
609+
610+
repo_instance = repo.Repo()
611+
repo_instance.set_config(config)
612+
page_instance = repo_instance.page(file_name)
613+
614+
authors_summary = util.page_authors_summary(page_instance, config)
615+
616+
# Contribution is shown if there are multiple authors, ordered by contribution
617+
assert authors_summary == "<span class='git-page-authors git-authors'>"\
618+
"<a href='mailto:[email protected]'>Tim</a> (66.67%), "\
619+
"<a href='mailto:[email protected]'>John</a> (33.33%)"\
620+
"</span>"
621+
622+
os.chdir(cwd)
623+
624+
625+
def test_page_authors_summary_showing_contribution_ordering_by_page_contribution(tmp_path):
626+
"""
627+
Builds a fake git project with some commits.
628+
629+
Args:
630+
tmp_path (PosixPath): Directory of a tempdir
631+
"""
632+
cwd = os.getcwd()
633+
os.chdir(str(tmp_path))
634+
635+
config = DEFAULT_CONFIG.copy()
636+
config["show_contribution"] = True
637+
638+
# Create a git repo and files
639+
r = gitpython.Repo.init(tmp_path)
640+
file_name = str(tmp_path / "new-file")
641+
file_name2 = str(tmp_path / "new-file2")
642+
643+
# Commits by multiple authors on multiple files
644+
commit_lines(r, file_name, "Tim", "[email protected]", 8)
645+
commit_lines(r, file_name, "John", "[email protected]", 4)
646+
commit_lines(r, file_name, "Thomas", "[email protected]", 2)
647+
648+
commit_lines(r, file_name2, "Tim", "[email protected]", 4)
649+
commit_lines(r, file_name2, "John", "[email protected]", 16)
650+
commit_lines(r, file_name2, "Thomas", "[email protected]", 8)
651+
652+
repo_instance = repo.Repo()
653+
repo_instance.set_config(config)
654+
page_instance = repo_instance.page(file_name)
655+
page_instance2 = repo_instance.page(file_name2)
656+
657+
authors_summary = util.page_authors_summary(page_instance, config)
658+
659+
# Contribution is shown if there are multiple authors, ordered by contribution on page
660+
assert authors_summary == "<span class='git-page-authors git-authors'>"\
661+
"<a href='mailto:[email protected]'>Tim</a> (57.14%), "\
662+
"<a href='mailto:[email protected]'>John</a> (28.57%), "\
663+
"<a href='mailto:[email protected]'>Thomas</a> (14.29%)"\
664+
"</span>"
665+
666+
authors_summary = util.page_authors_summary(page_instance2, config)
667+
668+
assert authors_summary == "<span class='git-page-authors git-authors'>"\
669+
"<a href='mailto:[email protected]'>John</a> (57.14%), "\
670+
"<a href='mailto:[email protected]'>Thomas</a> (28.57%), "\
671+
"<a href='mailto:[email protected]'>Tim</a> (14.29%)"\
672+
"</span>"
673+
674+
os.chdir(cwd)
675+
676+
480677
def test_summarize_authors():
481678
"""
482679
Test summary functions.

0 commit comments

Comments
 (0)