dramaling-app/sop/scripts/file_version_manager.sh

174 lines
4.9 KiB
Bash
Executable File

#!/bin/bash
# 文件版本管理 SOP 腳本
# 用途: 安全處理文件更新時的舊版本歸檔
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}"))" && pwd)
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
ARCHIVE_DIR="$PROJECT_ROOT/archive"
LOG_FILE="$PROJECT_ROOT/logs/file_migration.log"
# 顏色定義
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m'
# 確保必要目錄存在
setup_directories() {
mkdir -p "$PROJECT_ROOT/logs"
mkdir -p "$ARCHIVE_DIR"
if [[ ! -f "$LOG_FILE" ]]; then
echo "# 文件遷移日誌" > "$LOG_FILE"
echo "# 格式: [日期時間] 操作類型 | 原文件 -> 目標位置 | 操作者 | 原因" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
fi
}
# 記錄遷移日誌
log_migration() {
local operation="$1"
local source_file="$2"
local target_file="$3"
local reason="$4"
local operator="${5:-Claude Code}"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
local log_entry="[$timestamp] $operation | $source_file -> $target_file | $operator | $reason"
echo "$log_entry" >> "$LOG_FILE"
echo -e "${GREEN}📋 記錄遷移: ${NC}$log_entry"
}
# 歸檔舊文件
archive_file() {
local source_file="$1"
local reason="$2"
local operator="${3:-Claude Code}"
if [[ ! -f "$source_file" ]]; then
echo -e "${RED}❌ 文件不存在: $source_file${NC}"
return 1
fi
# 生成歸檔目錄 (按日期)
local date_dir=$(date '+%Y-%m-%d')
local archive_date_dir="$ARCHIVE_DIR/$date_dir"
mkdir -p "$archive_date_dir"
# 生成新文件名 (加上時間前綴)
local filename=$(basename "$source_file")
local timestamp=$(date '+%H%M%S')
local archived_filename="${timestamp}_${filename}"
local target_file="$archive_date_dir/$archived_filename"
# 移動文件
mv "$source_file" "$target_file"
if [[ $? -eq 0 ]]; then
echo -e "${BLUE}📦 歸檔成功: ${NC}$source_file -> $target_file"
log_migration "ARCHIVE" "$source_file" "$target_file" "$reason" "$operator"
return 0
else
echo -e "${RED}❌ 歸檔失敗: $source_file${NC}"
return 1
fi
}
# 安全替換文件 (先歸檔舊版本)
safe_replace() {
local old_file="$1"
local new_file="$2"
local reason="$3"
local operator="${4:-Claude Code}"
if [[ ! -f "$new_file" ]]; then
echo -e "${RED}❌ 新文件不存在: $new_file${NC}"
return 1
fi
if [[ -f "$old_file" ]]; then
# 先歸檔舊文件
archive_file "$old_file" "$reason" "$operator"
if [[ $? -ne 0 ]]; then
echo -e "${RED}❌ 無法歸檔舊文件,中止替換${NC}"
return 1
fi
fi
# 移動新文件到目標位置
mv "$new_file" "$old_file"
if [[ $? -eq 0 ]]; then
echo -e "${GREEN}✅ 安全替換完成: ${NC}$old_file"
log_migration "REPLACE" "$new_file" "$old_file" "$reason" "$operator"
return 0
else
echo -e "${RED}❌ 替換失敗${NC}"
return 1
fi
}
# 查看遷移日誌
view_log() {
if [[ -f "$LOG_FILE" ]]; then
echo -e "${BLUE}📋 文件遷移日誌:${NC}"
cat "$LOG_FILE"
else
echo -e "${YELLOW}⚠️ 尚無遷移日誌${NC}"
fi
}
# 列出歸檔文件
list_archives() {
if [[ -d "$ARCHIVE_DIR" ]]; then
echo -e "${BLUE}📦 歸檔文件列表:${NC}"
find "$ARCHIVE_DIR" -type f -exec ls -la {} \; | sort
else
echo -e "${YELLOW}⚠️ 尚無歸檔文件${NC}"
fi
}
# 主函數
main() {
setup_directories
case "$1" in
"archive")
if [[ $# -lt 3 ]]; then
echo -e "${RED}使用方法: $0 archive 文件路徑 原因 [操作者]${NC}"
exit 1
fi
archive_file "$2" "$3" "$4"
;;
"replace")
if [[ $# -lt 4 ]]; then
echo -e "${RED}使用方法: $0 replace 舊文件 新文件 原因 [操作者]${NC}"
exit 1
fi
safe_replace "$2" "$3" "$4" "$5"
;;
"log")
view_log
;;
"list")
list_archives
;;
*)
echo -e "${BLUE}🗃️ 文件版本管理工具${NC}"
echo "用法:"
echo " $0 archive 文件路徑 原因 [操作者] # 歸檔文件"
echo " $0 replace 舊文件 新文件 原因 [操作者] # 安全替換文件"
echo " $0 log # 查看遷移日誌"
echo " $0 list # 列出歸檔文件"
echo ""
echo "範例:"
echo " $0 archive TASK_MANAGEMENT_OLD.md \"系統重構\" \"Claude Code\""
echo " $0 replace old.md new.md \"功能更新\" \"開發者\""
;;
esac
}
main "$@"