Files
meta/tools/sync-domains.sh
T
jiantw83andClaude Opus 5 9ab5b42864 fix(meta): 補齊稽核缺失並修掉護欄失效
What:依 jsc-meta:skill-check 的稽核結果修正技能與工具——補上每個步驟的可檢核完成條件、
把留在內文的標準輸入輸出流程下放 tools/、修正查表與退碼路由造成的誤判。

Why:稽核發現這些缺失會讓技能在實際執行時走錯分支或靜默通過。
完成條件缺漏是最常被違反的一項;退碼誤判與查表錯誤則會讓良性狀況被當成失敗。

How:逐項對照 references/guidelines.md 的審核檢查清單修正,新增的工具都有
documented exit codes,並以真實執行驗證每條路徑。

Who:jsc-meta:skill-check 例行稽核(2026-08-25)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 14:58:54 +08:00

90 lines
4.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env sh
# sync-domains.sh — 依 Gitea 正本 marketplace 把所有 domain 存取庫同步到本機。
#
# 用法: sync-domains.sh(不吃參數)
#
# 流程:
# 1. 透過 jsc-gitea/tools/gitea.sh 讀正本 marketplace
# (plugins/meta 的 .claude-plugin/marketplace.json),取得權威 domain 清單。
# 2. 本機缺少的 domain:用 gitea.sh clone-url plugins/{domain} 取網址後 clone。
# 3. 本機已有的 domain:git pull。工作區有未提交變更就跳過 pull,只在 stderr 提醒——
# 正在改的 repo 不該被自動 pull 覆蓋。
#
# 根目錄: 預設取本腳本位置的上兩層(meta/tools -> meta -> 根)。
# 用 JSC_PLUGINS_ROOT 覆寫,換機器不必改腳本。
# 存取庫目錄名: 先找 {root}/{domain},再找 {root}/jsc-{domain};都沒有才 clone 成 {root}/{domain}。
#
# 輸出: 一行一個 domain,格式 {domain}<TAB>{path}(stdout);警告與失敗說明走 stderr。
# 結束碼: 0=正本讀到、每個 domain 都在本機,而且每個既有存取庫都更新到最新
# 1=讀不到正本 marketplace 或找不到 gitea.sh(不輸出任何 domain)
# 2=正本讀到,但有 domain 沒能取得或 clone 失敗(已輸出其餘 domain)
# 3=每個 domain 都在本機,但有存取庫沒更新到最新:工作區脏而跳過 pull,
# 或 pull 失敗。stderr 會逐一列出這些路徑。**exit 0 才代表「全部最新」**;
# 拿 3 當乾淨會讓後續步驟改在落後的檔案上。
# 同時發生時回較嚴重的那個:2 蓋過 3。
# 環境變數: JSC_PLUGINS_ROOT(根目錄)
# JSC_SYNC_DRY_RUN=1(只印出會做什麼,不動檔案;不執行 pull/clone,
# 所以也不因為「沒更新」回 3)
set -u
HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
ROOT="${JSC_PLUGINS_ROOT:-$(CDPATH= cd -- "$HERE/../.." && pwd)}"
DRY="${JSC_SYNC_DRY_RUN:-}"
[ -d "$ROOT" ] || { echo "找不到 plugins 根目錄:$ROOT(可用 JSC_PLUGINS_ROOT 指定)" >&2; exit 1; }
GITEA=""
for g in "$ROOT/gitea/tools/gitea.sh" "$ROOT/jsc-gitea/tools/gitea.sh"; do
[ -f "$g" ] && { GITEA="$g"; break; }
done
[ -n "$GITEA" ] || { echo "找不到 gitea.sh:請先取得 jsc-gitea 存取庫" >&2; exit 1; }
mkt=$(sh "$GITEA" api GET /repos/plugins/meta/raw/.claude-plugin/marketplace.json 2>/dev/null) || mkt=""
[ -n "$mkt" ] || { echo "讀不到正本 marketplace:檢查 GITEA_HOST、GITEA_TOKEN 或 tea 登入" >&2; exit 1; }
DOMAINS=$(printf '%s\n' "$mkt" | sed -n 's/.*"name": *"jsc-\([a-z0-9-]*\)".*/\1/p' | sort -u)
[ -n "$DOMAINS" ] || { echo "正本 marketplace 裡沒有 jsc-{domain} 條目" >&2; exit 1; }
repo_path() { # $1=domain;印出既有路徑(return 0)或預設路徑(return 1)
for d in "$ROOT/$1" "$ROOT/jsc-$1"; do
[ -d "$d" ] && { printf '%s' "$d"; return 0; }
done
printf '%s' "$ROOT/$1"
return 1
}
rc=0
stale=0
for domain in $DOMAINS; do
if path=$(repo_path "$domain"); then
if [ -n "$(git -C "$path" status --porcelain 2>/dev/null)" ]; then
echo "工作區有未提交變更,跳過 pull,未更新到最新:$path" >&2
stale=1
elif [ "$DRY" = 1 ]; then
echo "[dry-run] git -C $path pull --ff-only" >&2
elif ! git -C "$path" pull --quiet --ff-only >/dev/null 2>&1; then
echo "pull 失敗,保留本機版本,未更新到最新:$path" >&2
stale=1
fi
else
url=$(sh "$GITEA" clone-url "plugins/$domain" 2>/dev/null) || url=""
if [ -z "$url" ]; then
echo "取不到 clone 網址,略過:plugins/$domain" >&2
rc=2
continue
fi
if [ "$DRY" = 1 ]; then
echo "[dry-run] git clone $url $path" >&2
elif ! git clone --quiet "$url" "$path" >/dev/null 2>&1; then
echo "clone 失敗:$url" >&2
rc=2
continue
fi
fi
printf '%s\t%s\n' "$domain" "$path"
done
# 2(取不到或 clone 失敗)比 3(沒更新到最新)嚴重,優先回報。
[ "$rc" -eq 0 ] && [ "$stale" -eq 1 ] && rc=3
exit $rc