| import os |
| import subprocess |
| from huggingface_hub import snapshot_download |
|
|
| |
| SENSITIVE_EXCLUDES = [ |
| "auth.json", |
| ".sandbox-secrets/**", |
| ] |
|
|
| |
| HEAVY_EXCLUDES = [ |
| "plugins/cache/**", |
| "projects/**", |
| "shell-snapshots/**", |
| "statsig/**", |
| "todos/**", |
| "log/**", |
| "tmp/**", |
| "sessions/**", |
| ] |
|
|
| def run_rsync(src: str, dst: str, excludes=None, delete=True): |
| excludes = excludes or [] |
| os.makedirs(dst, exist_ok=True) |
| cmd = ["rsync", "-a"] |
| if delete: |
| cmd.append("--delete") |
| for ex in excludes: |
| cmd += ["--exclude", ex] |
| cmd += [src.rstrip("/") + "/", dst.rstrip("/") + "/"] |
| p = subprocess.run(cmd) |
| |
| if p.returncode not in (0, 24): |
| raise RuntimeError(f"rsync failed with code {p.returncode}") |
|
|
| def main(): |
| repo = os.getenv("DOTFILES_DATASET_REPO", "").strip() |
| if not repo: |
| print("DOTFILES_DATASET_REPO 未设置,跳过 dotfiles 同步") |
| return |
|
|
| token = os.getenv("HF_TOKEN") or os.getenv("HUGGINGFACE_HUB_TOKEN") |
| if not token: |
| print("HF_TOKEN 未设置(Private Dataset 必需),跳过 dotfiles 同步") |
| return |
|
|
| |
| allow = [ |
| "ubuntu/home/.claude/**", |
| "ubuntu/home/.codex/**", |
| "dotfiles/home/.claude/**", |
| "dotfiles/home/.codex/**", |
| "ubuntu/project/**", |
| "dotfiles/project/**", |
| "project/**", |
| ] |
|
|
| local_dir = snapshot_download( |
| repo_id=repo, |
| repo_type="dataset", |
| allow_patterns=allow, |
| token=token, |
| ) |
|
|
| |
| cand_home = [ |
| os.path.join(local_dir, "ubuntu", "home"), |
| os.path.join(local_dir, "dotfiles", "home"), |
| os.path.join(local_dir, "home"), |
| ] |
| home_root = next((p for p in cand_home if os.path.isdir(p)), None) |
|
|
| if not home_root: |
| print("未找到 home 根目录(例如 ubuntu/home)") |
| return |
|
|
| claude_src = os.path.join(home_root, ".claude") |
| codex_src = os.path.join(home_root, ".codex") |
|
|
| |
| if os.path.isdir(claude_src): |
| print(f"Sync ~/.claude: {claude_src} -> /home/user/.claude") |
| run_rsync(claude_src, "/home/user/.claude", excludes=HEAVY_EXCLUDES, delete=True) |
| else: |
| print("未找到 .claude 目录,跳过") |
|
|
| if os.path.isdir(codex_src): |
| excludes = SENSITIVE_EXCLUDES + HEAVY_EXCLUDES |
| print(f"Sync ~/.codex: {codex_src} -> /home/user/.codex (exclude auth/secrets)") |
| run_rsync(codex_src, "/home/user/.codex", excludes=excludes, delete=True) |
| else: |
| print("未找到 .codex 目录,跳过") |
|
|
| |
| cand_proj = [ |
| os.path.join(local_dir, "ubuntu", "project"), |
| os.path.join(local_dir, "dotfiles", "project"), |
| os.path.join(local_dir, "project"), |
| ] |
| proj_src = next((p for p in cand_proj if os.path.isdir(p)), None) |
| if proj_src: |
| print(f"Sync project: {proj_src} -> /home/user/work") |
| run_rsync(proj_src, "/home/user/work", excludes=[], delete=True) |
| else: |
| print("未找到 PROJECT dotfiles 源目录(可忽略)") |
|
|
| print("Dotfiles sync done.") |
|
|
| if __name__ == "__main__": |
| main() |