Files
flow/cli.py
2026-02-12 09:42:59 +02:00

93 lines
2.6 KiB
Python

"""CLI entry point — argparse routing and context creation."""
import argparse
import subprocess
import sys
from flow import __version__
from flow.commands import bootstrap, completion, container, dotfiles, enter, package, sync
from flow.core.config import FlowContext, load_config, load_manifest
from flow.core.console import ConsoleLogger
from flow.core.paths import ensure_dirs
from flow.core.platform import detect_platform
COMMAND_MODULES = [enter, container, dotfiles, bootstrap, package, sync, completion]
def main():
parser = argparse.ArgumentParser(
prog="flow",
description="DevFlow - A unified toolkit for managing development instances, containers, and profiles",
)
parser.add_argument(
"-v", "--version", action="version", version=f"flow {__version__}"
)
subparsers = parser.add_subparsers(dest="command")
for module in COMMAND_MODULES:
module.register(subparsers)
args = parser.parse_args()
if not args.command:
parser.print_help()
sys.exit(0)
if args.command == "completion":
handler = getattr(args, "handler", None)
if handler:
handler(None, args)
return
parser.print_help()
return
ensure_dirs()
console = ConsoleLogger()
try:
platform_info = detect_platform()
except RuntimeError as e:
console.error(str(e))
sys.exit(1)
try:
config = load_config()
manifest = load_manifest()
except Exception as e:
console.error(f"Failed to load configuration: {e}")
sys.exit(1)
ctx = FlowContext(
config=config,
manifest=manifest,
platform=platform_info,
console=console,
)
handler = getattr(args, "handler", None)
if handler:
try:
handler(ctx, args)
except KeyboardInterrupt:
console.error("Interrupted")
sys.exit(130)
except subprocess.CalledProcessError as e:
detail = (e.stderr or "").strip() or (e.stdout or "").strip()
if detail:
console.error(detail.splitlines()[-1])
else:
console.error(f"Command failed with exit code {e.returncode}")
sys.exit(e.returncode or 1)
except RuntimeError as e:
console.error(str(e))
sys.exit(1)
except OSError as e:
console.error(str(e))
sys.exit(1)
except Exception as e:
console.error(f"Unexpected error: {e}")
sys.exit(1)
else:
parser.print_help()