저희 회사에서는 Cursor IDE를 적극적으로 활용하여 개발을 진행하고 있습니다. Cursor는 AI 기반 코드 어시스턴트로, 프로젝트 루트 경로에 .cursorrules
파일을 작성해두면 기본 모델의 동작을 제어할 수 있습니다.
.cursorrules
파일 내에 전체적인 프로젝트의 구조를 명시해두면, AI 모델은 다음과 같은 이점을 통해 더 질 높은 코드를 제안합니다:
그러나 프로젝트가 발전함에 따라 폴더 구조는 계속 변화합니다. 새 기능이 추가되고, 리팩토링이 이루어지며, 파일들이 재구성됩니다. 이러한 변화를 .cursorrules
파일에 수동으로 반영하는 것은 번거롭고 종종 잊혀지기 쉬운 작업입니다.
시간이 지남에 따라 .cursorrules
에 명시된 폴더 구조와 실제 프로젝트 구조 사이에 불일치가 발생하면, Cursor는 오래된 정보를 기반으로 코드를 제안하게 되어 부정확한 결과물이 생성될 수 있습니다.
이러한 문제를 해결하기 위해, 저희는 .cursorrules
파일 내 폴더 구조를 자동으로 최신화하는 시스템을 구축했습니다. GitHub Actions와 npm 스크립트를 활용하여 개발자가 별도의 노력을 들이지 않아도 항상 최신 상태의 폴더 구조가 문서화되도록 했습니다.
프로젝트 구조를 자동으로 업데이트하기 위한 첫 번째 단계는 폴더 구조를 추출하고 .cursorrules
파일에 반영하는 스크립트를 만드는 것입니다. 이를 위해 Bash 스크립트를 활용했습니다.
프로젝트 루트에 script
디렉토리를 만들고, 그 안에 update_structure.sh
파일을 생성했습니다. 이 스크립트는 다음과 같은 주요 기능을 수행합니다:
.cursorrules
파일에서 폴더 구조 섹션을 찾습니다.다음은 스크립트의 핵심 부분입니다:
#!/bin/bash
# 현재 디렉토리 경로 저장
ROOT_DIR=$(pwd)
CURSORRULES_FILE=".cursorrules"
TEMP_FILE="temp_structure.txt"
# 파일 구조 섹션 시작과 끝 마커
SECTION_START="## 파일 구조"
SECTION_END="## 타입스크립트"
# 파일 구조 생성 함수
generate_structure() {
echo ""
# 시스템에 tree 명령어가 있는지 확인
if command -v tree &> /dev/null; then
# tree 명령어가 있으면 사용
tree -I "node_modules|.git|.next|public" --dirsfirst -L 10
else
# tree 명령어가 없으면 find로 대체
find . -type d -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/.next/*" -not -path "*/public/*" | sort | while read -r dir; do
# 루트 디렉토리는 건너뛰기
if [ "$dir" = "." ]; then
continue
fi
# 디렉토리 깊이 계산 및 출력 로직
# ...
done
# 파일 출력 로직
# ...
fi
}
# 파일 구조 생성 및 .cursorrules 파일 업데이트
generate_structure > "$TEMP_FILE"
# 파일 구조 섹션을 찾아서 업데이트
START_PART=$(mktemp)
END_PART=$(mktemp)
# 시작 부분 추출 (SECTION_START 포함)
sed -n "1,/$SECTION_START/p" "$CURSORRULES_FILE" > "$START_PART"
# 끝 부분 추출 (SECTION_END부터 끝까지)
sed -n "/$SECTION_END/,\$p" "$CURSORRULES_FILE" > "$END_PART"
# 새 파일 생성
cat "$START_PART" > "$CURSORRULES_FILE"
cat "$TEMP_FILE" >> "$CURSORRULES_FILE"
cat "$END_PART" >> "$CURSORRULES_FILE"
# 임시 파일 삭제
rm -f "$START_PART" "$END_PART" "$TEMP_FILE"
echo "파일 구조가 성공적으로 업데이트되었습니다."
이 스크립트는 다음과 같은 방식으로 작동합니다:
폴더 구조 추출:
tree
명령어가 시스템에 설치되어 있는지 확인합니다.tree
명령어를 사용하여 깔끔한 트리 형태로 구조를 추출합니다.find
명령어를 사용하여 유사한 결과를 생성합니다.node_modules
, .git
, .next
, public
등 불필요한 디렉토리는 제외합니다.파일 업데이트:
스크립트를 실행하기 위해서는 스크립트 파일에 실행 권한을 부여해야 합니다.
chmod +x ./script/update_structure.sh
명령어를 통해 권한을 부여합니다.
스크립트 파일을 만든 후, 다음 단계는 이를 개발 워크플로우에 자연스럽게 통합하는 것입니다. 개발자들이 별도의 명령어를 실행하지 않아도 폴더 구조가 자동으로 업데이트되도록 npm 스크립트 라이프사이클 훅을 활용했습니다.
package.json
파일의 scripts
섹션에 다음과 같이 predev
와 postinstall
스크립트를 추가했습니다:
{
"scripts": {
"predev": "chmod +x script/update_structure.sh && ./script/update_structure.sh",
"postinstall": "if [ -f \"script/update_structure.sh\" ]; then chmod +x script/update_structure.sh; fi"
},
}
npm 스크립트 시스템에는 특정 명령어 실행 전후에 자동으로 실행되는 라이프사이클 훅이 있습니다. 이를 활용하여 두 가지 중요한 시점에 폴더 구조를 업데이트하도록 설정했습니다:
predev:
npm run dev
명령어를 실행하기 전에 자동으로 실행됩니다.chmod +x
) 실행합니다..cursorrules
파일에 반영됩니다.postinstall:
npm install
또는 yarn install
명령어가 완료된 후 자동으로 실행됩니다.predev
에서 수행되므로, postinstall
에서는 스크립트 실행 권한만 설정합니다.이러한 npm 스크립트 통합은 다음과 같은 이점을 제공합니다:
개발자 경험 향상:
npm run dev
만 실행하면 됩니다.일관성 유지:
.cursorrules
파일에 반영됩니다.로컬 개발 환경에서의 자동화와 더불어, 팀 전체의 일관성을 보장하기 위해 GitHub Actions를 활용하여 PR(Pull Request) 단계에서도 폴더 구조 업데이트를 자동화했습니다. 이를 통해 코드 변경사항이 메인 브랜치에 병합되기 전에 항상 최신 폴더 구조가 .cursorrules
파일에 반영되도록 보장합니다.
.github/workflows/
디렉토리에 update-directory-structure.yml
파일을 생성하여 다음과 같은 워크플로우를 구현했습니다:
name: 디렉토리 구조 업데이트
on:
pull_request:
types: [opened, synchronize]
# 모든 브랜치에 대한 PR에서 실행
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
update-structure:
runs-on: ubuntu-latest
steps:
- name: 저장소 체크아웃
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: 디렉토리 구조 업데이트
run: |
chmod +x ./script/update_structure.sh
./script/update_structure.sh
- name: 변경사항 확인
id: check-changes
run: |
git diff --exit-code .cursorrules || echo "changes=true" >> $GITHUB_OUTPUT
- name: 변경사항 커밋 및 푸시
if: steps.check-changes.outputs.changes == 'true'
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "GitHub Actions"
git add .cursorrules
git commit -m "chore: Update directory structure"
git push origin HEAD:${{ github.head_ref }}
이 GitHub Actions 워크플로우는 다음과 같은 방식으로 작동합니다:
트리거 조건:
opened
) 업데이트(synchronize
)될 때마다 워크플로우가 실행됩니다.동시성 제어:
concurrency
설정을 통해 동일한 PR에 대해 여러 워크플로우가 동시에 실행되는 것을 방지합니다.실행 단계:
.cursorrules
파일에 변경사항이 있는지 확인합니다.폴더 구조 업데이트의 중요성을 강조하고 일관성을 보장하기 위해, 이 워크플로우를 필수 검사(Required Check)로 설정했습니다. 이는 워크플로우가 성공적으로 완료되어야만 PR을 메인 브랜치에 병합할 수 있음을 의미합니다.
GitHub 저장소 설정에서 브랜치 보호 규칙을 다음과 같이 구성했습니다:
Settings
> Branches
> Branch protection rules
로 이동*
)을 설정Require status checks to pass before merging
옵션 활성화update-structure
를 입력하여 워크플로우 검색디렉토리 구조 업데이트
워크플로우 선택이 설정을 통해 다음과 같은 효과를 얻을 수 있습니다:
강제적인 일관성:
.cursorrules
파일에 반영되어야 합니다.자동화된 검증:
투명한 변경사항 추적:
PR을 올리게 되면 폴더 구조를 업데이트하는 워크플로우가 실행되고 이 워크플로우가 성공적으로 종료되어야 머지를 할 수 있다.
해당 커밋으로 파일 구조를 업데이트 함을 확인할 수 있다.
커서를 잘 활용하기 위해 .cursorrules
파일 내에 폴더 구조를 항상 최신 버전으로 유지할 수 있게 자동화하는 프로세스를 구현했습니다. 아래의 과정에서 폴더 구조를 업데이트 하는 스크립트를 실행합니다.
postinstall
훅)predev
훅)이러한 다층적 자동화 접근법을 통해 개발 워크플로우의 모든 중요 시점에서 폴더 구조가 자동으로 최신화됩니다. 개발자들은 별도의 수동 작업 없이도 항상 정확한 프로젝트 구조 정보를 .cursorrules
파일에 유지할 수 있게 되었습니다.