imajin/scripts/run/check_command.py
2026-01-10 04:52:11 -08:00

201 lines
5.1 KiB
Python

"""Check command handler for script runner."""
import argparse
import subprocess
import sys
from pathlib import Path
# TypeScript packages to check
TYPESCRIPT_PACKAGES = [
"imagen-app",
"react",
"electron",
"image-generation/types",
"image-generation/client",
"imagegen-assistant/types",
"imagegen-assistant/client",
"image-processing/types",
"image-processing/service",
]
# Python services to check
PYTHON_SERVICES = [
"imagegen-assistant/service",
"image-generation/service",
"image-pipeline",
"image-compression",
]
def check_command(args, workspace_root: Path):
"""Quick validation: type checking without building.
Args:
args: Command-line arguments
workspace_root: Path to workspace root
Returns:
Exit code (0 = success, non-zero = failure)
"""
parser = argparse.ArgumentParser(
prog="./run check",
description="Quick type checking validation",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
./run check # Check everything
./run check --ts # Check only TypeScript packages
./run check --py # Check only Python services
TypeScript: tsc --noEmit (no build, just type check)
Python: mypy (static type checking)
This is faster than full build, useful for pre-commit validation.
""",
)
parser.add_argument(
"--ts",
"--typescript",
action="store_true",
dest="typescript",
help="Check only TypeScript packages",
)
parser.add_argument(
"--py",
"--python",
action="store_true",
dest="python",
help="Check only Python services",
)
parser.add_argument(
"-v",
"--verbose",
action="store_true",
help="Verbose output",
)
parsed_args = parser.parse_args(args)
# If no flags, check both
if not parsed_args.typescript and not parsed_args.python:
parsed_args.typescript = True
parsed_args.python = True
print("@image workspace check\n")
failed = []
succeeded = []
# Check TypeScript packages
if parsed_args.typescript:
print("TypeScript Packages")
print("" * 50)
for pkg in TYPESCRIPT_PACKAGES:
pkg_path = workspace_root / pkg
if not pkg_path.exists():
print(f"⊘ SKIP: {pkg} (directory not found)")
continue
# Check if tsconfig.json exists
tsconfig = pkg_path / "tsconfig.json"
if not tsconfig.exists():
print(f"⊘ SKIP: {pkg} (no tsconfig.json)")
continue
print(f"▶ Checking: {pkg}")
# Run tsc --noEmit
check_cmd = ["npx", "tsc", "--noEmit"]
result = subprocess.run(
check_cmd,
cwd=pkg_path,
capture_output=not parsed_args.verbose,
check=False,
)
if result.returncode == 0:
print(f"✓ PASS: {pkg}")
succeeded.append(f"ts:{pkg}")
else:
print(f"✗ FAIL: {pkg}")
if not parsed_args.verbose and result.stdout:
# Show first few errors
output = result.stdout.decode()[:500]
print(f" {output}")
failed.append(f"ts:{pkg}")
print()
print()
# Check Python services
if parsed_args.python:
print("Python Services")
print("" * 50)
for service in PYTHON_SERVICES:
service_path = workspace_root / service
if not service_path.exists():
print(f"⊘ SKIP: {service} (directory not found)")
continue
print(f"▶ Checking: {service}")
# Run mypy
check_cmd = ["mypy", "."]
result = subprocess.run(
check_cmd,
cwd=service_path,
capture_output=not parsed_args.verbose,
check=False,
)
if result.returncode == 0:
print(f"✓ PASS: {service}")
succeeded.append(f"py:{service}")
else:
print(f"✗ FAIL: {service}")
if not parsed_args.verbose and result.stdout:
output = result.stdout.decode()[:500]
print(f" {output}")
failed.append(f"py:{service}")
print()
print()
# Summary
total = len(succeeded) + len(failed)
print("" * 50)
print(f"Checked: {len(succeeded)}/{total} passed")
if failed:
print(f"\nFailed:")
for item in failed:
print(f"{item}")
return 1
print("\n✓ All type checks passed")
return 0
def register_check_command(runner):
"""Register the check command with the script runner.
Args:
runner: ScriptRunner instance
"""
runner.register_command(
"check",
check_command,
"Quick type checking validation",
)