Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
28 changes: 18 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@ plugins:

> If you have no `plugins` entry in your config file yet, you'll likely also want to add the `search` plugin. MkDocs enables it by default if there is no `plugins` entry set.

### Note when using on CI runners
### Note when using build environments

The plugin needs access to the last commit that touched a file to be able to retrieve the date. If you build your docs using CI then you might need to change your settings:
This plugin needs access to the last commit that touched a specific file to be able to retrieve the date. By default many build environments only retrieve the last commit, which means you might need to:
<details>
<summary>Change your CI settings</summary>

- github actions: set `fetch_depth` to `0` ([docs](https://github.com/actions/checkout))
- gitlab runners: set `GIT_DEPTH` to `1000` ([docs](https://docs.gitlab.com/ee/user/project/pipelines/settings.html#git-shallow-clone))
- bitbucket pipelines: set `clone: depth: full` ([docs](https://support.atlassian.com/bitbucket-cloud/docs/configure-bitbucket-pipelinesyml/))
</details>

- github actions: set `fetch_depth` to `0` ([docs](https://github.com/actions/checkout))
- gitlab runners: set `GIT_DEPTH` to `1000` ([docs](https://docs.gitlab.com/ee/user/project/pipelines/settings.html#git-shallow-clone))

----

## Usage

Expand Down Expand Up @@ -72,9 +75,10 @@ You can customize the plugin by setting options in `mkdocs.yml`. For example:
```yml
plugins:
- git-revision-date-localized:
type: timeago
locale: en
fallback_to_build_date: false
type: timeago
time_zone: Europe/Amsterdam
locale: en
fallback_to_build_date: false
```

### `type`
Expand All @@ -89,6 +93,10 @@ Default is `date`. To change the date format, set the `type` parameter to one of
20 hours ago # type: timeago
```

### `time_zone`

Default is `UTC`. Specify a time zone database name ([reference](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)). This option is especially relevant when using `type: datetime` and `type: iso_datetime`. Note that when using [timeago](http://timeago.yarp.com/) (with `type: timeago`) any difference in time zones between server and client will be handled automatically.

### `locale`

Default is `None`. Specify a two letter [ISO639](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code to display dates in your preferred language.
Expand All @@ -99,7 +107,7 @@ Default is `None`. Specify a two letter [ISO639](https://en.wikipedia.org/wiki/L

### `fallback_to_build_date`

Default is `false`. If set to `true` the plugin will use the time when running `mkdocs build` instead of the git revision date. This means the revision date will be inaccurate, but this can be useful if your build environment has no access to GIT and you want to ignore the Git exceptions during `git log`.
Default is `false`. If set to `true` the plugin will use the time at `mkdocs build` instead of the file's last git revision date. This means the revision date is incorrect, but this can be acceptable if you want your project to also successfully build in environments with no access to GIT.

## Contributing

Expand Down
8 changes: 5 additions & 3 deletions mkdocs_git_revision_date_localized_plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ class GitRevisionDateLocalizedPlugin(BasePlugin):
("fallback_to_build_date", config_options.Type(bool, default=False)),
("locale", config_options.Type(str, default=None)),
("type", config_options.Type(str, default="date")),
("timezone", config_options.Type(str, default="UTC")),
)

def on_config(self, config: config_options.Config) -> dict:
def on_config(self, config: config_options.Config, **kwargs) -> dict:
"""
Determine which locale to use.

Expand All @@ -33,7 +34,7 @@ def on_config(self, config: config_options.Config) -> dict:
Returns:
dict: global configuration object
"""
self.util = Util(path=config["docs_dir"])
self.util = Util(path=config["docs_dir"], config=self.config)

# Get locale settings - might be added in future mkdocs versions
# see: https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/issues/24
Expand Down Expand Up @@ -124,7 +125,7 @@ def on_post_page(self, output_content: str, **kwargs) -> str:
return output_content[:idx] + extra_js + output_content[idx:]

def on_page_markdown(
self, markdown: str, page: Page, config: config_options.Config, files
self, markdown: str, page: Page, config: config_options.Config, files, **kwargs
) -> str:
"""
Replace jinja2 tags in markdown and templates with the localized dates
Expand All @@ -149,6 +150,7 @@ def on_page_markdown(
revision_dates = self.util.get_revision_date_for_file(
path=page.file.abs_src_path,
locale=self.config.get("locale", "en"),
time_zone=self.config.get("time_zone", "UTC"),
fallback_to_build_date=self.config.get("fallback_to_build_date"),
)
revision_date = revision_dates[self.config["type"]]
Expand Down
105 changes: 70 additions & 35 deletions mkdocs_git_revision_date_localized_plugin/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,34 @@
from datetime import datetime

# 3rd party
from babel.dates import format_date
from babel.dates import format_date, get_timezone
from git import Repo, Git, GitCommandError, GitCommandNotFound


class Util:
def __init__(self, path: str = "."):
git_repo = Repo(path, search_parent_directories=True)
self.repo = git_repo.git
def __init__(self, path: str = ".", config={}):

# Checks when running builds on CI
self.fallback_enabled = False

try:
git_repo = Repo(path, search_parent_directories=True)
self.repo = git_repo.git
except:
if config.get("fallback_to_build_date"):
self.fallback_enabled = True
logging.warning(
"[git-revision-date-localized-plugin] Unable to find a git directory and/or git is not installed."
" Option 'fallback_to_build_date' set to 'true': Falling back to build date"
)
return None
else:
logging.error(
"[git-revision-date-localized-plugin] Unable to find a git directory and/or git is not installed."
" To ignore this error, set option 'fallback_to_build_date: true'"
)
raise

# Checks if user is running builds on CI
# See https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/issues/10
if is_shallow_clone(self.repo):
n_commits = commit_count(self.repo)
Expand All @@ -40,89 +58,106 @@ def __init__(self, path: str = "."):
"""
)

# TODO add bitbucket

@staticmethod
def _date_formats(unix_timestamp: float, locale="en") -> dict:
def _date_formats(
unix_timestamp: float, locale: str = "en", time_zone: str = "UTC"
) -> dict:
"""
Returns different date formats / types.

Args:
unix_timestamp (datetiment): a timestamp in seconds since 1970
unix_timestamp (float): a timestamp in seconds since 1970
locale (str): Locale code of language to use. Defaults to 'en'.
time_zone (str): timezone database name (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)

Returns:
dict: different date formats
"""

# Convert to millisecond timestamp
unix_timestamp = int(unix_timestamp)
timestamp_in_ms = unix_timestamp * 1000

revision_date = datetime.utcfromtimestamp(unix_timestamp)
logging.debug("Revision date: %s - Locale: %s" % (revision_date, locale))
utc_revision_date = datetime.utcfromtimestamp(int(unix_timestamp))
loc_revision_date = utc_revision_date.replace(
tzinfo=get_timezone("UTC")
).astimezone(get_timezone(time_zone))

return {
"date": format_date(revision_date, format="long", locale=locale),
"datetime": format_date(revision_date, format="long", locale=locale)
"date": format_date(loc_revision_date, format="long", locale=locale),
"datetime": format_date(loc_revision_date, format="long", locale=locale)
+ " "
+ revision_date.strftime("%H:%M:%S"),
"iso_date": revision_date.strftime("%Y-%m-%d"),
"iso_datetime": revision_date.strftime("%Y-%m-%d %H:%M:%S"),
+ loc_revision_date.strftime("%H:%M:%S"),
"iso_date": loc_revision_date.strftime("%Y-%m-%d"),
"iso_datetime": loc_revision_date.strftime("%Y-%m-%d %H:%M:%S"),
"timeago": "<span class='timeago' datetime='%s' locale='%s'></span>"
% (timestamp_in_ms, locale),
% (loc_revision_date.isoformat(), locale),
}

def get_revision_date_for_file(
self, path: str, locale: str = "en", fallback_to_build_date: bool = False
self,
path: str,
locale: str = "en",
time_zone: str = "UTC",
fallback_to_build_date: bool = False,
) -> dict:
"""
Determine localized date variants for a given file

Args:
path (str): Location of a markdownfile that is part of a GIT repository
locale (str, optional): Locale code of language to use. Defaults to 'en'.
timezone (str): timezone database name (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)

Returns:
dict: localized date variants
"""

unix_timestamp = None

# perform git log operation
try:
unix_timestamp = self.repo.log(path, n=1, date="short", format="%at")
if not self.fallback_enabled:
# Retrieve author date in UNIX format (%at)
# https://git-scm.com/docs/git-log#Documentation/git-log.txt-ematem
unix_timestamp = self.repo.log(path, n=1, date="short", format="%at")

except GitCommandError as err:
if fallback_to_build_date:
unix_timestamp = None
logging.warning(
"Unable to read git logs of '%s'."
" Is git log readable?"
" Option 'fallback_to_build_date' enabled: so keep building..."
"[git-revision-date-localized-plugin] Unable to read git logs of '%s'. Is git log readable?"
" Option 'fallback_to_build_date' set to 'true': Falling back to build date"
% path
)
else:
logging.error(
"Unable to read git logs of '%s'. "
"To ignore this error, set option 'fallback_to_build_date: true'"
"[git-revision-date-localized-plugin] Unable to read git logs of '%s'. "
" To ignore this error, set option 'fallback_to_build_date: true'"
% path
)
raise err
except GitCommandNotFound as err:
if fallback_to_build_date:
unix_timestamp = None
logging.warning(
"Unable to perform command: git log. Is git installed?"
" Option 'fallback_to_build_date' enabled: so keep building..."
"[git-revision-date-localized-plugin] Unable to perform command: 'git log'. Is git installed?"
" Option 'fallback_to_build_date' set to 'true': Falling back to build date"
)
else:
logging.error(
"Unable to perform command: git log. Is git installed?"
"To ignore this error, set option 'fallback_to_build_date: true'"
"[git-revision-date-localized-plugin] Unable to perform command 'git log'. Is git installed?"
" To ignore this error, set option 'fallback_to_build_date: true'"
)
raise err

# create timestamp
if not unix_timestamp:
unix_timestamp = time.time()
logging.warning("%s has no git logs, using current timestamp" % path)
if not self.fallback_enabled:
logging.warning(
"[git-revision-date-localized-plugin] '%s' has no git logs, using current timestamp"
% path
)

return self._date_formats(unix_timestamp=unix_timestamp, locale=locale)
return self._date_formats(
unix_timestamp=unix_timestamp, time_zone=time_zone, locale=locale
)


def is_shallow_clone(repo: Git) -> bool:
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name="mkdocs-git-revision-date-localized-plugin",
version="0.5.2",
version="0.6",
description="Mkdocs plugin that enables displaying the localized date of the last git modification of a markdown file.",
long_description=long_description,
long_description_content_type="text/markdown",
Expand All @@ -20,7 +20,7 @@
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
install_requires=["mkdocs>=0.17", "GitPython", "jinja2", "babel>=2.7.0"],
install_requires=["mkdocs>=1.0", "GitPython", "babel>=2.7.0"],
packages=find_packages(),
entry_points={
"mkdocs.plugins": [
Expand Down
5 changes: 1 addition & 4 deletions tests/fixtures/basic_project/docs/page_with_tag.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# test page

this page has a git authors tag.

Markdown tag: {{ git_revision_date_localized }}

Tag <mark>\{\{ git_revision_date_localized \}\}</mark> renders as: {{ git_revision_date_localized }}
10 changes: 10 additions & 0 deletions tests/fixtures/basic_project/mkdocs_theme_language.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
site_name: test gitrevisiondatelocalized_plugin
use_directory_urls: true

theme:
name: 'material'
language: de

plugins:
- search
- git-revision-date-localized
2 changes: 1 addition & 1 deletion tests/fixtures/basic_project/mkdocs_theme_locale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use_directory_urls: true

theme:
name: 'material'
language: de
locale: de

plugins:
- search
Expand Down
10 changes: 10 additions & 0 deletions tests/fixtures/basic_project/mkdocs_theme_timeago.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
site_name: test gitrevisiondatelocalized_plugin
use_directory_urls: true

theme:
name: 'material'

plugins:
- search
- git-revision-date-localized:
type: timeago
Loading