diff --git a/tools/patrol.sh b/tools/patrol.sh index a789a88..9ba9ef3 100755 --- a/tools/patrol.sh +++ b/tools/patrol.sh @@ -237,6 +237,7 @@ usage() { usage: patrol.sh collect [--out 目錄] [--trigger 排程|事件|手動] patrol.sh finish --round 輪次代號 [--out 目錄] [--dry-run] patrol.sh abort --round 輪次代號 [--out 目錄] + patrol.sh rebuild --old 舊頁檔 [--out 目錄] EOF exit 6 } @@ -1078,7 +1079,7 @@ compose() { CMD="${1:-}" [ -n "$CMD" ] || usage shift -case "$CMD" in collect|finish|abort) ;; *) usage ;; esac +case "$CMD" in collect|finish|abort|rebuild) ;; *) usage ;; esac OUT='' while [ "$#" -gt 0 ]; do @@ -1087,9 +1088,11 @@ while [ "$#" -gt 0 ]; do --trigger) [ "$#" -ge 2 ] || usage; TRIGGER="$2"; shift 2 ;; --round) [ "$#" -ge 2 ] || usage; ROUND="$2"; shift 2 ;; --dry-run) DRYRUN=1; shift ;; + --old) [ "$#" -ge 2 ] || usage; OLD_PAGE="$2"; shift 2 ;; *) usage ;; esac done +OLD_PAGE="${OLD_PAGE:-}" [ -n "$OUT" ] && RD="$OUT" case "$CMD" in @@ -1204,4 +1207,54 @@ case "$CMD" in printf 'heartbeat=not-written\n' lock_release exit 0 ;; + + # 拿舊頁重組出要寫回去的整頁。三塊的接法固定,所以由這一支做完,呼叫端只要「讀回舊頁、 + # 叫這一支、把結果寫回去」三步。 + # + # 為什麼要有這個子命令:接三塊這件事本來留給呼叫端,而呼叫端是一個代理人,於是它每一輪 + # 臨場挑工具——實測某一輪挑了 awk,兩次都被權限擋掉;那一輪有人在場所以它改用別的方式繞 + # 過去了,並且自己指出無人值守那一輪遇到同一個擋法會直接卡住,而鎖在第一步就取走了。 + # 更根本的是暫存目錄實測累積了 124 個檔案,名字是 newpage.md、new-page.md、new_page.md、 + # page-new.md 這種——同一件事每輪重做一次,每輪換一組檔名。規格說那裡只該有五個檔案。 + # 接法寫死在這裡之後,那一步不再需要任何通用文字工具,也就沒有東西可以被擋。 + rebuild) + [ -n "$OLD_PAGE" ] || usage + [ -f "$OLD_PAGE" ] || die 6 "舊頁檔讀不到:$OLD_PAGE。這一支不自己讀 wiki,舊頁要由呼叫端先取下來。" + for _f in "$RD/latest.md" "$RD/summary.md"; do + [ -f "$_f" ] || die 6 "$_f 不在。rebuild 要接的是同一輪 collect 產出的那幾塊,先跑 collect。" + done + _out="$RD/rebuilt.md" + # 舊頁那一塊「本頁基本資料」原樣留著,從它的標題到「最新一輪」前一行為止。整頁沒有 + # 「最新一輪」那個標題時視為舊格式:基本資料留著、堆疊的各輪小節丟掉,摘要表從本輪開始。 + if grep -q '^## 最新一輪' "$OLD_PAGE" 2>/dev/null; then + awk '/^## 最新一輪/{exit} {print}' "$OLD_PAGE" >"$RD/rb-head.md" 2>/dev/null || die 5 "暫存檔寫不進去:$RD/rb-head.md。" + printf 'old_format=no\n' + else + awk '/^## /{n++} n<=1{print}' "$OLD_PAGE" >"$RD/rb-head.md" 2>/dev/null || die 5 "暫存檔寫不進去:$RD/rb-head.md。" + printf 'old_format=yes converted=1\n' + fi + # 舊表的資料列照原順序留在本輪那一列底下,整張表截到 24 列。摘要那一塊已經含標題、 + # 表頭與本輪那一列,所以這裡只補舊列。 + awk '/^## 近 24 輪摘要/{f=1;next} f && /^\| 2/{print}' "$OLD_PAGE" >"$RD/rb-rows.md" 2>/dev/null || die 5 "暫存檔寫不進去:$RD/rb-rows.md。" + _new_rows=$(awk '/^\| 2/{n++} END{print n+0}' "$RD/summary.md") + _keep=$((24 - _new_rows)) + [ "$_keep" -lt 0 ] && _keep=0 + # 基本資料那一塊逐字照抄,連尾端空行都不動——技能本文寫的是「逐字保留」,剝掉再補一個 + # 雖然內容沒少,那句話就變成假的了。只在它沒有以空行收尾時補一個分隔,免得下一塊的 + # 標題黏在表格最後一列後面。 + _tail=$(awk 'END{print (NF==0 ? "blank" : "text")}' "$RD/rb-head.md" 2>/dev/null) + { + cat "$RD/rb-head.md" + [ "$_tail" = "blank" ] || printf '\n' + cat "$RD/latest.md" + printf '\n' + cat "$RD/summary.md" + [ "$_keep" -gt 0 ] && head -n "$_keep" "$RD/rb-rows.md" + } >"$_out" 2>/dev/null || die 5 "暫存檔寫不進去:$_out。" + printf 'rebuilt_file=%s\n' "$_out" + printf 'blocks=%s summary_rows=%s old_rows_kept=%s\n' \ + "$(grep -c '^## ' "$_out")" \ + "$(awk '/^## 近 24 輪摘要/{f=1;next} f && /^\| 2/{n++} END{print n+0}' "$_out")" \ + "$([ "$_keep" -gt 0 ] && awk 'END{print NR+0}' "$RD/rb-rows.md" | awk -v k="$_keep" '{print ($1