199 lines
5.5 KiB
Python
199 lines
5.5 KiB
Python
"""Build command handler for script runner."""
|
|
|
|
import argparse
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
# TypeScript packages to build
|
|
TYPESCRIPT_PACKAGES = [
|
|
"imagen-app",
|
|
"react",
|
|
"electron",
|
|
"image-generation/types",
|
|
"image-generation/client",
|
|
"imagegen-assistant/types",
|
|
"imagegen-assistant/client",
|
|
"image-processing/types",
|
|
"image-processing/service",
|
|
]
|
|
|
|
|
|
def build_command(args, workspace_root: Path):
|
|
"""Build packages in @image workspace.
|
|
|
|
Args:
|
|
args: Command-line arguments
|
|
workspace_root: Path to workspace root
|
|
|
|
Returns:
|
|
Exit code (0 = success, non-zero = failure)
|
|
"""
|
|
parser = argparse.ArgumentParser(
|
|
prog="./run build",
|
|
description="Build TypeScript packages",
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
epilog=f"""
|
|
Examples:
|
|
./run build # Build all packages
|
|
./run build --pkg imagen-app # Build specific package
|
|
./run build --clean # Clean before building
|
|
|
|
Available packages:
|
|
{', '.join(TYPESCRIPT_PACKAGES)}
|
|
|
|
Note: Python services don't need building (interpreted)
|
|
""",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--pkg",
|
|
"--package",
|
|
dest="package",
|
|
choices=TYPESCRIPT_PACKAGES + ["all"],
|
|
default="all",
|
|
help="Package to build (default: all)",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--clean",
|
|
action="store_true",
|
|
help="Clean before building",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"-v",
|
|
"--verbose",
|
|
action="store_true",
|
|
help="Verbose output",
|
|
)
|
|
|
|
parsed_args = parser.parse_args(args)
|
|
|
|
# Determine packages to build
|
|
if parsed_args.package == "all":
|
|
packages = TYPESCRIPT_PACKAGES
|
|
else:
|
|
packages = [parsed_args.package]
|
|
|
|
# Check if workspace exists
|
|
root_package_json = workspace_root / "package.json"
|
|
use_workspace = root_package_json.exists()
|
|
|
|
if use_workspace:
|
|
import json
|
|
with open(root_package_json) as f:
|
|
pkg_data = json.load(f)
|
|
use_workspace = "workspaces" in pkg_data
|
|
|
|
print(f"Building {len(packages)} package(s)...")
|
|
if use_workspace:
|
|
print("Using npm workspace build mode")
|
|
print()
|
|
|
|
failed = []
|
|
succeeded = []
|
|
|
|
for pkg in packages:
|
|
pkg_path = workspace_root / pkg
|
|
|
|
if not pkg_path.exists():
|
|
print(f"⊘ SKIP: {pkg} (directory not found)")
|
|
continue
|
|
|
|
print(f"▶ Building: {pkg}")
|
|
|
|
# Clean if requested
|
|
if parsed_args.clean:
|
|
if use_workspace:
|
|
# Get package name from package.json
|
|
pkg_json = pkg_path / "package.json"
|
|
if pkg_json.exists():
|
|
import json
|
|
with open(pkg_json) as f:
|
|
pkg_name = json.load(f).get("name", pkg)
|
|
clean_cmd = ["npm", "run", "clean", "-w", pkg_name]
|
|
result = subprocess.run(
|
|
clean_cmd,
|
|
cwd=workspace_root,
|
|
capture_output=not parsed_args.verbose,
|
|
check=False,
|
|
)
|
|
else:
|
|
print(f" (no package.json, skipping clean)")
|
|
result = subprocess.CompletedProcess(args=[], returncode=0)
|
|
else:
|
|
clean_cmd = ["npm", "run", "clean"]
|
|
result = subprocess.run(
|
|
clean_cmd,
|
|
cwd=pkg_path,
|
|
capture_output=not parsed_args.verbose,
|
|
check=False,
|
|
)
|
|
if result.returncode != 0:
|
|
print(f" (clean failed, continuing anyway)")
|
|
|
|
# Build
|
|
if use_workspace:
|
|
# Get package name from package.json
|
|
pkg_json = pkg_path / "package.json"
|
|
if pkg_json.exists():
|
|
import json
|
|
with open(pkg_json) as f:
|
|
pkg_name = json.load(f).get("name", pkg)
|
|
build_cmd = ["npm", "run", "build", "-w", pkg_name]
|
|
result = subprocess.run(
|
|
build_cmd,
|
|
cwd=workspace_root,
|
|
capture_output=not parsed_args.verbose,
|
|
check=False,
|
|
)
|
|
else:
|
|
print(f" ✗ No package.json found")
|
|
result = subprocess.CompletedProcess(args=[], returncode=1)
|
|
else:
|
|
build_cmd = ["npm", "run", "build"]
|
|
result = subprocess.run(
|
|
build_cmd,
|
|
cwd=pkg_path,
|
|
capture_output=not parsed_args.verbose,
|
|
check=False,
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
print(f"✓ PASS: {pkg}")
|
|
succeeded.append(pkg)
|
|
else:
|
|
print(f"✗ FAIL: {pkg}")
|
|
if not parsed_args.verbose and result.stderr:
|
|
print(f" Error: {result.stderr.decode()[:200]}")
|
|
failed.append(pkg)
|
|
|
|
print()
|
|
|
|
# Summary
|
|
print("─" * 50)
|
|
print(f"Built: {len(succeeded)}/{len(packages)} succeeded")
|
|
|
|
if failed:
|
|
print(f"\nFailed packages:")
|
|
for pkg in failed:
|
|
print(f" ✗ {pkg}")
|
|
return 1
|
|
|
|
print("\n✓ All builds succeeded")
|
|
return 0
|
|
|
|
|
|
def register_build_command(runner):
|
|
"""Register the build command with the script runner.
|
|
|
|
Args:
|
|
runner: ScriptRunner instance
|
|
"""
|
|
runner.register_command(
|
|
"build",
|
|
build_command,
|
|
"Build TypeScript packages",
|
|
)
|