commit 70340486ff2eab48ba1d263a6725f4edca9da4ff Author: insulee Date: Tue Feb 10 12:46:20 2026 +0900 chore: 프로젝트 공용 도구 초기 커밋 - release.bat: Gitea 릴리즈 자동화 (태그+릴리즈+파일업로드) - newproject.bat: 새 프로젝트 초기화 (git+템플릿+remote 설정) - template/: 공용 설정 파일 (.gitignore, .gitattributes, .gitmessage) 파일: release.bat - git remote에서 Gitea 정보 자동 추출 - 태그 생성, 릴리즈 생성, 파일 업로드 일괄 처리 - 한글 릴리즈 노트 지원 (JSON 파일 방식) 파일: newproject.bat - 현재 폴더에 git init + 템플릿 복사 - 커밋 메시지 규칙 자동 적용 - Gitea 원격 저장소 연결 파일: template/ - .gitignore: Python/빌드/IDE 제외 규칙 - .gitattributes: LF/CRLF 줄바꿈 관리 - .gitmessage: 한글 커밋 메시지 규칙 Co-Authored-By: Claude Opus 4.6 diff --git a/newproject.bat b/newproject.bat new file mode 100644 index 0000000..a5505d5 --- /dev/null +++ b/newproject.bat @@ -0,0 +1,124 @@ +@echo off +chcp 65001 >nul +setlocal EnableDelayedExpansion + +REM ============================================================ +REM 새 프로젝트 초기화 스크립트 +REM +REM 현재 폴더에 git 초기화 + 템플릿 파일 복사 + 커밋 규칙 적용 +REM Gitea 저장소가 있으면 remote까지 연결 +REM +REM 사용법: newproject [gitea저장소URL] +REM 예시: newproject http://dabit.synology.me:3052/islee/my_project +REM newproject (URL 없이 로컬 초기화만) +REM ============================================================ + +set TEMPLATE_DIR=%~dp0template +set CURRENT_DIR=%CD% +set FOLDER_NAME=%~n0 + +REM --- 현재 폴더명 추출 --- +for %%a in ("%CURRENT_DIR%") do set FOLDER_NAME=%%~na + +echo. +echo ============================================================ +echo 새 프로젝트 초기화 +echo ============================================================ +echo 폴더: %CURRENT_DIR% +echo 이름: %FOLDER_NAME% +echo ============================================================ + +REM --- 이미 git 저장소인지 확인 --- +git rev-parse --git-dir >nul 2>&1 +if %errorlevel%==0 ( + echo. + echo [알림] 이미 git 저장소입니다. 템플릿 파일만 추가합니다. + goto :copy_templates +) + +REM --- git 초기화 --- +echo. +echo [1/4] git 저장소 초기화... +git init +echo 완료. + +:copy_templates +REM --- 템플릿 파일 복사 --- +echo [2/4] 템플릿 파일 복사... + +if not exist "%TEMPLATE_DIR%" ( + echo [오류] 템플릿 폴더를 찾을 수 없습니다: %TEMPLATE_DIR% + exit /b 1 +) + +REM .gitignore (기존 파일이 있으면 건너뛰기) +if not exist ".gitignore" ( + copy "%TEMPLATE_DIR%\.gitignore" ".gitignore" >nul + echo .gitignore 복사됨 +) else ( + echo .gitignore 이미 존재 - 건너뜀 +) + +REM .gitattributes +if not exist ".gitattributes" ( + copy "%TEMPLATE_DIR%\.gitattributes" ".gitattributes" >nul + echo .gitattributes 복사됨 +) else ( + echo .gitattributes 이미 존재 - 건너뜀 +) + +REM .gitmessage +if not exist ".gitmessage" ( + copy "%TEMPLATE_DIR%\.gitmessage" ".gitmessage" >nul + echo .gitmessage 복사됨 +) else ( + echo .gitmessage 이미 존재 - 건너뜀 +) + +REM --- 커밋 메시지 템플릿 적용 (로컬 git 설정) --- +echo [3/4] 커밋 규칙 적용... +git config --local commit.template .gitmessage +echo 커밋 메시지 템플릿 적용됨 + +REM --- Gitea 원격 저장소 연결 --- +echo [4/4] 원격 저장소 설정... + +set GITEA_URL=%~1 +if "%GITEA_URL%"=="" ( + echo 원격 저장소 URL이 없습니다. 나중에 아래 명령으로 추가하세요: + echo git remote add origin http://dabit.synology.me:3052/islee/%FOLDER_NAME% + goto :done +) + +REM .git 접미사 추가 +echo %GITEA_URL% | findstr /r "\.git$" >nul +if %errorlevel% neq 0 set GITEA_URL=%GITEA_URL%.git + +REM 기존 remote 확인 +git remote get-url origin >nul 2>&1 +if %errorlevel%==0 ( + echo origin이 이미 설정되어 있습니다. + git remote get-url origin +) else ( + git remote add origin %GITEA_URL% + echo 원격 저장소 연결됨: %GITEA_URL% +) + +:done +echo. +echo ============================================================ +echo 초기화 완료! +echo ============================================================ +echo. +echo 적용된 항목: +echo .gitignore - Python/빌드/IDE 파일 제외 +echo .gitattributes - 줄바꿈 자동 관리 (LF/CRLF) +echo .gitmessage - 커밋 메시지 규칙 (feat/fix/docs...) +echo. +echo 다음 단계: +echo 1. 파일 추가: git add -A +echo 2. 첫 커밋: git commit -m "chore: 프로젝트 초기 설정" +echo 3. 푸시: git push -u origin master +echo. + +endlocal diff --git a/release.bat b/release.bat new file mode 100644 index 0000000..d2e97ea --- /dev/null +++ b/release.bat @@ -0,0 +1,149 @@ +@echo off +chcp 65001 >nul +setlocal EnableDelayedExpansion + +REM ============================================================ +REM Gitea 릴리즈 스크립트 (글로벌) +REM +REM 어떤 프로젝트 폴더에서든 실행 가능 +REM git remote 정보를 자동으로 읽어서 동작합니다 +REM +REM 사용법: release [버전] [첨부파일경로] +REM 예시: release v1.0 dist\MyApp.exe +REM release v2.1 +REM ============================================================ + +REM --- git remote에서 Gitea 정보 자동 추출 --- +for /f "tokens=*" %%a in ('git remote get-url origin 2^>nul') do set REMOTE_URL=%%a + +if "%REMOTE_URL%"=="" ( + echo [오류] git 저장소가 아니거나 remote가 설정되지 않았습니다. + echo git 프로젝트 폴더에서 실행해주세요. + exit /b 1 +) + +REM --- URL 파싱: http://host:port/owner/repo.git --- +REM .git 제거 +set REMOTE_URL=%REMOTE_URL:.git=% + +REM 마지막 두 경로에서 owner/repo 추출 +for %%a in ("%REMOTE_URL%") do set REPO_NAME=%%~na +for %%a in ("%REMOTE_URL%") do set TEMP_PARENT=%%~dpa +set TEMP_PARENT=%TEMP_PARENT:~0,-1% +for %%a in ("%TEMP_PARENT%") do set OWNER=%%~na + +REM base URL 추출 (owner 앞까지) +call set GITEA_URL=%%REMOTE_URL:/!OWNER!/!REPO_NAME!=%% + +echo. +echo ============================================================ +echo Gitea 릴리즈 스크립트 +echo ============================================================ +echo 서버 : %GITEA_URL% +echo 소유자: %OWNER% +echo 저장소: %REPO_NAME% +echo ============================================================ + +REM --- 버전 입력 --- +set VERSION=%~1 +if "%VERSION%"=="" ( + echo. + set /p VERSION="버전을 입력하세요 (예: v1.0): " +) + +REM --- 첨부 파일 --- +set EXE_PATH=%~2 +set HAS_FILE=0 +if not "%EXE_PATH%"=="" ( + if exist "%EXE_PATH%" ( + set HAS_FILE=1 + for %%F in ("%EXE_PATH%") do set EXE_NAME=%%~nxF + for %%F in ("%EXE_PATH%") do set EXE_SIZE=%%~zF + ) else ( + echo [경고] 파일을 찾을 수 없습니다: %EXE_PATH% + set /p CONTINUE="파일 없이 릴리즈만 생성할까요? (y/n): " + if /i not "!CONTINUE!"=="y" exit /b 1 + ) +) + +echo. +echo 버전 : %VERSION% +if %HAS_FILE%==1 ( + echo 파일 : %EXE_NAME% (%EXE_SIZE% bytes) +) else ( + echo 파일 : 없음 (릴리즈만 생성) +) +echo. + +REM --- 비밀번호 입력 --- +set /p GITEA_PASS="%OWNER% 계정 비밀번호: " + +REM --- 1단계: 태그 생성 & 푸시 --- +echo. +echo [1/4] 태그 %VERSION% 생성 중... +git tag %VERSION% 2>nul +if %errorlevel% neq 0 ( + echo 태그 %VERSION%이(가) 이미 존재합니다. 기존 태그를 사용합니다. +) +git push origin %VERSION% 2>nul +if %errorlevel% neq 0 ( + echo [오류] 태그 푸시에 실패했습니다. 네트워크를 확인하세요. + exit /b 1 +) +echo 태그 푸시 완료. + +REM --- 2단계: 릴리즈 생성 (JSON 파일로 전송하여 한글 깨짐 방지) --- +echo [2/4] Gitea 릴리즈 생성 중... + +REM 릴리즈 노트 입력 (선택) +set /p RELEASE_NOTE="릴리즈 노트 (Enter로 건너뛰기): " +if "!RELEASE_NOTE!"=="" set RELEASE_NOTE=%REPO_NAME% %VERSION% + +REM JSON 파일 생성 (UTF-8) +echo {"tag_name": "%VERSION%", "name": "%VERSION% - %REPO_NAME%", "body": "## %REPO_NAME% %VERSION%\n\n!RELEASE_NOTE!", "draft": false, "prerelease": false}> _release_body.json + +curl -s -o _release_resp.json -X POST "%GITEA_URL%/api/v1/repos/%OWNER%/%REPO_NAME%/releases" ^ + -u "%OWNER%:%GITEA_PASS%" ^ + -H "Content-Type: application/json; charset=utf-8" ^ + -d @_release_body.json + +REM --- 릴리즈 ID 추출 --- +for /f "tokens=2 delims=:," %%a in ('type _release_resp.json ^| findstr /r "\"id\":"') do ( + set RELEASE_ID=%%a + goto :got_id +) +:got_id +set RELEASE_ID=%RELEASE_ID: =% + +if "%RELEASE_ID%"=="" ( + echo [오류] 릴리즈 생성 실패. 비밀번호 또는 권한을 확인하세요. + type _release_resp.json + del _release_resp.json _http_code.txt 2>nul + exit /b 1 +) +echo 릴리즈 생성 완료 (ID: %RELEASE_ID%). + +REM --- 3단계: 파일 업로드 --- +if %HAS_FILE%==1 ( + echo [3/4] %EXE_NAME% 업로드 중... 잠시 기다려주세요. + curl -s -o _upload_resp.json -X POST "%GITEA_URL%/api/v1/repos/%OWNER%/%REPO_NAME%/releases/%RELEASE_ID%/assets?name=%EXE_NAME%" ^ + -u "%OWNER%:%GITEA_PASS%" ^ + -H "Content-Type: application/octet-stream" ^ + --data-binary "@%EXE_PATH%" + echo 업로드 완료. +) else ( + echo [3/4] 첨부 파일 없음. 건너뜁니다. +) + +REM --- 4단계: 결과 출력 --- +echo [4/4] 완료! +echo. +echo ============================================================ +echo 릴리즈 URL: %GITEA_URL%/%OWNER%/%REPO_NAME%/releases/tag/%VERSION% +echo ============================================================ +echo. + +REM --- 임시파일 정리 --- +del _release_resp.json _upload_resp.json _release_body.json 2>nul + +endlocal diff --git a/template/.gitattributes b/template/.gitattributes new file mode 100644 index 0000000..bbee1b4 --- /dev/null +++ b/template/.gitattributes @@ -0,0 +1,14 @@ +# Auto-detect text files and normalize line endings +* text=auto + +# Force LF for scripts and source files (Linux에서 실행되는 파일) +*.sh text eol=lf +*.py text eol=lf +*.yml text eol=lf +*.yaml text eol=lf +*.env* text eol=lf +Dockerfile text eol=lf + +# Force CRLF for Windows-only files +*.bat text eol=crlf +*.ps1 text eol=crlf diff --git a/template/.gitignore b/template/.gitignore new file mode 100644 index 0000000..cf17ded --- /dev/null +++ b/template/.gitignore @@ -0,0 +1,52 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +dist/ +*.egg-info/ +*.egg + +# 가상환경 +venv/ +.venv/ +ENV/ +env/ + +# 환경변수 (민감정보) +.env +.env.local +.env.*.local + +# IDE +.idea/ +.vscode/ +*.swp +*.swo +.cursor/ + +# 로그 +logs/ +*.log + +# 데이터베이스 +*.db +*.sqlite3 + +# OS +.DS_Store +Thumbs.db + +# Jupyter +.ipynb_checkpoints/ + +# 테스트 +.pytest_cache/ +.coverage +htmlcov/ + +# 임시 파일 +*.tmp +*.bak diff --git a/template/.gitmessage b/template/.gitmessage new file mode 100644 index 0000000..5703261 --- /dev/null +++ b/template/.gitmessage @@ -0,0 +1,52 @@ +# : <파일/컴포넌트> <제목> (70자 이내) +# +# <본문 - 변경 사항> +# - 항목1 +# - 항목2 +# - 항목3 +# +# <파일별 상세 (필수)> +# 파일: <경로> +# - 변경 내용 1 +# - 변경 내용 2 +# +# <추가 컨텍스트/이유 (선택)> +# +# --- 커밋 규칙 --- +# Type: +# feat: 새 기능 +# fix: 버그 수정 +# docs: 문서 변경 +# refactor: 리팩토링 +# chore: 빌드/설정 +# perf: 성능 개선 +# test: 테스트 +# +# 제목: +# - 70자 이내 +# - 파일/컴포넌트 명시 (예: "admin.html", "logging_service.py", "관리자 페이지") +# - 명령형 ("추가", "수정") +# - 마침표 없음 +# - 구체적으로 +# +# 본문: +# - 불릿 포인트 사용 +# - 무엇을, 왜 변경했는지 +# - 파일별 상세 섹션 필수 (어떤 함수/클래스를 추가/수정했는지) +# +# 좋은 예시: +# feat: admin.html 세션 목록에 읽음 상태 뱃지 추가 +# +# - localStorage 기반 세션 읽음 상태 관리 +# - 읽지 않음 뱃지(빨강): 한 번도 클릭하지 않은 세션 +# - 신규 메시지 뱃지(주황): 마지막 확인 이후 추가된 메시지 수 +# +# 파일: apps/user_chatbot/static/admin.html +# - getSessionReadStatus() 함수 추가 +# - markSessionAsRead() 함수 추가 +# - getSessionBadges() 함수 추가 +# - CSS: .badge-unread, .badge-new 스타일 추가 +# +# 나쁜 예시: +# feat: 세션 목록에 뱃지 추가 (어느 파일인지 불명확) +# fix: 버그 수정 (무엇을 고쳤는지 불명확)