#!/usr/bin/env python3 """github-publish-sanitize.py — 對匯出樹做內容級改寫,讓公開版真的能被別人使用。 由 publish-github.sh 自動呼叫(步驟 3.5),參數=匯出樹的暫存目錄。 為什麼需要(leo 2026-07-21): 「我不想給它 Gitea 網址,因為我們已經計劃要把 gitea 改用 CF 版本了。」 install.sh / update.sh 內建的抓取來源指向我們的 **private Gitea**: - 別人抓不到(private)→ 裝不起來 - 且該網址即將換成 CF 版 → 公開出去的網址馬上失效 → 公開版一律改指 GitHub raw。私有工作區維持 Gitea 不動, 兩邊不必手工維護兩份(改寫發生在發佈當下)。 """ import pathlib import re import sys GITEA_BASE = "https://git.uncle6.me/Leo/system-dev-template/raw/branch/main" GITHUB_BASE = "https://raw.githubusercontent.com/youlinhsieh/system-dev-template/main" # 純文字取代(來源網址)。放這裡的規則要「冪等」——重跑不會壞。 REPLACEMENTS = [ (GITEA_BASE, GITHUB_BASE), # 保險:任何殘留的 Gitea 主機名(例如註解、文件裡的說明連結) ("https://git.uncle6.me/Leo/system-dev-template", "https://github.com/youlinhsieh/system-dev-template"), # 🔴 舊 GitHub 帳號 uncle6me-web **已被 suspend**:README 的安裝指令仍指向它 # → 別人照著跑會抓不到(2026-07-20 已在 update.sh 撞過同一顆雷)。 ("raw.githubusercontent.com/uncle6me-web/", "raw.githubusercontent.com/youlinhsieh/"), ("github.com/uncle6me-web/", "github.com/youlinhsieh/"), # 文件註解裡拿舊帳號當範例 → 對外改通用佔位符(別人看到我們的帳號名沒意義) ("(例:uncle6me-web)", "(例:your-github-account)"), ("(e.g. uncle6me-web)", "(e.g. your-github-account)"), ] TEXT_SUFFIXES = {".sh", ".md", ".json", ".py", ".yaml", ".yml", ".txt"} def main(root_arg: str) -> int: root = pathlib.Path(root_arg) if not root.is_dir(): print(f"❌ sanitize:找不到匯出樹 {root}", file=sys.stderr) return 1 changed = [] for path in root.rglob("*"): if not path.is_file() or path.suffix not in TEXT_SUFFIXES: continue try: original = path.read_text(encoding="utf-8") except (UnicodeDecodeError, OSError): continue text = original for old, new in REPLACEMENTS: text = text.replace(old, new) if text != original: path.write_text(text, encoding="utf-8") changed.append(str(path.relative_to(root))) if changed: print(f"🧼 sanitize:改寫來源網址 → GitHub({len(changed)} 檔)") for c in changed: print(f" {c}") else: print("🧼 sanitize:無需改寫") # 驗證:公開樹不得殘留「別人抓不到的來源」——漏了就是別人裝不起來。 # ① git.uncle6.me = 我們的 private Gitea(且即將換 CF 版) # ② uncle6me-web = 已被 suspend 的舊 GitHub 帳號 BAD_HOSTS = ("git.uncle6.me", "uncle6me-web") leaked = [] for path in root.rglob("*"): if not path.is_file() or path.suffix not in TEXT_SUFFIXES: continue try: content = path.read_text(encoding="utf-8") if any(bad in content for bad in BAD_HOSTS): leaked.append(str(path.relative_to(root))) except (UnicodeDecodeError, OSError): continue if leaked: print("❌ sanitize:公開樹仍殘留失效來源(Gitea/suspend 帳號),中止發佈:", file=sys.stderr) for f in leaked: print(f" {f}", file=sys.stderr) return 1 return 0 if __name__ == "__main__": sys.exit(main(sys.argv[1] if len(sys.argv) > 1 else "."))