✨ feat: 공통 Skill 관리 및 링크 스크립트 추가
This commit is contained in:
@@ -97,10 +97,35 @@ else
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 4) 공통 skill 심볼릭 링크 (.claude/common/skills/* → .claude/skills/*)
|
||||
SKILLS_SRC="$TARGET_PATH/skills"
|
||||
SKILLS_DEST=".claude/skills"
|
||||
|
||||
if [[ -d "$SKILLS_SRC" ]]; then
|
||||
echo "🔗 공통 skill 을 $SKILLS_DEST 로 링크합니다..."
|
||||
mkdir -p "$SKILLS_DEST"
|
||||
for dir in "$SKILLS_SRC"/*/; do
|
||||
[[ -d "$dir" ]] || continue
|
||||
name="$(basename "$dir")"
|
||||
[[ "$name" == "README"* ]] && continue
|
||||
link_src="../common/skills/$name"
|
||||
link_dest="$SKILLS_DEST/$name"
|
||||
if [[ -L "$link_dest" ]]; then
|
||||
echo " ⏭ $link_dest (이미 링크됨)"
|
||||
elif [[ -e "$link_dest" ]]; then
|
||||
echo " ⚠️ $link_dest (실제 파일/폴더 존재 - 건너뜀. link-skills.sh --force 로 덮어쓰기)"
|
||||
else
|
||||
ln -s "$link_src" "$link_dest"
|
||||
echo " ✅ $link_dest → $link_src"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🎉 설치가 완료되었습니다."
|
||||
echo " - 공통 지침: $TARGET_PATH/CLAUDE.md"
|
||||
echo " - 프로젝트 지침: $PROJECT_PATH/"
|
||||
echo " - 공통 skill: $SKILLS_DEST/ (submodule 에 심볼릭 링크)"
|
||||
echo " - 엔트리 파일: CLAUDE.md"
|
||||
echo ""
|
||||
echo "다음 작업을 진행해 주세요:"
|
||||
|
||||
139
scripts/link-skills.sh
Executable file
139
scripts/link-skills.sh
Executable file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# fe-common-rules skill linker
|
||||
# 공통 저장소의 skills/* 를 프로젝트의 .claude/skills/* 로 심볼릭 링크합니다.
|
||||
# 심볼릭 링크이므로 submodule 업데이트 시 skill 도 자동으로 최신 버전이 됩니다.
|
||||
#
|
||||
# 사용법:
|
||||
# bash .claude/common/scripts/link-skills.sh # 모든 skill 링크
|
||||
# bash .claude/common/scripts/link-skills.sh <skill-name> # 특정 skill 만
|
||||
# bash .claude/common/scripts/link-skills.sh --dry-run # 실제 링크 없이 미리보기
|
||||
# bash .claude/common/scripts/link-skills.sh --force # 기존 링크/폴더 덮어쓰기
|
||||
# bash .claude/common/scripts/link-skills.sh --unlink # 공통 skill 링크 제거
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
COMMON_PATH=".claude/common"
|
||||
SKILLS_SRC="$COMMON_PATH/skills"
|
||||
SKILLS_DEST=".claude/skills"
|
||||
|
||||
MODE="safe" # safe | force | dry-run | unlink
|
||||
TARGET=""
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--dry-run) MODE="dry-run" ;;
|
||||
--force) MODE="force" ;;
|
||||
--unlink) MODE="unlink" ;;
|
||||
-h|--help)
|
||||
grep '^#' "$0" | sed 's/^# \{0,1\}//'
|
||||
exit 0
|
||||
;;
|
||||
-*)
|
||||
echo "❌ 알 수 없는 옵션: $arg" >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
TARGET="$arg"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
echo "❌ 현재 디렉토리는 Git 저장소가 아닙니다." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
|
||||
if [[ ! -d "$SKILLS_SRC" ]]; then
|
||||
echo "❌ $SKILLS_SRC 가 없습니다. 먼저 submodule 을 설치/업데이트하세요:" >&2
|
||||
echo " git submodule update --init --recursive" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$SKILLS_DEST"
|
||||
|
||||
# 링크 대상 결정
|
||||
declare -a skills
|
||||
if [[ -n "$TARGET" ]]; then
|
||||
if [[ ! -d "$SKILLS_SRC/$TARGET" ]]; then
|
||||
echo "❌ '$TARGET' skill 을 $SKILLS_SRC 에서 찾지 못했습니다." >&2
|
||||
echo " 사용 가능한 skill:" >&2
|
||||
ls -1 "$SKILLS_SRC" 2>/dev/null | grep -v '^README' | sed 's/^/ - /' >&2
|
||||
exit 1
|
||||
fi
|
||||
skills=("$TARGET")
|
||||
else
|
||||
shopt -s nullglob
|
||||
for dir in "$SKILLS_SRC"/*/; do
|
||||
name="$(basename "$dir")"
|
||||
# README 같은 파일은 이미 걸러지지만 추가 보호
|
||||
[[ "$name" == "README"* ]] && continue
|
||||
skills+=("$name")
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ ${#skills[@]} -eq 0 ]]; then
|
||||
echo "ℹ️ 링크할 skill 이 없습니다."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "🔗 공통 skill 링크 (mode=$MODE)"
|
||||
echo " source: $SKILLS_SRC"
|
||||
echo " dest: $SKILLS_DEST"
|
||||
echo ""
|
||||
|
||||
linked=0
|
||||
skipped=0
|
||||
removed=0
|
||||
|
||||
for name in "${skills[@]}"; do
|
||||
src="../common/skills/$name" # 심볼릭 링크의 상대 경로 (.claude/skills 기준)
|
||||
dest="$SKILLS_DEST/$name"
|
||||
|
||||
case "$MODE" in
|
||||
unlink)
|
||||
if [[ -L "$dest" ]]; then
|
||||
rm "$dest"
|
||||
echo " 🗑 $dest (링크 제거)"
|
||||
removed=$((removed + 1))
|
||||
else
|
||||
echo " ⏭ $dest (링크 아님 - 건너뜀)"
|
||||
fi
|
||||
;;
|
||||
dry-run)
|
||||
if [[ -e "$dest" || -L "$dest" ]]; then
|
||||
echo " ⏭ $dest (이미 존재)"
|
||||
else
|
||||
echo " ➕ ln -s $src $dest"
|
||||
fi
|
||||
;;
|
||||
force)
|
||||
rm -rf "$dest"
|
||||
ln -s "$src" "$dest"
|
||||
echo " ✅ $dest → $src (덮어씀)"
|
||||
linked=$((linked + 1))
|
||||
;;
|
||||
safe)
|
||||
if [[ -L "$dest" ]]; then
|
||||
echo " ⏭ $dest (이미 링크됨)"
|
||||
skipped=$((skipped + 1))
|
||||
elif [[ -e "$dest" ]]; then
|
||||
echo " ⚠️ $dest (실제 파일/폴더가 존재. --force 로 덮어쓰세요)"
|
||||
skipped=$((skipped + 1))
|
||||
else
|
||||
ln -s "$src" "$dest"
|
||||
echo " ✅ $dest → $src"
|
||||
linked=$((linked + 1))
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo ""
|
||||
case "$MODE" in
|
||||
unlink) echo "🎉 제거 완료: $removed 개 링크 제거됨";;
|
||||
dry-run) echo "🔍 미리보기 완료 (실제 변경 없음)";;
|
||||
*) echo "🎉 완료: 링크 $linked개 / 건너뜀 $skipped개";;
|
||||
esac
|
||||
Reference in New Issue
Block a user