Files
log/tools/worklog-target.sh
T
jiantw83andClaude Sonnet 5 deddd448a6 feat(log): worklog-target.sh 新增 week 子命令,輸出 yyyy-MM-Wn 工作週編號
因為 worklog 頁面內容是照週五整理的,需要一個能直接算出「這是當月第幾個工作週」
的指令,判斷基準是週五落在哪個月、當月第幾個週五,而不是 ISO 週次或週一所在月份。

新增 `worklog-target.sh week [基準日期 yyyy-MM-dd]`,重用既有 `friday`(週一加四天)
的邏輯算出週五日期,再往前推算當月第幾個週五,組成 `yyyy-MM-Wn` 格式輸出;同時把
`friday`/`week` 兩分支原本各自重複的基準日期格式檢查收進 `friday_of_week()` 內部,
消除重複程式碼,並補齊函式註解的層級標記、步驟條列與範例值,以及 usage() 說明中
原本漏掉的 week 用法。

已用 TDD 驗證跨月週與本週遞增兩種情境、跑過語法檢查與註解掃描,並經兩輪 code
review(六組壞味道)確認無殘留問題。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-08 11:03:45 +08:00

112 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
# worklog-target.sh: 由已算好的 hash 組出 worklog wiki 目標頁名稱,並算出工作週的週五。
# hash 一律由 jsc-gitea/tools/hash-id 算出後傳入,本腳本不再自行計算 SHA-1。
# 用法:
# worklog-target.sh <hash> [page|contents|all]
# worklog-target.sh friday [基準日期 yyyy-MM-dd]
# worklog-target.sh week [基準日期 yyyy-MM-dd]
#
# friday 印出一行 yyyy-MM-dd:基準日期所在工作週的週五(基準日期省略時用今天)。
# 週界不在這裡算,一律問 report-range.sh weekly——週一起算的 ISO 週定義只有那一支說了算,
# 兩邊各算一次就會在跨月、跨年的那一週各走各的。這裡只做「週一加四天」這一步。
#
# week 印出一行 yyyy-MM-Wn(例:輸入 2026-08-31 或 2026-09-06 都印出 2026-09-W1;
# 輸入 2026-09-11 印出 2026-09-W2)。規則:
# 1. 先用 friday_of_week 取出該工作週的週五
# 2. yyyy-MM 一律取週五那天的月份,不看週一——一週橫跨兩個月時(例如週一在八月、
# 週日在九月),worklog 頁內容照週五整理,跨月的那一週不該被算進週一那個月
# 3. n 不是 ISO 週次,是「當月第幾個週五」:同月份的週五彼此相距固定 7 天,
# (日期-1)/7 取整數再加 1 就是第幾個,不必逐週從月初數起
#
# 結束碼: 0=成功 2=用法錯誤 4=系統的 date 不支援日期運算(由 report-range.sh 判定)
set -eu
HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
usage() {
cat >&2 <<'EOF'
用法:
worklog-target.sh <hash> [page|contents|all] 組出 LOG_{HASH} 與 LOG_CONTENTS
worklog-target.sh friday [yyyy-MM-dd] 印出該工作週的週五日期
worklog-target.sh week [yyyy-MM-dd] 印出該工作週的 yyyy-MM-Wn
結束碼: 0=成功 2=用法錯誤 4=系統的 date 不支援日期運算
EOF
exit 2
}
add_days() { # $1=yyyy-MM-dd $2=要加的天數
if date -d "$1 +$2 days" +%Y-%m-%d >/dev/null 2>&1; then
date -d "$1 +$2 days" +%Y-%m-%d
return 0
fi
if date -j -f %Y-%m-%d -v"+$2d" "$1" +%Y-%m-%d >/dev/null 2>&1; then
date -j -f %Y-%m-%d -v"+$2d" "$1" +%Y-%m-%d
return 0
fi
echo "系統的 date 不支援日期運算,算不出工作週的週五" >&2
exit 4
}
[ "$#" -ge 1 ] || usage
[ "$#" -le 2 ] || usage
# 檢查層:擋掉格式錯誤的基準日期,不算日期。$1=基準日期(例:2026-08-31,可為空)
# 1. 空字串 -> 放行,呼叫端自己決定要不要用今天
# 2. yyyy-MM-dd -> 放行
# 3. 其他任何寫法 -> 印錯誤訊息並 exit 2,不猜使用者的意思
check_base_format() {
case "${1:-}" in
'') ;;
[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) ;;
*) echo "基準日期格式要是 yyyy-MM-dd:$1" >&2; exit 2 ;;
esac
}
# 邏輯層:算出基準日期所在工作週的週五。$1=基準日期(例:2026-08-31,可為空,
# 空字串代表用今天)-> 該工作週的週五 yyyy-MM-dd(例:2026-09-04)
# 1. 格式檢查交給 check_base_format,格式錯誤就地中止,不進到下一步
# 2. 呼叫 report-range.sh weekly 取得該工作週的週一
# 3. 週一加 4 天就是週五
friday_of_week() {
base="${1:-}"
check_base_format "$base"
range=$(sh "$HERE/report-range.sh" weekly ${base:+"$base"}) || exit $?
monday=$(printf '%s\n' "$range" | cut -f1)
add_days "$monday" 4
}
if [ "$1" = friday ]; then
friday_of_week "${2:-}"
exit 0
fi
if [ "$1" = week ]; then
friday=$(friday_of_week "${2:-}")
month=$(printf '%s' "$friday" | cut -c1-7)
day=$(printf '%s' "$friday" | cut -c9-10)
day=${day#0} # 去掉前導零:dash 的 $(()) 沒有 10# 進位前綴語法,前導零會被誤判成八進位
nth=$(( (day - 1) / 7 + 1 ))
printf '%s-W%s\n' "$month" "$nth"
exit 0
fi
hash=$1
field=${2:-page}
if [ -z "$hash" ]; then
usage
fi
page="LOG_${hash}"
contents='LOG_CONTENTS'
case "$field" in
page) printf '%s\n' "$page" ;;
contents) printf '%s\n' "$contents" ;;
all)
printf 'PAGE=%s\n' "$page"
printf 'CONTENTS=%s\n' "$contents"
;;
*) usage ;;
esac