feat(link): 連結一律寫成 [文字](絕對網址),寫入前先驗證連得到
取消 [[頁名]] 與 [[顯示文字|頁名]] 兩種同 wiki 寫法,不再分「同存取庫」與 「跨存取庫」兩條規則。那種寫法只在自己那個 wiki 內解析,寫錯不報錯,畫面上 看起來像普通文字或死連結,巡不到也修不了。 連結寫進頁面前先過 jsc-gitea 的 link-check.sh,結束碼 0 才寫。驗證一律走 API, 不看網頁狀態碼:私有存取庫的網頁網址對未登入請求一律回 404,拿狀態碼判會把 好連結判成壞的。認證失敗回 7,與死連結的 1 分開,免得金鑰一過期就把還在的頁 整批判死。
This commit is contained in:
+84
-11
@@ -25,12 +25,22 @@
|
||||
# --target-branch NAME 目標分支(省略時等同來源分支)
|
||||
#
|
||||
# 輸出: 繁體中文 markdown 階段回報,直接貼給使用者。
|
||||
# 結束碼: 0=回報完整 1=有警告(缺工作日誌,內容已暫存) 2=用法錯誤 3=相依工具找不到
|
||||
# 結束碼: 0=回報完整 1=有警告(缺工作日誌或有連不到的連結) 2=用法錯誤 3=相依工具找不到
|
||||
#
|
||||
# 連結驗證:
|
||||
# 本檔輸出的是一張給人點的 wiki 連結清單,所以印之前先把這些網址交給
|
||||
# jsc-gitea/tools/link-check.sh 驗一次,逐列標出「通過、連不到、未驗證」。
|
||||
# 驗證走 API 不看網頁狀態碼:私有存取庫的網頁網址對沒帶金鑰的請求一律回 404。
|
||||
# 這裡的驗證只註記、不阻擋——頁面在呼叫本檔之前就寫完了,擋下去只會讓使用者連回報都拿不到。
|
||||
# 呼叫端該做的事在寫入之前:每個要放進頁面的連結先過 link-check.sh,結束碼 0 才寫入,
|
||||
# 有 DEAD 就不寫並回報。本檔是最後一道複查,不是那一道關卡的替代品。
|
||||
#
|
||||
# 陷阱:
|
||||
# - 結束碼 1 是警告,不是阻擋:階段的工作已經做完了,擋下去只會讓使用者拿不到回報。
|
||||
# - 缺工作日誌時一定要給 --pending-file 與 --log-hash,否則內容留在對話裡,換一個工作階段就沒了。
|
||||
# - 模型閘門那一列只轉述 sdlc-gate.sh report 的結果,不自己判定標籤。
|
||||
# - 金鑰失效(link-check.sh 結束碼 7)標成「未驗證」,不標成「連不到」:把金鑰問題寫成死連結,
|
||||
# 下一手就會照著去刪還活著的頁。
|
||||
set -u
|
||||
|
||||
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
@@ -83,6 +93,13 @@ sdlc_gate_sh() {
|
||||
resolve_dep hooks hooks/sdlc-gate.sh
|
||||
}
|
||||
|
||||
link_check_sh() {
|
||||
if [ -n "${JSC_GITEA_TOOLS:-}" ] && [ -f "$JSC_GITEA_TOOLS/link-check.sh" ]; then
|
||||
printf '%s\n' "$JSC_GITEA_TOOLS/link-check.sh"; return 0
|
||||
fi
|
||||
resolve_dep gitea tools/link-check.sh
|
||||
}
|
||||
|
||||
stage="${1:-}"
|
||||
case "$stage" in
|
||||
plan|analyze|implement|maintain) shift ;;
|
||||
@@ -250,6 +267,56 @@ EOF
|
||||
)
|
||||
fi
|
||||
|
||||
# ---- 連結驗證 ----
|
||||
# 先把頁名全部解成網址收在 page_rows,再一次餵給 link-check.sh:一頁一次呼叫是白付的往返成本。
|
||||
TAB=$(printf '\t')
|
||||
page_rows=''
|
||||
url_list=''
|
||||
if [ -n "$pages" ]; then
|
||||
page_rows=$(printf '%s' "$pages" | while IFS= read -r item; do
|
||||
[ -n "$item" ] || continue
|
||||
type=${item%%:*}
|
||||
page=${item#*:}
|
||||
url=$(page_url "$type" "$page" || true)
|
||||
printf '%s%s%s\n' "$page" "$TAB" "${url:-}"
|
||||
done)
|
||||
url_list=$(printf '%s\n' "$page_rows" | awk -F"$TAB" 'NF>1 && $2!=""{print $2}')
|
||||
fi
|
||||
[ -n "$worklog_cell" ] && [ -n "${wl_url:-}" ] && url_list=$(printf '%s\n%s' "$url_list" "$wl_url")
|
||||
|
||||
LINKCHECK=''
|
||||
link_note=''
|
||||
dead_urls=''
|
||||
skip_urls=''
|
||||
if [ -n "$url_list" ]; then
|
||||
LINKCHECK=$(link_check_sh || true)
|
||||
if [ -z "$LINKCHECK" ]; then
|
||||
link_note='找不到 jsc-gitea/tools/link-check.sh,這次的連結沒有驗證過。'
|
||||
else
|
||||
lc_out=$(printf '%s\n' "$url_list" | "$LINKCHECK" 2>/dev/null)
|
||||
lc_rc=$?
|
||||
case "$lc_rc" in
|
||||
0|1)
|
||||
dead_urls=$(printf '%s\n' "$lc_out" | awk -F"$TAB" '$1=="DEAD"{print $2}')
|
||||
# SKIP 是「沒有可查的端點」,不影響 link-check.sh 的結束碼,所以分開標、不進警告。
|
||||
skip_urls=$(printf '%s\n' "$lc_out" | awk -F"$TAB" '$1=="SKIP"{print $2}')
|
||||
;;
|
||||
3) link_note='GITEA_HOST 沒設定,連結沒有驗證過;設好變數再跑一次。' ;;
|
||||
7) link_note='Gitea 金鑰失效(401、403),連結沒有驗證過。這不代表連結是死的,先處理金鑰。' ;;
|
||||
*) link_note="連結驗證沒跑完(link-check.sh 結束碼 $lc_rc)。" ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
[ -n "$dead_urls" ] && warn=1
|
||||
|
||||
verify_cell() { # $1=網址 -> 驗證結果欄
|
||||
[ -n "$1" ] || { printf '未驗證'; return 0; }
|
||||
if [ -z "$LINKCHECK" ] || [ -n "$link_note" ]; then printf '未驗證'; return 0; fi
|
||||
if printf '%s\n' "$dead_urls" | grep -Fxq -- "$1"; then printf '**連不到**'
|
||||
elif printf '%s\n' "$skip_urls" | grep -Fxq -- "$1"; then printf '無可查端點'
|
||||
else printf '通過'; fi
|
||||
}
|
||||
|
||||
# ---- 輸出 ----
|
||||
printf '## 階段回報:%s\n\n' "$(stage_zh "$stage")"
|
||||
printf '| 項目 | 內容 |\n| --- | --- |\n'
|
||||
@@ -257,23 +324,29 @@ printf '| 模型能力標籤 | %s |\n' "$gate_result"
|
||||
printf '| 工作日誌 | %s |\n' "$worklog_cell"
|
||||
[ -n "$branch_rows" ] && printf '%s\n' "$branch_rows"
|
||||
printf '\n### 寫入的 wiki 頁\n\n'
|
||||
if [ -n "$pages" ]; then
|
||||
printf '| 頁面 | 連結 |\n| --- | --- |\n'
|
||||
printf '%s' "$pages" | while IFS= read -r item; do
|
||||
[ -n "$item" ] || continue
|
||||
type=${item%%:*}
|
||||
page=${item#*:}
|
||||
url=$(page_url "$type" "$page" || true)
|
||||
printf '| %s | %s |\n' "$page" "${url:-(取不到網址)}"
|
||||
if [ -n "$page_rows" ]; then
|
||||
printf '| 頁面 | 連結 | 連結驗證 |\n| --- | --- | --- |\n'
|
||||
printf '%s\n' "$page_rows" | while IFS="$TAB" read -r page url; do
|
||||
[ -n "$page" ] || continue
|
||||
url=${url:-}
|
||||
printf '| %s | %s | %s |\n' "$page" "${url:-(取不到網址)}" "$(verify_cell "$url")"
|
||||
done
|
||||
else
|
||||
printf '本階段沒有寫入任何 wiki 頁。\n'
|
||||
fi
|
||||
|
||||
if [ "$warn" -eq 1 ]; then
|
||||
if [ "$warn" -eq 1 ] || [ -n "$link_note" ]; then
|
||||
printf '\n### 警告\n\n'
|
||||
[ -n "$worklog" ] || printf -- '- 這個階段還沒有寫入工作日誌,請自行檢查是不是漏了。%s\n' "$pending_note"
|
||||
[ "$stage" = implement ] && [ -z "$pr_url" ] && printf -- '- 目標分支還沒有 PR,工作尚未交出去。\n'
|
||||
exit 1
|
||||
[ -n "$link_note" ] && printf -- '- %s\n' "$link_note"
|
||||
if [ -n "$dead_urls" ]; then
|
||||
printf -- '- 下列連結連不到,請修好再貼給別人:\n'
|
||||
printf '%s\n' "$dead_urls" | while IFS= read -r dead; do
|
||||
[ -n "$dead" ] || continue
|
||||
printf -- ' - %s\n' "$dead"
|
||||
done
|
||||
fi
|
||||
[ "$warn" -eq 1 ] && exit 1
|
||||
fi
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user