doc: use Sphinx extension for showing last updated date in footers

Remove the proof-of-concept shell script that post-processes the
generated HTML to add the git date when the corresponding .rst file as
the last modified date, augmenting the existing published date.

Instead, use a custom last_updated.py Sphinx extension that's integrated
into the Sphinx build itself. Remove the old fix-git-modified-date.sh
script and calls to it.

Signed-off-by: David B. Kinder <david.b.kinder@intel.com>
This commit is contained in:
David B. Kinder 2022-03-18 10:18:35 -07:00 committed by David Kinder
parent d776e4ad47
commit 81336a8ee4
5 changed files with 171 additions and 26 deletions

View File

@ -62,9 +62,6 @@ html: content doxy
$(Q)./scripts/show-versions.py
$(Q)$(SPHINXBUILD) -t $(DOC_TAG) -b html -d $(BUILDDIR)/doctrees $(SOURCEDIR) $(BUILDDIR)/html $(SPHINXOPTS) $(OPTS) >> $(BUILDDIR)/doc.log 2>&1
$(Q)./scripts/filter-doc-log.sh $(BUILDDIR)/doc.log
ifeq ($(BUILDDIR),_build)
$(Q)./scripts/fix-git-modified-date.sh
endif
singlehtml: content doxy
$(Q)$(SPHINXBUILD) -t $(DOC_TAG) -b singlehtml -d $(BUILDDIR)/doctrees $(SOURCEDIR) $(BUILDDIR)/html $(SPHINXOPTS) $(OPTS) >> $(BUILDDIR)/doc.log 2>&1

13
doc/_templates/footer.html vendored Normal file
View File

@ -0,0 +1,13 @@
{% extends "!footer.html" %}
{% block contentinfo %}
<p>
{%- if show_copyright %}
{%- if hasdoc('copyright') %}
{%- trans path=pathto('copyright'), copyright=copyright|e %}&#169; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
{%- else %}
{%- trans copyright=copyright|e %}&#169; Copyright {{ copyright }}.{% endtrans %}
{%- endif %}
{%- endif %}
<span class="lastupdated">Last updated on {{last_updated}}. Published on {{last_published}}</span>
{% endblock %}

View File

@ -40,7 +40,7 @@ sys.path.insert(0, os.path.join(os.path.abspath('.'), 'extensions'))
extensions = [
'breathe', 'sphinx.ext.graphviz', 'sphinx.ext.extlinks',
'eager_only', 'html_redirects', 'link_roles',
'sphinx_tabs.tabs'
'sphinx_tabs.tabs', 'last_updated'
]
# extlinks provides a macro template
@ -388,3 +388,9 @@ html_redirect_pages = [
('tutorials/using_zephyr_as_uos', 'tutorials/using_zephyr_as_user_vm'),
('tutorials/using_windows_as_uos', 'tutorials/using_windows_as_user_vm')
]
# Custom last_updated extension for updating last updated date based on git information
# needs to know the folders where the cloned files can be found, relative to
# where the Sphinx .rst build folder
last_updated_git_path = ['../..', '../../..', '../../../doc/']

View File

