Files
Vijay Janapa Reddi 27d4f8114b binder: fix repo-root, build, doctor and info bugs; clearer errors; dedup
Bug fixes
- Build lock is keyed on books/ so builds started from different
  directories block each other (fixes two tests broken by 89b828efa3).
- ConfigManager resolves the repo root when binder runs from books/ or
  binder/, so bib, newsletter, doctor and render paths are right.
- `build <word> --all` treats intro/scaling/agentic/physical as chapter
  names (it built every volume), and Ctrl-C stops a --all loop.
- doctor checked chapter names that no longer exist and failed on the
  generated _quarto.yml; info defaulted to a deleted books/contents.
- `headings apply --path <typo>` no longer rewrites the whole book;
  `bib clean` stops on unreadable chapters instead of dropping entries.
- Discovery falls back to a line scan on invalid YAML instead of crashing.
- Volume III/IV were labeled Volume II in layout and release output.

Output
- Unexpected errors print the command, exception type, and raising
  file:line (new cli/core/errors.py), with the traceback on stderr.
- Chapter-not-found suggests the closest names and the list command.
- Silent except blocks in bib lookups, info, headings, layout,
  maintenance, preview and debug now say what went wrong.

Cleanup
- Shared qmd_files_under/display_path, file-rewrite loop, doctor result
  helper, preview server, clean helpers, volume display names.
- Removed legacy import fallbacks, dead config attributes, legacy backup
  restore logic, and unused imports.
2026-10-19 19:28:49 +02:00

55 lines
1.6 KiB
Python

"""Shared build-artifact cleanup primitives for Binder."""
from __future__ import annotations
import shutil
from dataclasses import dataclass
from pathlib import Path
from rich.console import Console
@dataclass(frozen=True)
class ArtifactCleanupResult:
"""Number of artifacts removed (a dry run counts what it would remove)."""
cleaned_count: int
def clean_build_artifacts(
book_dir: Path,
*,
dry_run: bool = False,
console: Console | None = None,
) -> ArtifactCleanupResult:
"""Remove the book's build output and Quarto caches: ``_build/``, ``index_files/``, ``.quarto/``."""
out = console or Console()
book_dir = Path(book_dir)
out.print(f"[bold blue]Build Artifact Cleanup[/bold blue] [dim]({book_dir})[/dim]")
artifacts_to_clean = [
(book_dir / "_build", "Build directory (all formats)"),
(book_dir / "index_files", "Book index files"),
(book_dir / ".quarto", "Quarto cache (book)"),
]
cleaned_count = 0
for artifact_path, description in artifacts_to_clean:
if not artifact_path.exists():
continue
out.print(f"[yellow] Removing: {artifact_path.name} ({description})[/yellow]")
if not dry_run:
if artifact_path.is_dir():
shutil.rmtree(artifact_path)
else:
artifact_path.unlink()
cleaned_count += 1
if cleaned_count:
out.print(f"[green] Cleaned {cleaned_count} item(s)[/green]")
else:
out.print("[green] No artifacts to clean[/green]")
return ArtifactCleanupResult(cleaned_count=cleaned_count)