flow
This commit is contained in:
92
cli.py
Normal file
92
cli.py
Normal file
@@ -0,0 +1,92 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user