From 6015bab80e28aef2669f6fac53423aa65f70cb08 Mon Sep 17 00:00:00 2001
From: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Date: Tue, 28 Feb 2023 13:14:51 +0100
Subject: [PATCH] Refs #34140 -- Added configurations to run blacken-docs
 linter and adjusted docs.

This adds:
- GitHub actions,
- tox configuration,
- pre-commit hook, and
- makefile rules
to run blacken-docs linter.

Co-authored-by: David Smith <smithdc@gmail.com>
---
 .github/workflows/docs.yml                    | 21 +++++++++++++++++++
 .pre-commit-config.yaml                       |  6 ++++++
 docs/Makefile                                 |  8 +++++++
 .../writing-code/submitting-patches.txt       |  6 +++---
 .../contributing/writing-code/unit-tests.txt  | 11 +++++-----
 .../contributing/writing-documentation.txt    | 10 +++++++++
 docs/make.bat                                 |  9 ++++++++
 docs/requirements.txt                         |  1 +
 tox.ini                                       | 11 ++++++++++
 9 files changed, 75 insertions(+), 8 deletions(-)

diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index b1a8b27107..0e0958ea97 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -38,3 +38,24 @@ jobs:
         run: |
           cd docs
           sphinx-build -b spelling -n -q -W --keep-going -d _build/doctrees -D language=en_US -j auto . _build/spelling
+
+  blacken-docs:
+    runs-on: ubuntu-latest
+    name: blacken-docs
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+      - name: Set up Python
+        uses: actions/setup-python@v4
+        with:
+          python-version: '3.11'
+      - run: python -m pip install blacken-docs
+      - name: Build docs
+        run: |
+          cd docs
+          make black
+          RESULT=`cat _build/black/output.txt`
+          if [ "$RESULT" -gt 0 ]; then
+              echo "💥 📢 Code blocks in documentation must be reformatted with blacken-docs 📢 💥"
+          fi;
+          exit $RESULT
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index f12d7fc766..1d480fc1ab 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -4,6 +4,12 @@ repos:
     hooks:
     - id: black
       exclude: \.py-tpl$
+  - repo: https://github.com/adamchainz/blacken-docs
+    rev: 1.13.0
+    hooks:
+      - id: blacken-docs
+        additional_dependencies:
+        - black==23.1.0
   - repo: https://github.com/PyCQA/isort
     rev: 5.12.0
     hooks:
diff --git a/docs/Makefile b/docs/Makefile
index 2b44830531..d97a7ff07c 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -49,6 +49,7 @@ help:
 	@echo "  linkcheck  to check all external links for integrity"
 	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
 	@echo "  spelling   to check for typos in documentation"
+	@echo "  black      to apply the black formatting to code blocks in documentation"
 
 
 clean:
@@ -165,3 +166,10 @@ spelling:
 	@echo
 	@echo "Check finished. Wrong words can be found in " \
 		"$(BUILDDIR)/spelling/output.txt."
+
+black:
+	@mkdir -p $(BUILDDIR)/black
+	find -name "*.txt" -not -path "./_build/*" -not -path "./_theme/*" \
+		| xargs blacken-docs --rst-literal-block; echo $$? > "$(BUILDDIR)/black/output.txt"
+	@echo
+	@echo "Code blocks reformatted"
diff --git a/docs/internals/contributing/writing-code/submitting-patches.txt b/docs/internals/contributing/writing-code/submitting-patches.txt
index 0ab3e27def..14cb2ef2fa 100644
--- a/docs/internals/contributing/writing-code/submitting-patches.txt
+++ b/docs/internals/contributing/writing-code/submitting-patches.txt
@@ -291,9 +291,9 @@ All code changes
 
 * Does the :doc:`coding style
   </internals/contributing/writing-code/coding-style>` conform to our
-  guidelines? Are there any  ``black``, ``flake8``, or ``isort`` errors? You
-  can install the :ref:`pre-commit <coding-style-pre-commit>` hooks to
-  automatically catch these errors.
+  guidelines? Are there any  ``black``, ``blacken-docs``, ``flake8``, or
+  ``isort`` errors? You can install the :ref:`pre-commit
+  <coding-style-pre-commit>` hooks to automatically catch these errors.
 * If the change is backwards incompatible in any way, is there a note
   in the release notes (``docs/releases/A.B.txt``)?
 * Is Django's test suite passing?