@ -0,0 +1,151 @@
# Copyright (c) 2022 Anton Bobkov, Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# Use git to retrieve a more meaningful last updated date than the usual
# Sphinx-generated date that's actually just the last published date.
# Inspired by a shell script by David Kinder.
#
# Add the extension to your conf.py file:
# extensions = ['last_updated']
#
# If you copy documentation files from one or multiple git repositories prior to
# running Sphinx, specify the list of paths to the git folders in the
# last_updated_git_path parameter. You can either specify absolute paths or
# relative paths from the documentation root directory in this list. For
# example:
#
# last_updated_git_path = ['../../', '../../../']
#
# Specify the date format in the html_last_updated_fmt parameter. For
# information about the strftime() format, see https://strftime.org. If you do
# not specify this parameter, the extension uses the default value of "%b %d, %Y"
# for short month name, date, and four-digit year.
#
# Use the variables provided by the extension in your jinja templates:
#
# last_updated. The date of the last update of the rst file in the specified
# git repository.
# last_published. The publication date of the rst file.
#
# Note: Sphinx already provides the last_updated variable. However, this
# variable includes the publication time. This extension overwrites the
# last_updated variable with the file modification time in git.
#
# To override the default footer in the sphinx_rtd_theme, create the footer.html
# file in the _templates directory:
#
# {% extends "!footer.html" %}
# {% block contentinfo %}
#
# <!-- yourcopyright info goes here, possibly copied from the theme's # footer.html -->
#
# <span class="lastupdated">Last updated on {{last_updated}}. Published on {{last_published}}</span>
#
# {% endblock %}
#
# This snippet overrides the contentinfo block of the default footer.html
# template that initially contains the information about the copyright and
# publication date.
__version__ = '0.1.0'
import subprocess
from datetime import date, datetime
import os
import urllib.parse
from sphinx.util import logging
def _not_git_repo(dir):
res = subprocess.call(['git', '-C', dir, 'rev-parse'],
stderr=subprocess.STDOUT, stdout = open(os.devnull, 'w')) != 0
return res
def _get_last_updated_from_git(file_path, git_repo, doc_root):
rel_path = os.path.relpath(file_path, doc_root)
for git_repo_path in git_repo:
new_path = os.path.join(git_repo_path, rel_path)
if os.path.isfile(new_path):
try:
time_format = "%Y-%m-%d"
output=subprocess.check_output(
f'git --no-pager log -1 --date=format:"{time_format}" --pretty="format:%cd" {new_path}',
shell=True, cwd=git_repo_path)
except:
# Could not get git info for an existing file, try the next
# folder on the list
continue
else:
last_updated = datetime.strptime(output.decode('utf-8'), time_format).date()
return last_updated
else:
continue
return None
def on_html_page_context(app, pagename, templatename, context, doctree):
if doctree:
# If last_updated_git_path (with a list of potential folders where the
# actual git-managed files are) is not specified,
# then just use the doc source path
if app.config.last_updated_git_path is None:
app.config.last_updated_git_path = [app.srcdir]
# If last_updated_git_path is a relative path, convert it to absolute
last_updated_git_path_abs = []
for last_updated_git_path_el in app.config.last_updated_git_path:
if not os.path.isabs(last_updated_git_path_el):
last_updated_git_path_el_abs = os.path.normpath(os.path.join(app.srcdir, last_updated_git_path_el))
last_updated_git_path_abs.append(last_updated_git_path_el_abs)
else:
last_updated_git_path_abs.append(last_updated_git_path_el)
if _not_git_repo(last_updated_git_path_abs[-1]):
app.logger.error(f"The last_updated extension is disabled because of the error:\
\n {last_updated_git_path_abs} is not a git repository.\
\n Specify correct path(s) to the git source folder(s) in last_updated_git_path.")
app.disconnect(app.listener_id)
return
app.config.last_updated_git_path = last_updated_git_path_abs
# Get the absolute path to the current rst document
rst_file_path = doctree.attributes['source']
# Set the date format based on html_last_updated_fmt or default of Mar 18, 2022
if app.config.html_last_updated_fmt is None:
date_fmt = "%b %d, %Y"
else:
date_fmt = app.config.html_last_updated_fmt
context['last_published'] = date.today().strftime(date_fmt)
last_updated_value = _get_last_updated_from_git(file_path=rst_file_path,
git_repo=app.config.last_updated_git_path,
doc_root=app.srcdir)
if last_updated_value is None:
app.logger.warning(f'Could not get the last updated value from git for the following file:\
\n {rst_file_path}\n Ensure that you specified the correct folder in last_updated_git_path.')
context['last_updated'] = None
else:
context['last_updated'] = last_updated_value.strftime(date_fmt)
def setup(app):
app.logger = logging.getLogger(__name__)
app.add_config_value('last_updated_git_path', None, 'html')
app.listener_id = app.connect('html-page-context', on_html_page_context)
return {
'version': '0.1',
'parallel_read_safe': True,
}

View File

@ -1,22 +0,0 @@
#!/bin/bash
# Copyright (C) 2021 Intel Corporation.
# SPDX-License-Identifier: BSD-3-Clause
#
# Run this script in the _build/html folder after generating the HTML content.
#
# Scan through HTML files look for the corresponding .rst file (in doc or misc
# for ACRN project). Replace the "Last updated" date in the footer with the last
# commit date for the corresponding .rst file (if we can find it). Tweak
# wording to mention Last modified and published dates.
cd _build/html
find -type f -name "*.html" | \
while read filename;
do
f=${filename%.*}.rst
[[ -f "../../$f" ]] && prefix="../.."
[[ -f "../../../$f" ]] && prefix="../../.."
d="$(git log -1 --format="%ad" --date=format:"%b %d, %Y" -- "$prefix/$f")";
[[ ! -z "$d" ]] && sed -i "s/\(^ *<span class=\"lastupdated\">\)Last updated on \(.*\)\.$/\1Last modified: $d. Published: \2./" $filename;
done