์ฌ๋ฌ Git ์ ์ฅ์์ ์ฝ๋๋ฅผ AST ๊ธฐ๋ฐ์ผ๋ก ๋ถ์ํ๊ณ , ์คํ์์ค ์ ์ ๋ถ์ ๋๊ตฌ๋ฅผ ํตํฉํ๋ฉฐ, ์ฌ์ฉ์ ํผ๋๋ฐฑ(๋ณ์ + ์ฝ๋ฉํธ)์ ๋ฐ์ํ ์ฝ๋ ๊ฐ์ ๊ฐ๋ฅ์ฑ์ ์ ์ํ๋ ์จํ๋ ๋ฏธ์ค ์น ๋์๋ณด๋์ ๋๋ค.
- ๋ฉํฐ ์ ์ฅ์ ์ง์: GitHub, GitLab, ๋ก์ปฌ Git ์ ์ฅ์ ์ฐ๊ฒฐ
- ์ ์ ๋ถ์ ํตํฉ: cppcheck (C++), pylint + bandit (Python), PMD (Java), ESLint (JavaScript)
- AST ๊ธฐ๋ฐ ๋ถ์: ํ์ผ/ํจ์/ํด๋์ค ๋จ์ ์ฌ๋ณผ ์ถ์ถ, ๋ณต์ก๋, ์์กด์ฑ ๋ถ์
- ์ฝ๋ ๋ฉํธ๋ฆญ: Cyclomatic Complexity, Maintainability Index, ์ฝ๋ ์ค๋ณต, Fan-in/Fan-out
- ์ปค๋ฐ ์ธํ ๋ฆฌ์ ์ค: ๋ณ๊ฒฝ ๋น๋ ๋ถ์ + ML ๊ธฐ๋ฐ ์ปค๋ฐ ๋ชฉ์ ๋ถ๋ฅ (๋น์ง๋ KMeans โ ์ง๋ Naive Bayes ํ์ด๋ธ๋ฆฌ๋)
- ์ฌ์ฉ์ ํผ๋๋ฐฑ: ์ ์ฒด ๋ถ์ ๊ฒฐ๊ณผ์ ๋ํ ๋ณ์ (1~5) ๋ฐ ์ฝ๋ฉํธ, ๊ฐ์ฑ ๋ถ์
- ์ฐ์ ์์ ์ ์: ์ ์ ๋ฐ๊ฒฌ์ฌํญ(35%) + ๋ณต์ก๋(20%) + ์ค๋ณต(10%) + ์์กด์ฑ(10%) + ๋ณ๊ฒฝ๋น๋(15%) + ํผ๋๋ฐฑ(10%)
- ์ธํฐ๋ํฐ๋ธ ๋์๋ณด๋: ์งํ ์นด๋, ์ฌ๊ฐ๋/์ค๋ฉ/๋ณต์ก๋ ์ฐจํธ, ์ปค๋ฐ ๋ชฉ์ ๋ถํฌ, Top ๊ฐ์ ๋์
- ํํฐ: ์ ์ฅ์, ์ธ์ด, ๊ธฐ๊ฐ(1์ฃผ/1๊ฐ์/3๊ฐ์/์ง์ ์ง์ ), ์ฌ๊ฐ๋, ์ค๋ฉ ์ ํ, ์ฐ์ ์์
- ์ธ๋ผ์ธ ๋๋ฆด๋ค์ด: ์ถ์ฒ ํญ๋ชฉ ํด๋ฆญ ์ ํ์ผ/ํจ์ ์์ธ findings, ์ฌ๋ณผ, ์ปค๋ฐ ๋ด์ญ ํ์
- ๋ฆฌํฌํธ ์ต์คํฌํธ: Markdown (AI ์์ด์ ํธ ํธ๋์คํ์ฉ) + JSON (๋๊ตฌ ์ฐ๋์ฉ)
| ์๊ตฌ์ฌํญ | ๋ฒ์ | ํ์ธ |
|---|---|---|
| Python | 3.9 ์ด์ | python --version |
| Git | 2.20 ์ด์ | git --version |
| pip | ์ต์ | python -m pip install --upgrade pip |
์ธ๋ถ ์ ์ ๋ถ์ ๋๊ตฌ๋ฅผ ์ค์นํ์ง ์์๋ ๋์๋ณด๋๋ ์ ์ ์๋ํฉ๋๋ค. ๋๊ตฌ๊ฐ ์์ผ๋ฉด ํด๋น ์ธ์ด๋ ๋ด์ฅ AST ๋ถ์ + ๋ณต์ก๋ ์ธก์ ๋ง ์ํํ๊ณ ์ ์ ๋ถ์ findings๋ ๊ฑด๋๋๋๋ค.
# C++ (cppcheck)
winget install cppcheck
# Python (pylint, bandit)
pip install pylint bandit
# Java (PMD) - https://pmd.github.io ์์ pmd-bin-*.zip ๋ค์ด๋ก๋ ํ PATH ๋ฑ๋ก
# ๋๋ scoop install pmd
# JavaScript (ESLint)
npm install -g eslint# C++
brew install cppcheck
# Python
pip3 install pylint bandit
# Java
brew install pmd
# JavaScript
npm install -g eslint# C++
sudo apt install cppcheck
# Python
pip install pylint bandit
# Java - https://pmd.github.io ์์ ๋ค์ด๋ก๋
# JavaScript
npm install -g eslintgit clone https://github.com/kernullist/into-the-git.git
cd into-the-git# Windows (PowerShell)
.\scripts\setup.ps1
# macOS / Linux
bash scripts/setup.sh# ๊ฐ์ํ๊ฒฝ ์์ฑ
python -m venv venv
# ๊ฐ์ํ๊ฒฝ ํ์ฑํ
# Windows:
venv\Scripts\activate
# macOS/Linux:
source venv/bin/activate
# ์์กด์ฑ ์ค์น
pip install -e ".[dev]" # ๊ฐ๋ฐ ์์กด์ฑ ํฌํจ
# ๋๋ ์ต์ ์ค์น:
pip install -e .make setup # ๊ฐ์ํ๊ฒฝ ์์ฑ + ์์กด์ฑ ์ค์น (์ต์ด 1ํ)
make run # ๊ฐ๋ฐ ์๋ฒ ์์
make test # ํ
์คํธ ์คํ
make clean # ์บ์ ์ ๋ฆฌ
make help # ๋ชจ๋ ๋ช
๋ น์ด ํ์ธ# ์ค์น๋ ํจํค์ง ํ์ธ
pip list
# ๋๋ requirements.txt๋ก ์ค์น (pyproject.toml ๊ธฐ๋ฐ ์๋ ์์ฑ)
pip install -r requirements.txtrequirements.txt๋ pyproject.toml์์ ์์ฑ๋ ๊ณ ์ ๋ฒ์ ์
๋๋ค. ์ต์ ํธํ ๋ฒ์ ์ด ํ์ํ๋ฉด pip install -e ".[dev]"๋ฅผ ์ฌ์ฉํ์ธ์.
# .env ํ์ผ ์์ฑ (Windows)
echo GITHUB_TOKEN=ghp_your_token_here > .env
echo GITLAB_TOKEN=glpat_your_token_here >> .env
# .env ํ์ผ ์์ฑ (macOS/Linux)
cat > .env << EOF
GITHUB_TOKEN=ghp_your_token_here
GITLAB_TOKEN=glpat_your_token_here
FLASK_DEBUG=1
EOFํ๊ฒฝ๋ณ์ ๋ชฉ๋ก:
| ๋ณ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|
SECRET_KEY |
๋๋ค ์์ฑ | Flask ์ธ์ ์ํธํ ํค |
DATABASE_URL |
sqlite:///data/dashboard.db |
DB ์ฐ๊ฒฐ ๋ฌธ์์ด |
GITHUB_TOKEN |
์์ | GitHub Personal Access Token |
GITLAB_TOKEN |
์์ | GitLab Personal Access Token |
FLASK_DEBUG |
0 |
๋๋ฒ๊ทธ ๋ชจ๋ (1 = ํ์ฑํ) |
MAX_ANALYSIS_TIMEOUT |
3600 |
๋ถ์ ์ต๋ ์๊ฐ(์ด) |
WORKER_THREADS |
2 |
๋ฐฑ๊ทธ๋ผ์ด๋ ์์ปค ์ค๋ ๋ ์ |
CLUSTER_MIN_SAMPLES |
30 |
ML ํด๋ฌ์คํฐ๋ง ์ต์ ์ํ ์ |
CLASSIFIER_CONFIDENCE_THRESHOLD |
0.6 |
์ง๋ ๋ถ๋ฅ๊ธฐ ์ ๋ขฐ๋ ์๊ณ๊ฐ |
# ๊ฐ๋ฐ ์๋ฒ
python app.py๋ธ๋ผ์ฐ์ ์์ http://localhost:5000 ์ผ๋ก ์ ์ํฉ๋๋ค.
# ๋ชจ๋ ํ
์คํธ ์คํ
python -m unittest discover tests -v
# 55 tests OK ๊ฐ ์ถ๋ ฅ๋๋ฉด ์ ์Project ์์ฑ โ Repository ์ฐ๊ฒฐ โ Branch ์ ํ โ ๋ถ์ ์คํ โ ๋์๋ณด๋ ๊ฒํ โ ํผ๋๋ฐฑ โ ๋ฆฌํฌํธ Export
- ๋ฉ์ธ ํ์ด์ง์์ "+ New Project" ํด๋ฆญ
- Project ์ด๋ฆ๊ณผ ์ค๋ช ์ ๋ ฅ
- "Create Project" ํด๋ฆญ
Project ํ์ด์ง์์ "+ Add Repository" ํด๋ฆญ:
| Provider | URL ์์ | ํ ํฐ ํ์ |
|---|---|---|
| Local Path | C:\Projects\my-repo ๋๋ /home/user/my-repo |
์๋์ค |
| GitHub | https://github.com/user/repo.git |
๊ถ์ฅ |
| GitLab | https://gitlab.com/user/repo.git |
๊ถ์ฅ |
- Repository ์นด๋์์ "Select Branch" ํด๋ฆญ
- ๋ถ์ํ Branch ์ ํ (๋๋กญ๋ค์ด์์ ์๋ ์กฐํ)
- ๋ถ์ ๊ธฐ๊ฐ ์ ํ: ๊ธฐ๋ณธ๊ฐ Last 1 Month
- Last 1 Week / Last 1 Month / Last 3 Months / Custom (๋ ์ง ์ง์ ์ง์ )
- "Confirm & Analyze" ํด๋ฆญ
- Project ํ์ด์ง์์ "Run Analysis" ํด๋ฆญ
- ๋ถ์ ์คํ ํ์ด์ง์์ ์ค์๊ฐ ๋ก๊ทธ, ์งํ๋ฅ , ์ํ ํ์ธ
- ์คํ ์ค์ธ ์์ ์ Cancel ๊ฐ๋ฅ
- ์คํจํ ์์ ์ Retry ๊ฐ๋ฅ (์ฑ๊ณตํ ์ ์ฅ์ ๊ฒฐ๊ณผ ๋ณด์กด)
๋์๋ณด๋ ํ๋ฉด ๊ตฌ์ฑ:
- ์๋จ: 6๊ฐ ์งํ ์นด๋ (Findings, Recommendations, Avg Rating, Feedbacks, Complexity, Changes)
- ์ค๋จ ์ข์ธก: Findings by Severity (๋ง๋ ์ฐจํธ), Top Functions by Complexity (์ํ ๋ง๋)
- ์ค๋จ ์ฐ์ธก: Code Smell Distribution (๋๋ ์ฐจํธ), Commit Purpose Distribution (๋๋ ์ฐจํธ)
- ํ๋จ ์ข์ธก: Top Improvement Targets (์ฐ์ ์์ ์ ์ถ์ฒ ๋ชฉ๋ก)
- ํ๋จ ์ฐ์ธก: Recent Feedback (์ต์ ํผ๋๋ฐฑ ์ฝ๋ฉํธ)
- ์ตํ๋จ: ๋ณ์ + ์ฝ๋ฉํธ ํผ๋๋ฐฑ ์ ์ถ ํผ
์ข์ธก ์ฌ์ด๋๋ฐ์์ ํํฐ ์ ์ฉ:
- Project: ํ๋ก์ ํธ ์ ํ
- Repository: ์ ์ฅ์๋ณ ํํฐ
- Language: Python / JavaScript / Java / C++
- Period: 1์ฃผ / 1๊ฐ์ / 3๊ฐ์
- Severity: Critical / Major / Minor / Info
- Smell Type: ๋ถ์ ์คํ ์ ๋ฐ๊ฒฌ๋ ์นดํ ๊ณ ๋ฆฌ ๊ธฐ์ค ๋์ ์์ฑ
- Priority: High (75+) / Medium (50-74) / Low (<50)
์ถ์ฒ ๋ชฉ๋ก์ ํญ๋ชฉ์ ํด๋ฆญํ๋ฉด ์ฐ์ธก ํจ๋์ ์์ธ ์ ๋ณด ํ์:
- Contributing Signals: ๊ฐ ์ ํธ๋ณ ์ ์์ ๊ฐ์ค์น
- Findings: ํ์ผ๋ณ ์ ์ ๋ถ์ ๋ฐ๊ฒฌ์ฌํญ (๋๊ตฌ, ๊ท์น, ์ฌ๊ฐ๋)
- Symbols: ํจ์/ํด๋์ค ๋ชฉ๋ก, ๋ณต์ก๋, ๋ผ์ธ ์์น
- Commit History: ํด๋น ํ์ผ์ ์ต๊ทผ ์ปค๋ฐ ๋ด์ญ (์์ฑ์, ๋ชฉ์ , ๋ฉ์์ง)
๋์๋ณด๋ ํ๋จ์์:
- ๋ณ์ 1~5 ์ ํ (ํด๋ฆญ)
- ์ฝ๋ฉํธ ์์ฑ (ํ๊ตญ์ด/์์ด ๋ชจ๋ ์ง์)
- "Submit Feedback" ํด๋ฆญ
์ ์ถ ์:
- ๊ฐ์ฑ ์ ์ ์๋ ๊ณ์ฐ (๊ธ์ /๋ถ์ ํค์๋ ๊ธฐ๋ฐ)
- ๋ชจ๋ ์ถ์ฒ ํญ๋ชฉ์ feedback_score ์ฌ๊ณ์ฐ
- ๋์๋ณด๋ ์งํ ์๋ ๊ฐฑ์
- ๋ถ์ ์๋ฃ ํ "Export Report" ํด๋ฆญ
- Format ์ ํ:
- Markdown: AI ์ฝ๋ฉ ์์ด์ ํธ์๊ฒ ์ ๋ฌํ ํธ๋์คํ ๋ฌธ์
- JSON: ์๋ํ ๋๊ตฌ/API ์ฐ๋์ฉ ๊ธฐ๊ณ ํ๋ ํ์
- "Generate Export" โ "Download" ํด๋ฆญ
# ํ๋ก์ ํธ ๋ชฉ๋ก
curl http://localhost:5000/api/projects
# ํ๋ก์ ํธ ์์ฑ
curl -X POST http://localhost:5000/api/projects \
-H "Content-Type: application/json" \
-d '{"name": "My Project", "description": "ํ๋ก์ ํธ ์ค๋ช
"}'
# ํ๋ก์ ํธ ์ญ์
curl -X DELETE http://localhost:5000/api/projects/1# ์ ์ฅ์ ์ถ๊ฐ
curl -X POST http://localhost:5000/api/projects/1/repositories \
-H "Content-Type: application/json" \
-d '{"provider": "local", "remote_url": "/path/to/repo", "default_branch": "main"}'
# ์ ์ฅ์ ๋ธ๋์น ์กฐํ
curl http://localhost:5000/api/repositories/1/branches
# ์ ์ฅ์ ์ ๋ณด ์์ (๋ธ๋์น ์ ํ)
curl -X PUT http://localhost:5000/api/repositories/1 \
-H "Content-Type: application/json" \
-d '{"selected_branches": ["main"], "default_branch": "main"}'# ๋ถ์ ์คํ
curl -X POST http://localhost:5000/api/analysis-runs \
-H "Content-Type: application/json" \
-d '{"project_id": 1, "repository_ids": [1], "period": "1m"}'
# ์คํ ์ํ ํ์ธ
curl http://localhost:5000/api/analysis-runs/1
# ์คํ ์ทจ์
curl -X POST http://localhost:5000/api/analysis-runs/1/cancel
# ์คํจํ ์ ์ฅ์๋ง ์ฌ์๋
curl -X POST http://localhost:5000/api/analysis-runs/1/retry \
-H "Content-Type: application/json" \
-d '{"repository_ids": [1], "period": "1m"}'# ๋ฐ๊ฒฌ์ฌํญ ์กฐํ (ํ์ด์ง + ํํฐ)
curl "http://localhost:5000/api/analysis-runs/1/findings?page=1&per_page=50&severity=critical&repository_id=1"
# ๋ฐ๊ฒฌ์ฌํญ ์์ฝ
curl http://localhost:5000/api/analysis-runs/1/findings/summary
# ๋ฉํธ๋ฆญ ์กฐํ
curl http://localhost:5000/api/analysis-runs/1/metrics
# ์ถ์ฒ ๋ชฉ๋ก
curl http://localhost:5000/api/analysis-runs/1/recommendations# ๋์๋ณด๋ ๊ฐ์ (ํํฐ ํฌํจ)
curl "http://localhost:5000/api/dashboard/overview?project_id=1&repository_id=1&severity=critical&period=1m"
# ํ์ผ ์์ธ (๋๋ฆด๋ค์ด)
curl "http://localhost:5000/api/analysis-runs/1/files/src/main.py"
# ๋ณต์ก๋ ํธ๋ ๋
curl http://localhost:5000/api/analysis-runs/1/complexity-trend# ํผ๋๋ฐฑ ์ ์ถ
curl -X POST http://localhost:5000/api/analysis-runs/1/feedback \
-H "Content-Type: application/json" \
-d '{"rating": 4, "comment": "๋ถ์ ๊ฒฐ๊ณผ๊ฐ ๋งค์ฐ ์ ์ฉํฉ๋๋ค"}'
# ํผ๋๋ฐฑ ์กฐํ
curl http://localhost:5000/api/analysis-runs/1/feedback
# ๋ฆฌํฌํธ ์ต์คํฌํธ (Markdown)
curl "http://localhost:5000/api/analysis-runs/1/export?format=markdown"
# ๋ฆฌํฌํธ ์ต์คํฌํธ (JSON)
curl "http://localhost:5000/api/analysis-runs/1/export?format=json"
# ์ต์คํฌํธ ๋ค์ด๋ก๋
curl -O http://localhost:5000/api/exports/1/downloadinto-the-git/
โโโ app.py # Flask ์ ํ๋ฆฌ์ผ์ด์
์ง์
์
โโโ config.py # ์ค์ (ํ๊ฒฝ๋ณ์, DB ๊ฒฝ๋ก, ํ ํฐ)
โโโ database.py # SQLAlchemy ์ด๊ธฐํ
โโโ models.py # 11๊ฐ ์ํฐํฐ ๋ฐ์ดํฐ ๋ชจ๋ธ
โโโ requirements.txt # Python ์์กด์ฑ
โ
โโโ connectors/ # Git ์ ์ฅ์ ์ปค๋ฅํฐ
โ โโโ base.py # ์ถ์ ๋ฒ ์ด์ค ํด๋์ค
โ โโโ local.py # ๋ก์ปฌ Git (clone/fetch/branch/commit)
โ โโโ github.py # GitHub (ํ ํฐ ์ธ์ฆ)
โ โโโ gitlab.py # GitLab (ํ ํฐ ์ธ์ฆ)
โ
โโโ analysis/ # ๋ถ์ ์ค์ผ์คํธ๋ ์ด์
โ โโโ runner.py # ๋ถ์ ์คํ๊ธฐ (ThreadPoolExecutor, timeout, ๋ก๊ทธ)
โ
โโโ analyzers/ # ์ ์ ๋ถ์ ์ด๋ํฐ + AST ์์ง
โ โโโ base.py # ์ด๋ํฐ ๋ฒ ์ด์ค (subprocess ์คํ, timeout)
โ โโโ adapters.py # cppcheck / pylint / bandit / PMD / ESLint
โ โโโ ast_engine.py # ๋ค์ค ์ธ์ด AST ํ์ฑ (Python ast + ์ ๊ท์)
โ โโโ complexity.py # Cyclomatic Complexity, MI (radon + ์์ฒด)
โ โโโ duplication.py # ์ฝ๋ ๋ธ๋ก ์ค๋ณต ํ์ง (ํด์ ๊ธฐ๋ฐ)
โ โโโ dependency.py # Import/Include ์์กด์ฑ ๋ถ์
โ
โโโ commit_intel/ # ์ปค๋ฐ ์ธํ
๋ฆฌ์ ์ค
โ โโโ frequency.py # ๋ณ๊ฒฝ ๋น๋ ๊ณ์ฐ
โ โโโ classifier.py # ML ์ปค๋ฐ ๋ชฉ์ ๋ถ๋ฅ (KMeans โ NaiveBayes)
โ
โโโ scoring/ # ์ ์ ์์ง
โ โโโ engine.py # ์ฐ์ ์์ ์ ์, ์ถ์ฒ ์์ฑ
โ โโโ sentiment.py # ๊ฐ์ฑ ๋ถ์ (ํ/์ ํค์๋)
โ
โโโ normalization/ # ์ ๊ทํ ์คํค๋ง
โ โโโ schemas.py # Finding/Metric/CommitSignal ์ ๊ทํ ํจ์
โ
โโโ api/ # REST API
โ โโโ routes.py # Flask Blueprint (16+ ์๋ํฌ์ธํธ)
โ
โโโ templates/ # Jinja2 HTML ํ
ํ๋ฆฟ
โ โโโ base.html # ๊ณตํต ๋ ์ด์์ (์ฌ์ด๋๋ฐ + Chart.js CDN)
โ โโโ index.html # ํ๋ก์ ํธ ๋ชฉ๋ก + ์์ฑ
โ โโโ project.html # ์ ์ฅ์ ์ฐ๊ฒฐ + ๋ธ๋์น/๊ธฐ๊ฐ ์ ํ
โ โโโ analysis.html # ๋ถ์ ์คํ ๋ชจ๋ํฐ๋ง
โ โโโ dashboard.html # ๋ฉ์ธ ๋์๋ณด๋ (์ฐจํธ, ํํฐ, ๋๋ฆด๋ค์ด)
โ โโโ export.html # ๋ฆฌํฌํธ ์ต์คํฌํธ
โ
โโโ static/ # ์ ์ ํ์ผ
โ โโโ css/style.css # ์คํ์ผ์ํธ
โ โโโ js/dashboard.js # ๊ณตํต ์ ํธ๋ฆฌํฐ ํจ์
โ
โโโ tests/ # ํ
์คํธ
โ โโโ test_core.py # 55๊ฐ ๋จ์/ํตํฉ ํ
์คํธ
โ โโโ fixtures/ # ์ธ์ด๋ณ ์ํ ์ฝ๋
โ โโโ sample.py
โ โโโ sample.java
โ โโโ sample.js
โ โโโ sample.cpp
โ
โโโ data/ # ๋ฐํ์ ๋ฐ์ดํฐ (์๋ ์์ฑ)
โโโ dashboard.db # SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค
โโโ repos/ # ํด๋ก ๋ ์ ์ฅ์
โโโ reports/ # ์ต์คํฌํธ๋ ๋ฆฌํฌํธ
| ์ํฐํฐ | ์ฃผ์ ํ๋ | ๊ด๊ณ |
|---|---|---|
| Project | id, name, description | has many Repositories, AnalysisRuns |
| Repository | id, project_id, provider, remote_url, branches | has many SourceFiles, Findings, CommitSignals |
| AnalysisRun | id, project_id, repository_ids, status, progress, logs | has many Findings, Metrics, Feedbacks, Recommendations, Exports |
| SourceFile | id, repository_id, path, language, size, hash, owner_hint | has many CodeSymbols |
| CodeSymbol | id, file_id, kind, name, location, signature, complexity | belongs to SourceFile |
| Finding | id, run_id, repository_id, file_id, tool, rule_id, severity, category, fingerprint | belongs to AnalysisRun, Repository |
| MetricSnapshot | id, run_id, scope_type, scope_id, metric_name, value | belongs to AnalysisRun |
| CommitSignal | id, repository_id, file_id, commit_sha, author, purpose_category | belongs to Repository |
| Feedback | id, run_id, rating (1-5), comment, sentiment_score | belongs to AnalysisRun |
| Recommendation | id, run_id, target_type, priority_score, rationale, contributing_signals | belongs to AnalysisRun |
| ExportReport | id, run_id, title, format, content | belongs to AnalysisRun |
queued โ running โ completed
โ failed
โ cancelled
priority_score = (
finding_score ร 0.35 +
complexity_score ร 0.20 +
duplication_score ร 0.10 +
dependency_score ร 0.10 +
change_freq_score ร 0.15 +
feedback_score ร 0.10
) ร 10
improvement_score = star_rating ร 0.7 + sentiment_score ร 0.3
star_rating: ์ฌ์ฉ์ ๋ณ์ (1~5)sentiment_score: ํค์๋ ๊ธฐ๋ฐ ๊ฐ์ฑ ์ ์ (1.0~5.0)- ๊ธ์ /๋ถ์ ํค์๋ ๋น์จ์ ๋ฐ๋ผ ๊ณ์ฐ
- ํค์๋ ์์ผ๋ฉด ์ค๋ฆฝ (3.0)
new_feedback_score = (old_feedback_score + improvement_score) / 2
# ์ ์ฒด ํ
์คํธ ์คํ (55 tests)
python -m unittest discover tests -v
# ํน์ ํ
์คํธ ํด๋์ค๋ง ์คํ
python -m unittest tests.test_core.TestModels -v
python -m unittest tests.test_core.TestAPI -v
python -m unittest tests.test_core.TestCommitClassifier -v
# ํน์ ํ
์คํธ๋ง ์คํ
python -m unittest tests.test_core.TestRetryPreservation.test_retry_preserves_other_repo_findings -v| ์์ญ | ํ ์คํธ ์ | ์ค๋ช |
|---|---|---|
| Models | 6 | CRUD, ๊ด๊ณ, ๋ผ์ดํ์ฌ์ดํด |
| API | 5 | ํ๋ก์ ํธ, ์ ์ฅ์, ํผ๋๋ฐฑ, ์ต์คํฌํธ, ๋ฐธ๋ฆฌ๋ฐ์ด์ |
| AST Engine | 4 | Python/JS AST ํ์ฑ, ๋ณต์ก๋, import ์ถ์ถ |
| Complexity | 2 | Python ๋ณต์ก๋, Generic ๋ณต์ก๋ |
| Duplication | 2 | ์ค๋ณต ํ์ง, ์ค๋ณต ์์ ์ผ์ด์ค |
| Dependencies | 1 | ๋ด๋ถ/์ธ๋ถ ์์กด์ฑ ๋ถ์ |
| Commit Classifier | 9 | ๊ท์น ๊ธฐ๋ฐ ๋ถ๋ฅ, ๋ฐฐ์น ๋ถ๋ฅ, ํด๋ฌ์คํฐ๋ง, ์ง๋ ์ ํ |
| Change Frequency | 1 | ํ์ผ/์์ฑ์ ๋ณ๊ฒฝ ๋น๋ |
| Scoring | 2 | finding ์ ์, ์ฐ์ ์์ ์ ์ |
| Sentiment | 5 | ๊ธ์ /๋ถ์ /์ค๋ฆฝ/ํ๊ตญ์ด/๊ฐ์ ์ ์ |
| Fixture Files | 10 | 4๊ฐ ์ธ์ด ร AST + ๋ณต์ก๋ + ์ค๋ณต + import |
| Frontend Pages | 6 | ๋ชจ๋ ํ์ด์ง ๋ ๋๋ง ํ์ธ |
| Retry Preservation | 2 | ์ ํ์ ์ฌ์๋, ํผ๋๋ฐฑ ์ฌ๊ณ์ฐ |
pip install gunicorn
# 4 worker๋ก ์คํ
gunicorn -w 4 -b 0.0.0.0:5000 app:create_app\()
# ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ
gunicorn -w 4 -b 0.0.0.0:5000 app:create_app\(\) --daemonpip install waitress
# waitress ์คํ
python -c "from waitress import serve; from app import create_app; serve(create_app(), host='0.0.0.0', port=5000)"- SECRET_KEY ์ค์ :
export SECRET_KEY=$(python -c "import secrets; print(secrets.token_hex(32))") - ๋ฐฉํ๋ฒฝ:
data/repos/๋๋ ํ ๋ฆฌ์ ์ธ๋ถ ์ ๊ทผ ์ฐจ๋จ - ํ ํฐ:
GITHUB_TOKEN,GITLAB_TOKEN์ ํ๊ฒฝ๋ณ์๋ก๋ง ์ฃผ์ (์ฝ๋์ ํ๋์ฝ๋ฉ ๊ธ์ง) - ๋ฆฌ๋ฒ์ค ํ๋ก์: Nginx ๋ค์์ ์คํํ์ฌ HTTPS, rate limiting ์ ์ฉ
server {
listen 443 ssl;
server_name dashboard.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}# GitHub ์ธ์ฆ ์ค๋ฅ
โ GITHUB_TOKEN ํ๊ฒฝ๋ณ์ ์ค์ ํ์ธ
โ Personal Access Token์ repo ์ค์ฝํ๊ฐ ์๋์ง ํ์ธ
# ๋ก์ปฌ ๊ฒฝ๋ก ์ ๊ทผ ๋ถ๊ฐ
โ provider๋ฅผ "local"๋ก ์ค์ ํ๊ณ ์ ๋๊ฒฝ๋ก ์ฌ์ฉ
โ Windows: C:\Projects\my-repo (์ญ์ฌ๋์)
โ Linux/macOS: /home/user/my-repo
# ๊ฐ ๋๊ตฌ๊ฐ PATH์ ์๋์ง ํ์ธ
cppcheck --version
pylint --version
bandit --version
pmd --version
eslint --version
# ์์ผ๋ฉด ๋์๋ณด๋๋ ๋ด์ฅ AST ๋ถ์๋ง ์ํ
โ ๋ก๊ทธ์ "No <language> static analyzers available" ๋ฉ์์ง ์ถ๋ ฅ
# SQLite DB ์ฌ์์ฑ
rm data/dashboard.db # macOS/Linux
del data\dashboard.db # Windows
python app.py # ์ฌ์์ ์ ์๋ ์์ฑโ MAX_ANALYSIS_TIMEOUT ํ๊ฒฝ๋ณ์๋ก ์ ํ ์๊ฐ ์ค์
โ ๋ถ์ ๊ธฐ๊ฐ์ 1์ฃผ(1w)๋ก ์ค์ด๊ธฐ
โ ๋์ฉ๋ ์ ์ฅ์๋ ๋ธ๋์น ํํฐ ์ฌ์ฉ
โ ๋ก๊ทธ์์ "WARNING: Truncating analysis to 200 files" ๋ฉ์์ง ํ์ธ
# ๋ค๋ฅธ ํฌํธ๋ก ์คํ (Linux/macOS)
FLASK_RUN_PORT=8080 python app.py
# Windows PowerShell
$env:FLASK_RUN_PORT = "8080"
python app.py| Format | ๋์ | ์ฉ๋ |
|---|---|---|
| Markdown (.md) | AI ์ฝ๋ฉ ์์ด์ ํธ | Findings, Recommendations, Feedback ํฌํจ ํธ๋์คํ ๋ฌธ์ |
| JSON (.json) | ์๋ํ ๋๊ตฌ | CI/CD ํ์ดํ๋ผ์ธ, ์๋ฆผ ์์คํ ์ฐ๋ |
| Dashboard HTML | ๊ฐ๋ฐ์, ํ์ฅ | ์ธํฐ๋ํฐ๋ธ ์ฐจํธ, ํํฐ, ๋๋ฆด๋ค์ด์ผ๋ก ์ง์ ํ์ |
์ด ํ๋ก์ ํธ๋ ์คํ์์ค ๋๊ตฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ํตํฉ๋ ์ธ๋ถ ๋๊ตฌ์ ๋ผ์ด์ ์ค๋ฅผ ๋ฐฐํฌ ์ ์ ๊ฒํ ํ์ธ์:
- cppcheck: GPL v3
- pylint: GPL v2
- bandit: Apache 2.0
- PMD: BSD-style
- ESLint: MIT