feat: Add install.sh for one-line skill distribution and update
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+104
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env bash
|
||||
# ============================================================
|
||||
# spec-coding-skills 安装/更新脚本
|
||||
# 用法: bash <(curl -sL <raw-url>/install.sh)
|
||||
# 或: bash install.sh [目标目录]
|
||||
# ============================================================
|
||||
set -euo pipefail
|
||||
|
||||
REPO_URL="https://git.internal.intelligrow.cn/zhangfucai/spec-coding-skills.git"
|
||||
SKILLS_SRC=".claude/skills"
|
||||
DEFAULT_TARGET=".claude/skills"
|
||||
|
||||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
||||
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log_title() { echo -e "${CYAN}$1${NC}"; }
|
||||
|
||||
TARGET="${1:-$DEFAULT_TARGET}"
|
||||
TMP_DIR=$(mktemp -d)
|
||||
trap "rm -rf $TMP_DIR" EXIT
|
||||
|
||||
# ---------- 拉取最新 ----------
|
||||
log_title "📦 spec-coding-skills 安装/更新"
|
||||
echo ""
|
||||
log_info "拉取最新版本..."
|
||||
git clone --depth 1 --quiet "$REPO_URL" "$TMP_DIR"
|
||||
|
||||
VERSION=$(git -C "$TMP_DIR" describe --tags --always 2>/dev/null || git -C "$TMP_DIR" rev-parse --short HEAD)
|
||||
log_info "版本: $VERSION"
|
||||
|
||||
# ---------- 统计变更 ----------
|
||||
NEW=0
|
||||
UPDATED=0
|
||||
SKIPPED=0
|
||||
KEPT=0
|
||||
|
||||
mkdir -p "$TARGET"
|
||||
|
||||
# 遍历上游 skill 目录
|
||||
for skill_dir in "$TMP_DIR/$SKILLS_SRC"/*/; do
|
||||
[ -d "$skill_dir" ] || continue
|
||||
skill_name=$(basename "$skill_dir")
|
||||
src_file="$skill_dir/SKILL.md"
|
||||
dst_dir="$TARGET/$skill_name"
|
||||
dst_file="$dst_dir/SKILL.md"
|
||||
|
||||
[ -f "$src_file" ] || continue
|
||||
|
||||
if [ ! -f "$dst_file" ]; then
|
||||
# 新 skill,直接复制
|
||||
mkdir -p "$dst_dir"
|
||||
cp "$src_file" "$dst_file"
|
||||
log_info "✨ 新增: $skill_name"
|
||||
NEW=$((NEW + 1))
|
||||
elif diff -q "$src_file" "$dst_file" >/dev/null 2>&1; then
|
||||
# 内容一致,跳过
|
||||
SKIPPED=$((SKIPPED + 1))
|
||||
else
|
||||
# 内容不同:上游有更新 或 用户本地修改过
|
||||
# 策略:备份本地版本,写入上游新版本
|
||||
cp "$dst_file" "$dst_file.local.bak"
|
||||
cp "$src_file" "$dst_file"
|
||||
log_warn "🔄 更新: $skill_name (本地版本已备份为 SKILL.md.local.bak)"
|
||||
UPDATED=$((UPDATED + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
# 复制模板文件(非 skill 目录的文件)
|
||||
for tpl_file in "$TMP_DIR/$SKILLS_SRC"/*.template "$TMP_DIR/$SKILLS_SRC"/*.md; do
|
||||
[ -f "$tpl_file" ] || continue
|
||||
tpl_name=$(basename "$tpl_file")
|
||||
dst="$TARGET/$tpl_name"
|
||||
|
||||
if [ ! -f "$dst" ]; then
|
||||
cp "$tpl_file" "$dst"
|
||||
log_info "✨ 新增模板: $tpl_name"
|
||||
NEW=$((NEW + 1))
|
||||
elif ! diff -q "$tpl_file" "$dst" >/dev/null 2>&1; then
|
||||
cp "$dst" "$dst.local.bak"
|
||||
cp "$tpl_file" "$dst"
|
||||
log_warn "🔄 更新模板: $tpl_name (本地版本已备份为 ${tpl_name}.local.bak)"
|
||||
UPDATED=$((UPDATED + 1))
|
||||
else
|
||||
SKIPPED=$((SKIPPED + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
# ---------- 汇总 ----------
|
||||
echo ""
|
||||
log_title "✅ 完成!"
|
||||
echo ""
|
||||
echo " 📁 目标目录: $TARGET"
|
||||
echo " 📦 版本: $VERSION"
|
||||
echo ""
|
||||
echo " ✨ 新增: $NEW"
|
||||
echo " 🔄 更新: $UPDATED(本地版本已备份为 .local.bak)"
|
||||
echo " ⏭️ 无变化: $SKIPPED"
|
||||
echo ""
|
||||
|
||||
if [ "$UPDATED" -gt 0 ]; then
|
||||
log_warn "有 $UPDATED 个文件被更新,本地修改已备份为 .local.bak"
|
||||
log_warn "如需恢复本地版本: mv SKILL.md.local.bak SKILL.md"
|
||||
log_warn "如需对比差异: diff SKILL.md SKILL.md.local.bak"
|
||||
fi
|
||||
Reference in New Issue
Block a user