"""Format command handler for script runner.""" import argparse import subprocess import sys from pathlib import Path # TypeScript packages to format 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 format PYTHON_SERVICES = [ "imagegen-assistant/service", "image-generation/service", "image-pipeline", "image-compression", ] def format_command(args, workspace_root: Path): """Format code with prettier and ruff. Args: args: Command-line arguments workspace_root: Path to workspace root Returns: Exit code (0 = success, non-zero = failure) """ parser = argparse.ArgumentParser( prog="./run format", description="Format TypeScript and Python code", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: ./run format # Format everything ./run format --ts # Format only TypeScript packages ./run format --py # Format only Python services ./run format --check # Check formatting without modifying files TypeScript formatter: prettier Python formatter: ruff format """, ) parser.add_argument( "--ts", "--typescript", action="store_true", dest="typescript", help="Format only TypeScript packages", ) parser.add_argument( "--py", "--python", action="store_true", dest="python", help="Format only Python services", ) parser.add_argument( "--check", action="store_true", help="Check formatting without modifying files", ) parser.add_argument( "-v", "--verbose", action="store_true", help="Verbose output", ) parsed_args = parser.parse_args(args) # If no flags, format both if not parsed_args.typescript and not parsed_args.python: parsed_args.typescript = True parsed_args.python = True print("@image workspace format\n") failed = [] succeeded = [] # Format 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 package.json has format script package_json = pkg_path / "package.json" if not package_json.exists(): print(f"⊘ SKIP: {pkg} (no package.json)") continue print(f"▶ Formatting: {pkg}") # Run prettier if parsed_args.check: format_cmd = ["npm", "run", "format:check"] else: format_cmd = ["npm", "run", "format"] result = subprocess.run( format_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: output = result.stdout.decode()[:300] print(f" {output}") failed.append(f"ts:{pkg}") print() print() # Format 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"▶ Formatting: {service}") # Run ruff format format_cmd = ["ruff", "format", "."] if parsed_args.check: format_cmd.append("--check") result = subprocess.run( format_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()[:300] print(f" {output}") failed.append(f"py:{service}") print() print() # Summary total = len(succeeded) + len(failed) print("─" * 50) print(f"Formatted: {len(succeeded)}/{total} succeeded") if failed: print(f"\nFailed:") for item in failed: print(f" ✗ {item}") return 1 if parsed_args.check: print("\n✓ All files properly formatted") else: print("\n✓ All files formatted successfully") return 0 def register_format_command(runner): """Register the format command with the script runner. Args: runner: ScriptRunner instance """ runner.register_command( "format", format_command, "Format code with prettier and ruff", )