148 lines
3.6 KiB
Bash
148 lines
3.6 KiB
Bash
#!/usr/bin/env bash
|
|
# docker-compose 註解對齊工具
|
|
# 用法: bash align_comments.sh [file_or_directory] [--yes]
|
|
#
|
|
# 功能:
|
|
# 1. 如果未指定檔案,則搜尋專案中所有 docker-compose.yaml。
|
|
# 2. 每個檔案獨立計算註解對齊欄位。
|
|
# 3. 更新標題中的更新日期。
|
|
|
|
set -euo pipefail
|
|
|
|
# 參數處理
|
|
target_path=""
|
|
auto_confirm=false
|
|
had_failure=false
|
|
|
|
for arg in "$@"; do
|
|
if [[ "$arg" == "--yes" ]] || [[ "$arg" == "-y" ]]; then
|
|
auto_confirm=true
|
|
else
|
|
target_path="$arg"
|
|
fi
|
|
done
|
|
|
|
AWK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/awk"
|
|
|
|
write_with_tmp() {
|
|
local source_file="$1"
|
|
local awk_file="$2"
|
|
shift 2
|
|
|
|
local tmp_file
|
|
tmp_file="$(mktemp "${source_file}.tmp.XXXXXX")"
|
|
if awk "$@" -f "$awk_file" "$source_file" > "$tmp_file"; then
|
|
mv -- "$tmp_file" "$source_file"
|
|
else
|
|
rm -f -- "$tmp_file"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
process_file() {
|
|
local file="$1"
|
|
if [[ ! -f "$file" ]]; then
|
|
echo "Skip: $file is not a file."
|
|
return
|
|
fi
|
|
|
|
echo ">>> Processing: $file"
|
|
|
|
# 步驟 0:還原多餘空白 (Strip)
|
|
write_with_tmp "$file" "$AWK_DIR/strip_col.awk"
|
|
echo "[0] Strip done."
|
|
|
|
# 步驟 1:人工修正註解內容 (Review)
|
|
if [[ "$auto_confirm" == "false" ]]; then
|
|
echo "[1] 請檢查註解內容是否正確 ($file)。"
|
|
read -r -p "完成後按 Enter 繼續 (或輸入 's' 跳過此檔, 'a' 全部自動完成): " input
|
|
if [[ "$input" == "s" ]]; then
|
|
echo "Skipped."
|
|
return
|
|
fi
|
|
if [[ "$input" == "a" ]]; then
|
|
auto_confirm=true
|
|
fi
|
|
fi
|
|
|
|
# 步驟 2:找出最大對齊欄位 (Find)
|
|
local target
|
|
target=$(awk -f "$AWK_DIR/find_col.awk" "$file" | awk -F= '{print $2}')
|
|
|
|
if [[ -z "$target" ]] || [[ "$target" -eq 0 ]]; then
|
|
echo "[2] No inline comments found. Skipping alignment."
|
|
else
|
|
echo "[2] Calculated TARGET column: $target"
|
|
|
|
# 步驟 3:對齊 (Align)
|
|
write_with_tmp "$file" "$AWK_DIR/align_col.awk" -v TARGET="$target"
|
|
echo "[3] Align done."
|
|
|
|
# 步驟 4:驗證 (Verify)
|
|
local verify
|
|
verify=$(awk -v TARGET="$target" -f "$AWK_DIR/verify_col.awk" "$file")
|
|
if [[ -z "$verify" ]]; then
|
|
echo "[4] Verify OK."
|
|
else
|
|
echo "[4] Verify FAILED for $file:"
|
|
echo "$verify"
|
|
had_failure=true
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
# 步驟 5:更新標題日期 (Update)
|
|
local today
|
|
today=$(date +%Y-%m-%d)
|
|
# 支援不同的 sed 版本 (Linux/GNU vs BSD/MacOS)
|
|
if sed --version >/dev/null 2>&1; then
|
|
# GNU sed
|
|
sed -i "s/# 更新日期: [0-9-]*/# 更新日期: $today/" "$file"
|
|
else
|
|
# BSD sed (MacOS)
|
|
sed -i '' "s/# 更新日期: [0-9-]*/# 更新日期: $today/" "$file"
|
|
fi
|
|
echo "[5] Updated '更新日期' to $today."
|
|
echo ""
|
|
}
|
|
|
|
find_compose_files() {
|
|
local root="$1"
|
|
|
|
find "$root" \
|
|
\( -path '*/node_modules' -o -path '*/.git' -o -path '*/bin' -o -path '*/obj' \) -prune \
|
|
-o -name 'docker-compose.yaml' -type f -print0
|
|
}
|
|
|
|
process_found_files() {
|
|
local root="$1"
|
|
local found=false
|
|
|
|
while IFS= read -r -d '' file; do
|
|
found=true
|
|
process_file "$file" || had_failure=true
|
|
done < <(find_compose_files "$root")
|
|
|
|
if [[ "$found" == "false" ]]; then
|
|
echo "No docker-compose.yaml files found."
|
|
fi
|
|
}
|
|
|
|
# 執行邏輯
|
|
if [[ -z "$target_path" ]]; then
|
|
echo "No target specified. Searching for all docker-compose.yaml files in the project..."
|
|
process_found_files "."
|
|
elif [[ -d "$target_path" ]]; then
|
|
echo "Target is a directory. Searching for docker-compose.yaml files within: $target_path"
|
|
process_found_files "$target_path"
|
|
else
|
|
process_file "$target_path" || had_failure=true
|
|
fi
|
|
|
|
if [[ "$had_failure" == "true" ]]; then
|
|
echo "Done with failures."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Done!"
|