#!/usr/bin/env python3 import argparse import json import os import platform import re import shutil import subprocess import sys import time import urllib.request from dataclasses import dataclass, field from pathlib import Path from typing import Any, Dict, List, Optional, Union import yaml from src.dotfiles_manager import DotfilesManager @dataclass class Action: type: str description: str data: Dict[str, Any] skip_on_error: bool = True os_filter: Optional[str] = None # "macos", "linux", or None for all status: str = "pending" # pending, completed, failed, skipped error: Optional[str] = None def main(): parser = argparse.ArgumentParser(description="Action-based Dotfiles Manager") subparsers = parser.add_subparsers(dest="command", help="Commands") # Setup command setup_parser = subparsers.add_parser("setup", help="Setup complete environment") setup_parser.add_argument("environment", help="Environment name") setup_parser.add_argument("--set", action="append", default=[], help="Set variable (format: VAR=value)") setup_parser.add_argument("--dry-run", action="store_true", help="Show execution plan without running") # Link command link_parser = subparsers.add_parser("link", help="Link configurations") link_parser.add_argument("environment", help="Environment name") link_parser.add_argument("--copy", action="store_true", help="Copy instead of symlink") link_parser.add_argument("-f", "--force", action="store_true", help="Force overwrite") link_parser.add_argument("-p", "--package", help="Link specific package") link_parser.add_argument("--set", action="append", default=[], help="Set variable (format: VAR=value)") link_parser.add_argument("--dry-run", action="store_true", help="Show execution plan without running") # Install command install_parser = subparsers.add_parser("install", help="Install packages") install_parser.add_argument("environment", help="Environment name") install_parser.add_argument("-p", "--package", help="Install specific package") install_parser.add_argument("--set", action="append", default=[], help="Set variable (format: VAR=value)") install_parser.add_argument("--dry-run", action="store_true", help="Show execution plan without running") args = parser.parse_args() if not args.command: parser.print_help() return try: manager = DotfilesManager(args.environment) manager.add_variables(args.set) if args.command == "setup": manager.setup_environment(dry_run=getattr(args, "dry_run", False)) elif args.command == "link": manager.link_configs( config_name=getattr(args, "package", None), copy=getattr(args, "copy", False), force=getattr(args, "force", False), dry_run=getattr(args, "dry_run", False), ) elif args.command == "install": manager.install_packages( package_name=getattr(args, "package", None), dry_run=getattr(args, "dry_run", False) ) except KeyboardInterrupt: print("\n[INFO] Operation cancelled by user") sys.exit(1) except Exception as e: print(f"[ERROR] Unexpected error: {e}") import traceback traceback.print_exc() sys.exit(1) if __name__ == "__main__": main()