CmdForge/src/cmdforge/cli/collections_commands.py

195 lines
6.0 KiB
Python

"""Collections commands for CmdForge CLI."""
import json
import sys
from ..resolver import install_from_registry
def cmd_collections(args):
"""Handle collections subcommands."""
if args.collections_cmd == "list":
return _cmd_collections_list(args)
elif args.collections_cmd == "info":
return _cmd_collections_info(args)
elif args.collections_cmd == "install":
return _cmd_collections_install(args)
else:
# Default: show help
print("Collections commands:")
print(" list List available collections")
print(" info <name> Show collection details")
print(" install <name> Install all tools in a collection")
return 0
def _cmd_collections_list(args):
"""List available collections."""
from ..registry_client import RegistryError, get_client
try:
client = get_client()
collections = client.get_collections()
# JSON output
if getattr(args, 'json', False):
print(json.dumps({"collections": collections}, indent=2))
return 0
if not collections:
print("No collections available.")
return 0
print(f"Available collections ({len(collections)}):\n")
for coll in collections:
name = coll.get("name", "")
display_name = coll.get("display_name", name)
description = coll.get("description", "")
tools = coll.get("tools", [])
tool_count = len(tools) if isinstance(tools, list) else 0
print(f" {name}")
print(f" {display_name}")
if description:
desc_short = description[:60] + ('...' if len(description) > 60 else '')
print(f" {desc_short}")
print(f" Tools: {tool_count}")
print()
print("Install a collection with: cmdforge collections install <name>")
except RegistryError as e:
if e.code == "CONNECTION_ERROR":
print("Could not connect to the registry.", file=sys.stderr)
else:
print(f"Error: {e.message}", file=sys.stderr)
return 1
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
return 1
return 0
def _cmd_collections_info(args):
"""Show collection details."""
from ..registry_client import RegistryError, get_client
name = args.name
try:
client = get_client()
coll = client.get_collection(name)
# JSON output
if getattr(args, 'json', False):
print(json.dumps(coll, indent=2))
return 0
display_name = coll.get("display_name", name)
description = coll.get("description", "")
maintainer = coll.get("maintainer", "")
tools = coll.get("tools", [])
pinned = coll.get("pinned", {})
tags = coll.get("tags", [])
print(f"{display_name}")
print("=" * 50)
if description:
print(f"\n{description}\n")
if maintainer:
print(f"Maintainer: {maintainer}")
if tags:
print(f"Tags: {', '.join(tags)}")
print(f"\nTools ({len(tools)}):")
for tool_ref in tools:
version_constraint = pinned.get(tool_ref, "")
if version_constraint:
print(f" - {tool_ref} @ {version_constraint}")
else:
print(f" - {tool_ref}")
print(f"\nInstall all: cmdforge collections install {name}")
except RegistryError as e:
if e.code == "COLLECTION_NOT_FOUND":
print(f"Collection '{name}' not found.", file=sys.stderr)
print("List available collections: cmdforge collections list", file=sys.stderr)
elif e.code == "CONNECTION_ERROR":
print("Could not connect to the registry.", file=sys.stderr)
else:
print(f"Error: {e.message}", file=sys.stderr)
return 1
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
return 1
return 0
def _cmd_collections_install(args):
"""Install all tools in a collection."""
from ..registry_client import RegistryError, get_client
name = args.name
use_pinned = getattr(args, 'pinned', False)
try:
client = get_client()
coll = client.get_collection(name)
tools = coll.get("tools", [])
pinned = coll.get("pinned", {}) if use_pinned else {}
display_name = coll.get("display_name", name)
if not tools:
print(f"Collection '{name}' has no tools.")
return 0
print(f"Installing collection: {display_name}")
print(f"Tools to install: {len(tools)}")
if use_pinned and pinned:
print(f"Using pinned versions: {len(pinned)} tools")
print()
installed = 0
failed = 0
for tool_ref in tools:
version = pinned.get(tool_ref)
try:
print(f" Installing {tool_ref}...", end=" ", flush=True)
resolved = install_from_registry(tool_ref, version)
print(f"v{resolved.version}")
installed += 1
except RegistryError as e:
print(f"FAILED: {e.message}")
failed += 1
except Exception as e:
print(f"FAILED: {e}")
failed += 1
print()
print(f"Installed: {installed}/{len(tools)}")
if failed:
print(f"Failed: {failed}")
return 1
print(f"\nCollection '{name}' installed successfully!")
except RegistryError as e:
if e.code == "COLLECTION_NOT_FOUND":
print(f"Collection '{name}' not found.", file=sys.stderr)
print("List available collections: cmdforge collections list", file=sys.stderr)
elif e.code == "CONNECTION_ERROR":
print("Could not connect to the registry.", file=sys.stderr)
else:
print(f"Error: {e.message}", file=sys.stderr)
return 1
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
return 1
return 0