Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OO refactoring and git-blame preloading #12

Merged
merged 28 commits into from
Mar 4, 2020
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b41e299
Remove GitPython dependency
uliska Mar 1, 2020
f90ef72
Object oriented refactoring
uliska Mar 2, 2020
558dfc3
Preload git blame data
uliska Mar 2, 2020
7dbec73
Merge remote-tracking branch 'origin/master' into preload-blame
uliska Mar 2, 2020
f37c9f8
Handle uncommitted changes
uliska Mar 2, 2020
98bffc3
Document uncommitted_changes
uliska Mar 2, 2020
2739240
Add {{ git_authors_list }} (book-level summary)
uliska Mar 3, 2020
0869525
Make sort order configurable
uliska Mar 3, 2020
bc2fa53
Fix tracebacks with uncommitted files
uliska Mar 3, 2020
ca06d20
Add option count_empty_lines
uliska Mar 3, 2020
bac88c0
Remove obsolete counter variable
uliska Mar 3, 2020
251adc3
Rename show_lines to show_line_count
uliska Mar 3, 2020
0da9409
Rename sort_by to sort_authors_by
uliska Mar 3, 2020
e5c54ed
Clean up plugin events signature and docstrings
uliska Mar 3, 2020
bbba457
Add lines_all_pages and contribution_all_pages to page context
uliska Mar 3, 2020
7b178dc
Rename authors() to get_authors()
uliska Mar 3, 2020
270cc1f
Remove (unused) function Repo.root()
uliska Mar 3, 2020
7f1726c
Use repo argument directly in Commit.__init__
uliska Mar 3, 2020
422653b
Proper comment for populating uncommitted lines
uliska Mar 3, 2020
acd4506
Remove Commit.sha()
uliska Mar 3, 2020
71eeae2
Factor out commit_datetime function
uliska Mar 3, 2020
d5f6159
Rename Page._execute to _process_git_blame
uliska Mar 3, 2020
709b0e0
Rename Repo.commit() to Repo.get_commit()
uliska Mar 3, 2020
e6c6a8b
Remove localization config variables
uliska Mar 3, 2020
65d1779
Wrap authors list in a <span>
uliska Mar 4, 2020
4a208dc
Clarify event order in on_files
uliska Mar 4, 2020
ba91edd
Format repo_authors list in util
uliska Mar 4, 2020
6f5822c
Use --porcelain version of git blame
uliska Mar 4, 2020
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
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
![PyPI](https://img.shields.io/pypi/v/mkdocs-git-authors-plugin)
![PyPI - Downloads](https://img.shields.io/pypi/dm/mkdocs-git-authors-plugin)
[![codecov](https://codecov.io/gh/timvink/mkdocs-git-authors-plugin/branch/master/graph/badge.svg)](https://codecov.io/gh/timvink/mkdocs-git-authors-plugin)

# mkdocs-git-authors-plugin

[MkDocs](https://www.mkdocs.org/) plugin to display git authors of a markdown page:
Expand Down Expand Up @@ -39,7 +39,7 @@ plugins:

### In markdown pages

You can use ``{{ git_authors_summary }}`` to insert a summary of the authors of a page. Authors are sorted by their name and have a `mailto:` link with their email.
You can use ``{{ git_authors_summary }}`` to insert a summary of the authors of a page. Authors are sorted by their name and have a `mailto:` link with their email.

An example output:

Expand All @@ -57,7 +57,7 @@ no supported themes *yet*.

### Customizing existing themes

[MkDocs](https://www.mkdocs.org/) offers possibilities to [customize an existing theme](https://www.mkdocs.org/user-guide/styling-your-docs/#customizing-a-theme).
[MkDocs](https://www.mkdocs.org/) offers possibilities to [customize an existing theme](https://www.mkdocs.org/user-guide/styling-your-docs/#customizing-a-theme).

As an example, if you use [mkdocs-material](https://github.com/squidfunk/mkdocs-material) you can easily implement git-authors by [overriding a template block](https://squidfunk.github.io/mkdocs-material/customization/#overriding-template-blocks):

Expand Down Expand Up @@ -134,6 +134,13 @@ Example output:
* Authors: [John Doe](#) (33.33%), [Jane Doe](#) (66.67%) *(more than one author)*
* Authors: [John Doe](#) *(one author)*

### `uncommitted_name` and `uncommitted_email`

Lines that `git blame` consideres uncommitted can't be attributed to an author,
therefore they are assigned to a virtual author `Uncommitted` with a pseudo
email address of `#`. These values can be changed with the options
`uncommitted_name` (default “Uncommitted”) and `uncommitted_email` (default “#”).

### Aggregating Authors

In some repositories authors may have committed with differing name/email combinations.
Expand All @@ -150,4 +157,3 @@ Jane Doe <jane.doe@company.com> <jane.doe@private-email.com>
This will map commits made with the `private-email.com` to the company address. For more details
and further options (e.g. mapping between different names or misspellings etc. see the
[git-blame documentation](https://git-scm.com/docs/git-blame#_mapping_authors).

130 changes: 107 additions & 23 deletions mkdocs_git_authors_plugin/plugin.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,81 @@
import re
from mkdocs.config import config_options
from mkdocs.plugins import BasePlugin
from .util import Util
from .repo import Repo

class GitAuthorsPlugin(BasePlugin):
config_scheme = (
uliska marked this conversation as resolved.
Show resolved Hide resolved
('show_contribution', config_options.Type(bool, default=False)),
('show_lines', config_options.Type(bool, default=False)),
uliska marked this conversation as resolved.
Show resolved Hide resolved
('count_empty_lines', config_options.Type(bool, default=True)),
timvink marked this conversation as resolved.
Show resolved Hide resolved
('label_lines', config_options.Type(str, default='lines')),
('sort_by', config_options.Choice(
uliska marked this conversation as resolved.
Show resolved Hide resolved
['name', 'contribution'], default='name')
),
('sort_reverse', config_options.Type(bool, default=False)),
('uncommitted_name', config_options.Type(str, default='Uncommitted')),
('uncommitted_email', config_options.Type(str, default='#'))
)

def __init__(self):
self.util = Util()
self._repo = Repo()

def on_config(self, config, **kwargs):
"""
Store the plugin configuration in the Repo object.

This is only the dictionary with the plugin configuration,
not the global config which is passed to the various event handlers.
uliska marked this conversation as resolved.
Show resolved Hide resolved
"""
self.repo().set_config(self.config)

def on_files(self, files, **kwargs):
uliska marked this conversation as resolved.
Show resolved Hide resolved
"""
Preprocess all markdown pages in the project

This populates all the lines and total_lines properties
of the pages and the repository, so the total
contribution of an author to the repository can be
retrieved on *any* Markdown page.
timvink marked this conversation as resolved.
Show resolved Hide resolved
"""
for file in files:
path = file.abs_src_path
if path.endswith('.md'):
_ = self.repo().page(path)

def on_page_content(self, html, page, config, files, **kwargs):
"""
Replace jinja tag {{ git_authors_list }} in HTML.
uliska marked this conversation as resolved.
Show resolved Hide resolved

The page_content event is called after the Markdown text is
rendered to HTML (but before being passed to a template) and
can be used to alter the HTML body of the page.

https://www.mkdocs.org/user-guide/plugins/#on_page_content

We replace the authors list in this event in order to be able
to replace it with arbitrary HTML content (which might otherwise
end up in styled HTML in a code block).

Args:
html: the processed HTML of the page
page: mkdocs.nav.Page instance
config: global configuration object
site_navigation: global navigation object

Returns:
str: HTML text of page as string
"""
list_pattern = re.compile(
r"\{\{\s*git_authors_list\s*\}\}",
flags=re.IGNORECASE
)
if list_pattern.search(html):
html = list_pattern.sub(
self.repo().authors_summary(),
html
)
return html

def on_page_markdown(self, markdown, page, config, files):
"""
Expand All @@ -32,20 +98,19 @@ def on_page_markdown(self, markdown, page, config, files):
str: Markdown source text of page as string
"""

pattern = r"\{\{\s*git_authors_summary\s*\}\}"
summary_pattern = re.compile(
r"\{\{\s*git_authors_summary\s*\}\}",
flags=re.IGNORECASE
)

if not re.search(pattern, markdown, flags=re.IGNORECASE):
return markdown
if not summary_pattern.search(markdown):
return markdown

authors = self.util.get_authors(
path = page.file.abs_src_path
page_obj = self.repo().page(page.file.abs_src_path)
return summary_pattern.sub(
page_obj.authors_summary(),
markdown
)
authors_summary = self.util.summarize(authors, self.config)

return re.sub(pattern,
authors_summary,
markdown,
flags=re.IGNORECASE)

def on_page_context(self, context, page, **kwargs):
"""
Expand All @@ -66,13 +131,32 @@ def on_page_context(self, context, page, **kwargs):
dict: template context variables
"""


authors = self.util.get_authors(
path = page.file.abs_src_path
)
authors_summary = self.util.summarize(authors, self.config)

context['git_authors'] = authors
context['git_authors_summary'] = authors_summary

return context
path = page.file.abs_src_path
page_obj = self.repo().page(path)
authors = page_obj.authors()

# NOTE: last_datetime is currently given as a
# string in the format
# '2020-02-24 17:49:14 +0100'
# omitting the 'str' argument would result in a
# datetime.datetime object with tzinfo instead.
# Should this be formatted differently?
context['git_authors'] = [
{
'name' : author.name(),
'email' : author.email(),
'last_datetime' : author.datetime(path, str),
'lines' : author.lines(path),
'contribution' : author.contribution(path, str)
uliska marked this conversation as resolved.
Show resolved Hide resolved
}
for author in authors
]
context['git_authors_summary'] = page_obj.authors_summary()

return context

def repo(self):
"""
Reference to the Repo object of the current project.
"""
return self._repo
timvink marked this conversation as resolved.
Show resolved Hide resolved
Loading