refactor: restructure mytoolkit with new subcommands and md-to-pdf improvements
- 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
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
"""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")
|
||||
Reference in New Issue
Block a user