diff --git a/scripts/install.sh b/scripts/install.sh index c66b0e5..8ae8cb6 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -26,9 +26,29 @@ t() { if [ "$IS_ZH" = "yes" ]; then printf '%s\n' "$1"; else printf '%s\n' "$2"; # tn = 不換行版(給 prompt 用) tn() { if [ "$IS_ZH" = "yes" ]; then printf '%s' "$1"; else printf '%s' "$2"; fi; } -REPO_URL="https://raw.githubusercontent.com/uncle6me-web/system-dev-template/main/template" +# 來源預設=公開 GitHub(leo 2026-07-21:「要發佈的正稿,從頭就不要用奇怪的網址, +# 以免改來改去」)。舊的 uncle6me-web 帳號已被 suspend(讀 404)=自動更新靜默失效, +# 這顆雷已在 system-dev-template 本體修過(正解=改指 youlinhsieh 這個公開帳號), +# 這裡只是把同一個修法補進 Arcrun 這份沒跟到的 copy。 +# 內部要指私有草稿源時用環境變數覆寫,不改檔: +# TEMPLATE_SOURCE=https://<私有 raw base> bash scripts/install.sh +TEMPLATE_SOURCE="${TEMPLATE_SOURCE:-https://raw.githubusercontent.com/youlinhsieh/system-dev-template/main}" +REPO_URL="$TEMPLATE_SOURCE/template" CREATED=() SKIPPED=() +FAILED=() + +# 404 頁面常常「非空」(GitHub raw 對不存在的路徑回 "404: Not Found"), +# 只判斷 [ -s file ] 會把錯誤頁內容當成檔案寫進去且完全不報錯(template issue #13 撞過的雷)。 +# 這裡量身做一個輕量判斷:檔案很短又長得像錯誤訊息 → 當失敗。 +looks_like_error_page() { + local f="$1" + [ -s "$f" ] || return 0 + if [ "$(wc -l < "$f" | tr -d ' ')" -le 2 ] && head -c 200 "$f" | grep -qiE '40[0-9]|not found|/dev/null && ! looks_like_error_page "$dest"; then + CREATED+=("$dest") + else + rm -f "$dest" + FAILED+=("$dest $(tn "(來源抓不到:$src)" "(source unreachable: $src)")") + fi else SKIPPED+=("$dest $(tn '(已存在,跳過)' '(already exists, skipped)')") fi @@ -332,6 +356,16 @@ if [ ${#SKIPPED[@]} -gt 0 ]; then for item in "${SKIPPED[@]}"; do echo " - $item"; done fi +# 來源抓不到要出聲,不能安靜吞掉——404 內容不會被寫進檔案(已在 download_if_missing 擋掉), +# 但使用者必須知道「這幾個檔沒裝到」,不然會誤以為裝完整了。 +if [ ${#FAILED[@]} -gt 0 ]; then + echo "" + t "❌ 抓取失敗(來源不可達,未寫入任何檔案):" "❌ Fetch failed (source unreachable, no file was written):" + for item in "${FAILED[@]}"; do echo " x $item"; done + t " 請檢查網路,或用 TEMPLATE_SOURCE=<其他來源> 重跑。" \ + " Check your network, or rerun with TEMPLATE_SOURCE=." +fi + echo "" echo "─────────────────────────────────" @@ -429,3 +463,8 @@ fi t " GitHub issue:CC 可直接 /issue-handle 讀回自己 repo 的 issue(禁自動輪詢)" \ " GitHub issues: CC can use /issue-handle to read issues from its own repo (no auto-polling)" echo "" + +# 有任何來源抓取失敗 → 用非零 exit code 出聲,不能靜靜地當「裝完了」收工。 +if [ ${#FAILED[@]} -gt 0 ]; then + exit 1 +fi diff --git a/scripts/update.sh b/scripts/update.sh index 4961c2b..0c806e9 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -23,18 +23,43 @@ esac t() { if [ "$IS_ZH" = "yes" ]; then printf '%s\n' "$1"; else printf '%s\n' "$2"; fi; } tn() { if [ "$IS_ZH" = "yes" ]; then printf '%s' "$1"; else printf '%s' "$2"; fi; } -REPO_RAW="https://raw.githubusercontent.com/uncle6me-web/system-dev-template/main" +# 來源預設=公開 GitHub(leo 2026-07-21:「要發佈的正稿,從頭就不要用奇怪的網址, +# 以免改來改去」)。舊的 uncle6me-web 帳號已被 suspend(讀 404)=自動更新靜默失效, +# 這顆雷已在 system-dev-template 本體修過(正解=改指 youlinhsieh 這個公開帳號), +# 這裡只是把同一個修法補進 Arcrun 這份沒跟到的 copy。 +# 內部要指私有草稿源時用環境變數覆寫,不改檔: +# TEMPLATE_SOURCE=https://<私有 raw base> bash scripts/update.sh +REPO_RAW="${TEMPLATE_SOURCE:-https://raw.githubusercontent.com/youlinhsieh/system-dev-template/main}" TEMPLATE_URL="$REPO_RAW/template" UPDATED=() KEPT=() NEW=() TEMPLATED=() +FAILED=() + +# 404 頁面常常「非空」(GitHub raw 對不存在的路徑回 "404: Not Found"), +# 只判斷 [ -s file ] 會把錯誤頁內容當成檔案寫進去且完全不報錯(template issue #13 撞過的雷)。 +looks_like_error_page() { + local f="$1" + [ -s "$f" ] || return 0 + if [ "$(wc -l < "$f" | tr -d ' ')" -le 2 ] && head -c 200 "$f" | grep -qiE '40[0-9]|not found|/dev/null | tr -d '[:space:]' || echo '')" +# 容錯:curl 對 404 會把「404: Not Found」當內容輸出(非空),舊版直接把它寫進 REMOTE_VER +# 拿去跟本機版本比對,比對邏輯不會報錯、只會靜靜判斷「版本不同」或誤判「已最新」。 +# 這裡驗證必須像版號(X.Y.Z),否則一律視為取不到。 +case "$REMOTE_VER" in + [0-9]*.[0-9]*.[0-9]*) : ;; # 形如 1.9.0 → 合法 + *) REMOTE_VER="" ;; # 404 / HTML 錯誤頁 / 其他 → 當作沒抓到 +esac echo "" echo "🔄 system-dev-template updater" @@ -64,7 +89,7 @@ update_file() { local dest="$1" src="$2" mkdir -p "$(dirname "$dest")" if [ -f "$dest" ]; then - if curl -sSL "$src" -o "$dest.tmp" 2>/dev/null && [ -s "$dest.tmp" ]; then + if curl -sSL "$src" -o "$dest.tmp" 2>/dev/null && ! looks_like_error_page "$dest.tmp"; then if cmp -s "$dest" "$dest.tmp"; then rm -f "$dest.tmp" # 內容相同,不算更新 else @@ -73,13 +98,15 @@ update_file() { fi else rm -f "$dest.tmp" + FAILED+=("$dest") t " ⚠️ 抓取失敗,保留原檔:$dest" " ⚠️ Download failed, keeping the original: $dest" fi else - if curl -sSL "$src" -o "$dest" 2>/dev/null && [ -s "$dest" ]; then + if curl -sSL "$src" -o "$dest" 2>/dev/null && ! looks_like_error_page "$dest"; then NEW+=("$dest") # 新功能:舊版沒有的檔 else rm -f "$dest" + FAILED+=("$dest") t " ⚠️ 抓取失敗:$dest" " ⚠️ Download failed: $dest" fi fi @@ -98,7 +125,7 @@ keep_with_template() { if [ -f "$dest" ]; then KEPT+=("$dest") local tmpl="${dest%.sh}.template.sh" - if curl -sSL "$src" -o "$tmpl.tmp" 2>/dev/null && [ -s "$tmpl.tmp" ]; then + if curl -sSL "$src" -o "$tmpl.tmp" 2>/dev/null && ! looks_like_error_page "$tmpl.tmp"; then if [ -f "$tmpl" ] && cmp -s "$tmpl" "$tmpl.tmp"; then rm -f "$tmpl.tmp" # 模板版沒變,不重複提示 else @@ -227,8 +254,22 @@ if [ -f ".claude/settings.json" ]; then fi fi +# 有任何檔案抓取失敗要出聲,不能安靜吞掉(404 內容已被 looks_like_error_page 擋掉、 +# 不會污染既有檔案,但使用者必須知道「這幾個檔沒更新到」)。 +if [ ${#FAILED[@]} -gt 0 ]; then + echo "" + t "❌ 抓取失敗(來源不可達,原檔已保留不動):" "❌ Fetch failed (source unreachable, original files kept untouched):" + for f in "${FAILED[@]}"; do echo " x $f"; done + t " 請檢查網路,或用 TEMPLATE_SOURCE=<其他來源> 重跑。" \ + " Check your network, or rerun with TEMPLATE_SOURCE=." +fi + echo "" t "🚀 更新完成:${LOCAL_VER} → ${REMOTE_VER}" "🚀 Update complete: ${LOCAL_VER} → ${REMOTE_VER}" t " 下次更新直接跑:bash scripts/update.sh" " Next time, just run: bash scripts/update.sh" t " 改了什麼看:CHANGELOG.md" " See what changed: CHANGELOG.md" echo "" + +if [ ${#FAILED[@]} -gt 0 ]; then + exit 1 +fi