diff --git a/docs/internals/contributing/writing-code/unit-tests.txt b/docs/internals/contributing/writing-code/unit-tests.txt
index b547a28049..8789e0ef7b 100644
--- a/docs/internals/contributing/writing-code/unit-tests.txt
+++ b/docs/internals/contributing/writing-code/unit-tests.txt
@@ -69,17 +69,18 @@ command from any place in the Django source tree:
     $ tox
 
 By default, ``tox`` runs the test suite with the bundled test settings file for
-SQLite, ``black``, ``flake8``, ``isort``, and the documentation spelling
-checker. In addition to the system dependencies noted elsewhere in this
-documentation, the command ``python3`` must be on your path and linked to the
-appropriate version of Python. A list of default environments can be seen as
-follows:
+SQLite, ``black``, ``blacken-docs``, ``flake8``, ``isort``, and the
+documentation spelling checker. In addition to the system dependencies noted
+elsewhere in this documentation, the command ``python3`` must be on your path
+and linked to the appropriate version of Python. A list of default environments
+can be seen as follows:
 
 .. console::
 
     $ tox -l
     py3
     black
+    blacken-docs
     flake8>=3.7.0
     docs
     isort>=5.1.0
diff --git a/docs/internals/contributing/writing-documentation.txt b/docs/internals/contributing/writing-documentation.txt
index a89ea050d5..3e6b846a7a 100644
--- a/docs/internals/contributing/writing-documentation.txt
+++ b/docs/internals/contributing/writing-documentation.txt
@@ -211,6 +211,9 @@ documentation:
   "last bit" of that path. So ``:mod:`~django.contrib.auth``` will
   display a link with the title "auth".
 
+* All Python code blocks should be formatted using the `blacken-docs`_
+  auto-formatter. This will be run by ``pre-commit`` if that is configured.
+
 * Use :mod:`~sphinx.ext.intersphinx` to reference Python's and Sphinx'
   documentation.
 
@@ -258,6 +261,13 @@ documentation:
   also need to define a reference to the documentation for that environment
   variable using :rst:dir:`.. envvar:: <envvar>`.
 
+.. versionchanged:: 4.2
+
+    All Python code blocks in the Django documentation were reformatted with
+    `blacken-docs`_.
+
+.. _blacken-docs: https://pypi.org/project/blacken-docs/
+
 Django-specific markup
 ======================
 
diff --git a/docs/make.bat b/docs/make.bat
index 4743692ca3..72d71136c2 100644
--- a/docs/make.bat
+++ b/docs/make.bat
@@ -35,6 +35,7 @@ if "%1" == "help" (
 	echo.  linkcheck  to check all external links for integrity
 	echo.  doctest    to run all doctests embedded in the documentation if enabled
 	echo.  spelling   to check for typos in documentation
+	echo.  black      to apply the black formatting to code blocks in documentation
 	goto end
 )
 
@@ -196,4 +197,12 @@ spelling/output.txt.
 	goto end
 )
 
+if "%1" == "black" (
+	for /f "usebackq tokens=*" %%i in (`dir *.txt /s /b ^| findstr /v /c:"_build" /c:"_theme"`) do (
+		blacken-docs --rst-literal-block %%i
+	)
+	echo.
+	echo.Code blocks reformatted
+)
+
 :end
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 344d3bcc8c..e234972a3b 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,3 +1,4 @@
 pyenchant
 Sphinx>=4.5.0
 sphinxcontrib-spelling
+blacken-docs
diff --git a/tox.ini b/tox.ini
index 38fbaaab65..fa32144e68 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,6 +9,7 @@ skipsdist = true
 envlist =
     py3
     black
+    blacken-docs
     flake8
     docs
     isort
@@ -39,6 +40,16 @@ deps = black
 changedir = {toxinidir}
 commands = black --check --diff .
 
+[testenv:blacken-docs]
+basepython = python3
+usedevelop = false
+allowlist_externals =
+    make
+deps = blacken-docs
+changedir = docs
+commands =
+    make black
+
 [testenv:flake8]
 basepython = python3
 usedevelop = false