feat(n7web): enhance control workflows and status feedback
This commit is contained in:
@@ -7,6 +7,7 @@ import argparse
|
||||
import json
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
@@ -21,6 +22,7 @@ PYTHON_SOURCE_PATHS = (
|
||||
REPOSITORY_ROOT / "src",
|
||||
REPOSITORY_ROOT / "domains" / "seat" / "src",
|
||||
)
|
||||
WEB_CONSOLE_ROOT = REPOSITORY_ROOT / "apps" / "web-console"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -90,6 +92,11 @@ def _parser() -> argparse.ArgumentParser:
|
||||
action="store_true",
|
||||
help="print the resolved commands without starting processes",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip-web-build",
|
||||
action="store_true",
|
||||
help="reuse the existing Vite dist output instead of rebuilding it",
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
@@ -176,6 +183,37 @@ def _display_command(command: Sequence[str]) -> str:
|
||||
return shlex.join(command)
|
||||
|
||||
|
||||
def _resolve_npm() -> Path:
|
||||
executable = shutil.which("npm.cmd" if os.name == "nt" else "npm")
|
||||
if not executable:
|
||||
raise ValueError(
|
||||
"npm is required to build the Vue 3 + Vite web console; "
|
||||
"install Node.js or pass --skip-web-build to reuse an existing dist"
|
||||
)
|
||||
return Path(executable).resolve()
|
||||
|
||||
|
||||
def _web_build_commands(npm: Path) -> list[list[str]]:
|
||||
commands: list[list[str]] = []
|
||||
vite_binary = WEB_CONSOLE_ROOT / "node_modules" / ".bin" / (
|
||||
"vite.cmd" if os.name == "nt" else "vite"
|
||||
)
|
||||
if not vite_binary.is_file():
|
||||
commands.append([str(npm), "ci"])
|
||||
commands.append([str(npm), "run", "build"])
|
||||
return commands
|
||||
|
||||
|
||||
def _build_web_console(npm: Path) -> None:
|
||||
for command in _web_build_commands(npm):
|
||||
print(f"Web build: {_display_command(command)}", flush=True)
|
||||
completed = subprocess.run(command, cwd=WEB_CONSOLE_ROOT, check=False)
|
||||
if completed.returncode != 0:
|
||||
raise RuntimeError(
|
||||
f"Vue 3 + Vite web build failed with exit code {completed.returncode}"
|
||||
)
|
||||
|
||||
|
||||
def _catalog_is_ready(path: Path) -> bool:
|
||||
try:
|
||||
document = json.loads(path.read_text(encoding="utf-8"))
|
||||
@@ -257,6 +295,7 @@ def run(argv: Sequence[str] | None = None) -> int:
|
||||
try:
|
||||
python = _resolve_python(args.python)
|
||||
catalog = _resolve_path(args.catalog)
|
||||
npm = None if args.skip_web_build else _resolve_npm()
|
||||
if args.catalog_ready_timeout <= 0:
|
||||
raise ValueError("catalog-ready-timeout must be greater than zero")
|
||||
except ValueError as exc:
|
||||
@@ -269,9 +308,20 @@ def run(argv: Sequence[str] | None = None) -> int:
|
||||
print(f"Catalog: {catalog}", flush=True)
|
||||
print(f"Main: {_display_command(main_command)}", flush=True)
|
||||
print(f"Cards: {_display_command(scene_command)}", flush=True)
|
||||
if npm is not None:
|
||||
for command in _web_build_commands(npm):
|
||||
print(f"Web build: {_display_command(command)}", flush=True)
|
||||
if args.dry_run:
|
||||
return 0
|
||||
|
||||
|
||||
if npm is not None:
|
||||
try:
|
||||
_build_web_console(npm)
|
||||
except RuntimeError as exc:
|
||||
print(f"startup failed: {exc}", file=sys.stderr, flush=True)
|
||||
return 1
|
||||
|
||||
children: list[ChildProcess] = []
|
||||
interrupted = False
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user