From 120b9175c8149b082688e0984b39e0989bd351fe Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Thu, 16 Oct 2025 23:45:23 +0800 Subject: [PATCH 1/5] chore: Update project template to sphinx-notes/cookiecutter@800a79a0 --- .cruft.json | 27 +++ .github/workflows/lint.yml | 9 + .github/workflows/pages.yml | 39 ++-- .github/workflows/pypi.yml | 22 +++ .github/workflows/release.yml | 18 ++ .gitignore | 7 +- .pre-commit-config.yaml | 7 + LICENSE | 4 +- MANIFEST.in | 13 +- Makefile | 102 ++++++++-- README.rst | 29 ++- doc/confval.py | 17 -- doc/index.rst | 180 ------------------ doc/make.bat | 35 ---- doc/requirements.txt | 7 - {doc => docs}/Makefile | 11 +- docs/_images/.gitkeep | 0 docs/_static/.gitkeep | 0 .../_images => docs/_static}/sphinx-notes.png | Bin docs/changelog.rst | 28 +++ {doc => docs}/conf.py | 117 +++++++----- docs/conf.rst | 56 ++++++ docs/index.rst | 106 +++++++++++ docs/make.bat | 37 ++++ docs/usage.rst | 63 ++++++ pyproject.toml | 100 ++++++++++ requirements.txt | 3 - ruff.toml | 14 ++ setup.py | 43 ----- sphinxnotes/__init__.py | 13 -- .../sphinxnotes}/recentupdate/__init__.py | 87 +++++---- src/sphinxnotes/recentupdate/meta.py | 35 ++++ src/sphinxnotes/recentupdate/py.typed | 0 33 files changed, 801 insertions(+), 428 deletions(-) create mode 100644 .cruft.json create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/pypi.yml create mode 100644 .github/workflows/release.yml create mode 100644 .pre-commit-config.yaml delete mode 100644 doc/confval.py delete mode 100644 doc/index.rst delete mode 100644 doc/make.bat delete mode 100644 doc/requirements.txt rename {doc => docs}/Makefile (68%) create mode 100644 docs/_images/.gitkeep create mode 100644 docs/_static/.gitkeep rename {doc/_images => docs/_static}/sphinx-notes.png (100%) create mode 100644 docs/changelog.rst rename {doc => docs}/conf.py (55%) create mode 100644 docs/conf.rst create mode 100644 docs/index.rst create mode 100644 docs/make.bat create mode 100644 docs/usage.rst create mode 100644 pyproject.toml delete mode 100644 requirements.txt create mode 100644 ruff.toml delete mode 100644 setup.py delete mode 100644 sphinxnotes/__init__.py rename {sphinxnotes => src/sphinxnotes}/recentupdate/__init__.py (81%) create mode 100644 src/sphinxnotes/recentupdate/meta.py create mode 100644 src/sphinxnotes/recentupdate/py.typed 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 $`_ 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..28a3c4c --- /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 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. + diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..37b504d --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,106 @@ +.. 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:: + +.. 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..766b798 --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,63 @@ +===== +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 +-------- + +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 81% rename from sphinxnotes/recentupdate/__init__.py rename to src/sphinxnotes/recentupdate/__init__.py index 2931166..0c083d7 100644 --- a/sphinxnotes/recentupdate/__init__.py +++ b/src/sphinxnotes/recentupdate/__init__.py @@ -26,6 +26,7 @@ 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 @@ -34,21 +35,25 @@ from git import Repo import jinja2 -__title__= 'sphinxnotes-recentupdate' +from . import meta + +__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' +__description__ = ( + 'Get document change information from git log and Display in Sphinx documentation' +) __keywords__ = 'documentation, sphinx, extension, rss, git' 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 +68,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 +88,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,25 +105,25 @@ 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]: relsrcdir_to_repo = path.relpath(self.env.srcdir, self.repo.working_dir) @@ -142,16 +147,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: @@ -187,7 +193,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,12 +203,16 @@ 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 @@ -208,7 +220,6 @@ def _context(self, count: int) -> Dict[str,Any]: return res - def run(self) -> List[nodes.Node]: if len(self.arguments) >= 1: count = directives.nonnegative_int(self.arguments[0]) @@ -219,19 +230,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 +262,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 +280,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 From fc5cbff4c19d86c8fd41c59711a9c1abb4366821 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Thu, 16 Oct 2025 23:49:48 +0800 Subject: [PATCH 2/5] chore: Run ruff fmt --- src/sphinxnotes/recentupdate/__init__.py | 30 +++++++----------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/src/sphinxnotes/recentupdate/__init__.py b/src/sphinxnotes/recentupdate/__init__.py index 0c083d7..ee1f4e2 100644 --- a/src/sphinxnotes/recentupdate/__init__.py +++ b/src/sphinxnotes/recentupdate/__init__.py @@ -9,43 +9,29 @@ """ 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 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 from . import meta -__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' logger = logging.getLogger(__name__) @@ -105,11 +91,11 @@ 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): @@ -125,7 +111,7 @@ class RecentUpdateDirective(SphinxDirective): #: Repo info 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) @@ -155,7 +141,7 @@ def _get_docname(self, relfn_to_repo: str) -> Optional[str]: 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} @@ -220,7 +206,7 @@ def _context(self, count: int) -> Dict[str, Any]: 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: From cbd5d858e29e7336117ba88a31400d9f1b4e4160 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Fri, 17 Oct 2025 00:05:16 +0800 Subject: [PATCH 3/5] docs: Some ref fixes --- docs/conf.rst | 6 +++--- docs/index.rst | 6 ++---- docs/usage.rst | 4 +++- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/conf.rst b/docs/conf.rst index 28a3c4c..db1eddd 100644 --- a/docs/conf.rst +++ b/docs/conf.rst @@ -8,13 +8,13 @@ The extension provides the following configuration: :type: int :default: 10 - The default count of recent revisions. See Functionalities_. + 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 Functionalities_. + The default Jinja template of update information. See :doc:`usage`. Here is the default value: @@ -40,7 +40,7 @@ The extension provides the following configuration: :type: str :default: "%Y-%m-%dT" - The default date format of strftime_ filter. + The default date format of :ref:`strftime` filter. .. confval:: recentupdate_exclude_path :type: List[str] diff --git a/docs/index.rst b/docs/index.rst index 37b504d..781dfec 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -30,7 +30,7 @@ Introduction 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. +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/ @@ -69,15 +69,13 @@ Then, add the extension name to ``extensions`` configuration item in your .. ADDITIONAL CONTENT START -Add ``recentupdate`` directive to your document, Build your document, the directive will be rendered to: +Add ``recentupdate`` directive to your document, build your document, the directive will be rendered to: .. example:: :style: grid .. recentupdate:: -.. recentupdate:: - .. ADDITIONAL CONTENT END Contents diff --git a/docs/usage.rst b/docs/usage.rst index 766b798..a8ec91f 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -34,7 +34,7 @@ All available variables_: {{ revisions }} --------------- -``{{ revisions }}`` is an an array of revisions. The length of array is determined by the argument of`recentupdate `_ directive. +``{{ 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: @@ -44,6 +44,8 @@ Here is the schema of array element: Filters ======= +.. _strftime: + strftime -------- From 6a89fdc36749c4c6cfa5310bcd44155d8e55af53 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Fri, 17 Oct 2025 00:17:19 +0800 Subject: [PATCH 4/5] fix: use pathlib.Path Close #2. --- src/sphinxnotes/recentupdate/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sphinxnotes/recentupdate/__init__.py b/src/sphinxnotes/recentupdate/__init__.py index ee1f4e2..69e5fc3 100644 --- a/src/sphinxnotes/recentupdate/__init__.py +++ b/src/sphinxnotes/recentupdate/__init__.py @@ -14,6 +14,7 @@ from datetime import datetime from dataclasses import dataclass from os import path +from pathlib import Path from docutils import nodes from docutils.statemachine import StringList @@ -115,7 +116,7 @@ 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 From 3a10decdf396c22a3fcac01bda1d6cf2a0ca5a53 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Fri, 17 Oct 2025 00:33:31 +0800 Subject: [PATCH 5/5] chore: Warning log --- src/sphinxnotes/recentupdate/__init__.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/sphinxnotes/recentupdate/__init__.py b/src/sphinxnotes/recentupdate/__init__.py index 69e5fc3..e3d76e6 100644 --- a/src/sphinxnotes/recentupdate/__init__.py +++ b/src/sphinxnotes/recentupdate/__init__.py @@ -157,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 @@ -203,7 +207,9 @@ def _context(self, count: int) -> dict[str, any]: 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