From b31faa5a2418a9bedd67825c5b4fec80637ce6bc Mon Sep 17 00:00:00 2001 From: Emmanuel Roux <15956441+fesaille@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:48:30 +0100 Subject: [PATCH 1/9] feat(cli): add post-build argument --- README.rst | 9 +++++++++ sphinx_autobuild/__main__.py | 10 +++++++++- sphinx_autobuild/build.py | 18 +++++++++++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index dbf2935..844bab8 100644 --- a/README.rst +++ b/README.rst @@ -67,6 +67,7 @@ which can seen by running ``sphinx-autobuild --help``: --delay DELAY how long to wait before opening the browser --watch DIR additional directories to watch --pre-build COMMAND additional command(s) to run prior to building the documentation + --post-build COMMAND additional command(s) to run after building the documentation (default: []) Using with Makefile ------------------- @@ -126,6 +127,14 @@ all pages are built from the same state of the HTML theme. It also works around a `known issue in Sphinx `__ which causes significant problems during theme development. +Post-build resources can be processed by passing a user-defined command to +``--post-build``. + +.. code-block:: bash + + --post-build "npx tailwindcss -i ./src/input.css -o ./src/output.css" + + Working on multiple projects ---------------------------- diff --git a/sphinx_autobuild/__main__.py b/sphinx_autobuild/__main__.py index 2a37a03..ed40ace 100644 --- a/sphinx_autobuild/__main__.py +++ b/sphinx_autobuild/__main__.py @@ -49,11 +49,12 @@ def main(argv=()): url_host = f"{host_name}:{port_num}" pre_build_commands = list(map(shlex.split, args.pre_build)) - + post_build_commands = list(map(shlex.split, args.post_build)) builder = Builder( build_args, url_host=url_host, pre_build_commands=pre_build_commands, + post_build_commands=post_build_commands, ) watch_dirs = [src_dir] + args.additional_watched_dirs @@ -233,6 +234,13 @@ def _add_autobuild_arguments(parser): default=[], help="additional command(s) to run prior to building the documentation", ) + group.add_argument( + "--post-build", + action="append", + metavar="COMMAND", + default=[], + help="additional command(s) to run after building the documentation", + ) return group diff --git a/sphinx_autobuild/build.py b/sphinx_autobuild/build.py index f0d8126..ee3c245 100644 --- a/sphinx_autobuild/build.py +++ b/sphinx_autobuild/build.py @@ -15,9 +15,10 @@ class Builder: - def __init__(self, sphinx_args, *, url_host, pre_build_commands): + def __init__(self, sphinx_args, *, url_host, pre_build_commands, post_build_commands): self.sphinx_args = sphinx_args self.pre_build_commands = pre_build_commands + self.post_build_commands = post_build_commands self.uri = f"http://{url_host}" def __call__(self, *, changed_paths: Sequence[Path]): @@ -70,5 +71,20 @@ def __call__(self, *, changed_paths: Sequence[Path]): "Please fix the cause of the error above or press Ctrl+C to stop the " "server." ) + else: + # Run the post-build commands only if the build was successful + try: + for command in self.post_build_commands: + show_message("post-build") + show_command(command) + subprocess.run(command, check=True) + except subprocess.CalledProcessError as e: + print(f"Post-build command exited with exit code: {e.returncode}") + print( + "Please fix the cause of the error above or press Ctrl+C to stop" + " the server." + ) + raise + # Remind the user of the server URL for convenience. show_message(f"Serving on {self.uri}") From 514c07ece0b163a4317e29e1685ef824216f2198 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Fri, 23 May 2025 00:43:58 +0800 Subject: [PATCH 2/9] docs: Add ``--post-build`` use case --- README.rst | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index 844bab8..7158071 100644 --- a/README.rst +++ b/README.rst @@ -67,7 +67,7 @@ which can seen by running ``sphinx-autobuild --help``: --delay DELAY how long to wait before opening the browser --watch DIR additional directories to watch --pre-build COMMAND additional command(s) to run prior to building the documentation - --post-build COMMAND additional command(s) to run after building the documentation (default: []) + --post-build COMMAND additional command(s) to run after building the documentation Using with Makefile ------------------- @@ -127,14 +127,6 @@ all pages are built from the same state of the HTML theme. It also works around a `known issue in Sphinx `__ which causes significant problems during theme development. -Post-build resources can be processed by passing a user-defined command to -``--post-build``. - -.. code-block:: bash - - --post-build "npx tailwindcss -i ./src/input.css -o ./src/output.css" - - Working on multiple projects ---------------------------- @@ -149,6 +141,18 @@ to avoid needing to manually manage ports and opening browser windows sphinx-autobuild --port=0 --open-browser pikachu/docs pikachu/docs/_build/html & sphinx-autobuild --port=0 --open-browser magikarp/docs magickarp/docs/_build/html & +Notify when build starts and ends +--------------------------------- + +When running sphinx-autobuild as a daemon, users may need to be notified when +the build starts and ends (require libnotify and a notification server). + +.. code-block:: bash + + sphinx-autobuild docs docs/_build/html/ \ + --pre-build 'notify-send "sphinx-autobuild: build start"' \ + --post-build 'notify-send "sphinx-autobuild: build end"' + Relevant Sphinx Bugs ==================== From 0277d8b5872c5717abb530ea86356529d851be4a Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Fri, 23 May 2025 00:50:14 +0800 Subject: [PATCH 3/9] chore: Run ``ruff format`` --- sphinx_autobuild/build.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sphinx_autobuild/build.py b/sphinx_autobuild/build.py index ee3c245..45cb988 100644 --- a/sphinx_autobuild/build.py +++ b/sphinx_autobuild/build.py @@ -15,7 +15,9 @@ class Builder: - def __init__(self, sphinx_args, *, url_host, pre_build_commands, post_build_commands): + def __init__( + self, sphinx_args, *, url_host, pre_build_commands, post_build_commands + ): self.sphinx_args = sphinx_args self.pre_build_commands = pre_build_commands self.post_build_commands = post_build_commands From 31a86d122ca52028d665c4fe7de1c1e2d0020a20 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Sun, 25 May 2025 10:39:18 +0800 Subject: [PATCH 4/9] refactor: Simplify Builder.__call__ --- sphinx_autobuild/build.py | 57 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/sphinx_autobuild/build.py b/sphinx_autobuild/build.py index 45cb988..75167e3 100644 --- a/sphinx_autobuild/build.py +++ b/sphinx_autobuild/build.py @@ -23,28 +23,16 @@ def __init__( self.post_build_commands = post_build_commands self.uri = f"http://{url_host}" - def __call__(self, *, changed_paths: Sequence[Path]): - """Generate the documentation using ``sphinx``.""" - if changed_paths: - cwd = Path.cwd() - rel_paths = [] - for changed_path in changed_paths[:5]: - if not changed_path.exists(): - continue - with contextlib.suppress(ValueError): - changed_path = changed_path.relative_to(cwd) - rel_paths.append(changed_path.as_posix()) - if rel_paths: - show_message(f"Detected changes ({', '.join(rel_paths)})") - show_message("Rebuilding...") - + def _run_commands(self, commands, log_context): try: - for command in self.pre_build_commands: - show_message("pre-build") + for command in commands: + show_message(log_context) show_command(command) subprocess.run(command, check=True) except subprocess.CalledProcessError as e: - print(f"Pre-build command exited with exit code: {e.returncode}") + print( + f"{log_context.title()} command exited with exit code: {e.returncode}" + ) print( "Please fix the cause of the error above or press Ctrl+C to stop the " "server." @@ -56,6 +44,26 @@ def __call__(self, *, changed_paths: Sequence[Path]): "server." ) traceback.print_exception(e) + return e.returncode + else: + return 0 + + def __call__(self, *, changed_paths: Sequence[Path]): + """Generate the documentation using ``sphinx``.""" + if changed_paths: + cwd = Path.cwd() + rel_paths = [] + for changed_path in changed_paths[:5]: + if not changed_path.exists(): + continue + with contextlib.suppress(ValueError): + changed_path = changed_path.relative_to(cwd) + rel_paths.append(changed_path.as_posix()) + if rel_paths: + show_message(f"Detected changes ({', '.join(rel_paths)})") + show_message("Rebuilding...") + + if self._run_commands(self.pre_build_commands, "pre-build") != 0: return if sphinx.version_info[:3] >= (7, 2, 3): @@ -75,18 +83,7 @@ def __call__(self, *, changed_paths: Sequence[Path]): ) else: # Run the post-build commands only if the build was successful - try: - for command in self.post_build_commands: - show_message("post-build") - show_command(command) - subprocess.run(command, check=True) - except subprocess.CalledProcessError as e: - print(f"Post-build command exited with exit code: {e.returncode}") - print( - "Please fix the cause of the error above or press Ctrl+C to stop" - " the server." - ) - raise + self._run_commands(self.post_build_commands, "post-build") # Remind the user of the server URL for convenience. show_message(f"Serving on {self.uri}") From 72feb255a2b3cd7c0f33877317f96e771ea89850 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Sun, 25 May 2025 10:56:08 +0800 Subject: [PATCH 5/9] tests: Fix test case --- tests/test_application.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_application.py b/tests/test_application.py index b937c13..6919d9a 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -21,7 +21,10 @@ def test_application(tmp_path): url_host = "127.0.0.1:7777" ignore_handler = IgnoreFilter([out_dir], []) builder = Builder( - [str(src_dir), str(out_dir)], url_host=url_host, pre_build_commands=[] + [str(src_dir), str(out_dir)], + url_host=url_host, + pre_build_commands=[], + post_build_commands=[], ) app = _create_app([src_dir], ignore_handler, builder, out_dir, url_host) client = TestClient(app) From 412d80271e9c1206957c9431cb33e8ff052912a2 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Wed, 28 May 2025 08:57:44 +0100 Subject: [PATCH 6/9] Update README.rst --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 7158071..2208d41 100644 --- a/README.rst +++ b/README.rst @@ -141,8 +141,8 @@ to avoid needing to manually manage ports and opening browser windows sphinx-autobuild --port=0 --open-browser pikachu/docs pikachu/docs/_build/html & sphinx-autobuild --port=0 --open-browser magikarp/docs magickarp/docs/_build/html & -Notify when build starts and ends ---------------------------------- +Notifications for build cycles +------------------------------ When running sphinx-autobuild as a daemon, users may need to be notified when the build starts and ends (require libnotify and a notification server). From fce2c119cf6ae91ff70ed64cdb5ef304c1b89893 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Wed, 28 May 2025 08:59:26 +0100 Subject: [PATCH 7/9] Update README.rst --- README.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 2208d41..4aeaa72 100644 --- a/README.rst +++ b/README.rst @@ -144,8 +144,9 @@ to avoid needing to manually manage ports and opening browser windows Notifications for build cycles ------------------------------ -When running sphinx-autobuild as a daemon, users may need to be notified when -the build starts and ends (require libnotify and a notification server). +As an example of using the ``--pre-build`` and ``--post-build`` arguments, +the command below uses `notify-send` to send a notification when a build +starts and finishes. .. code-block:: bash From 1d138ef528d862df8eb3bf80a62d63d6f5099811 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Wed, 28 May 2025 18:31:35 +0800 Subject: [PATCH 8/9] chore: Move __call__ first --- sphinx_autobuild/build.py | 50 +++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/sphinx_autobuild/build.py b/sphinx_autobuild/build.py index 75167e3..b87bad6 100644 --- a/sphinx_autobuild/build.py +++ b/sphinx_autobuild/build.py @@ -23,31 +23,6 @@ def __init__( self.post_build_commands = post_build_commands self.uri = f"http://{url_host}" - def _run_commands(self, commands, log_context): - try: - for command in commands: - show_message(log_context) - show_command(command) - subprocess.run(command, check=True) - except subprocess.CalledProcessError as e: - print( - f"{log_context.title()} command exited with exit code: {e.returncode}" - ) - print( - "Please fix the cause of the error above or press Ctrl+C to stop the " - "server." - ) - print( - "The server will continue serving the build folder, but the contents " - "being served are no longer in sync with the documentation sources. " - "Please fix the cause of the error above or press Ctrl+C to stop the " - "server." - ) - traceback.print_exception(e) - return e.returncode - else: - return 0 - def __call__(self, *, changed_paths: Sequence[Path]): """Generate the documentation using ``sphinx``.""" if changed_paths: @@ -87,3 +62,28 @@ def __call__(self, *, changed_paths: Sequence[Path]): # Remind the user of the server URL for convenience. show_message(f"Serving on {self.uri}") + + def _run_commands(self, commands, log_context): + try: + for command in commands: + show_message(log_context) + show_command(command) + subprocess.run(command, check=True) + except subprocess.CalledProcessError as e: + print( + f"{log_context.title()} command exited with exit code: {e.returncode}" + ) + print( + "Please fix the cause of the error above or press Ctrl+C to stop the " + "server." + ) + print( + "The server will continue serving the build folder, but the contents " + "being served are no longer in sync with the documentation sources. " + "Please fix the cause of the error above or press Ctrl+C to stop the " + "server." + ) + traceback.print_exception(e) + return e.returncode + else: + return 0 From 8fe1eab9b5770699f306be3ebc71824873e50f4b Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Wed, 28 May 2025 11:37:00 +0100 Subject: [PATCH 9/9] Update sphinx_autobuild/build.py --- sphinx_autobuild/build.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sphinx_autobuild/build.py b/sphinx_autobuild/build.py index b87bad6..5f4470a 100644 --- a/sphinx_autobuild/build.py +++ b/sphinx_autobuild/build.py @@ -85,5 +85,4 @@ def _run_commands(self, commands, log_context): ) traceback.print_exception(e) return e.returncode - else: - return 0 + return 0