package commands import ( "fmt" "os" "path/filepath" "github.com/spf13/cobra" "github.com/user/devpack/internal/config" "github.com/user/devpack/internal/logging" ) func newInitCmd() *cobra.Command { var ( profile string template string force bool ) cmd := &cobra.Command{ Use: "init", Short: "初始化 DevPack 配置", Long: `初始化 DevPack,创建配置目录和默认配置文件。`, RunE: func(cmd *cobra.Command, args []string) error { log := logging.G() fmt.Println("🚀 正在初始化 DevPack...") // 获取标准路径 paths, err := config.DefaultPaths() if err != nil { return fmt.Errorf("无法获取用户主目录: %w", err) } // 检测是否已初始化 if !force { if _, err := os.Stat(paths.Config); err == nil { fmt.Println("⚠️ DevPack 已初始化过。使用 --force 覆盖。") return nil } } // 创建所有目录 (~/.devpack/, profiles/, packs/, logs/, tmp/) log.Debug("正在创建目录结构...") if err := paths.EnsureDirs(); err != nil { return fmt.Errorf("创建目录失败: %w", err) } log.Debugf("目录结构已创建: %s", paths.Home) // 生成默认配置文件 log.Debug("正在生成默认配置文件...") if err := writeDefaultConfig(paths.Config, force); err != nil { return fmt.Errorf("创建配置文件失败: %w", err) } fmt.Printf(" ✅ 配置文件: %s\n", paths.Config) // 创建默认 Profile profileName := template if profile != "" { profileName = profile } log.Debugf("正在创建 Profile: %s (模板: %s)", profileName, template) if err := writeDefaultProfile(paths.Profiles, profileName, template, force); err != nil { return fmt.Errorf("创建 Profile 失败: %w", err) } fmt.Printf(" ✅ Profile: %s\n", filepath.Join(paths.Profiles, profileName+".yaml")) fmt.Println("\n✅ DevPack 初始化完成!") fmt.Println("\n运行 'devpack scan' 扫描当前开发环境。") return nil }, } cmd.Flags().StringVarP(&profile, "profile", "p", "", "创建并使用指定名称的 Profile") cmd.Flags().StringVarP(&template, "template", "t", "standard", "使用预设模板 (minimal|standard|full)") cmd.Flags().BoolVar(&force, "force", false, "覆盖已有配置") return cmd } // writeDefaultConfig 写入默认配置文件 func writeDefaultConfig(path string, force bool) error { if !force { if _, err := os.Stat(path); err == nil { return nil // 已存在且不强制覆盖,跳过 } } defaultConfig := `# DevPack 配置文件 # 详见文档: https://github.com/user/devpack # 日志设置 log_level: info # log_file: ~/.devpack/logs/devpack.log # 默认 Profile default_profile: standard # 还原选项 restore: conflict_strategy: prompt # skip | overwrite | merge | prompt | newest create_restore_point: true dry_run_first: false ` return os.WriteFile(path, []byte(defaultConfig), 0o644) } // writeDefaultProfile 根据模板写入默认 Profile func writeDefaultProfile(dir, name, template string, force bool) error { path := filepath.Join(dir, name+".yaml") if !force { if _, err := os.Stat(path); err == nil { return nil // 已存在且不强制覆盖,跳过 } } var content string switch template { case "minimal": content = `# DevPack Profile - 最小配置 name: ` + name + ` description: "最小开发环境配置" collectors: runtime: enabled: true include: [] editor: enabled: false shell: enabled: false package: enabled: false git: enabled: true env: enabled: false ` case "full": content = `# DevPack Profile - 完整配置 name: ` + name + ` description: "完整开发环境配置" collectors: runtime: enabled: true include: [go, node, python] editor: enabled: true include: [vscode] options: vscode: capture_extensions: true capture_settings: true capture_keybindings: true capture_snippets: true shell: enabled: true include: [powershell] package: enabled: true include: [scoop] git: enabled: true options: capture_aliases: true env: enabled: true options: include_patterns: ["GOPATH", "GOROOT", "PATH", "NODE_*", "PYTHON*"] exclude_patterns: ["*_KEY", "*_SECRET", "*_TOKEN"] ` default: // standard content = `# DevPack Profile - 标准配置 name: ` + name + ` description: "标准开发环境配置" collectors: runtime: enabled: true include: [go, node, python] editor: enabled: true include: [vscode] options: vscode: capture_extensions: true capture_settings: true shell: enabled: true include: [powershell] package: enabled: true include: [scoop] git: enabled: true env: enabled: true options: include_patterns: ["GOPATH", "GOROOT", "PATH"] exclude_patterns: ["*_KEY", "*_SECRET", "*_TOKEN"] ` } return os.WriteFile(path, []byte(content), 0o644) }