Skip to content

Commit 96fb712

Browse files
rcgoncalvestimvink
authored andcommitted
Add support to ignore authors and/or commits
1 parent 0f3f1b5 commit 96fb712

File tree

7 files changed

+191
-3
lines changed

7 files changed

+191
-3
lines changed

docs/options.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ plugins:
1313
fallback_to_empty: false
1414
sort_authors_by: name
1515
authorship_threshold_percent: 10
16+
ignore_authors:
17+
18+
ignore_commits: .git-blame-ignore-revs
1619
exclude:
1720
- index.md
1821
enabled: true
@@ -59,6 +62,14 @@ If this option is set to `true` (default: `false`) the plugin will work even out
5962

6063
Default is empty. Specify a list of page source paths (one per line) that should not have author(s) included (excluded from processing by this plugin). This can be useful for example to remove the authors from the front page. The source path of a page is relative to your `docs/` folder. You can also use [globs](https://docs.python.org/3/library/glob.html) instead of full source paths. To exclude `docs/subfolder/page.md` specify in your `mkdocs.yml` a line under `exclude:` with `- subfolder/page.md`. Some examples:
6164

65+
## `ignore_authors`
66+
67+
Default is empty. Specifies a list of emails for authors whose contributions should be ignored by this plugin.
68+
69+
## `ignore_commits`
70+
71+
Default is empty. Specifies a file containing a list of commit hashes (one per line) that should be ignored. Changes made in these commits will be attributed to the previous commit that changed the line.
72+
6273
```yaml
6374
# mkdocs.yml
6475
plugins:

mkdocs_git_authors_plugin/git/page.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,13 @@ def _process_git_blame(self):
146146

147147
re_sha = re.compile(r"^\w{40}")
148148

149-
cmd = GitCommand("blame", ["--porcelain", str(self._path)])
149+
args = []
150+
if self.repo().config("ignore_commits"):
151+
args.append("--ignore-revs-file")
152+
args.append(self.repo().config("ignore_commits"))
153+
args.append("--porcelain")
154+
args.append(str(self._path))
155+
cmd = GitCommand("blame", args)
150156
cmd.run()
151157

152158
lines = cmd.stdout()
@@ -155,6 +161,7 @@ def _process_git_blame(self):
155161
if len(lines) == 0:
156162
raise GitCommandError
157163

164+
ignore_authors = self.repo().config("ignore_authors")
158165
commit_data = {}
159166
for line in lines:
160167
key = line.split(" ")[0]
@@ -183,7 +190,7 @@ def _process_git_blame(self):
183190
author_tz=commit_data.get("author-tz"),
184191
summary=commit_data.get("summary"),
185192
)
186-
if len(line) > 1 or self.repo().config("count_empty_lines"):
193+
if commit.author().email() not in ignore_authors and (len(line) > 1 or self.repo().config("count_empty_lines")):
187194
author = commit.author()
188195
if author not in self._authors:
189196
self._authors.append(author)

mkdocs_git_authors_plugin/plugin.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class GitAuthorsPlugin(BasePlugin):
2121
("count_empty_lines", config_options.Type(bool, default=True)),
2222
("fallback_to_empty", config_options.Type(bool, default=False)),
2323
("exclude", config_options.Type(list, default=[])),
24+
("ignore_commits", config_options.Type(str, default=None)),
25+
("ignore_authors", config_options.Type(list, default=[])),
2426
("enabled", config_options.Type(bool, default=True)),
2527
("enabled_on_serve", config_options.Type(bool, default=True)),
2628
("sort_authors_by", config_options.Type(str, default="name")),

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name="mkdocs-git-authors-plugin",
8-
version="0.8.0",
8+
version="0.9.0",
99
description="Mkdocs plugin to display git authors of a page",
1010
long_description=long_description,
1111
long_description_content_type="text/markdown",
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
site_name: test gitauthors_plugin
2+
use_directory_urls: true
3+
4+
plugins:
5+
- search
6+
- git-authors:
7+
ignore_authors:
8+

tests/test_basic.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,23 @@ def test_exclude_working(tmp_path):
146146

147147

148148

149+
def test_ignore_authors_working(tmp_path):
150+
151+
result = build_docs_setup("tests/basic_setup/mkdocs_ignore_authors.yml", tmp_path)
152+
assert result.exit_code == 0, (
153+
"'mkdocs build' command failed. Error: %s" % result.stdout
154+
)
155+
156+
page_file = tmp_path / "page_with_tag/index.html"
157+
assert page_file.exists(), "%s does not exist" % page_file
158+
159+
contents = page_file.read_text()
160+
assert re.search("<span class='git-page-authors", contents)
161+
assert re.search("<a href='mailto:[email protected]'>Tim Vink</a>", contents)
162+
assert not re.search("Julien", contents)
163+
164+
165+
149166
def test_exclude_working_with_genfiles(tmp_path):
150167
"""
151168
A warning for uncommited files should not show up

tests/test_util.py

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"sort_reverse": False,
3636
"sort_authors_by": "name",
3737
"authorship_threshold_percent": 0,
38+
"ignore_authors": [],
3839
}
3940

4041
#### Helpers ####
@@ -275,6 +276,148 @@ def test_retrieve_authors(tmp_path):
275276
os.chdir(cwd)
276277

277278

279+
def test_retrieve_authors_ignoring_commits(tmp_path):
280+
"""
281+
Builds a fake git project with some commits.
282+
283+
Args:
284+
tmp_path (PosixPath): Directory of a tempdir
285+
"""
286+
cwd = os.getcwd()
287+
os.chdir(str(tmp_path))
288+
289+
# Create file
290+
file_name = str(tmp_path / "new-file")
291+
with open(file_name, "w") as the_file:
292+
the_file.write("line 1\n")
293+
the_file.write("line 2\n")
294+
295+
# Create git repo and commit file
296+
r = gitpython.Repo.init(tmp_path)
297+
r.index.add([file_name])
298+
author = gitpython.Actor("Tim", "[email protected]")
299+
r.index.commit("initial commit", author=author)
300+
301+
# Update the file
302+
with open(file_name, "w") as the_file:
303+
the_file.write("line 1.1\n")
304+
the_file.write("line 2.1\n")
305+
r.index.add([file_name])
306+
author = gitpython.Actor("John", "[email protected]")
307+
commit = r.index.commit("second commit", author=author)
308+
309+
repo_instance = repo.Repo()
310+
repo_instance.set_config(DEFAULT_CONFIG)
311+
repo_instance.page(file_name)
312+
authors = repo_instance.get_authors()
313+
authors = util.page_authors(authors, file_name)
314+
authors[0]["last_datetime"] = None
315+
316+
assert authors == [
317+
{
318+
"name": "John",
319+
"email": "[email protected]",
320+
"last_datetime": None,
321+
"lines": 2,
322+
"lines_all_pages": 2,
323+
"contribution": "100.0%",
324+
"contribution_all_pages": "100.0%",
325+
}
326+
]
327+
328+
# Get the authors while ignoring the last commit
329+
ignored_commits_files = str(tmp_path / "ignored_commits.txt")
330+
with open(ignored_commits_files, "w") as the_file:
331+
the_file.write(commit.hexsha + "\n")
332+
repo_instance = repo.Repo()
333+
config = DEFAULT_CONFIG.copy()
334+
config['ignore_commits'] = ignored_commits_files
335+
repo_instance.set_config(config)
336+
repo_instance.page(file_name)
337+
authors = repo_instance.get_authors()
338+
authors = util.page_authors(authors, file_name)
339+
authors[0]["last_datetime"] = None
340+
341+
assert authors == [
342+
{
343+
"name": "Tim",
344+
"email": "[email protected]",
345+
"last_datetime": None,
346+
"lines": 2,
347+
"lines_all_pages": 2,
348+
"contribution": "100.0%",
349+
"contribution_all_pages": "100.0%",
350+
},
351+
]
352+
353+
os.chdir(cwd)
354+
355+
356+
def test_retrieve_authors_ignoring_emails(tmp_path):
357+
"""
358+
Builds a fake git project with some commits.
359+
360+
Args:
361+
tmp_path (PosixPath): Directory of a tempdir
362+
"""
363+
cwd = os.getcwd()
364+
os.chdir(str(tmp_path))
365+
366+
# Create file
367+
file_name = str(tmp_path / "new-file")
368+
with open(file_name, "w") as the_file:
369+
the_file.write("line 1\n")
370+
the_file.write("line 2\n")
371+
372+
# Create git repo and commit file
373+
r = gitpython.Repo.init(tmp_path)
374+
r.index.add([file_name])
375+
author = gitpython.Actor("Tim", "[email protected]")
376+
r.index.commit("initial commit", author=author)
377+
378+
# Add more content
379+
with open(file_name, "a+") as the_file:
380+
the_file.write("line 3\n")
381+
the_file.write("line 4\n")
382+
r.index.add([file_name])
383+
author = gitpython.Actor("John", "[email protected]")
384+
r.index.commit("second commit", author=author)
385+
386+
# Get the authors while ignoring [email protected] user
387+
repo_instance = repo.Repo()
388+
config = DEFAULT_CONFIG.copy()
389+
config['ignore_authors'] = ['[email protected]']
390+
repo_instance.set_config(config)
391+
repo_instance.page(file_name)
392+
authors = repo_instance.get_authors()
393+
authors = util.page_authors(authors, file_name)
394+
authors[0]["last_datetime"] = None
395+
authors[1]["last_datetime"] = None
396+
397+
assert authors == [
398+
{
399+
"contribution": "0.0%",
400+
"contribution_all_pages": "0.0%",
401+
"email": "[email protected]",
402+
"last_datetime": None,
403+
"lines": 0,
404+
"lines_all_pages": 0,
405+
"name": "John"
406+
},
407+
{
408+
"name": "Tim",
409+
"email": "[email protected]",
410+
"last_datetime": None,
411+
"lines": 2,
412+
"lines_all_pages": 2,
413+
"contribution": "100.0%",
414+
"contribution_all_pages": "100.0%",
415+
},
416+
]
417+
418+
os.chdir(cwd)
419+
420+
278421
def test_mkdocs_in_git_subdir(tmp_path):
279422
"""
280423
Sometimes `mkdocs.yml` is not in the root of the repo.

0 commit comments

Comments
 (0)