236 lines
6.7 KiB
Python
236 lines
6.7 KiB
Python
"""Publish command handler for script runner."""
|
|
|
|
import argparse
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
# Publishable packages
|
|
PUBLISHABLE_PACKAGES = {
|
|
"imagen-app": {
|
|
"dir": "imagen-app",
|
|
"name": "@lilith/imagen-app",
|
|
},
|
|
"imagen-react": {
|
|
"dir": "react",
|
|
"name": "@lilith/imagen-react",
|
|
},
|
|
"imagen-electron": {
|
|
"dir": "electron",
|
|
"name": "@lilith/imagen-electron",
|
|
},
|
|
"image-generation-types": {
|
|
"dir": "image-generation/types",
|
|
"name": "@lilith/image-generation-types",
|
|
},
|
|
"image-generation-client": {
|
|
"dir": "image-generation/client",
|
|
"name": "@lilith/image-generation-client",
|
|
},
|
|
"imagegen-assistant-types": {
|
|
"dir": "imagegen-assistant/types",
|
|
"name": "@lilith/imagegen-assistant-types",
|
|
},
|
|
"imagegen-assistant-client": {
|
|
"dir": "imagegen-assistant/client",
|
|
"name": "@lilith/imagegen-assistant-client",
|
|
},
|
|
"image-processing-types": {
|
|
"dir": "image-processing/types",
|
|
"name": "@lilith/image-processing-types",
|
|
},
|
|
"image-processing-client": {
|
|
"dir": "image-processing/client",
|
|
"name": "@lilith/image-processing-client",
|
|
},
|
|
}
|
|
|
|
|
|
def publish_command(args, workspace_root: Path):
|
|
"""Publish packages to registry.
|
|
|
|
Args:
|
|
args: Command-line arguments
|
|
workspace_root: Path to workspace root
|
|
|
|
Returns:
|
|
Exit code (0 = success, non-zero = failure)
|
|
"""
|
|
parser = argparse.ArgumentParser(
|
|
prog="./run publish",
|
|
description="Publish packages to registry",
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
epilog=f"""
|
|
Examples:
|
|
./run publish # Publish all packages (interactive)
|
|
./run publish --all --dry-run # Preview what would be published
|
|
./run publish imagen-app # Publish specific package
|
|
./run publish --skip-build # Publish without building first
|
|
|
|
Available packages:
|
|
{', '.join(PUBLISHABLE_PACKAGES.keys())}
|
|
|
|
Registry: http://forge.nasty.sh/api/packages/lilith/npm/
|
|
|
|
Note: Packages are published in dependency order.
|
|
Related packages (imagen-app + imagen-react + imagen-electron) should be versioned together.
|
|
""",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"package",
|
|
nargs="?",
|
|
choices=list(PUBLISHABLE_PACKAGES.keys()) + ["all"],
|
|
help="Package to publish (default: interactive)",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--all",
|
|
action="store_true",
|
|
help="Publish all packages",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--dry-run",
|
|
action="store_true",
|
|
help="Preview what would be published without actually publishing",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--skip-build",
|
|
action="store_true",
|
|
help="Skip building before publishing",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"-v",
|
|
"--verbose",
|
|
action="store_true",
|
|
help="Verbose output",
|
|
)
|
|
|
|
parsed_args = parser.parse_args(args)
|
|
|
|
# Determine packages to publish
|
|
if parsed_args.all or parsed_args.package == "all":
|
|
packages = list(PUBLISHABLE_PACKAGES.keys())
|
|
elif parsed_args.package:
|
|
packages = [parsed_args.package]
|
|
else:
|
|
# Interactive mode
|
|
print("Available packages:")
|
|
for i, pkg in enumerate(PUBLISHABLE_PACKAGES.keys(), 1):
|
|
print(f" {i}. {pkg}")
|
|
print(f" {len(PUBLISHABLE_PACKAGES) + 1}. all")
|
|
print()
|
|
|
|
try:
|
|
choice = input("Select package to publish (number or name): ").strip()
|
|
if choice.isdigit():
|
|
idx = int(choice) - 1
|
|
if idx == len(PUBLISHABLE_PACKAGES):
|
|
packages = list(PUBLISHABLE_PACKAGES.keys())
|
|
elif 0 <= idx < len(PUBLISHABLE_PACKAGES):
|
|
packages = [list(PUBLISHABLE_PACKAGES.keys())[idx]]
|
|
else:
|
|
print("Invalid selection")
|
|
return 1
|
|
elif choice in PUBLISHABLE_PACKAGES:
|
|
packages = [choice]
|
|
elif choice == "all":
|
|
packages = list(PUBLISHABLE_PACKAGES.keys())
|
|
else:
|
|
print(f"Unknown package: {choice}")
|
|
return 1
|
|
except (KeyboardInterrupt, EOFError):
|
|
print("\nCancelled")
|
|
return 0
|
|
|
|
print(f"Publishing {len(packages)} package(s)...")
|
|
if parsed_args.dry_run:
|
|
print("DRY RUN MODE - No actual publishing will occur\n")
|
|
print()
|
|
|
|
failed = []
|
|
succeeded = []
|
|
|
|
for pkg in packages:
|
|
pkg_info = PUBLISHABLE_PACKAGES[pkg]
|
|
pkg_path = workspace_root / pkg_info["dir"]
|
|
|
|
if not pkg_path.exists():
|
|
print(f"⊘ SKIP: {pkg} (directory not found)")
|
|
continue
|
|
|
|
print(f"▶ Publishing: {pkg} ({pkg_info['name']})")
|
|
|
|
# Build if not skipped
|
|
if not parsed_args.skip_build:
|
|
print(" Building...")
|
|
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"✗ FAIL: {pkg} (build failed)")
|
|
if not parsed_args.verbose and result.stderr:
|
|
print(f" Error: {result.stderr.decode()[:200]}")
|
|
failed.append(pkg)
|
|
print()
|
|
continue
|
|
|
|
# Publish
|
|
publish_cmd = ["npm", "publish"]
|
|
if parsed_args.dry_run:
|
|
publish_cmd.append("--dry-run")
|
|
|
|
result = subprocess.run(
|
|
publish_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"Published: {len(succeeded)}/{len(packages)} succeeded")
|
|
|
|
if failed:
|
|
print(f"\nFailed packages:")
|
|
for pkg in failed:
|
|
print(f" ✗ {pkg}")
|
|
return 1
|
|
|
|
print("\n✓ All packages published successfully")
|
|
if parsed_args.dry_run:
|
|
print("(DRY RUN - no actual changes made)")
|
|
|
|
return 0
|
|
|
|
|
|
def register_publish_command(runner):
|
|
"""Register the publish command with the script runner.
|
|
|
|
Args:
|
|
runner: ScriptRunner instance
|
|
"""
|
|
runner.register_command(
|
|
"publish",
|
|
publish_command,
|
|
"Publish packages to registry",
|
|
)
|