- Add new subcommands: convert, preflight, server, templates, webpage - Migrate config from bin/config.json to ~/.config/mytoolkit - Fix expand_bookmarks to modify writer objects instead of reader - Improve md_to_pdf with CJK bookmark support - Update README and project metadata
90 lines
2.9 KiB
Python
90 lines
2.9 KiB
Python
"""Webpage project utilities (Docusaurus build / clear / etc.).
|
|
|
|
Project metadata lives in `server.py` so that adding a new webpage there
|
|
automatically wires it up here.
|
|
"""
|
|
|
|
import subprocess
|
|
import time
|
|
|
|
import click
|
|
|
|
from bin.commands.server import manageable_services, get_service, no_color_env
|
|
|
|
|
|
_PROJECTS = manageable_services()
|
|
_NAMES = [s.name for s in _PROJECTS]
|
|
|
|
|
|
def _run_npm(name: str, script: str, label: str) -> None:
|
|
"""Run `npm run <script>` in the project's directory, streaming output."""
|
|
svc = get_service(name)
|
|
assert svc.project_dir is not None # _NAMES is manageable services only
|
|
|
|
if not svc.project_dir.exists():
|
|
click.secho(f"Project directory not found: {svc.project_dir}", fg="red")
|
|
raise click.Abort()
|
|
|
|
click.secho(f"{label} {svc.name} ({svc.description}) ...", fg="cyan")
|
|
started = time.time()
|
|
proc = subprocess.run(["npm", "run", script], cwd=svc.project_dir, env=no_color_env())
|
|
elapsed = time.time() - started
|
|
if proc.returncode != 0:
|
|
click.secho(f"{script} failed for {svc.name} (exit {proc.returncode})", fg="red")
|
|
raise click.Abort()
|
|
click.secho(f"{svc.name} {script} done in {elapsed:.1f}s", fg="green")
|
|
|
|
|
|
@click.group(name="webpage")
|
|
def webpage_cmd():
|
|
"""Manage Docusaurus webpage projects."""
|
|
pass
|
|
|
|
|
|
@webpage_cmd.command("list")
|
|
def webpage_list():
|
|
"""List managed webpage projects and their build status."""
|
|
click.echo("")
|
|
click.secho(
|
|
f"{'Name':<16} {'Build':<12} {'Description':<36} {'Project'}",
|
|
fg="bright_blue",
|
|
bold=True,
|
|
)
|
|
click.echo("-" * 100)
|
|
for svc in _PROJECTS:
|
|
assert svc.project_dir is not None # _PROJECTS is manageable services only
|
|
build_dir = svc.project_dir / "build"
|
|
if build_dir.exists():
|
|
build_status = time.strftime("%m-%d %H:%M", time.localtime(build_dir.stat().st_mtime))
|
|
color = "green"
|
|
else:
|
|
build_status = "missing"
|
|
color = "yellow"
|
|
click.secho(
|
|
f"{svc.name:<16} {build_status:<12} {svc.description:<36} {svc.project_dir}",
|
|
fg=color,
|
|
)
|
|
click.echo("")
|
|
|
|
|
|
@webpage_cmd.command("build")
|
|
@click.argument("name", type=click.Choice(_NAMES, case_sensitive=False))
|
|
def webpage_build(name):
|
|
"""Build a webpage project (`npm run build`)."""
|
|
_run_npm(name, "build", "Building")
|
|
|
|
|
|
@webpage_cmd.command("clear")
|
|
@click.argument("name", type=click.Choice(_NAMES, case_sensitive=False))
|
|
def webpage_clear(name):
|
|
"""Clear Docusaurus build artifacts and cache (`npm run clear`)."""
|
|
_run_npm(name, "clear", "Clearing")
|
|
|
|
|
|
@webpage_cmd.command("rebuild")
|
|
@click.argument("name", type=click.Choice(_NAMES, case_sensitive=False))
|
|
def webpage_rebuild(name):
|
|
"""Clear cache then build (`npm run clear && npm run build`)."""
|
|
_run_npm(name, "clear", "Clearing")
|
|
_run_npm(name, "build", "Building")
|