From dcd6c2fea6f37fd3aa1da4e98b56797fe2d83b44 Mon Sep 17 00:00:00 2001 From: d0zingcat Date: Wed, 4 Mar 2026 14:44:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=20dotfiles=20?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E5=8A=9F=E8=83=BD=E5=92=8C=E5=A4=87=E4=BB=BD?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要改进: - .gitignore: 添加敏感数据排除规则和备份文件排除 - .zshrc: 添加工作函数标记注释 (# ==== WORK:) - git/config: 模板化占位符 (YOUR_NAME, YOUR_EMAIL, YOUR_SSH_SIGNING_KEY) - setup.sh: 增强备份功能,支持完整配置导出 - Brewfile 备份 - Git 配置摘要(脱敏) - SSH 公钥备份 - 1Password 配置文档 - VSCode 扩展列表 - 备份报告生成 - README.md: 重写为完整项目文档 - CHECKLIST.md: 新机器配置检查清单 - MIGRATION_GUIDE.md: 个人备份说明文档 - QUICKSTART.md: 3-5 分钟快速开始指南 使用方式: ./setup.sh backup # 备份当前配置 ./setup.sh full-recover # 新机器完整恢复 --- .gitignore | 77 +++ .sisyphus/boulder.json | 7 + .sisyphus/plans/dotfiles-migration.md | 448 +++++++++++++++ .zshrc | 13 + Brewfile | 19 +- CHECKLIST.md | 226 ++++++++ MIGRATION_GUIDE.md | 320 +++++++++++ QUICKSTART.md | 91 +++ README.md | 304 +++++++++- git/config | 10 +- setup.sh | 784 ++++++++++++++++++++------ 11 files changed, 2105 insertions(+), 194 deletions(-) create mode 100644 .sisyphus/boulder.json create mode 100644 .sisyphus/plans/dotfiles-migration.md create mode 100644 CHECKLIST.md create mode 100644 MIGRATION_GUIDE.md create mode 100644 QUICKSTART.md diff --git a/.gitignore b/.gitignore index a67974d..5e6fc67 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,80 @@ zed/.tmp* zed/embeddings zed/conversations ssh/config + +# === 敏感数据排除 === +# SSH 密钥和配置 +.ssh/ +known_hosts +authorized_keys +id_rsa* +id_ed25519* +*.pem + +# 1Password +.1password/ + +# Kubernetes +.kube/ +kubeconfig* +*.kubeconfig + +# 环境变量和 secrets +*.secret +*.key +credentials.json +secrets.txt + +# 缓存目录 +__pycache__/ +.pytest_cache/ +.mypy_cache/ +.node_cache/ +.cache/ +tmp/ +temp/ + +# IDE +.idea/ +.vscode/workspace* +*.swp +*.swo +*~ + +# 语言版本文件 +.python-version +.node-version +.rust-version +.tool-versions + +# 构建产物 +dist/ +build/ +target/ +*.o +*.a +*.so +*.dylib + +# Mac 特有 +.Trash/ +.VolumeIcon.icns +.apdisk + +# 日志 +*.log +npm-debug.log* +yarn-error.log +pnpm-debug.log* + +# === 备份文件排除 === +# Backup reports and sensitive configs +.git_config_summary.txt +*.backup.* +ssh_backup_*/ +.backup_report_*.md + +# Generated config exports (contain sensitive info) +.1password_config.txt +.kube_contexts.txt +.vscode_extensions.txt diff --git a/.sisyphus/boulder.json b/.sisyphus/boulder.json new file mode 100644 index 0000000..2c6eb96 --- /dev/null +++ b/.sisyphus/boulder.json @@ -0,0 +1,7 @@ +{ + "active_plan": "/Users/lilithgames/.dotfiles/.sisyphus/plans/dotfiles-migration.md", + "started_at": "2026-03-04T02:43:04.177Z", + "session_ids": ["ses_349531330ffex65VV620eMrnTx"], + "plan_name": "dotfiles-migration", + "worktree_path": "/Users/lilithgames/.dotfiles" +} diff --git a/.sisyphus/plans/dotfiles-migration.md b/.sisyphus/plans/dotfiles-migration.md new file mode 100644 index 0000000..c7202b5 --- /dev/null +++ b/.sisyphus/plans/dotfiles-migration.md @@ -0,0 +1,448 @@ +# Dotfiles 迁移计划 + +## TL;DR + +> **目标**: 完善 dotfiles 仓库,使其能够通过 Git 同步方式迁移到新 Mac +> +> **核心改进**: +> - 敏感数据排除机制 (.gitignore 完善) +> - Git 配置模板化 (自动提示新机器配置) +> - 增强 setup.sh 脚本 (一键初始化) +> - 完整文档 (README + 迁移指南) +> +> **交付物**: 4 个文件修改/创建 + 1 个文档 +> **预估工作量**: 约 60 分钟 + +--- + +## Context + +### 用户需求确认 +- **新机器**: 全新 Mac (需要完整安装所有工具) +- **敏感数据**: 不迁移,重新配置 (SSH、1Password、Git 签名密钥) +- **迁移方式**: Git 仓库同步 + +### 当前状态分析 + +**已包含配置**: +| 文件 | 说明 | +|------|------| +| `.zshrc` | Shell 配置 (286 行,60+ alias/函数) | +| `.tmux.conf` | tmux 配置 (124 行) | +| `git/config` | ⚠️ 包含真实用户信息 | +| `nvim/` | Neovim 完整配置 (27 Lua 文件) | +| `wezterm/`, `alacritty/`, `ghostty/` | 终端配置 | +| `starship.toml` | Shell 提示符 | +| `Brewfile` | Homebrew 包 (180 行) | +| `setup.sh` | ⚠️ 功能不完整 | + +**问题点**: +1. `git/config` 包含 name/email/signingkey - 需要模板化 +2. `.zshrc` 包含工作函数需要标记区分 +3. `.gitignore` 不够完善 +4. `setup.sh` 缺少完整初始化流程 + +--- + +## Work Objectives + +### 必须完成 +1. **完善 .gitignore** - 添加敏感数据排除模式 +2. **模板化 git/config** - 替换为占位符,添加初始化提示 +3. **增强 setup.sh** - 添加完整的新机器初始化流程 +4. **完善 README.md** - 添加使用说明和迁移指南 + +### 交付定义 +- [ ] `.gitignore` 包含完整的敏感数据排除 +- [ ] `git/config` 模板化,可自动检测并提示配置 +- [ ] `setup.sh` 包含 `init`, `install`, `backup`, `sync` 子命令 +- [ ] `README.md` 包含完整的使用文档 + +--- + +## Execution Strategy + +### 任务依赖关系 + +``` +Wave 1 (基础工作 - 可并行): +├── T1: 完善 .gitignore +├── T2: 模板化 git/config +└── T3: 标记 .zshrc 工作函数 + +Wave 2 (核心功能): +├── T4: 增强 setup.sh 脚本 +└── T5: 创建迁移检查清单 + +Wave 3 (文档): +├── T6: 完善 README.md +└── T7: 创建快速开始指南 + +Wave FINAL: +└── T8: 整体验证和清理 +``` + +--- + +## TODOs + +--- + +- [ ] 1. 完善 .gitignore + + **What to do**: + - 读取现有 `.gitignore` + - 添加敏感数据排除模式: + - SSH: `.ssh/` (已存在) + - 1Password: `.1password/` + - Kubeconfig: `.kube/` + - 环境变量: `*.env`, `.env*` + - 缓存: `__pycache__`, `.cache/`, `node_modules/` + - IDE: `.idea/`, `.vscode/` + - Mac: `.DS_Store`, `*.swp` + - 临时文件: `*.tmp`, `*.log` + - 确保不排除核心配置文件 + + **Must NOT do**: + - 移除已有的有效排除规则 + - 排除核心配置文件 + + **Recommended Agent Profile**: + - **Category**: `quick` + - **Skills**: [] + - Justification: 简单的文件编辑任务 + + **Parallelization**: + - **Can Run In Parallel**: YES + - **Parallel Group**: Wave 1 (with T2, T3) + - **Blocks**: T4 (setup.sh 会使用这些规则) + - **Blocked By**: None + + **Acceptance Criteria**: + - [ ] 新增的排除模式覆盖所有已知敏感路径 + - [ ] 不影响核心配置文件同步 + - [ ] git status 显示合理的未跟踪文件列表 + + **Evidence to Capture**: + - [ ] `.gitignore` 文件 diff + +--- + +- [ ] 2. 模板化 git/config + + **What to do**: + - 读取现有 `git/config` + - 替换真实信息为占位符: + - `user.name` → `YOUR_NAME` + - `user.email` → `YOUR_EMAIL` + - `user.signingkey` → `YOUR_SSH_SIGNING_KEY` + - 添加自动检测和提示脚本: + - 检测是否未配置 + - 提示用户运行配置命令 + - 保持其他有效配置不变 + + **Must NOT do**: + - 破坏现有的 Git 功能配置 + - 移除 diff/merge 工具配置 + + **Recommended Agent Profile**: + - **Category**: `quick` + - **Skills**: [] + - Justification: 简单的模板替换任务 + + **Parallelization**: + - **Can Run In Parallel**: YES + - **Parallel Group**: Wave 1 (with T1, T3) + - **Blocks**: T4 + - **Blocked By**: None + + **Acceptance Criteria**: + - [ ] 真实用户信息被替换为占位符 + - [ ] 添加配置检测逻辑 + - [ ] 脚本可正确检测未配置状态 + + **Evidence to Capture**: + - [ ] `git/config` 文件内容 + +--- + +- [ ] 3. 标记 .zshrc 工作函数 + + **What to do**: + - 读取 `.zshrc` + - 为工作相关函数添加标记注释: + - `klogs`, `bitnami_seal` → Kubernetes 相关 + - `rsync_work`, `replace_remote` → 工作环境相关 + - `git_config_work`, `git_config_play` → 多环境 Git + - 添加"工作函数"区块注释块 + - 在文件头部添加说明 + + **Must NOT do**: + - 修改任何函数逻辑 + - 删除任何功能 + - 改变现有的 alias 行为 + + **Recommended Agent Profile**: + - **Category**: `quick` + - **Skills**: [] + - Justification: 纯注释编辑任务 + + **Parallelization**: + - **Can Run In Parallel**: YES + - **Parallel Group**: Wave 1 (with T1, T2) + - **Blocks**: T4 + - **Blocked By**: None + + **Acceptance Criteria**: + - [ ] 工作函数被清晰标记 + - [ ] 文件头部有说明注释 + - [ ] 逻辑未改变 + + **Evidence to Capture**: + - [ ] `.zshrc` diff 显示新增注释 + +--- + +- [ ] 4. 增强 setup.sh 脚本 + + **What to do**: + - 读取现有 `setup.sh` + - 添加/完善以下函数: + - `init`: 全新系统安装 (Homebrew, Xcode, 基础工具) + - `install`: 安装 dotfiles 软链接 + - `backup`: 导出当前配置到 dotfiles 仓库 + - `sync`: 从 Git 恢复配置 + - `full-recover`: 完整新机器初始化 (init + install) + - 添加参数解析 + - 添加环境检测 + - 添加进度提示 + - 添加回滚能力 + + **Must NOT do**: + - 破坏现有功能 + - 删除现有的 recover 函数 + + **Recommended Agent Profile**: + - **Category**: `unspecified-high` + - **Skills**: [] + - Justification: 需要编写完整的 shell 脚本逻辑 + + **Parallelization**: + - **Can Run In Parallel**: NO + - **Parallel Group**: Wave 2 + - **Blocks**: None + - **Blocked By**: T1, T2, T3 (依赖 .gitignore 完善) + + **Acceptance Criteria**: + - [ ] `setup.sh init` 可执行全新系统安装 + - [ ] `setup.sh install` 可建立软链接 + - [ ] `setup.sh backup` 可导出配置 + - [ ] `setup.sh sync` 可从 Git 恢复 + - [ ] `setup.sh full-recover` 可一键初始化 + - [ ] 脚本有完善的错误处理 + + **Evidence to Capture**: + - [ ] setup.sh 完整内容 + - [ ] 测试脚本可执行性 + +--- + +- [ ] 5. 创建迁移检查清单 + + **What to do**: + - 创建 `CHECKLIST.md` 文件 + - 包含新机器配置检查清单: + - 系统设置 (Xcode, Command Line Tools) + - Homebrew 安装 + - dotfiles 同步 + - 1Password 配置 + - SSH 密钥生成 + - Git 配置 + - Kubernetes 配置 + - 验证步骤 + - 每个项目标记为自动/手动 + + **Must NOT do**: + - 包含实际敏感数据 + + **Recommended Agent Profile**: + - **Category**: `writing` + - **Skills**: [] + - Justification: 文档编写任务 + + **Parallelization**: + - **Can Run In Parallel**: YES + - **Parallel Group**: Wave 2 (with T4) + - **Blocks**: T6 + - **Blocked By**: T1, T2, T3 + + **Acceptance Criteria**: + - [ ] 检查清单覆盖完整迁移流程 + - [ ] 区分自动和手动步骤 + - [ ] 包含验证命令 + + **Evidence to Capture**: + - [ ] CHECKLIST.md 文件 + +--- + +- [ ] 6. 完善 README.md + + **What to do**: + - 读取现有 README.md + - 重写为完整的文档: + - 简介 + - 安装/快速开始 + - 各个组件说明 + - 迁移指南 + - 故障排查 + - 贡献方式 (如果有) + - 包含目录导航 + + **Must NOT do**: + - 破坏现有 README 结构(如果有效) + + **Recommended Agent Profile**: + - **Category**: `writing` + - **Skills**: [] + - Justification: 技术文档编写 + + **Parallelization**: + - **Can Run In Parallel**: NO + - **Parallel Group**: Wave 3 + - **Blocks**: None + - **Blocked By**: T5 (CHECKLIST) + + **Acceptance Criteria**: + - [ ] 包含完整使用说明 + - [ ] 包含迁移步骤 + - [ ] 可读性强 + + **Evidence to Capture**: + - [ ] README.md 更新内容 + +--- + +- [ ] 7. 创建快速开始指南 + + **What to do**: + - 创建 `QUICKSTART.md` 简明指南 + - 包含 3 步快速开始: + 1. 克隆仓库 + 2. 运行初始化 + 3. 配置个人信息 + - 包含最常用的命令 + + **Must NOT do**: + - 包含过多细节 + + **Recommended Agent Profile**: + - **Category**: `writing` + - **Skills**: [] + - Justification: 简单文档 + + **Parallelization**: + - **Can Run In Parallel**: YES + - **Parallel Group**: Wave 3 (with T6) + - **Blocks**: None + - **Blocked By**: T5 + + **Acceptance Criteria**: + - [ ] 3-5 分钟可完成基础配置 + - [ ] 包含所有必要步骤 + + **Evidence to Capture**: + - [ ] QUICKSTART.md 文件 + +--- + +- [ ] 8. 整体验证和清理 + + **What to do**: + - 运行 git status 检查所有变更 + - 验证所有修改的文件语法正确 + - 确保敏感数据未被提交 + - 清理临时文件 + + **Must NOT do**: + - 遗漏任何问题 + + **Recommended Agent Profile**: + - **Category**: `unspecified-low` + - **Skills**: [] + - Justification: 验证性任务 + + **Parallelization**: + - **Can Run In Parallel**: NO + - **Parallel Group**: Wave FINAL + - **Blocks**: None + - **Blocked By**: T1-T7 + + **Acceptance Criteria**: + - [ ] 所有文件变更已保存 + - [ ] 无敏感数据泄漏 + - [ ] 脚本可执行 + + **Evidence to Capture**: + - [ ] git status 输出 + - [ ] 最终文件列表 + +--- + +## Final Verification Wave + +### 验证清单 +- [ ] `.gitignore` 包含所有敏感路径 +- [ ] `git/config` 不包含真实用户信息 +- [ ] `setup.sh` 所有子命令可用 +- [ ] README.md 完整可用 +- [ ] CHECKLIST.md 覆盖完整流程 +- [ ] 无临时文件遗留 + +--- + +## Success Criteria + +### 验证命令 +```bash +# 检查敏感数据排除 +git status --porcelain | grep -E "\.(env|ssh|key)" || echo "No sensitive files staged" + +# 检查脚本可执行 +./setup.sh --help + +# 检查 README +cat README.md | head -20 +``` + +### 交付检查 +- [ ] 所有 TODO 完成 +- [ ] 文档完整 +- [ ] 脚本功能正常 +- [ ] 敏感数据已排除 + +--- + +## Commit Strategy + +单个提交包含所有变更: +- Message: `chore: 完善 dotfiles 迁移功能` +- Files: 所有修改的文件 +- Pre-commit: 无 (dotfiles 仓库特性) + +--- + +## 补充说明 + +### 后续步骤 (用户自行执行) +1. 在新机器上克隆仓库 +2. 运行 `setup.sh full-recover` +3. 配置个人信息 (Git, SSH, 1Password) +4. 验证所有工具正常工作 + +### 需要手动配置的项目 +- Git 用户信息 (name, email, signingkey) +- SSH 密钥 (需要重新生成) +- 1Password SSH agent (需要在新机器上配置) +- Kubeconfig (工作相关,不包含在 dotfiles 中) +- 特定工作环境的 alias 和函数 \ No newline at end of file diff --git a/.zshrc b/.zshrc index 1097c0a..c6920eb 100644 --- a/.zshrc +++ b/.zshrc @@ -1,3 +1,10 @@ +############################################################################### +# My Dotfiles - Zsh Configuration +############################################################################### +# This configuration includes both personal and work-related functions. +# Work-related functions are marked with "# ==== WORK: xxx" comments. +############################################################################### + export GOPATH=$HOME/.go export PNPM_HOME="$HOME/.pnpm" export BUN_HOME="$HOME/.bun" @@ -93,11 +100,13 @@ function macnst (){ # echo "proxy all unset!" #} +# ==== WORK: Kubernetes logs viewer function klogs() { keyword=$1 k get pods --sort-by=.metadata.creationTimestamp | grep "$keyword" | head -n 1 | awk '{print $1}' | xargs kubectl logs -f } +# ==== WORK: Git remote URL switcher function replace_remote() { if (( $# != 1 )); then @@ -125,6 +134,7 @@ function replace_remote() { fi } +# ==== WORK: Remote sync to work servers function rsync_work() { remote_dir="/root" local_work=`pwd` @@ -193,6 +203,7 @@ function git_config() { git config user.signingkey "$3" } +# ==== WORK: Multi-environment Git config (work) function git_config_work() { if [ ! $# -eq 2 ]; then echo 'should be like git_config_work {name} {email}' @@ -200,6 +211,7 @@ function git_config_work() { git_config $1 $2 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF23DQtdH5PODF9fYUHr49I1J3lfKLAPk4LG54MVUTcg' } +# ==== WORK: Multi-environment Git config (play) function git_config_play() { if [ ! $# -eq 1 ]; then echo 'should be like gait_config_play {email}' @@ -207,6 +219,7 @@ function git_config_play() { git_config d0zingcat $1 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPaVruhhL4O9BiAncnW1wH3jc7/hsqsXLknA8Xtnjjee' } +# ==== WORK: Kubernetes secret sealer function bitnami_seal() { if [[ $# != 2 ]] then diff --git a/Brewfile b/Brewfile index 6e227ae..fae0f95 100644 --- a/Brewfile +++ b/Brewfile @@ -1,3 +1,4 @@ +tap "anomalyco/tap" tap "farion1231/ccswitch" tap "homebrew/cask" tap "minio/stable" @@ -10,8 +11,6 @@ brew "autojump" brew "bat" brew "btop" brew "cmake" -brew "ripgrep" -brew "codex" brew "difftastic" brew "direnv" brew "dosbox-staging" @@ -44,11 +43,10 @@ brew "mysql-client@8.4" brew "neofetch" brew "neovim" brew "nexttrace" -brew "opencode" -brew "postgresql@17" -brew "qwen-code" +brew "postgresql@17", restart_service: :changed brew "rclone" brew "redis", restart_service: :changed +brew "ripgrep" brew "rustup" brew "starship" brew "swiftformat" @@ -60,12 +58,14 @@ brew "xcbeautify" brew "xcode-build-server" brew "yarn" brew "zsh" +brew "anomalyco/tap/opencode" brew "minio/stable/mc" brew "telepresenceio/telepresence/telepresence-oss" brew "vitobotta/tap/hetzner_k3s" cask "1password" cask "1password-cli" cask "alacritty" +cask "alma" cask "apifox" cask "appcleaner" cask "battle-net" @@ -73,9 +73,10 @@ cask "brave-browser" cask "farion1231/ccswitch/cc-switch" cask "chatgpt" cask "cherry-studio" -cask "clash-verge-rev" cask "claude" cask "claude-code" +cask "codex" +cask "codex-app" cask "copilot-cli" cask "craft" cask "cursor" @@ -106,23 +107,21 @@ cask "squirrel-app" cask "stats" cask "steam" cask "telegram" +cask "typeless" cask "visual-studio-code" cask "wechat" -mas "Cult Of The Lamb", id: 1639580858 mas "HamHub", id: 6458691598 mas "Keynote", id: 409183694 mas "Lark", id: 6449830127 mas "Numbers", id: 409203825 mas "Pages", id: 409201541 mas "PDFgear", id: 6469021132 -mas "PowerWash Simulator", id: 6477445344 mas "Quantumult X", id: 1443988620 mas "SenPlayer", id: 6443975850 mas "Shadowrocket", id: 932747118 +mas "sing-box", id: 6673731168 mas "The Unarchiver", id: 425424353 -mas "Windows App", id: 1295203466 mas "Xcode", id: 497799835 -mas "网易爆米花", id: 6553989480 vscode "anthropic.claude-code" vscode "donjayamanne.githistory" vscode "dreamecho.git-blame-lens" diff --git a/CHECKLIST.md b/CHECKLIST.md new file mode 100644 index 0000000..016a922 --- /dev/null +++ b/CHECKLIST.md @@ -0,0 +1,226 @@ +# Dotfiles 迁移检查清单 + +> 用于新机器环境设置的完整检查清单 +> +> **自动** = 脚本自动完成 | **手动** = 需要用户操作 + +--- + +## 📋 准备工作 + +- [ ] **手动** 确认新 Mac 已登录 Apple ID +- [ ] **手动** 安装 1Password (从 Mac App Store 或 1password.com) +- [ ] **手动** 配置 1Password SSH Agent (System Settings → 1Password → Developer) + +--- + +## 🚀 系统初始化 (自动) + +运行:`./setup.sh init` + +- [ ] **自动** Xcode Command Line Tools 安装 +- [ ] **自动** Homebrew 安装 +- [ ] **自动** zsh antigen 安装 +- [ ] **自动** asdf 版本管理器安装 +- [ ] **自动** 创建必要目录 (~/.config, ~/.ssh, ~/.kube) +- [ ] **自动** macOS 偏好设置 (禁用长按字符弹出) + +--- + +## 📦 Dotfiles 安装 (自动) + +运行:`./setup.sh install` + +- [ ] **自动** .zshrc 软链接 +- [ ] **自动** .tmux.conf 软链接 +- [ ] **自动** ~/.config/git 软链接 +- [ ] **自动** ~/.config/nvim 软链接 +- [ ] **自动** ~/.config/tmux 软链接 +- [ ] **自动** ~/.config/wezterm 软链接 +- [ ] **自动** ~/.config/starship.toml 软链接 +- [ ] **自动** ~/.gitconfig 软链接 +- [ ] **自动** Git 全局配置 (excludesfile, defaultBranch) +- [ ] **自动** fzf 安装和配置 + +--- + +## ⚙️ 个人配置 (手动 - 重要!) + +### Git 配置 +```bash +# 替换为你的真实信息 +git config --file ~/.gitconfig user.name "Your Name" +git config --file ~/.gitconfig user.email "your@email.com" +git config --file ~/.gitconfig user.signingkey "your-ssh-public-key" +``` + +- [ ] **手动** 配置 user.name +- [ ] **手动** 配置 user.email +- [ ] **手动** 配置 user.signingkey + +### SSH 密钥 +```bash +# 生成新的 SSH 密钥 +ssh-keygen -t ed25519 -C "your@email.com" + +# 添加到 1Password SSH Agent +op ssh add ~/.ssh/id_ed25519 + +# 添加到 GitHub/GitLab +cat ~/.ssh/id_ed25519.pub | pbcopy +# 然后粘贴到 GitHub/GitLab 的 SSH Keys 设置 +``` + +- [ ] **手动** 生成 SSH 密钥 +- [ ] **手动** 添加密钥到 1Password +- [ ] **手动** 添加公钥到代码托管平台 + +### 验证 Git 配置 +```bash +# 检查配置 +git config --get user.name +git config --get user.email +git config --get user.signingkey + +# 测试签名 +git commit --allow-empty -m "Test signed commit" +git log -1 --format=full +``` + +- [ ] **手动** 验证配置正确 +- [ ] **手动** 测试提交签名 + +--- + +## 🍺 Homebrew 包安装 (自动) + +运行:`brew bundle install` + +- [ ] **自动** 安装 CLI 工具 (bat, ripgrep, fzf, lsd, difftastic, etc.) +- [ ] **自动** 安装开发工具 (go, rustup, node, lua, luarocks, etc.) +- [ ] **自动** 安装 Kubernetes 工具 (kubectl, helm, k9s, kubectx, etc.) +- [ ] **自动** 安装数据库 (mysql, postgresql, redis, etc.) +- [ ] **自动** 安装 Mac 应用 (1Password, Ghostty, WezTerm, Cursor, etc.) +- [ ] **自动** 安装 VSCode 扩展 +- [ ] **自动** 安装 Go 工具 (golangci-lint, gopls, delve, etc.) +- [ ] **自动** 安装 Cargo 工具 (sqlx-cli) + +--- + +## 🔧 验证安装 + +### Shell 环境 +```bash +# 重启 shell 或运行 +source ~/.zshrc + +# 验证常用命令 +which nvim tmux fzf bat rg lsd +``` + +- [ ] **手动** source ~/.zshrc 无错误 +- [ ] **手动** 验证 nvim 可用 +- [ ] **手动** 验证 tmux 可用 +- [ ] **手动** 验证常用 alias (l, la, lt, vi) + +### Neovim +```bash +# 打开 Neovim +nvim + +# 首次启动会自动安装插件 +# 等待插件安装完成 +:Lazy +``` + +- [ ] **手动** Neovim 启动无错误 +- [ ] **自动** lazy.nvim 自动安装插件 +- [ ] **手动** 验证 LSP 可用 (:LspInfo) +- [ ] **手动** 验证 treesitter 可用 + +### Kubernetes +```bash +# 验证 kubectl +kubectl version --client + +# 验证 krew +kubectl krew version + +# 验证常用工具 +k9s version +``` + +- [ ] **手动** kubectl 可用 +- [ ] **手动** k9s 可用 +- [ ] **手动** 配置 kubeconfig (工作相关) + +--- + +## 🏢 工作环境 (可选) + +如果你有特定的工作环境需求: + +- [ ] **手动** 配置 ~/.kube/config (工作集群) +- [ ] **手动** 配置 rsync_work 目标服务器 +- [ ] **手动** 配置 git_config_work 邮箱 +- [ ] **手动** 配置其他工作特定 alias + +--- + +## ✅ 最终检查 + +运行:`./setup.sh check` + +- [ ] **自动** Homebrew 检查 +- [ ] **自动** Zsh 检查 +- [ ] **自动** Neovim 检查 +- [ ] **自动** Tmux 检查 +- [ ] **自动** Antigen 检查 +- [ ] **自动** Symlinks 检查 +- [ ] **自动** Git Config 检查 + +--- + +## 📝 后续步骤 + +- [ ] **手动** 配置其他应用 (Raycast, Obsidian, etc.) +- [ ] **手动** 同步浏览器书签/扩展 +- [ ] **手动** 配置工作专用软件 +- [ ] **手动** 测试常用工作流 + +--- + +## 🔍 故障排查 + +### 常见问题 + +1. **zsh 配置不生效** + ```bash + source ~/.zshrc + # 或重启终端 + ``` + +2. **Neovim 插件报错** + ```bash + nvim --headless "+Lazy! sync" +qa + ``` + +3. **Homebrew 权限问题** + ```bash + sudo chown -R $(whoami) $(brew --prefix) + ``` + +4. **Git 签名失败** + ```bash + # 检查 1Password SSH agent + ls -la ~/.1password/agent.sock + op ssh list + ``` + +--- + +## 📞 需要帮助? + +- 查看 README.md 获取详细文档 +- 查看 setup.sh --help 获取命令说明 +- 查看 .sisyphus/plans/dotfiles-migration.md 获取计划详情 diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md new file mode 100644 index 0000000..4238ea4 --- /dev/null +++ b/MIGRATION_GUIDE.md @@ -0,0 +1,320 @@ +# Dotfiles 迁移指南 + +> 个人备份说明 - 用于新机器配置参考 +> +> **创建时间**: 2026-03-04 +> **适用场景**: 离职后新公司机器配置 + +--- + +## 📋 目录 + +1. [备份内容](#备份内容) +2. [不包含的内容](#不包含的内容) +3. [新机器配置步骤](#新机器配置步骤) +4. [常见问题](#常见问题) +5. [个性化配置](#个性化配置) + +--- + +## 📦 备份内容 + +### 已备份到 Git 仓库 + +| 文件/目录 | 说明 | 用途 | +|-----------|------|------| +| `.zshrc` | Shell 配置 | 60+ alias 和函数 | +| `.tmux.conf` | Tmux 配置 | 终端复用 | +| `git/config` | Git 配置模板 | 全局 Git 设置(占位符) | +| `nvim/` | Neovim 配置 | 编辑器配置 | +| `wezterm/` | WezTerm 配置 | 终端模拟器 | +| `alacritty/` | Alacritty 配置 | 备用终端 | +| `ghostty/` | Ghostty 配置 | 现代终端 | +| `starship.toml` | Starship 配置 | Shell 提示符 | +| `Brewfile` | Homebrew 包列表 | 所有工具和应用 | +| `setup.sh` | 安装脚本 | 一键配置 | +| `CHECKLIST.md` | 检查清单 | 配置验证 | +| `QUICKSTART.md` | 快速开始 | 3-5 分钟配置 | +| `README.md` | 完整文档 | 使用说明 | + +### .gitignore 排除规则 + +以下敏感数据**不会被提交**,需要在新机器重新配置: + +``` +.ssh/ # SSH 密钥 +.1password/ # 1Password 配置 +.kube/ # Kubernetes 配置 +*.env # 环境变量 +credentials.json # 凭据文件 +secrets.txt # 密钥文件 +``` + +--- + +## 🚫 不包含的内容 + +以下数据需要**手动迁移**或**重新配置**: + +### 需要重新生成的 + +- [ ] SSH 密钥对 (`~/.ssh/id_ed25519`) +- [ ] GPG 密钥(如果使用) +- [ ] Git 签名密钥 + +### 需要重新配置的 + +- [ ] Git 用户信息 (name, email) +- [ ] 1Password SSH Agent +- [ ] Kubeconfig (工作集群配置) +- [ ] SSH config (如果有自定义主机) + +### 需要单独备份的 + +- [ ] 浏览器书签 +- [ ] 应用许可证 +- [ ] 其他个人数据 + +--- + +## 🚀 新机器配置步骤 + +### 步骤 1: 克隆仓库 + +```bash +git clone ~/.dotfiles +cd ~/.dotfiles +``` + +### 步骤 2: 运行一键恢复 + +```bash +./setup.sh full-recover +``` + +这将自动完成: +- ✅ Xcode Command Line Tools 安装 +- ✅ Homebrew 安装 +- ✅ zsh antigen 安装 +- ✅ asdf 版本管理器安装 +- ✅ dotfiles 软链接创建 +- ✅ Git 基础配置 +- ✅ fzf 安装 + +### 步骤 3: 配置个人信息 + +#### Git 配置 + +```bash +# 替换为你的真实信息 +git config --file ~/.gitconfig user.name "Your Name" +git config --file ~/.gitconfig user.email "your@email.com" +git config --file ~/.gitconfig user.signingkey "your-ssh-public-key" +``` + +#### SSH 密钥生成 + +```bash +# 生成新密钥 +ssh-keygen -t ed25519 -C "your@email.com" + +# 查看公钥 +cat ~/.ssh/id_ed25519.pub + +# 添加到 GitHub/GitLab +# 1. 复制公钥: cat ~/.ssh/id_ed25519.pub | pbcopy +# 2. 粘贴到 GitHub: Settings → SSH and GPG keys → New SSH key +``` + +#### 1Password SSH Agent (如果使用) + +```bash +# 创建符号链接 +mkdir -p ~/.1password +ln -s ~/Library/Group\ Containers/2BUA8C4S2C.com.1password/t/agent.sock ~/.1password/agent.sock + +# 添加 SSH 密钥到 1Password +op ssh add ~/.ssh/id_ed25519 +``` + +### 步骤 4: 安装 Homebrew 包 + +```bash +# 安装所有包和应用 +brew bundle install +``` + +这会安装: +- CLI 工具 (bat, ripgrep, fzf, lsd, difftastic) +- 开发语言 (go, rustup, node, lua, bun, uv) +- 数据库 (mysql, postgresql, redis) +- Mac 应用 (1Password, Ghostty, Cursor, Obsidian, etc.) +- VSCode 扩展 + +### 步骤 5: 验证安装 + +```bash +# 运行检查脚本 +./setup.sh check +``` + +预期输出: +``` +Homebrew: ✓ installed +Zsh: ✓ installed +Neovim: ✓ installed +Tmux: ✓ installed +Antigen: ✓ installed +``` + +### 步骤 6: 重启终端 + +```bash +# 重启终端或重新加载配置 +source ~/.zshrc +``` + +--- + +## ❓ 常见问题 + +### Q1: zsh 配置不生效 + +```bash +# 重新加载配置 +source ~/.zshrc + +# 或重启终端 +``` + +### Q2: Neovim 插件报错 + +```bash +# 同步所有插件 +nvim --headless "+Lazy! sync" +qa + +# 或打开 Neovim 后运行 :Lazy sync +``` + +### Q3: Homebrew 权限问题 + +```bash +# 修复权限 +sudo chown -R $(whoami) $(brew --prefix) +``` + +### Q4: Git 签名失败 + +```bash +# 检查 1Password SSH agent +ls -la ~/.1password/agent.sock + +# 列出已添加的密钥 +op ssh list + +# 如果没有密钥,添加它 +op ssh add ~/.ssh/id_ed25519 +``` + +### Q5: Antigen 插件加载慢 + +```bash +# 更新 antigen +antigen selfupdate + +# 更新所有插件 +antigen update + +# 清理缓存 +antigen reset +antigen apply +``` + +### Q6: Tmux 插件未安装 + +```bash +# 在 tmux 中按下 Ctrl-a + I (大写的 i) +# 这会安装 TPM 插件 +``` + +--- + +## ⚙️ 个性化配置 + +### 修改 Git 配置 + +编辑 `~/.dotfiles/git/config` 或直接运行: + +```bash +git config --global user.name "Your Name" +git config --global user.email "your@email.com" +``` + +### 添加新 alias + +编辑 `~/.dotfiles/.zshrc`,在 alias 区域添加: + +```zsh +alias myalias='command' +``` + +然后运行 `source ~/.zshrc` + +### 添加 Homebrew 包 + +编辑 `~/.dotfiles/Brewfile`,添加: + +```ruby +brew "package-name" +cask "app-name" +``` + +然后运行 `brew bundle install` + +### 修改 Neovim 配置 + +编辑 `~/.dotfiles/nvim/lua/plugins/` 下的文件。 + +--- + +## 📞 需要帮助? + +- 查看 [README.md](./README.md) 获取完整文档 +- 查看 [CHECKLIST.md](./CHECKLIST.md) 获取检查清单 +- 查看 [QUICKSTART.md](./QUICKSTART.md) 获取快速开始 +- 运行 `./setup.sh help` 查看命令说明 + +--- + +## 📝 配置记录 + +### 当前配置 + +| 项目 | 值 | +|------|-----| +| Shell | zsh + antigen + oh-my-zsh | +| 编辑器 | Neovim (lazy.nvim) | +| 终端 | WezTerm / Ghostty / Alacritty | +| 终端复用 | Tmux (TPM) | +| 提示符 | Starship | +| 版本管理 | asdf | + +### 主要工具 + +- **语言**: Go, Rust, Node.js, Python, Lua, Bun +- **K8s**: kubectl, k9s, helm, kubectx +- **数据库**: MySQL, PostgreSQL, Redis +- **Git**: SSH 签名 (1Password) + +--- + +## 🔐 安全提醒 + +1. **不要提交敏感数据** - 所有敏感路径已在 `.gitignore` 中排除 +2. **新机器重新生成密钥** - SSH、GPG 等密钥应该在新机器重新生成 +3. **移除旧机器授权** - 离职前移除旧机器的 GitHub、1Password 授权 +4. **更新密码** - 如果可能,更新重要账户的密码 + +--- + +**祝新工作顺利!** 🎉 diff --git a/QUICKSTART.md b/QUICKSTART.md new file mode 100644 index 0000000..338302d --- /dev/null +++ b/QUICKSTART.md @@ -0,0 +1,91 @@ +# 快速开始指南 + +> 3-5 分钟完成新机器基础配置 + +--- + +## 步骤 1: 克隆仓库 (1 分钟) + +```bash +git clone ~/.dotfiles +cd ~/.dotfiles +``` + +--- + +## 步骤 2: 运行一键恢复 (2-3 分钟) + +```bash +./setup.sh full-recover +``` + +这将自动完成: +- ✅ Xcode Command Line Tools 安装 +- ✅ Homebrew 安装 +- ✅ zsh antigen 安装 +- ✅ dotfiles 软链接创建 +- ✅ Git 基础配置 + +--- + +## 步骤 3: 配置个人信息 (1 分钟) + +```bash +# Git 配置 +git config --file ~/.gitconfig user.name "Your Name" +git config --file ~/.gitconfig user.email "your@email.com" + +# SSH 密钥 +ssh-keygen -t ed25519 -C "your@email.com" +``` + +--- + +## 步骤 4: 安装 Homebrew 包 (后台运行) + +```bash +brew bundle install +``` + +这会安装所有 CLI 工具和应用程序。 + +--- + +## 步骤 5: 验证安装 + +```bash +./setup.sh check +``` + +--- + +## ✅ 完成! + +重启终端或运行 `source ~/.zshrc` 即可开始使用。 + +--- + +## 下一步 + +- [ ] 添加 SSH 公钥到 GitHub/GitLab +- [ ] 配置 1Password SSH Agent +- [ ] 配置工作特定的 kubeconfig +- [ ] 安装个人应用 (Chrome, Slack, etc.) + +--- + +## 常用命令 + +```bash +# 查看帮助 +./setup.sh help + +# 检查状态 +./setup.sh check + +# 同步最新配置 +./setup.sh sync + +# 备份当前配置 +./setup.sh backup +``` diff --git a/README.md b/README.md index 9d29c89..c687812 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,302 @@ -# dotfiles -My dotfiles. +# Dotfiles + +> 个人 macOS 开发环境配置 - 支持一键迁移到新机器 + +--- + +## 🚀 快速开始 + +### 新机器设置 (推荐) + +```bash +# 1. 克隆仓库 +git clone ~/.dotfiles +cd ~/.dotfiles + +# 2. 一键完整恢复 +./setup.sh full-recover + +# 3. 配置个人信息 +git config --file ~/.gitconfig user.name "Your Name" +git config --file ~/.gitconfig user.email "your@email.com" +ssh-keygen -t ed25519 -C "your@email.com" + +# 4. 安装 Homebrew 包 +brew bundle install +``` + +### 现有机器设置 + +```bash +# 安装 dotfiles 软链接 +./setup.sh install + +# 检查当前状态 +./setup.sh check +``` + +--- + +## 📋 命令说明 + +| 命令 | 说明 | +|------|------| +| `./setup.sh init` | 初始化新系统 (Homebrew, Xcode, antigen) | +| `./setup.sh install` | 安装 dotfiles 软链接 | +| `./setup.sh backup` | 备份当前配置到 Brewfile | +| `./setup.sh sync` | 从 git 仓库同步最新配置 | +| `./setup.sh full-recover` | 新机器完整恢复 (init + install + sync) | +| `./setup.sh check` | 检查当前安装状态 | +| `./setup.sh help` | 显示帮助信息 | + +--- + +## 📁 目录结构 + +``` +~/.dotfiles/ +├── .gitignore # Git 忽略规则 (敏感数据) +├── .tmux.conf # Tmux 配置 +├── .zshrc # Zsh 配置 (alias + 函数) +├── Brewfile # Homebrew 包列表 +├── CHECKLIST.md # 迁移检查清单 +├── setup.sh # 安装脚本 +├── git/ +│ ├── .gitignore # Git 全局忽略 +│ └── config # Git 配置 (模板化) +├── nvim/ # Neovim 配置 +│ ├── init.lua +│ └── lua/ +├── wezterm/ # WezTerm 终端配置 +├── alacritty/ # Alacritty 终端配置 +├── ghostty/ # Ghostty 终端配置 +├── starship.toml # Starship 提示符 +└── tmux/ # Tmux 插件 (TPM) +``` + +--- + +## 🔧 核心组件 + +### Shell (Zsh) + +- **框架**: antigen + oh-my-zsh +- **插件**: + - zsh-autosuggestions + - zsh-syntax-highlighting + - fzf-tab + - vi-mode +- **特性**: + - 60+ alias 和函数 + - Kubernetes 工具集成 + - Git 工作流优化 + - 工作环境标记 + +### 编辑器 (Neovim) + +- **插件管理**: lazy.nvim +- **语言支持**: Go, Python, Rust, Lua +- **核心插件**: + - LSP (lspconfig) + - 自动补全 (nvim-cmp) + - Treesitter (语法高亮) + - Telescope (模糊搜索) + - Snacks.nvim (UI 增强) +- **主题**: Tokyo Night + +### 终端 + +- **WezTerm**: GPU 加速终端 (主要使用) +- **Alacritty**: 备用终端 +- **Ghostty**: 现代化终端 + +### 终端复用 (Tmux) + +- **前缀键**: `Ctrl-a` +- **插件**: TPM (Tmux Plugin Manager) +- **主题**: Dracula 配色 +- **Vi 模式**: 复制/粘贴 + +### Kubernetes + +- kubectl + krew +- k9s (TUI 管理) +- kubectx / kubens +- helm + helmfile +- ArgoCD CLI + +--- + +## 📦 Homebrew 包 + +### CLI 工具 + +```bash +bat # cat 替代 +ripgrep # grep 替代 +lsd # ls 替代 +difftastic # diff 工具 +fzf # 模糊搜索 +``` + +### 开发语言 + +```bash +go # Go 语言 +rustup # Rust +node # Node.js +lua # Lua +pnpm # pnpm +bun # Bun +uv # Python uv +``` + +### 数据库 + +```bash +mysql # MySQL +postgresql # PostgreSQL +redis # Redis +``` + +### Mac 应用 + +```bash +1password # 密码管理 +ghostty # 终端 +cursor # 编辑器 +obsidian # 笔记 +raycast # 启动器 +figma # 设计 +``` + +--- + +## ⚙️ 配置说明 + +### Git 配置模板 + +`git/config` 使用占位符,首次使用时需要配置: + +```bash +git config --file ~/.gitconfig user.name "Your Name" +git config --file ~/.gitconfig user.email "your@email.com" +git config --file ~/.gitconfig user.signingkey "your-ssh-key" +``` + +### 工作环境函数 + +`.zshrc` 中包含工作环境相关的函数,已用 `# ==== WORK:` 标记: + +- `klogs` - Kubernetes 日志查看 +- `bitnami_seal` - Kubernetes 密钥加密 +- `rsync_work` - 远程同步到工作服务器 +- `replace_remote` - Git remote 切换 +- `git_config_work` / `git_config_play` - 多环境 Git 配置 + +--- + +## 🔐 敏感数据 + +以下路径已被 `.gitignore` 排除,**不会被提交**: + +- `.ssh/` - SSH 密钥 +- `.1password/` - 1Password 配置 +- `.kube/` - Kubernetes 配置 +- `*.env` - 环境变量 +- `credentials.json`, `secrets.txt` - 凭据 + +**需要在新机器上重新配置**。 + +--- + +## 🔄 迁移流程 + +### 从旧机器导出 + +```bash +cd ~/.dotfiles +./setup.sh backup +git add . +git commit -m "Update dotfiles before migration" +git push +``` + +### 在新机器恢复 + +```bash +git clone ~/.dotfiles +cd ~/.dotfiles +./setup.sh full-recover +``` + +详细步骤请参考 [CHECKLIST.md](./CHECKLIST.md) + +--- + +## 🐛 故障排查 + +### zsh 配置不生效 + +```bash +source ~/.zshrc +# 或重启终端 +``` + +### Neovim 插件报错 + +```bash +nvim --headless "+Lazy! sync" +qa +``` + +### Homebrew 权限问题 + +```bash +sudo chown -R $(whoami) $(brew --prefix) +``` + +### Git 签名失败 + +```bash +# 检查 1Password SSH agent +ls -la ~/.1password/agent.sock +op ssh list +``` + +--- + +## 📝 自定义 + +### 添加新包 + +编辑 `Brewfile`,然后运行: + +```bash +brew bundle install +``` + +### 添加新 alias + +编辑 `~/.dotfiles/.zshrc`,在 alias 区域添加: + +```zsh +alias myalias='command' +``` + +### 添加 Neovim 插件 + +编辑 `~/.dotfiles/nvim/lua/plugins/` 下的文件。 + +--- + +## 📄 License + +MIT + +--- + +## 🔗 相关链接 + +- [迁移检查清单](./CHECKLIST.md) +- [Neovim 配置](./nvim/README.md) +- [Dotfiles 迁移计划](./.sisyphus/plans/dotfiles-migration.md) diff --git a/git/config b/git/config index 8ad2ee5..fc1f696 100644 --- a/git/config +++ b/git/config @@ -2,9 +2,10 @@ defaultBranch = main [user] - name = Tony Tang - signingkey = ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF23DQtdH5PODF9fYUHr49I1J3lfKLAPk4LG54MVUTcg - email = tonytang@lilith.com + name = YOUR_NAME + signingkey = YOUR_SSH_SIGNING_KEY + email = YOUR_EMAIL + [commit] gpgsign = true @@ -19,7 +20,7 @@ [core] editor = nvim - excludesfile = /Users/lilithgames/.gitignore_global + excludesfile = ~/.config/git/.gitignore [pager] difftool = true @@ -49,6 +50,7 @@ d = diff ds = diff --staged dc = diff --cached + detect-placeholder-config = "!bash -lc 'CONFIG_FILE=$(git rev-parse --show-toplevel 2>/dev/null || echo \".\")/git/config; if [ -f \"$HOME/.dotfiles/git/config\" ]; then CONFIG_FILE=\"$HOME/.dotfiles/git/config\"; fi; if [ -f \"$CONFIG_FILE\" ]; then if grep -qE \"name\\s*=\\s*YOUR_NAME|email\\s*=\\s*YOUR_EMAIL|signingkey\\s*=\\s*YOUR_SSH_SIGNING_KEY\" \"$CONFIG_FILE\"; then echo \"[config] WARNING: Placeholder values detected in $CONFIG_FILE\"; echo \"[config] Please run: git config --file $CONFIG_FILE user.name 'Your Name'; git config --file $CONFIG_FILE user.email 'your@email.com'; git config --file $CONFIG_FILE user.signingkey 'your-ssh-key'\"; else echo \"[config] Git config looks good - no placeholders detected\"; fi; else echo \"[config] Config file not found: $CONFIG_FILE\"; fi'" #[difftool "sourcetree"] # cmd = opendiff \"$LOCAL\" \"$REMOTE\" diff --git a/setup.sh b/setup.sh index 833bac7..5d14c2e 100755 --- a/setup.sh +++ b/setup.sh @@ -1,35 +1,63 @@ #!/usr/bin/env zsh +# +# dotfiles Setup Script +# Usage: ./setup.sh [command] +# +# Commands: +# init - Initialize a brand new macOS system +# install - Install dotfiles symlinks +# backup - Backup current configuration +# sync - Sync from git repository +# full-recover - Full recovery on new machine (init + install + sync) +# check - Check current setup status +# help - Show this help message set -e +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Configuration +DOTFILES_DIR="${DOTFILES_DIR:-$HOME/.dotfiles}" +WORKING_DIR=$(cd "$(dirname "$0")" && pwd) +HOME_DIR="$HOME" + +# Files to link FILES=( - .zshrc - .tmux.conf - .ideavimrc + .zshrc + .tmux.conf ) +# Config directories to link CONFIG_FILES=( - git - nvim - tmux - pycodestyle - wezterm - starship.toml - stylua.toml - direnv + git + nvim + tmux + pycodestyle + wezterm + starship.toml + stylua.toml + direnv ghostty ) +# Custom file mappings (from -> to) CUSTOM_FILES=( - #"ssh/config .ssh/config" "git/config .gitconfig" ) +# Rustup components RUSTUP_COMPONENTS=( - clippy + clippy + rustfmt ) -KUBECTl_COMPONENTS=( +# Kubectl krew plugins (commented out by default - enable as needed) +KUBECTL_COMPONENTS=( # ctx # ns # tail @@ -42,194 +70,594 @@ KUBECTl_COMPONENTS=( # access-matrix # pod-dive # pod-chaos - # pod-lease # pod-shell # pod-logs - # pod-attach - # pod-exec - # pod-port-forward ) -WORKING_DIR=$(pwd) -HOME_DIR="$HOME" -is_brew_installed="$+commands[brew]" +# ============================================================================= +# Utility Functions +# ============================================================================= +function print_header() { + echo -e "\n${BLUE}=== $1 ===${NC}\n" +} + +function print_success() { + echo -e "${GREEN}✓ $1${NC}" +} + +function print_warning() { + echo -e "${YELLOW}⚠ $1${NC}" +} + +function print_error() { + echo -e "${RED}✗ $1${NC}" +} function command_exists() { - # Check if a command exists - # Usage: command_exists - local cmd="$1" + command -v "$1" >/dev/null 2>&1 +} - if command -v "$cmd" >/dev/null 2>&1; then - return 0 # Command exists +function ask() { + local prompt="$1" + local default="${2:-n}" + local choices="y/N" + [[ "$default" == "y" ]] && choices="Y/n" + + read -q "?$prompt [$choices] " response + echo + response=${response:-$default} + [[ "$response" =~ ^[Yy] ]] +} + +# ============================================================================= +# Commands +# ============================================================================= + +function cmd_help() { + cat << EOF +dotfiles Setup Script + +Usage: ./setup.sh [command] + +Commands: + init Initialize a brand new macOS system (Homebrew, Xcode, etc.) + install Install dotfiles symlinks to home directory + backup Backup current configuration to dotfiles repo + sync Sync from git repository + full-recover Full recovery on new machine (init + install + sync) + check Check current setup status + help Show this help message + +Examples: + ./setup.sh init # Initialize new system + ./setup.sh install # Link dotfiles + ./setup.sh full-recover # Full setup on new machine + ./setup.sh check # Check what's installed + +For more information, see README.md +EOF +} + +function cmd_init() { + print_header "Initializing macOS System" + + # Check for Homebrew + if command_exists brew; then + print_success "Homebrew already installed" else - return 1 # Command does not exist - fi -} - -function init() { - sudo xcode-select --install - sudo xcodebuild -license accept - git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.10.0 - if [[ $(command -v brew) = "" ]]; then - echo "Installing brew" - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - eval "$(/opt/homebrew/bin/brew shellenv)" - brew update - brew install zsh - chsh -s /bin/zsh - ssh-keygen - echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >>"$HOME/.zshrc" - source "$HOME/.zshrc" - fi -} - -function purge() { - uninstall_oh_my_zsh - brew remove $(brew list --formula) - for i in ${FILE_OR_DIRS[@]}; do - rm -rf $WORKING_DIR/$i $HOME_DIR/$i - done - - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)" -} - -function manual_install() { - wget -qO- http://stevenygard.com/download/class-dump-3.5.tar.gz | tar xvz - -C /usr/local/bin && chmod u+x /usr/local/bin/class-dump - wget -O /usr/local/bin/class-dump https://github.com/AloneMonkey/MonkeyDev/raw/master/bin/class-dump && chmod u+x /usr/local/bin/class-dump - pip install --user frida-tools - # mkdir -p $ZSH/custom/plugins/poetry - # poetry completions zsh > $ZSH/custom/plugins/poetry/_poetry -} - -function backup() { - brew bundle dump -f -} - -function softLink() { - echo "Linking files..." - for i in ${FILES[@]}; do - ln -svfn $WORKING_DIR/$i $HOME_DIR/$i - done - - echo "Linking config files..." - for i in ${CONFIG_FILES[@]}; do - ln -svfn $WORKING_DIR/$i $HOME_DIR/.config/$i - done - - echo 'Linking customized files' - for row in ${CUSTOM_FILES[@]}; do - IFS=' ' read -r from to <<< "$row" - ln -svfn $WORKING_DIR/$from $HOME_DIR/$to - done -} - -function recover() { - #softwareupdate --install-rosetta - OS="$(uname)" - - # Homebrew - if [ ! $(which brew) ]; then - echo "Installing homebrew..." + print_warning "Installing Homebrew..." /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + eval "$(/opt/homebrew/bin/brew shellenv)" + print_success "Homebrew installed" fi - export PATH=/usr/local/bin/:$PATH + + # Xcode Command Line Tools + print_warning "Installing Xcode Command Line Tools..." xcode-select --install - defaults write -g ApplePressAndHoldEnabled -bool false - - # antigen - if [ ! -f $HOME/.antigen/antigen.zsh ]; then - mkdir -p $HOME/.antigen/ - curl -L git.io/antigen >$HOME/.antigen/antigen.zsh + sudo xcodebuild -license accept 2>/dev/null || true + print_success "Xcode tools ready" + + # Install antigen for zsh + if [ ! -f "$HOME/.antigen/antigen.zsh" ]; then + print_warning "Installing zsh antigen..." + mkdir -p "$HOME/.antigen/" + curl -L git.io/antigen > "$HOME/.antigen/antigen.zsh" + print_success "Antigen installed" + else + print_success "Antigen already installed" fi - - mkdir -p $HOME/.kube/ - mkdir $HOME/.ssh - mkdir $HOME/.config/ - - # dotfiles - cp ssh/example $HOME/.ssh/config - - # submodules - echo 'Syncing Submodules...' - git submodule init - git submodule update --init --recursive - git submodule foreach --recursive git fetch - git submodule foreach git merge origin master - - # brew bundle - if (( $is_brew_installed )) - then - echo "Installing by brew..." - suffix="$OS."$(echo $(hostname) | cut -d '.' -f 1) - mv .Brewfile.$suffix Brewfile - brew bundle -v - mv Brewfile .Brewfile.$suffix + + # Install asdf + if [ ! -d "$HOME/.asdf" ]; then + print_warning "Installing asdf..." + git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.0 + print_success "asdf installed" + else + print_success "asdf already installed" fi - - mkdir -p ~/.1password && ln -s ~/Library/Group\ Containers/2BUA8C4S2C.com.1password/t/agent.sock ~/.1password/agent.sock - - # others - git config --global core.excludesfile ~/.config/git/.gitignore - git config --global init.defaultBranch main - $(brew --prefix)/opt/fzf/install + + # Create necessary directories + print_warning "Creating directories..." + mkdir -p "$HOME/.config/" + mkdir -p "$HOME/.ssh" + mkdir -p "$HOME/.kube" + print_success "Directories created" + + # Set default macOS preferences + print_warning "Setting macOS preferences..." + defaults write -g ApplePressAndHoldEnabled -bool false 2>/dev/null || true + print_success "Preferences set" + + print_header "Init Complete!" + echo "Now run: ./setup.sh install" } -function recover_rust() { - # install rustup - if ! command_exists rustup; then - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh - fi - # cargo commands installation - for command in ${RUSTUP_COMPONENTS[@]}; do - if ! command_exists $command; then - rustup component add $command - fi - done -} - -function recover_kubectl() { - # krew installation - if ! command_exists kubectl-krew; then - ( - set -x; cd "$(mktemp -d)" && - OS="$(uname | tr '[:upper:]' '[:lower:]')" && - ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" && - KREW="krew-${OS}_${ARCH}" && - curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" && - tar zxvf "${KREW}.tar.gz" && - ./"${KREW}" install krew - ) - fi - # kubectl plugins installation - for plugin in ${KUBECTl_COMPONENTS[@]}; do - if ! command_exists $plugin; then - kubectl krew install $plugin +function cmd_install() { + print_header "Installing Dotfiles Symlinks" + + # Link files + print_warning "Linking files..." + for i in "${FILES[@]}"; do + if [ -f "$WORKING_DIR/$i" ]; then + ln -svfn "$WORKING_DIR/$i" "$HOME_DIR/$i" + print_success "Linked: $i" + else + print_warning "Not found: $i" fi done + + # Link config directories + print_warning "Linking config directories..." + for i in "${CONFIG_FILES[@]}"; do + if [ -d "$WORKING_DIR/$i" ]; then + mkdir -p "$HOME_DIR/.config" + ln -svfn "$WORKING_DIR/$i" "$HOME_DIR/.config/$i" + print_success "Linked: .config/$i" + else + print_warning "Not found: $i" + fi + done + + # Link custom files + print_warning "Linking custom files..." + for row in "${CUSTOM_FILES[@]}"; do + IFS=' ' read -r from to <<< "$row" + if [ -f "$WORKING_DIR/$from" ]; then + # Create parent directory if needed + local to_dir=$(dirname "$HOME_DIR/$to") + mkdir -p "$to_dir" + ln -svfn "$WORKING_DIR/$from" "$HOME_DIR/$to" + print_success "Linked: $to" + else + print_warning "Not found: $from" + fi + done + + # Initialize git config excludesfile + print_warning "Configuring git..." + git config --global core.excludesfile ~/.config/git/.gitignore 2>/dev/null || true + git config --global init.defaultBranch main 2>/dev/null || true + print_success "Git configured" + + # Install fzf + if command_exists fzf; then + print_success "fzf already installed" + elif command_exists brew; then + print_warning "Installing fzf..." + $(brew --prefix)/opt/fzf/install --key-bindings --completion 2>/dev/null || true + print_success "fzf installed" + fi + + print_header "Installation Complete!" + echo "" + echo "Next steps:" + echo " 1. Configure git: git config --file ~/.gitconfig user.name 'Your Name'" + echo " 2. Restart terminal or run: source ~/.zshrc" + echo " 3. Run: brew bundle install (to install packages)" } -function new_recover() { - # recover_rust - recover_kubectl - echo "don't forget to change the email address in git config" +function cmd_backup() { + print_header "Backing Up Configuration" + + local backup_count=0 + local backup_warnings=0 + + # ========================================================================== + # 1. Brewfile 备份 + # ========================================================================== + print_warning "Dumping Brewfile..." + if command_exists brew; then + brew bundle dump -f --file="$WORKING_DIR/Brewfile" + print_success "Brewfile saved" + backup_count=$((backup_count + 1)) + else + print_error "Homebrew not found" + backup_warnings=$((backup_warnings + 1)) + fi + + # ========================================================================== + # 2. Git 配置检查与备份(脱敏) + # ========================================================================== + print_warning "Checking git config..." + if [ -f "$WORKING_DIR/git/config" ]; then + if grep -qE "YOUR_NAME|YOUR_EMAIL|YOUR_SSH_SIGNING_KEY" "$WORKING_DIR/git/config" 2>/dev/null; then + print_success "git/config uses placeholders (safe to commit)" + else + print_warning "git/config contains real values - backing up as .gitconfig.backup (NOT committed)" + cp "$WORKING_DIR/git/config" "$WORKING_DIR/git/config.backup.$(date +%Y%m%d)" + backup_count=$((backup_count + 1)) + fi + fi + + print_warning "Exporting git config summary..." + local git_name=$(git config --global user.name 2>/dev/null || echo "not set") + local git_email=$(git config --global user.email 2>/dev/null || echo "not set") + local git_key=$(git config --global user.signingkey 2>/dev/null || echo "not set") + + cat > "$WORKING_DIR/.git_config_summary.txt" << EOF +# Git Configuration Summary +# Generated: $(date '+%Y-%m-%d %H:%M:%S') +# WARNING: This file contains sensitive information - DO NOT COMMIT + +user.name = $git_name +user.email = $git_email +user.signingkey = $git_key + +# To restore on new machine: +# git config --global user.name "$git_name" +# git config --global user.email "$git_email" +# git config --global user.signingkey "$git_key" +EOF + print_success "Git config summary exported to .git_config_summary.txt" + backup_count=$((backup_count + 1)) + + # ========================================================================== + # 3. SSH 公钥备份 + # ========================================================================== + print_warning "Backing up SSH public keys..." + local ssh_backup_dir="$WORKING_DIR/ssh_backup_$(date +%Y%m%d_%H%M%S)" + + if [ -d "$HOME/.ssh" ]; then + mkdir -p "$ssh_backup_dir" + + for key in "$HOME"/.ssh/*.pub; do + if [ -f "$key" ]; then + cp "$key" "$ssh_backup_dir/" + print_success "Copied: $(basename "$key")" + fi + done + + if [ -f "$HOME/.ssh/config" ]; then + cp "$HOME/.ssh/config" "$ssh_backup_dir/" + print_success "Copied: ssh config" + fi + + if [ -f "$HOME/.ssh/id_ed25519.pub" ]; then + echo "# SSH Public Key Backup" > "$ssh_backup_dir/README.md" + echo "# Generated: $(date '+%Y-%m-%d %H:%M:%S')" >> "$ssh_backup_dir/README.md" + echo "# WARNING: Contains public keys only - DO NOT COMMIT" >> "$ssh_backup_dir/README.md" + echo "" >> "$ssh_backup_dir/README.md" + echo "## Public Keys" >> "$ssh_backup_dir/README.md" + for key in "$ssh_backup_dir"/*.pub; do + if [ -f "$key" ]; then + echo "### $(basename "$key")" >> "$ssh_backup_dir/README.md" + echo '```' >> "$ssh_backup_dir/README.md" + cat "$key" >> "$ssh_backup_dir/README.md" + echo '' >> "$ssh_backup_dir/README.md" + echo '```' >> "$ssh_backup_dir/README.md" + echo "" >> "$ssh_backup_dir/README.md" + fi + done + print_success "SSH backup created: $ssh_backup_dir" + backup_count=$((backup_count + 1)) + else + print_warning "No SSH keys found - you'll need to generate new ones on the new machine" + fi + else + print_warning "~/.ssh directory not found" + fi + + # ========================================================================== + # 4. 其他重要配置备份 + # ========================================================================== + print_warning "Backing up other configurations..." + + if [ -L "$HOME/.1password/agent.sock" ]; then + echo "# 1Password SSH Agent" > "$WORKING_DIR/.1password_config.txt" + echo "Symlink: ~/.1password/agent.sock -> $(readlink "$HOME/.1password/agent.sock")" >> "$WORKING_DIR/.1password_config.txt" + echo "# Setup on new machine:" >> "$WORKING_DIR/.1password_config.txt" + echo "# 1. Install 1Password" >> "$WORKING_DIR/.1password_config.txt" + echo "# 2. mkdir -p ~/.1password" >> "$WORKING_DIR/.1password_config.txt" + echo "# 3. ln -s ~/Library/Group\\ Containers/2BUA8C4S2C.com.1password/t/agent.sock ~/.1password/agent.sock" >> "$WORKING_DIR/.1password_config.txt" + print_success "1Password config documented" + backup_count=$((backup_count + 1)) + fi + + if [ -f "$HOME/.kube/config" ]; then + echo "# Kubernetes Contexts Backup" > "$WORKING_DIR/.kube_contexts.txt" + echo "# Generated: $(date '+%Y-%m-%d %H:%M:%S')" >> "$WORKING_DIR/.kube_contexts.txt" + echo "# WARNING: Context names only - NOT the actual config" >> "$WORKING_DIR/.kube_contexts.txt" + echo "" >> "$WORKING_DIR/.kube_contexts.txt" + echo "## Available Contexts:" >> "$WORKING_DIR/.kube_contexts.txt" + kubectl config get-contexts -o name 2>/dev/null >> "$WORKING_DIR/.kube_contexts.txt" || echo "Could not list contexts" >> "$WORKING_DIR/.kube_contexts.txt" + echo "" >> "$WORKING_DIR/.kube_contexts.txt" + echo "## To restore:" >> "$WORKING_DIR/.kube_contexts.txt" + echo "# Copy your kubeconfig from old machine or get from your team" >> "$WORKING_DIR/.kube_contexts.txt" + print_success "Kubernetes contexts documented" + backup_count=$((backup_count + 1)) + fi + + if command_exists code; then + echo "# VSCode Extensions Backup" > "$WORKING_DIR/.vscode_extensions.txt" + echo "# Generated: $(date '+%Y-%m-%d %H:%M:%S')" >> "$WORKING_DIR/.vscode_extensions.txt" + echo "# To restore: code --install-extension " >> "$WORKING_DIR/.vscode_extensions.txt" + echo "" >> "$WORKING_DIR/.vscode_extensions.txt" + code --list-extensions >> "$WORKING_DIR/.vscode_extensions.txt" 2>/dev/null || echo "Could not list extensions" >> "$WORKING_DIR/.vscode_extensions.txt" + print_success "VSCode extensions documented" + backup_count=$((backup_count + 1)) + fi + + # ========================================================================== + # 5. 生成备份报告 + # ========================================================================== + print_header "Backup Summary" + + local backup_report="$WORKING_DIR/.backup_report_$(date +%Y%m%d_%H%M%S).md" + cat > "$backup_report" << EOF +# Dotfiles Backup Report + +**Generated**: $(date '+%Y-%m-%d %H:%M:%S') +**Machine**: $(hostname) +**User**: $(whoami) + +## Backup Items + +| Item | Status | +|------|--------| +| Brewfile | $([ -f "$WORKING_DIR/Brewfile" ] && echo "✅ Saved" || echo "❌ Failed") | +| Git config summary | $([ -f "$WORKING_DIR/.git_config_summary.txt" ] && echo "✅ Saved" || echo "❌ Failed") | +| SSH public keys | $([ -d "$ssh_backup_dir" ] && echo "✅ Saved to $ssh_backup_dir" || echo "⚠️ Not found") | +| 1Password config | $([ -f "$WORKING_DIR/.1password_config.txt" ] && echo "✅ Documented" || echo "⚠️ Not configured") | +| Kubernetes contexts | $([ -f "$WORKING_DIR/.kube_contexts.txt" ] && echo "✅ Documented" || echo "⚠️ Not configured") | +| VSCode extensions | $([ -f "$WORKING_DIR/.vscode_extensions.txt" ] && echo "✅ Documented" || echo "⚠️ Not installed") | + +## Files Created + +- Brewfile (updated) +- .git_config_summary.txt ⚠️ DO NOT COMMIT +- .1password_config.txt +- .kube_contexts.txt +- .vscode_extensions.txt +$( [ -d "$ssh_backup_dir" ] && echo "- $ssh_backup_dir/ ⚠️ DO NOT COMMIT" ) + +## Next Steps + +1. Review changes: git status +2. Commit safe files: git add Brewfile .1password_config.txt .kube_contexts.txt .vscode_extensions.txt +3. git commit -m 'backup: update dotfiles' +4. ⚠️ DO NOT commit: .git_config_summary.txt, ssh_backup_*/ +EOF + + print_success "Backup report generated: $backup_report" + + echo "" + echo "==========================================" + echo "Backup Summary" + echo "==========================================" + echo " Items backed up: $backup_count" + echo " Warnings: $backup_warnings" + echo "" + echo "Files to review:" + echo " ✅ Safe to commit: Brewfile, .1password_config.txt, .kube_contexts.txt, .vscode_extensions.txt" + echo " ⚠️ DO NOT COMMIT: .git_config_summary.txt, ssh_backup_*/" + echo "" + echo "Next steps:" + echo " 1. Review: git status" + echo " 2. Commit safe files: git add Brewfile .1password_config.txt .kube_contexts.txt .vscode_extensions.txt" + echo " 3. git commit -m 'backup: update dotfiles'" + echo "==========================================" +} +function cmd_sync() { + print_header "Syncing from Git" + + if [ ! -d "$DOTFILES_DIR/.git" ]; then + print_error "Not a git repository: $DOTFILES_DIR" + return 1 + fi + + cd "$DOTFILES_DIR" + + # Pull latest changes + print_warning "Pulling latest changes..." + git pull origin main 2>/dev/null || git pull 2>/dev/null || true + print_success "Synced" + + # Check for placeholder config + if grep -qE "YOUR_NAME|YOUR_EMAIL" "$DOTFILES_DIR/git/config" 2>/dev/null; then + print_warning "⚠️ git/config contains placeholder values!" + echo " Run: git config --file ~/.gitconfig user.name 'Your Name'" + echo " Run: git config --file ~/.gitconfig user.email 'your@email.com'" + echo " Run: git config --file ~/.gitconfig user.signingkey 'your-ssh-key'" + fi + + print_header "Sync Complete!" } -function post_recover() { - mkdir -p ~/.1password && ln -s "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock" ~/.1password/agent.sock +function cmd_full_recover() { + print_header "Full Recovery (New Machine)" + + # Check for git + if ! command_exists git; then + print_error "Git not found. Please install Xcode Command Line Tools first." + return 1 + fi + + # Check if this is a fresh clone or existing setup + if [ ! -d "$DOTFILES_DIR/.git" ]; then + print_warning "This doesn't appear to be a git clone." + echo "Please clone your dotfiles repository first:" + echo " git clone $DOTFILES_DIR" + return 1 + fi + + # Run init + cmd_init + + # Run install + cmd_install + + # Run sync + cmd_sync + + print_header "Full Recovery Complete!" + echo "" + echo "IMPORTANT: Configure your personal settings:" + echo "" + echo " # Git configuration" + echo " git config --file ~/.gitconfig user.name 'Your Name'" + echo " git config --file ~/.gitconfig user.email 'your@email.com'" + echo " git config --file ~/.gitconfig user.signingkey 'your-ssh-key'" + echo "" + echo " # Generate new SSH keys" + echo " ssh-keygen -t ed25519 -C 'your@email.com'" + echo "" + echo " # Install Homebrew packages" + echo " brew bundle install" + echo "" } -option=$1 -case $option in - recover) - new_recover - ;; - uninstall) - uninstall - ;; - backup) - backup - ;; +function cmd_check() { + print_header "Checking Setup Status" + + local missing=0 + + # Check Homebrew + echo -n "Homebrew: " + if command_exists brew; then + print_success "installed ($(brew --version | head -1))" + else + print_error "not found" + ((missing++)) + fi + + # Check zsh + echo -n "Zsh: " + if command_exists zsh; then + print_success "installed ($(zsh --version))" + else + print_error "not found" + ((missing++)) + fi + + # Check Neovim + echo -n "Neovim: " + if command_exists nvim; then + print_success "installed ($(nvim --version | head -1))" + else + print_error "not found" + ((missing++)) + fi + + # Check tmux + echo -n "Tmux: " + if command_exists tmux; then + print_success "installed ($(tmux -V))" + else + print_error "not found" + ((missing++)) + fi + + # Check antigen + echo -n "Antigen: " + if [ -f "$HOME/.antigen/antigen.zsh" ]; then + print_success "installed" + else + print_error "not found" + ((missing++)) + fi + + # Check symlinks + echo "" + echo "Symlinks:" + for i in "${FILES[@]}"; do + echo -n " $i: " + if [ -L "$HOME_DIR/$i" ]; then + local target=$(readlink "$HOME_DIR/$i") + if [[ "$target" == *"$WORKING_DIR"* ]]; then + print_success "linked to dotfiles" + else + print_warning "linked elsewhere: $target" + fi + elif [ -f "$HOME_DIR/$i" ]; then + print_warning "exists but not linked" + else + print_error "not found" + fi + done + + # Check git config + echo "" + echo "Git Config:" + local git_name=$(git config --file "$HOME_DIR/.gitconfig" user.name 2>/dev/null || echo "") + local git_email=$(git config --file "$HOME_DIR/.gitconfig" user.email 2>/dev/null || echo "") + + echo -n " user.name: " + if [ "$git_name" == "YOUR_NAME" ] || [ -z "$git_name" ]; then + print_warning "not configured" + else + print_success "$git_name" + fi + + echo -n " user.email: " + if [ "$git_email" == "YOUR_EMAIL" ] || [ -z "$git_email" ]; then + print_warning "not configured" + else + print_success "$git_email" + fi + + echo "" + if [ $missing -eq 0 ]; then + print_success "All checks passed!" + else + print_warning "$missing items need attention" + fi +} + +# ============================================================================= +# Main +# ============================================================================= + +# Parse command +COMMAND="${1:-help}" + +case "$COMMAND" in + init) + cmd_init + ;; + install) + cmd_install + ;; + backup) + cmd_backup + ;; + sync) + cmd_sync + ;; + full-recover) + cmd_full_recover + ;; + check) + cmd_check + ;; + help|--help|-h) + cmd_help + ;; + *) + print_error "Unknown command: $COMMAND" + echo "Run './setup.sh help' for usage" + exit 1 + ;; esac exit 0