diff --git a/.cruft.json b/.cruft.json
new file mode 100644
index 0000000..23685ae
--- /dev/null
+++ b/.cruft.json
@@ -0,0 +1,27 @@
+{
+ "template": "https://github.com/sphinx-notes/cookiecutter",
+ "commit": "800a79a06f9a67494516bc14bcda85b3472dcac9",
+ "checkout": null,
+ "context": {
+ "cookiecutter": {
+ "namespace": "sphinxnotes",
+ "name": "recentupdate",
+ "full_name": "sphinxnotes-recentupdate",
+ "author": "Shengyu Zhang",
+ "description": "Get the document update information from git and display it in Sphinx documentation",
+ "version": "1.0a2",
+ "github_owner": "sphinx-notes",
+ "github_repo": "recentupdate",
+ "pypi_name": "sphinxnotes-recentupdate",
+ "pypi_owner": "SilverRainZ",
+ "is_python_project": true,
+ "python_version": "3.12",
+ "is_sphinx_extension": true,
+ "sphinx_version": "7.0",
+ "development_status": "3 - Alpha",
+ "_template": "https://github.com/sphinx-notes/cookiecutter",
+ "_commit": "800a79a06f9a67494516bc14bcda85b3472dcac9"
+ }
+ },
+ "directory": null
+}
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000..e9a39ba
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,9 @@
+name: Ruff
+on: [ push, pull_request ]
+
+jobs:
+ ruff:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: chartboost/ruff-action@v1
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index 558f186..0cf70c8 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -1,22 +1,25 @@
-name: Pages
+name: Deploy Sphinx documentation to Pages
+
+# Runs on pushes targeting the default branch
on:
push:
- branches:
- - master
+ branches: [master]
+
+# Cancel any in-progress job or run
+# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency
+concurrency:
+ group: ${{ github.ref }}
+ cancel-in-progress: true
+
jobs:
- build:
- runs-on: ubuntu-20.04
+ pages:
+ runs-on: ubuntu-latest
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ permissions:
+ pages: write
+ id-token: write
steps:
- - name: Checkout
- uses: actions/checkout@master
- with:
- fetch-depth: 0 # otherwise, you will failed to push refs to dest repo
- - name: Build and Commit
- uses: sphinx-notes/pages@master
- with:
- documentation_path: doc
- - name: Push changes
- uses: ad-m/github-push-action@master
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- branch: gh-pages
+ - id: deployment
+ uses: sphinx-notes/pages@v3
diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml
new file mode 100644
index 0000000..ad45cf1
--- /dev/null
+++ b/.github/workflows/pypi.yml
@@ -0,0 +1,22 @@
+name: Publish package distributions to PyPI
+
+on:
+ push:
+ tags:
+ - "*"
+
+jobs:
+ pypi:
+ runs-on: ubuntu-latest
+ environment:
+ name: pypi
+ url: https://pypi.org/p/sphinxnotes-recentupdate
+ permissions:
+ id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
+ - run: pip install build twine && make dist
+ - uses: pypa/gh-action-pypi-publish@release/v1
+ with:
+ password: ${{ secrets.PYPI_API_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..0604b24
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,18 @@
+name: Publish Github Release
+
+on:
+ push:
+ tags:
+ - "[0-9]+.[0-9]+" # MAJOR.MINOR (1.0: y, 1.0a0: n, 1.0.1: n)
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ steps:
+ - uses: actions/checkout@v4
+ - uses: ncipollo/release-action@v1
+ with:
+ body: |
+ Changelog: https://sphinx.silverrainz.me/recentupdate/changelog.html
diff --git a/.gitignore b/.gitignore
index a1da85b..52736b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -128,5 +128,10 @@ dmypy.json
# Pyre type checker
.pyre/
+# Poetry
+poetry.lock
+
# Sphinx
-doc/_build/
+docs/_build/
+# sphinxnotes-any >= 2.5
+docs/.any*
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..b631058
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,7 @@
+repos:
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.6.1
+ hooks:
+ - id: ruff-check
+ args: [ --fix ]
+ - id: ruff-format
diff --git a/LICENSE b/LICENSE
index 6c2b76b..9d45cee 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
BSD 3-Clause License
-Copyright (c) 2021, Sphinx Notes
+Copyright (c) 2025, Shengyu Zhang
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -26,4 +26,4 @@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/MANIFEST.in b/MANIFEST.in
index 8c37b94..4c868dc 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,11 @@
-include README.rst
+# This file is generated from sphinx-notes/cookiecutter.
+# You need to consider modifying the TEMPLATE or modifying THIS FILE.
+
include LICENSE
-recursive-include doc *
-prune doc/_build
+include README.rst
+
+recursive-include tests *
+recursive-exclude * __pycache__
+recursive-exclude * *.py[co]
+
+recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif
diff --git a/Makefile b/Makefile
index c14da97..f70db5d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,28 +1,92 @@
-LANG=en_US.UTF-8
+# This file is generated from sphinx-notes/cookiecutter.
+# You need to consider modifying the TEMPLATE or modifying THIS FILE.
-MAKE = make
-PY = python3
-RM = rm -rf
+LANG = en_US.UTF-8
-.PHONY: doc
-doc:
- $(RM) doc/_build
- $(MAKE) -C doc/
+MAKE = make
+PY = python3
+RM = rm -rf
+GIT = git
+OPEN = xdg-open
-.PHONY: dist
-dist: setup.py
- $(RM) dist/ build/ *.egg-info/
- $(PY) setup.py sdist bdist_wheel
- $(PY) -m twine check dist/*
+.PHONY: docs
+docs:
+ $(MAKE) -C docs/
-.PHONY: upload
-upload: dist/
- $(PY) -m twine upload --repository pypi $<*
+.PHONY: view
+view:
+ $(OPEN) docs/_build/html/index.html
+
+.PHONY: clean
+clean:
+ $(MAKE) -C docs/ clean; $(RM) dist/
+
+.PHONY: fmt
+fmt:
+ ruff format src/ && ruff check --fix src/
+
+.PHONY: test
+test:
+ $(PY) -m unittest discover -s tests -v
+
+################################################################################
+# Distribution Package
+################################################################################
+
+# Build distribution package, for "install" or "upload".
+.PHONY: dist
+dist: pyproject.toml clean
+ $(PY) -m build
+# Install distribution package to user directory.
+#
+# NOTE: It may breaks your system-level packages, use at your own risk.
.PHONY: install
install: dist
+ export PIP_BREAK_SYSTEM_PACKAGES=1 # required by Python 3.11+, see PEP-668
$(PY) -m pip install --user --no-deps --force-reinstall dist/*.whl
-.PHONY: test
-test: tests
- $(PY) -m unittest discover -s tests -v
+# Publish wheel to PyPI offical server when you want to
+# You should have a PyPI account and have PyPI token configured.
+#
+# See also https://packaging.python.org/en/latest/tutorials/packaging-projects/#uploading-the-distribution-archives
+.PHONY: upload
+upload: dist
+ $(PY) -m twine upload --repository pypi $*
+
+################################################################################
+# Cookiecutter Incremental Updates
+################################################################################
+
+# Keep up to date with the latest template.
+# See https://github.com/sphinx-notes/cookiecutter.
+.PHONY: tmpl-update tmpl-update-done tmpl-apply-rej
+
+tmpl-update:
+ $(PY) -m cruft update
+
+tmpl-update-done:
+ $(GIT) commit -m "chore: Update project template to sphinx-notes/cookiecutter@$(shell jq -r '.commit' .cruft.json | head -c8)"
+
+tmpl-apply-rej:
+ @for rej in $$(find . -name '*.rej'); do \
+ echo "applying $$rej..."; \
+ wiggle --replace $${rej%.rej} $$rej; \
+ done
+
+# Update project version.
+.PHONY: bump-version bump-version-done
+
+bump-version:
+ @echo -n "Please enter the version to bump: "
+ @read version && $(PY) -m cruft update --variables-to-update "{ \"version\" : \"$$version\" }"
+
+bump-version-done:
+ VERSION=$(shell jq -r '.context.cookiecutter.version' .cruft.json); \
+ $(GIT) commit -m "chore: Bump version to $$VERSION"; \
+ $(GIT) tag $$VERSION
+
+
+################################################################################
+# CUSTOM TARGETS
+################################################################################
diff --git a/README.rst b/README.rst
index fa599a2..249bd41 100644
--- a/README.rst
+++ b/README.rst
@@ -1,5 +1,32 @@
+.. This file is generated from sphinx-notes/cookiecutter.
+ You need to consider modifying the TEMPLATE or modifying THIS FILE.
+
========================
sphinxnotes-recentupdate
========================
-Please refer to https://sphinx-notes.github.io/recentupdate/ for documentation.
+.. |docs| image:: https://img.shields.io/github/deployments/sphinx-notes/recentupdate/github-pages
+ :target: https://sphinx.silverrainz.me/recentupdate
+ :alt: Documentation Status
+.. |license| image:: https://img.shields.io/github/license/sphinx-notes/recentupdate
+ :target: https://github.com/sphinx-notes/recentupdate/blob/master/LICENSE
+ :alt: Open Source License
+.. |pypi| image:: https://img.shields.io/pypi/v/sphinxnotes-recentupdate.svg
+ :target: https://pypi.python.org/pypi/sphinxnotes-recentupdate
+ :alt: PyPI Package
+.. |download| image:: https://img.shields.io/pypi/dm/sphinxnotes-recentupdate
+ :target: https://pypi.python.org/pypi/sphinxnotes-recentupdate
+ :alt: PyPI Package Downloads
+
+|docs| |license| |pypi| |download|
+
+Get the document update information from git and display it in Sphinx documentation.
+
+.. INTRODUCTION START
+ (MUST written in standard reStructuredText, without Sphinx stuff)
+
+.. INTRODUCTION END
+
+Please refer to Documentation_ for more details.
+
+.. _Documentation: https://sphinx.silverrainz.me/recentupdate
diff --git a/doc/confval.py b/doc/confval.py
deleted file mode 100644
index 88726e9..0000000
--- a/doc/confval.py
+++ /dev/null
@@ -1,17 +0,0 @@
-from textwrap import dedent
-from sphinxnotes.any import Schema, Field
-
-confval = Schema(
- 'confval',
- name=Field(unique=True, referenceable=True),
- attrs={
- 'type': Field(),
- 'default': Field(),
- },
- description_template=dedent("""
- :Type: ``{{ type }}``
- :Default: ``{{ default}}``
-
- {{ content }}"""),
- reference_template='⚙️{{ title }}',
- missing_reference_template='⚙️{{ title }}')
diff --git a/doc/index.rst b/doc/index.rst
deleted file mode 100644
index 64a5e75..0000000
--- a/doc/index.rst
+++ /dev/null
@@ -1,180 +0,0 @@
-========================
-sphinxnotes.recentupdate
-========================
-
-.. image:: https://img.shields.io/github/stars/sphinx-notes/recentupdate.svg?style=social&label=Star&maxAge=2592000
- :target: https://github.com/sphinx-notes/recentupdate
-
-:version: |version|
-:copyright: Copyright ©2021 by Shengyu Zhang.
-:license: BSD, see LICENSE for details.
-
-Get the document update information from git and display it in Sphinx documentation.
-
-This extensions provides a `recentupdate `_ directive, which can show recent document update of current Sphinx documentation. The update information is read from Git_ repository (So you must use Git to manage your documentation). You can customize the update information through generating reStructuredText from Jinja_ template.
-
-.. _Git: https://git-scm.com/
-.. _Jinja: https://jinja.palletsprojects.com/en/3.0.x/templates/
-
-.. contents::
- :local:
- :backlinks: none
-
-Installation
-============
-
-Download it from official Python Package Index:
-
-.. code:: console
-
- $ pip install sphinxnotes-recentupdate
-
-Add extension to :file:`conf.py` in your sphinx project:
-
-.. code:: python
-
- extensions = [
- # …
- 'sphinxnotes.recentupdate',
- # …
- ]
-
-Quick Start
-===========
-
-1. Installation_
-2. Add ``recentupdate`` directive to your document:
-
- .. code:: rst
-
- .. recentupdate::
-
-3. Build your document, The directive will be rendered to:
-
- .. recentupdate::
-
-Functionalities
-===============
-
-The extension provides a ``recentupdate`` directive:
-
-.. code:: rst
-
- .. recentupdate:: [count]
-
- [jinja template]
-
-count
- The optional argument of directive is the count of recent "revisions" you want to show. Revision is a git commit which contains document changes.
-
- If no count given, value of :confval:`recentupdate_count` is used.
-
-template
- The optional content of directive is a jinja template for generating reStructuredText, in the template you can access Variables_ named `{{ revisions }}`_.
-
- Beside, You can use `Builtin Filters`_ and Filters_ provided by extensions.
-
- If no template given, value of :confval:`recentupdate_template` is used.
-
-.. _Builtin Filters: https://jinja.palletsprojects.com/en/3.0.x/templates/#builtin-filters
-
-Variables
----------
-
-All available variables_:
-
-.. _variables: https://jinja.palletsprojects.com/en/3.0.x/templates/#variables
-
-{{ revisions }}
-~~~~~~~~~~~~~~~
-
-``{{ revisions }}`` is an an array of revisions. The length of array is determined by the argument of`recentupdate `_ directive.
-
-Here is the schema of array element:
-
-.. autoclass:: recentupdate.Revision
- :members:
-
-Filters
--------
-
-strftime
-~~~~~~~~
-
-Convert a :py:class:`datetime.datetime` to string in given format.
-
-If no format given, use value of :confval:`recentupdate_date_format`.
-
-It is used in :confval:`default template `.
-
-roles
-~~~~~
-
-Convert a list of string to list of reStructuredText roles.
-
-``{{ ['foo', 'bar'] | roles("doc") }}`` produces ``[':doc:`foo`', ':doc:`bar`']``.
-
-It is used in :confval:`default template `.
-
-Configuration
-=============
-
-The extension provides the following configuration:
-
-.. confval:: recentupdate_count
- :type: int
- :default: 10
-
- The default count of recent revisions. See Functionalities_.
-
-.. confval:: recentupdate_template
- :type: str
- :default: see below
-
- The default Jinja template of update information. See Functionalities_.
-
- Here is the default value:
-
- .. code:: jinja
-
- {% for r in revisions %}
- {{ r.date | strftime }}
- :Author: {{ r.author }}
- :Message: {{ r.message }}
-
- {% if r.modification %}
- - Modified {{ r.modification | roles("doc") | join(", ") }}
- {% endif %}
- {% if r.addition %}
- - Added {{ r.addition | roles("doc") | join(", ") }}
- {% endif %}
- {% if r.deletion %}
- - Deleted {{ r.deletion | join(", ") }}
- {% endif %}
- {% endfor %}
-
-.. confval:: recentupdate_date_format
- :type: str
- :default: "%Y-%m-%dT"
-
- The default date format of strftime_ filter.
-
-.. confval:: recentupdate_exclude_path
- :type: List[str]
- :default: []
-
- A list of path that should be excluded when looking for file changes.
-
-.. confval:: recentupdate_exclude_commit
- :type: List[str]
- :default: ["skip-recentupdate"]
-
- A list of commit message pattern that should be excluded when looking for file changes.
-
-Change Log
-==========
-
-2021-12-06 1.0a0
-----------------
-
-Release alpha version.
diff --git a/doc/make.bat b/doc/make.bat
deleted file mode 100644
index 2119f51..0000000
--- a/doc/make.bat
+++ /dev/null
@@ -1,35 +0,0 @@
-@ECHO OFF
-
-pushd %~dp0
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build
-)
-set SOURCEDIR=.
-set BUILDDIR=_build
-
-if "%1" == "" goto help
-
-%SPHINXBUILD% >NUL 2>NUL
-if errorlevel 9009 (
- echo.
- echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
- echo.installed, then set the SPHINXBUILD environment variable to point
- echo.to the full path of the 'sphinx-build' executable. Alternatively you
- echo.may add the Sphinx directory to PATH.
- echo.
- echo.If you don't have Sphinx installed, grab it from
- echo.http://sphinx-doc.org/
- exit /b 1
-)
-
-%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
-goto end
-
-:help
-%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
-
-:end
-popd
diff --git a/doc/requirements.txt b/doc/requirements.txt
deleted file mode 100644
index d1dd105..0000000
--- a/doc/requirements.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# Extension
-sphinx
-GitPython
-Jinja2
-
-# Documentation
-sphinxnotes-any
diff --git a/doc/Makefile b/docs/Makefile
similarity index 68%
rename from doc/Makefile
rename to docs/Makefile
index e5f180e..57d350d 100644
--- a/doc/Makefile
+++ b/docs/Makefile
@@ -1,10 +1,11 @@
+# This file is generated from sphinx-notes/cookiecutter.
+# You need to consider modifying the TEMPLATE or modifying THIS FILE.
+
# Minimal makefile for Sphinx documentation
-#
-# You can set these variables from the command line, and also
-# from the environment for the first two.
-SPHINXOPTS ?=
-SPHINXBUILD ?= sphinx-build
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = python3 -msphinx
SOURCEDIR = .
BUILDDIR = _build
diff --git a/docs/_images/.gitkeep b/docs/_images/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/docs/_static/.gitkeep b/docs/_static/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/doc/_images/sphinx-notes.png b/docs/_static/sphinx-notes.png
similarity index 100%
rename from doc/_images/sphinx-notes.png
rename to docs/_static/sphinx-notes.png
diff --git a/docs/changelog.rst b/docs/changelog.rst
new file mode 100644
index 0000000..3ca598b
--- /dev/null
+++ b/docs/changelog.rst
@@ -0,0 +1,28 @@
+.. This file is generated from sphinx-notes/cookiecutter.
+ You need to consider modifying the TEMPLATE or modifying THIS FILE.
+
+==========
+Change Log
+==========
+
+.. hint:: You may want to learn about our `Release Strategy`__
+
+ __ https://sphinx.silverrainz.me/release.html
+
+.. Example:
+
+ 1.0
+ ===
+
+ .. version:: _
+ :date: yyyy-mm-dd
+
+ Change log here.
+
+Version 1.x
+===========
+
+.. version:: 1.0a0
+ :date: 2021-12-06
+
+ Release alpha version.
diff --git a/doc/conf.py b/docs/conf.py
similarity index 55%
rename from doc/conf.py
rename to docs/conf.py
index a0ea626..217ff7b 100644
--- a/doc/conf.py
+++ b/docs/conf.py
@@ -1,31 +1,20 @@
+# This file is generated from sphinx-notes/cookiecutter.
+# You need to consider modifying the TEMPLATE or modifying THIS FILE.
+
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
-# -- Path setup --------------------------------------------------------------
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#
-import os
-import sys
-from datetime import datetime
-# Import proj's meta info
-sys.path.insert(0, os.path.abspath('../sphinxnotes'))
-import recentupdate as proj
-
# -- Project information -----------------------------------------------------
-project = proj.__title__
-copyright = '%s, %s' % (datetime.now().year, proj.__author__)
-author = proj.__author__
+project = 'sphinxnotes-recentupdate'
+author = 'Shengyu Zhang'
+copyright = "2025, " + author
# The full version, including alpha/beta/rc tags
-version = release = proj.__version__
-
+version = release = '1.0a2'
# -- General configuration ---------------------------------------------------
@@ -33,27 +22,12 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
- 'recentupdate',
'sphinx.ext.githubpages',
- 'sphinxnotes.any',
- 'sphinx.ext.autodoc',
- 'sphinx.ext.intersphinx',
-
-]
-
-sys.path.insert(0, os.path.abspath('.'))
-any_schemas = [
- __import__("confval").confval,
+ 'sphinx_design',
+ 'sphinx_copybutton',
+ 'sphinx_last_updated_by_git',
]
-intersphinx_mapping = {
- 'python': ('https://docs.python.org/3', None),
-}
-
-autoclass_content = 'class'
-autodoc_class_signature = 'separated'
-autodoc_typehints = 'description'
-
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -67,9 +41,6 @@
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
-# Provided by sphinxnotes.any
-primary_domain = 'any'
-
# A boolean that decides whether codeauthor and sectionauthor directives
# produce any output in the built files.
show_authors = True
@@ -79,20 +50,74 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = 'alabaster'
-
-html_theme_options = {
- 'nosidebar': True,
-}
+html_theme = 'furo'
+html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
+html_theme_options = {
+ "source_repository": "https://github.com/sphinx-notes/recentupdate/",
+ "source_branch": "master",
+ "source_directory": "docs/",
+}
# The URL which points to the root of the HTML documentation.
# It is used to indicate the location of document like canonical_url
-html_baseurl = proj.__url__
+html_baseurl = 'https://sphinx.silverrainz.me/recentupdate'
+
+html_logo = html_favicon = '_static/sphinx-notes.png'
+
+# -- Extensions -------------------------------------------------------------
+
+extensions.append('sphinx.ext.extlinks')
+extlinks = {
+ 'issue': ('https://github.com/sphinx-notes/recentupdate/issues/%s', '💬%s'),
+ 'pull': ('https://github.com/sphinx-notes/recentupdate/pull/%s', '🚀%s'),
+ 'tag': ('https://github.com/sphinx-notes/recentupdate/releases/tag/%s', '🏷️%s'),
+}
+
+extensions.append('sphinxcontrib.gtagjs')
+gtagjs_ids = ['G-E4SNX0WZYV']
+
+extensions.append('sphinx.ext.autodoc')
+autoclass_content = 'init'
+autodoc_typehints = 'description'
+
+extensions.append('sphinx.ext.intersphinx')
+intersphinx_mapping = {
+ 'python': ('https://docs.python.org/3', None),
+ 'sphinx': ('https://www.sphinx-doc.org/en/master', None),
+ 'jinja': ('https://jinja.palletsprojects.com/en/latest/', None),
+}
+
+extensions.append('sphinx_sitemap')
+sitemap_filename = "sitemap.xml"
+sitemap_url_scheme = "{link}"
+
+extensions.append('sphinxext.opengraph')
+ogp_site_url = html_baseurl
+ogp_site_name = project
+ogp_image = html_baseurl + '/' + html_logo
+
+extensions.append('sphinxnotes.comboroles')
+comboroles_roles = {
+ 'parsed_literal': (['literal'], True),
+}
+
+extensions.append('sphinxnotes.project')
+primary_domain = 'any'
+
+# -- Eat your own dog food --------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+import os
+import sys
+sys.path.insert(0, os.path.abspath('../src/sphinxnotes'))
+extensions.append('recentupdate')
-html_logo = html_favicon = '_images/sphinx-notes.png'
+# CUSTOM CONFIGURATION
diff --git a/docs/conf.rst b/docs/conf.rst
new file mode 100644
index 0000000..db1eddd
--- /dev/null
+++ b/docs/conf.rst
@@ -0,0 +1,56 @@
+=============
+Configuration
+=============
+
+The extension provides the following configuration:
+
+.. confval:: recentupdate_count
+ :type: int
+ :default: 10
+
+ The default count of recent revisions. See :doc:`usage`.
+
+.. confval:: recentupdate_template
+ :type: str
+ :default: see below
+
+ The default Jinja template of update information. See :doc:`usage`.
+
+ Here is the default value:
+
+ .. code:: jinja
+
+ {% for r in revisions %}
+ {{ r.date | strftime }}
+ :Author: {{ r.author }}
+ :Message: {{ r.message }}
+
+ {% if r.modification %}
+ - Modified {{ r.modification | roles("doc") | join(", ") }}
+ {% endif %}
+ {% if r.addition %}
+ - Added {{ r.addition | roles("doc") | join(", ") }}
+ {% endif %}
+ {% if r.deletion %}
+ - Deleted {{ r.deletion | join(", ") }}
+ {% endif %}
+ {% endfor %}
+
+.. confval:: recentupdate_date_format
+ :type: str
+ :default: "%Y-%m-%dT"
+
+ The default date format of :ref:`strftime` filter.
+
+.. confval:: recentupdate_exclude_path
+ :type: List[str]
+ :default: []
+
+ A list of path that should be excluded when looking for file changes.
+
+.. confval:: recentupdate_exclude_commit
+ :type: List[str]
+ :default: ["skip-recentupdate"]
+
+ A list of commit message pattern that should be excluded when looking for file changes.
+
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..781dfec
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,104 @@
+.. This file is generated from sphinx-notes/cookiecutter.
+ You need to consider modifying the TEMPLATE or modifying THIS FILE.
+
+========================
+sphinxnotes-recentupdate
+========================
+
+.. |docs| image:: https://img.shields.io/github/deployments/sphinx-notes/recentupdate/github-pages?label=docs
+ :target: https://sphinx.silverrainz.me/recentupdate
+ :alt: Documentation Status
+.. |license| image:: https://img.shields.io/github/license/sphinx-notes/recentupdate
+ :target: https://github.com/sphinx-notes/recentupdate/blob/master/LICENSE
+ :alt: Open Source License
+.. |pypi| image:: https://img.shields.io/pypi/v/sphinxnotes-recentupdate.svg
+ :target: https://pypi.python.org/pypi/sphinxnotes-recentupdate
+ :alt: PyPI Package
+.. |download| image:: https://img.shields.io/pypi/dm/sphinxnotes-recentupdate
+ :target: https://pypi.python.org/pypi/sphinxnotes-recentupdate
+ :alt: PyPI Package Downloads
+.. |github| image:: https://img.shields.io/badge/GitHub-181717?style=flat&logo=github&logoColor=white/
+ :target: https://github.com/sphinx-notes/recentupdate
+ :alt: GitHub Repository
+
+|docs| |license| |pypi| |download| |github|
+
+Introduction
+============
+
+.. INTRODUCTION START
+
+Get the document update information from git and display it in Sphinx documentation.
+
+This extensions provides a :doc:`recentupdate ` directive, which can show recent document update of current Sphinx documentation. The update information is read from Git_ repository (So you must use Git to manage your documentation). You can customize the update information through generating reStructuredText from Jinja_ template.
+
+.. _Git: https://git-scm.com/
+.. _Jinja: https://jinja.palletsprojects.com/en/3.0.x/templates/
+
+.. INTRODUCTION END
+
+Getting Started
+===============
+
+.. note::
+
+ We assume you already have a Sphinx documentation,
+ if not, see `Getting Started with Sphinx`_.
+
+
+First, downloading extension from PyPI:
+
+.. code-block:: console
+
+ $ pip install sphinxnotes-recentupdate
+
+
+Then, add the extension name to ``extensions`` configuration item in your
+:parsed_literal:`conf.py_`:
+
+.. code-block:: python
+
+ extensions = [
+ # …
+ 'sphinxnotes.recentupdate',
+ # …
+ ]
+
+.. _Getting Started with Sphinx: https://www.sphinx-doc.org/en/master/usage/quickstart.html
+.. _conf.py: https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+.. ADDITIONAL CONTENT START
+
+Add ``recentupdate`` directive to your document, build your document, the directive will be rendered to:
+
+.. example::
+ :style: grid
+
+ .. recentupdate::
+
+.. ADDITIONAL CONTENT END
+
+Contents
+========
+
+.. toctree::
+ :caption: Contents
+
+ usage
+ conf
+ changelog
+
+The Sphinx Notes Project
+========================
+
+The project is developed by `Shengyu Zhang`__,
+as part of **The Sphinx Notes Project**.
+
+.. toctree::
+ :caption: The Sphinx Notes Project
+
+ Home
+ Blog
+ PyPI
+
+__ https://github.com/SilverRainZ
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 0000000..b158787
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,37 @@
+REM This file is generated from sphinx-notes/cookiecutter. DO NOT EDIT.
+
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=python -msphinx
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The Sphinx module was not found. Make sure you have Sphinx installed,
+ echo.then set the SPHINXBUILD environment variable to point to the full
+ echo.path of the 'sphinx-build' executable. Alternatively you may add the
+ echo.Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+
+:end
+popd
diff --git a/docs/usage.rst b/docs/usage.rst
new file mode 100644
index 0000000..a8ec91f
--- /dev/null
+++ b/docs/usage.rst
@@ -0,0 +1,65 @@
+=====
+Usage
+=====
+
+The extension provides a ``recentupdate`` directive:
+
+.. code:: rst
+
+ .. recentupdate:: [count]
+
+ [jinja template]
+
+count
+ The optional argument of directive is the count of recent "revisions" you want to show. Revision is a git commit which contains document changes.
+
+ If no count given, value of :confval:`recentupdate_count` is used.
+
+template
+ The optional content of directive is a jinja template for generating reStructuredText, in the template you can access Variables_ named `{{ revisions }}`_.
+
+ Beside, You can use `Builtin Filters`_ and Filters_ provided by extensions.
+
+ If no template given, value of :confval:`recentupdate_template` is used.
+
+.. _Builtin Filters: https://jinja.palletsprojects.com/en/3.0.x/templates/#builtin-filters
+
+Variables
+=========
+
+All available variables_:
+
+.. _variables: https://jinja.palletsprojects.com/en/3.0.x/templates/#variables
+
+{{ revisions }}
+---------------
+
+``{{ revisions }}`` is an an array of revisions. The length of array is determined by the argument of ``recentupdate`` directive.
+
+Here is the schema of array element:
+
+.. autoclass:: recentupdate.Revision
+ :members:
+
+Filters
+=======
+
+.. _strftime:
+
+strftime
+--------
+
+Convert a :py:class:`datetime.datetime` to string in given format.
+
+If no format given, use value of :confval:`recentupdate_date_format`.
+
+It is used in :confval:`default template `.
+
+roles
+-----
+
+Convert a list of string to list of reStructuredText roles.
+
+``{{ ['foo', 'bar'] | roles("doc") }}`` produces ``[':doc:`foo`', ':doc:`bar`']``.
+
+It is used in :confval:`default template `.
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..48b00c0
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,100 @@
+# This file is generated from sphinx-notes/cookiecutter.
+# You need to consider modifying the TEMPLATE or modifying THIS FILE.
+
+# This file is used to configure your project.
+# Read more about the various options under:
+# https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#declaring-project-metadata
+
+[project]
+name = "sphinxnotes-recentupdate"
+description = "Get the document update information from git and display it in Sphinx documentation"
+readme = "README.rst"
+license = "BSD-3-Clause"
+license-files = ["LICENSE"]
+authors = [ { name = "Shengyu Zhang" } ]
+maintainers = [ { name = "Shengyu Zhang" } ]
+keywords = [
+ "sphinx",
+ "extension",
+ "documentation",
+ "sphinxnotes",
+
+ # CUSTOM KEYWORDS START
+ # CUSTOM KEYWORDS END
+]
+classifiers = [
+ "Development Status :: 3 - Alpha",
+ "Environment :: Plugins",
+ "Framework :: Sphinx",
+ "Framework :: Sphinx :: Extension",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 3",
+ "Topic :: Documentation",
+ "Topic :: Documentation :: Sphinx",
+
+ # CUSTOM CLASSIFIERS START
+ # CUSTOM CLASSIFIERS END
+]
+
+# See ``make pyver`` for more details.
+requires-python = ">=3.12"
+dependencies = [
+ "Sphinx >= 7.0",
+
+ # CUSTOM DEPENDENCIES START
+ # CUSTOM DEPENDENCIES END
+]
+
+dynamic = ["version"] # required by setuptools_scm, see section [build-system]
+
+[project.optional-dependencies]
+dev = [
+ "build",
+ "twine",
+ "cruft",
+ "ruff>=0.11.10", # pwndbg#2716
+ "pre-commit",
+]
+test = [
+ "pytest",
+]
+docs = [
+ "furo",
+ "sphinx_design",
+ "sphinx_copybutton",
+ "sphinxcontrib-gtagjs",
+ "sphinx-sitemap",
+ "sphinxext-opengraph",
+ "sphinx-last-updated-by-git",
+
+ # Dependencies of sphinxnotes projcts.
+ "sphinxnotes-project",
+ "sphinxnotes-comboroles",
+
+ # CUSTOM DOCS DEPENDENCIES START
+ # CUSTOM DOCS DEPENDENCIES END
+]
+
+[project.urls]
+homepage = "https://sphinx.silverrainz.me/recentupdate"
+documentation = "https://sphinx.silverrainz.me/recentupdate"
+repository = "https://github.com/sphinx-notes/recentupdate"
+changelog = "https://sphinx.silverrainz.me/recentupdate/changelog.html"
+tracker = "https://github.com/sphinx-notes/recentupdate/issues"
+
+[build-system]
+requires = ["setuptools>=46.1.0", "setuptools_scm[toml]>=5", "wheel"]
+build-backend = "setuptools.build_meta"
+
+[tool.setuptools_scm]
+# For smarter version schemes and other configuration options,
+# check out https://github.com/pypa/setuptools_scm
+version_scheme = "no-guess-dev"
+
+[tool.setuptools.packages.find]
+# Find namespace package,
+# check out https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#finding-namespace-packages
+where = ["src"]
+
+# CUSTOM CONFIGURATION
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 1e1f60d..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-sphinx
-GitPython
-Jinja2
diff --git a/ruff.toml b/ruff.toml
new file mode 100644
index 0000000..1774a67
--- /dev/null
+++ b/ruff.toml
@@ -0,0 +1,14 @@
+# This file is generated from sphinx-notes/cookiecutter.
+# You need to consider modifying the TEMPLATE or modifying THIS FILE.
+
+exclude = [
+ "docs/conf.py",
+]
+
+[format]
+quote-style = "single"
+
+[lint]
+ignore = [
+ "E741", # Checks for the use of the characters 'l', 'O', or 'I' as variable names
+]
diff --git a/setup.py b/setup.py
deleted file mode 100644
index a54761c..0000000
--- a/setup.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from setuptools import setup, find_packages
-import sys
-import os
-sys.path.insert(0, os.path.abspath('./sphinxnotes'))
-import recentupdate as proj
-
-with open('README.rst') as f:
- long_desc = f.read()
-
-setup(
- name=proj.__title__,
- version=proj.__version__,
- url=proj.__url__,
- download_url='http://pypi.python.org/pypi/' + proj.__title__,
- license=proj.__license__,
- author=proj.__author__,
- description=proj.__description__,
- long_description=long_desc,
- long_description_content_type = 'text/x-rst',
- zip_safe=False,
- classifiers=[
- 'Development Status :: 3 - Alpha',
- 'Environment :: Console',
- 'Environment :: Web Environment',
- 'Environment :: Plugins',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: BSD License',
- 'Operating System :: OS Independent',
- 'Programming Language :: Python',
- 'Topic :: Documentation',
- 'Topic :: Utilities',
- ],
- keywords=proj.__keywords__,
- platforms='any',
- python_requires='>=3',
- packages=find_packages(),
- include_package_data=True,
- # sphinx.util.compat.Directive class is now deprecated in 1.6
- install_requires=['Sphinx>=1.6', 'GitPython', 'Jinja2'],
- namespace_packages=['sphinxnotes'],
-)
diff --git a/sphinxnotes/__init__.py b/sphinxnotes/__init__.py
deleted file mode 100644
index 8476387..0000000
--- a/sphinxnotes/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- sphinxnotes
- ~~~~~~~~~~~
-
- This package is a namespace package that contains all extensions
- distributed in the ``sphinx-notes`` distribution.
-
- :copyright: Copyright 2020 by the Shengyu Zhang.
-"""
-
-__import__('pkg_resources').declare_namespace(__name__)
-
diff --git a/sphinxnotes/recentupdate/__init__.py b/src/sphinxnotes/recentupdate/__init__.py
similarity index 72%
rename from sphinxnotes/recentupdate/__init__.py
rename to src/sphinxnotes/recentupdate/__init__.py
index 2931166..e3d76e6 100644
--- a/sphinxnotes/recentupdate/__init__.py
+++ b/src/sphinxnotes/recentupdate/__init__.py
@@ -9,46 +9,38 @@
"""
from __future__ import annotations
-from typing import List, Iterable, TYPE_CHECKING, Optional
+from typing import Iterable, TYPE_CHECKING
from textwrap import dedent
from datetime import datetime
-from enum import Enum, auto
from dataclasses import dataclass
from os import path
+from pathlib import Path
from docutils import nodes
from docutils.statemachine import StringList
-from docutils.parsers.rst import directives, Parser
-from docutils.utils import new_document
+from docutils.parsers.rst import directives
from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import nested_parse_with_titles
from sphinx.util.matching import Matcher
-from sphinx.transforms import SphinxTransform
+
if TYPE_CHECKING:
from sphinx.application import Sphinx
- from sphinx.config import Config
- from sphinx.environment import BuildEnvironment
from git import Repo
import jinja2
-__title__= 'sphinxnotes-recentupdate'
-__license__ = 'BSD'
-__version__ = '1.0b2'
-__author__ = 'Shengyu Zhang'
-__url__ = 'https://sphinx-notes.github.io/recentupdate'
-__description__ = 'Get document change information from git log and Display in Sphinx documentation'
-__keywords__ = 'documentation, sphinx, extension, rss, git'
+from . import meta
+
logger = logging.getLogger(__name__)
class Environment(jinja2.Environment):
- datefmt:str
+ datefmt: str
- def __init__(self, datefmt:str, *args, **kwargs):
+ def __init__(self, datefmt: str, *args, **kwargs):
super().__init__(*args, **kwargs)
self.datefmt = datefmt
self.filters['strftime'] = self._strftime_filter
@@ -63,7 +55,7 @@ def _strftime_filter(self, value, format=None) -> str:
format = self.datefmt
return value.strftime(format)
- def _roles_filter(self, value:Iterable[str], role:str) -> Iterable[str]:
+ def _roles_filter(self, value: Iterable[str], role: str) -> Iterable[str]:
"""
A heplfer filter for converting list of string to list of role.
@@ -83,11 +75,11 @@ class Revision(object):
"""
#: Git commit message
- message:str
+ message: str
#: Git commit author
- author:str
+ author: str
#: Git commit author date
- date:datetime
+ date: datetime
# FYI, possible status letters are:
# :A: addition of a file
@@ -100,31 +92,31 @@ class Revision(object):
# :X: "unknown" change type (most probably a bug, please report it)
#: List of docname, corresponding to files which are modified
- addition:List[str]
+ addition: list[str]
#: List of docname, corresponding to files which are newly added
- modification:List[str]
+ modification: list[str]
#: List of docname, corresponding to files which are deleted
- deletion:List[str]
+ deletion: list[str]
class RecentUpdateDirective(SphinxDirective):
- """ Directive for displaying recent update. """
+ """Directive for displaying recent update."""
# Member of parent
- has_content:bool = True
- required_arguments:int = 0
- optional_arguments:int = 1
- final_argument_whitespace:bool = False
+ has_content: bool = True
+ required_arguments: int = 0
+ optional_arguments: int = 1
+ final_argument_whitespace: bool = False
option_spec = {}
#: Repo info
- repo:Repo = None
+ repo: Repo = None
- def _get_docname(self, relfn_to_repo: str) -> Optional[str]:
+ def _get_docname(self, relfn_to_repo: str) -> str | None:
relsrcdir_to_repo = path.relpath(self.env.srcdir, self.repo.working_dir)
relfn_to_srcdir = path.relpath(relfn_to_repo, relsrcdir_to_repo)
absfn = path.abspath(relfn_to_srcdir)
- if path.commonpath([self.env.srcdir, absfn]) != self.env.srcdir:
+ if Path(path.commonpath([self.env.srcdir, absfn])) != self.env.srcdir:
logger.debug(f'Skip {relfn_to_repo}: out of srcdir')
return None
@@ -142,16 +134,17 @@ def _get_docname(self, relfn_to_repo: str) -> Optional[str]:
for p in self.config.recentupdate_exclude_path:
absp = path.abspath(p)
if path.commonpath([absp, absfn]) == absp:
- logger.debug(f'Skip {relfn_to_repo}: excluded by recentupdate_exclude_path confval')
+ logger.debug(
+ f'Skip {relfn_to_repo}: excluded by recentupdate_exclude_path confval'
+ )
return None
logger.debug(f'Get docname: {docname}')
return docname
-
- def _context(self, count: int) -> Dict[str,Any]:
+ def _context(self, count: int) -> dict[str, any]:
revisions = []
- res = { 'revisions': revisions }
+ res = {'revisions': revisions}
cur = self.repo.head.commit
if cur is None:
@@ -164,9 +157,13 @@ def _context(self, count: int) -> Dict[str,Any]:
if prev is None:
break
- matches = [x in cur.message for x in self.config.recentupdate_exclude_commit]
+ matches = [
+ x in cur.message for x in self.config.recentupdate_exclude_commit
+ ]
if any(matches):
- logger.debug(f'Skip commit {cur.hexsha}: excluded by recentupdate_exclude_commit confval')
+ logger.debug(
+ f'Skip commit {cur.hexsha}: excluded by recentupdate_exclude_commit confval'
+ )
cur = prev
continue
@@ -187,7 +184,9 @@ def _context(self, count: int) -> Dict[str,Any]:
elif diff.change_type == 'D':
d.append(docname)
else:
- logger.debug(f'Skip {diff.a_path}: unsupport change type {diff.change_type}')
+ logger.warning(
+ f'Skip {diff.a_path}: unsupport change type {diff.change_type}'
+ )
if len(m) + len(a) + len(d) == 0:
# Dont create revisions when no document changes
@@ -195,21 +194,26 @@ def _context(self, count: int) -> Dict[str,Any]:
cur = prev
continue
- revisions.append(Revision(message=cur.message,
- author=cur.author,
- date=datetime.utcfromtimestamp(cur.authored_date),
- modification=m,
- addition=a,
- deletion=d))
+ revisions.append(
+ Revision(
+ message=cur.message,
+ author=cur.author,
+ date=datetime.utcfromtimestamp(cur.authored_date),
+ modification=m,
+ addition=a,
+ deletion=d,
+ )
+ )
cur = prev
n += 1
- logger.debug(f'Intend to get recent {count} commits, eventually get {n}')
+ logger.warning(
+ f'[recentupdate] Intend to get recent {count} commits, eventually get {n}'
+ )
return res
-
- def run(self) -> List[nodes.Node]:
+ def run(self) -> list[nodes.Node]:
if len(self.arguments) >= 1:
count = directives.nonnegative_int(self.arguments[0])
else:
@@ -219,19 +223,23 @@ def run(self) -> List[nodes.Node]:
env = Environment(self.config.recentupdate_date_format)
try:
- template = env.from_string('\n'.join(list(self.content)) or self.config.recentupdate_template)
+ template = env.from_string(
+ '\n'.join(list(self.content)) or self.config.recentupdate_template
+ )
lines = template.render(self._context(count)).split('\n')
except Exception as e:
msg = f'failed to render recentupdate template: {e}'
logger.warning(msg, location=self.state.parent)
- sm = nodes.system_message(msg, type='WARNING', level=2, backrefs=[], source='')
+ sm = nodes.system_message(
+ msg, type='WARNING', level=2, backrefs=[], source=''
+ )
return [sm]
else:
nested_parse_with_titles(self.state, StringList(lines), self.state.parent)
return []
-DEFAULT_TEMPLATE = dedent('''
+DEFAULT_TEMPLATE = dedent("""
{% for r in revisions %}
{{ r.date | strftime }}
:Author: {{ r.author }}
@@ -247,10 +255,12 @@ def run(self) -> List[nodes.Node]:
- Deleted {{ r.deletion | join(", ") }}
{% endif %}
{% endfor %}
- ''')
+ """)
+
-def setup(app:Sphinx):
+def setup(app: Sphinx):
"""Sphinx extension entrypoint."""
+ meta.pre_setup(app)
# Set current git repo
RecentUpdateDirective.repo = Repo(app.srcdir, search_parent_directories=True)
@@ -263,4 +273,4 @@ def setup(app:Sphinx):
app.add_config_value('recentupdate_exclude_path', [], 'env')
app.add_config_value('recentupdate_exclude_commit', ['skip-recentupdate'], 'env')
- return {'version': __version__}
+ return meta.post_setup(app)
diff --git a/src/sphinxnotes/recentupdate/meta.py b/src/sphinxnotes/recentupdate/meta.py
new file mode 100644
index 0000000..d0a9055
--- /dev/null
+++ b/src/sphinxnotes/recentupdate/meta.py
@@ -0,0 +1,35 @@
+# This file is generated from sphinx-notes/cookiecutter.
+# DO NOT EDIT!!!
+
+################################################################################
+# Project meta infos.
+################################################################################
+
+from __future__ import annotations
+from importlib import metadata
+
+__project__ = 'sphinxnotes-recentupdate'
+__author__ = 'Shengyu Zhang'
+__desc__ = 'Get the document update information from git and display it in Sphinx documentation'
+
+try:
+ __version__ = metadata.version('sphinxnotes-recentupdate')
+except metadata.PackageNotFoundError:
+ __version__ = 'unknown'
+
+
+################################################################################
+# Sphinx extension utils.
+################################################################################
+
+
+def pre_setup(app):
+ app.require_sphinx('7.0')
+
+
+def post_setup(app):
+ return {
+ 'version': __version__,
+ 'parallel_read_safe': True,
+ 'parallel_write_safe': True,
+ }
diff --git a/src/sphinxnotes/recentupdate/py.typed b/src/sphinxnotes/recentupdate/py.typed
new file mode 100644
index 0000000..e69de29