diff --git a/sphinx_autobuild/__main__.py b/sphinx_autobuild/__main__.py index 236912d..2a37a03 100644 --- a/sphinx_autobuild/__main__.py +++ b/sphinx_autobuild/__main__.py @@ -83,7 +83,7 @@ def main(argv=()): if not args.no_initial_build: show_message("Starting initial build") - builder(rebuild=False) + builder(changed_paths=()) if args.open_browser: open_browser(url_host, args.delay) diff --git a/sphinx_autobuild/build.py b/sphinx_autobuild/build.py index 2fa81d6..9579148 100644 --- a/sphinx_autobuild/build.py +++ b/sphinx_autobuild/build.py @@ -2,8 +2,11 @@ from __future__ import annotations +import contextlib import subprocess import sys +from collections.abc import Sequence +from pathlib import Path import sphinx @@ -16,10 +19,20 @@ def __init__(self, sphinx_args, *, url_host, pre_build_commands): self.pre_build_commands = pre_build_commands self.uri = f"http://{url_host}" - def __call__(self, *, rebuild: bool = True): + def __call__(self, *, changed_paths: Sequence[Path]): """Generate the documentation using ``sphinx``.""" - if rebuild: - show_message("Detected change. Rebuilding...") + 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...") try: for command in self.pre_build_commands: diff --git a/sphinx_autobuild/server.py b/sphinx_autobuild/server.py index 0f2f0ea..c32b3f2 100644 --- a/sphinx_autobuild/server.py +++ b/sphinx_autobuild/server.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: import os - from collections.abc import Callable + from collections.abc import Callable, Sequence from starlette.types import Receive, Scope, Send @@ -23,7 +23,7 @@ def __init__( self, paths: list[os.PathLike[str]], ignore_filter: IgnoreFilter, - change_callback: Callable[[], None], + change_callback: Callable[[Sequence[Path]], None], ) -> None: self.paths = [Path(path).resolve(strict=True) for path in paths] self.ignore = ignore_filter @@ -49,12 +49,13 @@ async def main(self) -> None: [task.result() for task in done] async def watch(self) -> None: - async for _changes in watchfiles.awatch( + async for changes in watchfiles.awatch( *self.paths, watch_filter=lambda _, path: not self.ignore(path), ): + changed_paths = [Path(path).resolve() for (_, path) in changes] with ProcessPoolExecutor() as pool: - fut = pool.submit(self.change_callback) + fut = pool.submit(self.change_callback, changed_paths=changed_paths) await asyncio.wrap_future(fut) self.flag.set() diff --git a/tests/test_application.py b/tests/test_application.py index 6a74f1f..b937c13 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -26,7 +26,7 @@ def test_application(tmp_path): app = _create_app([src_dir], ignore_handler, builder, out_dir, url_host) client = TestClient(app) - builder(rebuild=False) + builder(changed_paths=()) response = client.get("/") assert response.status_code == 200