釋出 wiki 目錄頁的 H2 區塊改寫與連結驗證至 master,版本 0.2.2 升到 0.2.5 #53

Merged
admin merged 12 commits from develop into master 2026-09-03 03:17:28 +00:00
Showing only changes of commit c7c14445e6 - Show all commits
+518
View File
@@ -0,0 +1,518 @@
#!/usr/bin/env sh
# check-contents-format.sh — 驗證目錄頁的區塊轉檔與 upsert 規則。
# 全部走 wiki-contents.sh 的 format 子命令,只讀寫暫存檔,不打任何 API。
# 涵蓋五種舊頁狀態:純表格、已是條列且鍵命中、已是條列且鍵未命中、表格與區塊混合、
# 用範本建新頁。另外驗三件事:表格取不出鍵那一列要擋下來不猜標題、轉檔後重跑同一筆
# 結果一字不變、區塊檔沒帶標題也照樣補上。
# 轉檔取 H2 標題另外驗四種身分欄:連結文字不是頁名、連結文字剛好等於頁名、純文字沒有
# 連結、網址帶百分號編碼。四種都要取到真正的頁名,呼叫端那一筆才會是 updated。
# 引言另外驗五種情形:轉檔且有範本要換成範本那一份、轉檔但沒範本保留舊的、已是條列
# 加了範本也不准動引言、--fresh 建新頁照舊、拿轉檔結果重跑引言不再變動。
# 全部通過印 OK 並 exit 0;任一項不符印出 want 與 got 並 exit 1。
# 結束碼: 0=全部通過,stdout 印 OK
# 1=有一項不符,stderr 印出 {項目}: want=… got=… 之後立刻停住,不續跑其餘項目。
# 只有 0 與 1 兩種;這支不吃參數,也沒有用法錯誤那條路。
set -eu
dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
contents="$dir/wiki-contents.sh"
work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT
fail() {
printf '%s\n' "$1" >&2
exit 1
}
expect_eq() { # got want label
[ "$1" = "$2" ] || fail "$(printf '%s: want=\n%s\ngot=\n%s' "$3" "$2" "$1")"
}
# run <label> <keycol> <key> <fresh|keep> [範本檔] — 讀 $work/old 與 $work/entry,
# 結果留在 $work/new,動作留在 $work/action。
run() {
rc=0
if [ "$4" = fresh ]; then
sh "$contents" format "$2" "$3" "$work/entry" "$work/old" "$work/new" --fresh > "$work/action" || rc=$?
elif [ -n "${5-}" ]; then
sh "$contents" format "$2" "$3" "$work/entry" "$work/old" "$work/new" "$5" > "$work/action" || rc=$?
else
sh "$contents" format "$2" "$3" "$work/entry" "$work/old" "$work/new" > "$work/action" || rc=$?
fi
[ "$rc" -eq 0 ] || fail "$1: want exit=0 got exit=$rc"
}
# ---- 1. 純表格舊頁:整頁轉成區塊,再換掉鍵相同那一筆 ----
cat > "$work/old" <<'EOF'
# 日誌目錄
> 由 `jsc-log:worklog` 維護。一個區塊代表一個日誌頁。
| 日誌頁 | 存取庫 | 條目數 |
| --- | --- | --- |
| [LOG_AAA](https://example.test/wiki/LOG_AAA) | plugins/meta | 3 |
| [LOG_BBB](https://example.test/wiki/LOG_BBB) | plugins/ask | 5 |
EOF
cat > "$work/entry" <<'EOF'
## LOG_BBB
- 日誌頁:[LOG_BBB](https://example.test/wiki/LOG_BBB)
- 存取庫:plugins/ask
- 條目數:9
EOF
run 'table page' 1 LOG_BBB keep
expect_eq "$(cat "$work/action")" updated 'table page action'
expect_eq "$(cat "$work/new")" '# 日誌目錄
> 由 `jsc-log:worklog` 維護。一個區塊代表一個日誌頁。
## LOG_AAA
- 日誌頁:[LOG_AAA](https://example.test/wiki/LOG_AAA)
- 存取庫:plugins/meta
- 條目數:3
## LOG_BBB
- 日誌頁:[LOG_BBB](https://example.test/wiki/LOG_BBB)
- 存取庫:plugins/ask
- 條目數:9' 'table page'
# ---- 2. 已是條列,鍵命中:只換那一塊,別人那一筆一字不動 ----
cat > "$work/old" <<'EOF'
# 日誌目錄
> 引言。
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:3
## LOG_BBB
- 存取庫:plugins/ask
- 條目數:5
EOF
cat > "$work/entry" <<'EOF'
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:7
EOF
run 'list hit' 1 LOG_AAA keep
expect_eq "$(cat "$work/action")" updated 'list hit action'
expect_eq "$(cat "$work/new")" '# 日誌目錄
> 引言。
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:7
## LOG_BBB
- 存取庫:plugins/ask
- 條目數:5' 'list hit'
# ---- 3. 已是條列,鍵未命中:附加到頁尾,前面的區塊照舊 ----
cat > "$work/entry" <<'EOF'
## LOG_CCC
- 存取庫:plugins/git
- 條目數:1
EOF
run 'list miss' 1 LOG_CCC keep
expect_eq "$(cat "$work/action")" added 'list miss action'
expect_eq "$(cat "$work/new")" '# 日誌目錄
> 引言。
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:3
## LOG_BBB
- 存取庫:plugins/ask
- 條目數:5
## LOG_CCC
- 存取庫:plugins/git
- 條目數:1' 'list miss'
# ---- 4. 表格與區塊混合:表格轉出來的區塊接在既有區塊後面 ----
cat > "$work/old" <<'EOF'
# 日誌目錄
> 引言。
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:3
| 日誌頁 | 存取庫 |
| --- | --- |
| [LOG_BBB](https://example.test/wiki/LOG_BBB) | plugins/ask |
EOF
cat > "$work/entry" <<'EOF'
## LOG_CCC
- 日誌頁:[LOG_CCC](https://example.test/wiki/LOG_CCC)
- 存取庫:plugins/git
EOF
run 'mixed page' 1 LOG_CCC keep
expect_eq "$(cat "$work/action")" added 'mixed page action'
expect_eq "$(cat "$work/new")" '# 日誌目錄
> 引言。
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:3
## LOG_BBB
- 日誌頁:[LOG_BBB](https://example.test/wiki/LOG_BBB)
- 存取庫:plugins/ask
## LOG_CCC
- 日誌頁:[LOG_CCC](https://example.test/wiki/LOG_CCC)
- 存取庫:plugins/git' 'mixed page'
# ---- 5. 用範本建新頁:示範區塊與示範表格都要剝掉,只留 H1 與引言 ----
cat > "$work/old" <<'EOF'
# 日誌目錄
> 由 `jsc-log:worklog` 維護。一個區塊代表一個日誌頁。
## {日誌頁頁名}
- 存取庫:{owner}/{repo}
- 條目數:{數字}
EOF
cat > "$work/entry" <<'EOF'
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:3
EOF
run 'fresh page' 1 LOG_AAA fresh
expect_eq "$(cat "$work/action")" added 'fresh page action'
expect_eq "$(cat "$work/new")" '# 日誌目錄
> 由 `jsc-log:worklog` 維護。一個區塊代表一個日誌頁。
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:3' 'fresh page'
# ---- 6. 表格那一列取不出鍵:擋下來回 1,不猜標題 ----
cat > "$work/old" <<'EOF'
# 日誌目錄
> 引言。
| 日誌頁 | 存取庫 |
| --- | --- |
| | plugins/ask |
EOF
cat > "$work/entry" <<'EOF'
## LOG_AAA
- 存取庫:plugins/meta
EOF
if sh "$contents" format 1 LOG_AAA "$work/entry" "$work/old" "$work/new" >/dev/null 2>&1; then
code=0
else
code=$?
fi
[ "$code" -eq 1 ] || fail "keyless table row: want exit=1 got exit=$code"
# ---- 7. 轉檔後重跑同一筆:結果一字不變,程式碼圍欄不被當成表格拆掉 ----
cat > "$work/old" <<'EOF'
# 監控目錄
> 引言。
```mermaid
flowchart LR
A --> B
```
| 監控頁 | 主機 |
| --- | --- |
| `MONITOR_AAA` | myhost |
EOF
cat > "$work/entry" <<'EOF'
## MONITOR_AAA
- 監控頁:[MONITOR_AAA](https://example.test/wiki/MONITOR_AAA)
- 主機:myhost
EOF
run 'converted once' 1 MONITOR_AAA keep
expect_eq "$(cat "$work/action")" updated 'converted once action'
expect_eq "$(cat "$work/new")" '# 監控目錄
> 引言。
```mermaid
flowchart LR
A --> B
```
## MONITOR_AAA
- 監控頁:[MONITOR_AAA](https://example.test/wiki/MONITOR_AAA)
- 主機:myhost' 'converted once'
cp "$work/new" "$work/old"
run 'converted twice' 1 MONITOR_AAA keep
expect_eq "$(cat "$work/action")" updated 'converted twice action'
expect_eq "$(cat "$work/new")" "$(cat "$work/old")" 'converted twice'
# ---- 8. 區塊檔沒帶「## 」標題:照樣補上,鍵就是標題 ----
cat > "$work/old" <<'EOF'
# 監控目錄
> 引言。
EOF
cat > "$work/entry" <<'EOF'
- 主機:myhost
EOF
run 'headless entry' 1 MONITOR_BBB keep
expect_eq "$(cat "$work/action")" added 'headless entry action'
expect_eq "$(cat "$work/new")" '# 監控目錄
> 引言。
## MONITOR_BBB
- 主機:myhost' 'headless entry'
# ---- 9. 連結文字不是頁名:標題取網址最後一段,這一筆算 updated 不是 added ----
# 頁名一律走變數帶進來。這支腳本的每一行「## 開頭」都會被註解掃描器當成註解讀,
# 頁名直接寫在那種行上就會被判成註解夾帶頁面編號。
page='ANALYZE_20260821_100552_104F0709'
cat > "$work/old" <<EOF
# 分析目錄
> 引言。
| 計畫名稱 | 分析頁 | HASH |
| --- | --- | --- |
| 某計畫 | [假 CLI 核心程式庫](https://example.test/knowledges/ANALYZE/wiki/$page) | 104F0709 |
EOF
printf '## %s\n\n- 計畫名稱:某計畫\n' "$page" > "$work/entry"
run 'link text differs' 2 "$page" keep
expect_eq "$(cat "$work/action")" updated 'link text differs action'
expect_eq "$(cat "$work/new")" "$(printf '# 分析目錄\n\n> 引言。\n\n## %s\n\n- 計畫名稱:某計畫' "$page")" 'link text differs'
# ---- 10. 轉檔後重跑同一筆:仍是 updated,不多出區塊 ----
cp "$work/new" "$work/old"
run 'link text differs twice' 2 "$page" keep
expect_eq "$(cat "$work/action")" updated 'link text differs twice action'
expect_eq "$(cat "$work/new")" "$(cat "$work/old")" 'link text differs twice'
# ---- 11. 連結文字剛好等於頁名:結果與連結文字不是頁名時一致 ----
page='PLAN_104F0709'
cat > "$work/old" <<EOF
# 計畫目錄
> 引言。
| 計畫頁 | 狀態 |
| --- | --- |
| [$page](https://example.test/knowledges/PLAN/wiki/$page) | 進行中 |
EOF
printf '## %s\n\n- 狀態:已完成\n' "$page" > "$work/entry"
run 'link text equals page' 1 "$page" keep
expect_eq "$(cat "$work/action")" updated 'link text equals page action'
expect_eq "$(cat "$work/new")" "$(printf '# 計畫目錄\n\n> 引言。\n\n## %s\n\n- 狀態:已完成' "$page")" 'link text equals page'
# ---- 12. 身分欄是純文字沒有連結:標題就是那段文字 ----
page='plugins/meta'
cat > "$work/old" <<EOF
# 維護目錄
> 引言。
| 存取庫 | 維護期限 |
| --- | --- |
| \`$page\` | 2026-12-31 |
EOF
printf '## %s\n\n- 維護期限:2027-06-30\n' "$page" > "$work/entry"
run 'plain identity cell' 1 "$page" keep
expect_eq "$(cat "$work/action")" updated 'plain identity cell action'
expect_eq "$(cat "$work/new")" "$(printf '# 維護目錄\n\n> 引言。\n\n## %s\n\n- 維護期限:2027-06-30' "$page")" 'plain identity cell'
# ---- 13. 網址帶百分號編碼:解碼後取最後一段 ----
page='ANALYZE_中文'
cat > "$work/old" <<'EOF'
# 分析目錄
> 引言。
| 分析頁 | HASH |
| --- | --- |
| [某工作包](https://example.test/knowledges/ANALYZE/wiki/ANALYZE_%E4%B8%AD%E6%96%87) | 104F0709 |
EOF
printf '## %s\n\n- HASH:104F0709\n' "$page" > "$work/entry"
run 'percent encoded url' 1 "$page" keep
expect_eq "$(cat "$work/action")" updated 'percent encoded url action'
expect_eq "$(cat "$work/new")" "$(printf '# 分析目錄\n\n> 引言。\n\n## %s\n\n- HASH:104F0709' "$page")" 'percent encoded url'
# ---- 14. 轉檔且有範本:引言換成範本那一份,紀錄區塊一筆不少、順序照舊 ----
# 範本的示範區塊不得混進來,所以範本檔也放一個示範區塊。
cat > "$work/tpl" <<'EOF'
# 日誌目錄
> 由 `jsc-log:worklog` 維護。每個存取庫一個區塊;頁面上不留 markdown 表格。
>
> 版面:H1 頁名、這段引言,然後一筆紀錄一個 H2 區塊。
## {日誌頁頁名}
- 存取庫:{owner}/{repo}
- 條目數:{數字}
EOF
cat > "$work/old" <<'EOF'
# 日誌目錄
> 由 `jsc-log:worklog` 維護。每個存取庫一列;`{HASH}` 為 SHA-1 前 8 碼。
| 日誌頁 | 存取庫 | 條目數 |
| --- | --- | --- |
| [LOG_AAA](https://example.test/wiki/LOG_AAA) | plugins/meta | 3 |
| [LOG_BBB](https://example.test/wiki/LOG_BBB) | plugins/ask | 5 |
EOF
cat > "$work/entry" <<'EOF'
## LOG_BBB
- 日誌頁:[LOG_BBB](https://example.test/wiki/LOG_BBB)
- 存取庫:plugins/ask
- 條目數:9
EOF
run 'converting with template' 1 LOG_BBB keep "$work/tpl"
expect_eq "$(cat "$work/action")" updated 'converting with template action'
expect_eq "$(cat "$work/new")" '# 日誌目錄
> 由 `jsc-log:worklog` 維護。每個存取庫一個區塊;頁面上不留 markdown 表格。
>
> 版面:H1 頁名、這段引言,然後一筆紀錄一個 H2 區塊。
## LOG_AAA
- 日誌頁:[LOG_AAA](https://example.test/wiki/LOG_AAA)
- 存取庫:plugins/meta
- 條目數:3
## LOG_BBB
- 日誌頁:[LOG_BBB](https://example.test/wiki/LOG_BBB)
- 存取庫:plugins/ask
- 條目數:9' 'converting with template'
expect_eq "$(grep -c '^## ' "$work/new")" 2 'converting with template block count'
# ---- 15. 轉檔但沒給範本:沒有正本可換,引言保留舊的 ----
run 'converting without template' 1 LOG_BBB keep
expect_eq "$(cat "$work/action")" updated 'converting without template action'
expect_eq "$(cat "$work/new")" '# 日誌目錄
> 由 `jsc-log:worklog` 維護。每個存取庫一列;`{HASH}` 為 SHA-1 前 8 碼。
## LOG_AAA
- 日誌頁:[LOG_AAA](https://example.test/wiki/LOG_AAA)
- 存取庫:plugins/meta
- 條目數:3
## LOG_BBB
- 日誌頁:[LOG_BBB](https://example.test/wiki/LOG_BBB)
- 存取庫:plugins/ask
- 條目數:9' 'converting without template'
# ---- 16. 已是條列還給了範本:不必轉檔,引言一字不動 ----
# 這一筆只是更新自己那一塊,沒有理由改掉別人寫的散文。
cat > "$work/old" <<'EOF'
# 日誌目錄
> 這段引言是頁面主人自己寫的,不准被範本蓋掉。
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:3
EOF
cat > "$work/entry" <<'EOF'
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:7
EOF
run 'list page with template' 1 LOG_AAA keep "$work/tpl"
expect_eq "$(cat "$work/action")" updated 'list page with template action'
expect_eq "$(cat "$work/new")" '# 日誌目錄
> 這段引言是頁面主人自己寫的,不准被範本蓋掉。
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:7' 'list page with template'
# ---- 17. --fresh 建新頁:整份用範本,示範區塊剝掉,行為與加了範本參數之前一樣 ----
cp "$work/tpl" "$work/old"
cat > "$work/entry" <<'EOF'
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:3
EOF
run 'fresh page with template intro' 1 LOG_AAA fresh
expect_eq "$(cat "$work/action")" added 'fresh page with template intro action'
expect_eq "$(cat "$work/new")" '# 日誌目錄
> 由 `jsc-log:worklog` 維護。每個存取庫一個區塊;頁面上不留 markdown 表格。
>
> 版面:H1 頁名、這段引言,然後一筆紀錄一個 H2 區塊。
## LOG_AAA
- 存取庫:plugins/meta
- 條目數:3' 'fresh page with template intro'
# ---- 18. 拿轉檔結果再跑同一筆:已經沒有表格,引言不再變動 ----
cat > "$work/old" <<'EOF'
# 日誌目錄
> 由 `jsc-log:worklog` 維護。每個存取庫一列;`{HASH}` 為 SHA-1 前 8 碼。
| 日誌頁 | 存取庫 | 條目數 |
| --- | --- | --- |
| [LOG_AAA](https://example.test/wiki/LOG_AAA) | plugins/meta | 3 |
| [LOG_BBB](https://example.test/wiki/LOG_BBB) | plugins/ask | 5 |
EOF
cat > "$work/entry" <<'EOF'
## LOG_BBB
- 日誌頁:[LOG_BBB](https://example.test/wiki/LOG_BBB)
- 存取庫:plugins/ask
- 條目數:9
EOF
run 'template intro once' 1 LOG_BBB keep "$work/tpl"
cp "$work/new" "$work/old"
run 'template intro twice' 1 LOG_BBB keep "$work/tpl"
expect_eq "$(cat "$work/action")" updated 'template intro twice action'
expect_eq "$(cat "$work/new")" "$(cat "$work/old")" 'template intro twice'
printf '%s\n' 'OK'