Pre-commit Setup Guide
October 22, 2025 · View on GitHub
ð¯ æŠèŠ
tree-sitter-analyzerãããžã§ã¯ãã§ã¯ãããã©ãŒãã³ã¹æé©åãããå æ¬çãªpre-commit hooksã䜿çšããŠããŸããä¿®æ£ãããã¡ã€ã«ã®ã¿ããã§ãã¯ããããšã§ãé«éãªéçºäœéšãšé«å質ãªã³ãŒãããŒã¹ã®äž¡ç«ãå®çŸããŠããŸãã
â¡ ããã©ãŒãã³ã¹æé©å
2段éãã§ãã¯æŠç¥
- ã³ãããæïŒé«éïŒ: ä¿®æ£ãããã¡ã€ã«ã®ã¿ããã§ãã¯
- ããã·ã¥æïŒå æ¬çïŒ: ãã詳现ãªãã§ãã¯ãå®è¡
ð ã»ããã¢ãã
1. Pre-commitã®ã€ã³ã¹ããŒã«
# éçºäŸåé¢ä¿ãã€ã³ã¹ããŒã«
uv sync --extra dev
# Pre-commit hooksãã€ã³ã¹ããŒã«
uv run pre-commit install
2. ååå®è¡ïŒæšå¥šïŒ
# å
šãã¡ã€ã«ã«å¯ŸããŠpre-commit hooksãå®è¡
uv run pre-commit run --all-files
ð å®è¡ãããå質ãã§ãã¯
ð ããŒã«å¥å®è¡ã¢ãŒã詳现
| ããŒã« | ã³ãããæ | ããã·ã¥æ | æåå®è¡ | 察象ãã¡ã€ã« |
|---|---|---|---|---|
| black | â | - | â | ä¿®æ£ãã¡ã€ã«ã®ã¿ |
| ruff | â | - | â | ä¿®æ£ãã¡ã€ã«ã®ã¿ |
| ruff-format | â | - | â | ä¿®æ£ãã¡ã€ã«ã®ã¿ |
| isort | â | - | â | ä¿®æ£ãã¡ã€ã«ã®ã¿ |
| pyupgrade | â | - | â | ä¿®æ£ãã¡ã€ã«ã®ã¿ |
| mypy | â | - | - | ä¿®æ£ãã¡ã€ã«ã®ã¿ |
| mypy-all | - | - | â | å šãã¡ã€ã« |
| bandit | â | - | - | ä¿®æ£ãã¡ã€ã«ã®ã¿ |
| bandit (all) | - | - | â | å šãã¡ã€ã« |
| pydocstyle | - | â | â | ä¿®æ£ãã¡ã€ã«ã®ã¿ |
| flake8 | - | â | â | ä¿®æ£ãã¡ã€ã«ã®ã¿ |
| safety | - | â | â | å šäŸåé¢ä¿ |
| quality-check | - | â | â | å šãã¡ã€ã« |
ã³ãããæïŒé«é - ä¿®æ£ãã¡ã€ã«ã®ã¿ïŒ
-
ã³ãŒããã©ãŒããã
black: Pythonã³ãŒãã®èªåãã©ãŒãããruff-format: é«éãªã³ãŒããã©ãŒããã
-
åºæ¬ãªã³ãã£ã³ã°
ruff: é«éãªPythonãªã³ã¿ãŒïŒpyflakes, pycodestyleçãçµ±åïŒ
-
åãã§ãã¯ïŒæéèŠïŒ
mypy: éçåãã§ãã¯ïŒä¿®æ£ãããã¡ã€ã«ã®ã¿ïŒ
-
ã€ã³ããŒãæŽç
isort: ã€ã³ããŒãæã®èªåæŽç
-
ã»ãã¥ãªãã£ãã§ãã¯
bandit: ã»ãã¥ãªãã£è匱æ§ã®æ€åºïŒä¿®æ£ãããã¡ã€ã«ã®ã¿ïŒ
-
PythonçŸä»£å
pyupgrade: Python 3.10+ã®æ°æ©èœãžã®èªåã¢ããã°ã¬ãŒã
-
ãã¡ã€ã«åœ¢åŒãã§ãã¯
- YAML, JSON, TOML圢åŒã®æ€èšŒ
- æ«å°Ÿç©ºçœãæ¹è¡ã®çµ±äž
- 倧ããªãã¡ã€ã«ã®æ€åº
ããã·ã¥æïŒå æ¬ç - ãã詳现ïŒ
-
ããã¥ã¡ã³ãå質
pydocstyle: Docstringå質ãã§ãã¯ïŒGoogle圢åŒïŒ
-
é«åºŠãªãªã³ãã£ã³ã°
flake8: 远å çãªã³ãŒãå質ãã§ãã¯
-
äŸåé¢ä¿è匱æ§ãã§ãã¯
safety: æ¢ç¥ã®è匱æ§ãæã€ããã±ãŒãžã®æ€åº
-
ã«ã¹ã¿ã å質ãã§ãã¯
check_quality.py: ãããžã§ã¯ãåºæã®å質ãã§ãã¯
æåå®è¡ïŒå šãã¡ã€ã« - å¿ èŠæïŒ
-
å®å šåãã§ãã¯
mypy-all: å šãã¡ã€ã«ã®åãã§ãã¯
-
å®å šã»ãã¥ãªãã£ãã§ãã¯
bandit (all): å šãã¡ã€ã«ã®ã»ãã¥ãªãã£ãã§ãã¯
ð ïž äœ¿çšæ¹æ³
éåžžã®éçºãããŒ
# ã³ãŒããç·šé
vim tree_sitter_analyzer/some_file.py
# éåžžéãã³ãããïŒèªåçã«pre-commit hooksãå®è¡ãããïŒ
git add .
git commit -m "feat: æ°æ©èœã远å "
# ããã·ã¥æã«ã远å ãã§ãã¯ãå®è¡ããã
git push origin develop
æåå®è¡
ä¿®æ£ãã¡ã€ã«ã®ã¿ïŒé«éïŒ
# ç¹å®ã®hookã®ã¿å®è¡
uv run pre-commit run mypy
uv run pre-commit run black
# å
šhookãå®è¡ïŒä¿®æ£ãã¡ã€ã«ã®ã¿ïŒ
uv run pre-commit run
# ç¹å®ã®ãã¡ã€ã«ã«å¯ŸããŠå®è¡
uv run pre-commit run --files tree_sitter_analyzer/core.py
å šãã¡ã€ã«ãã§ãã¯ïŒå æ¬çïŒ
# å
šãã¡ã€ã«ã®mypyãã§ãã¯
uv run pre-commit run mypy-all
# å
šãã¡ã€ã«ã®banditãã§ãã¯
uv run pre-commit run bandit --hook-stage manual
# å
šãŠã®æåãã§ãã¯ãå®è¡
uv run pre-commit run --hook-stage manual
# å
šhookãå
šãã¡ã€ã«ã«å¯ŸããŠå®è¡
uv run pre-commit run --all-files
段éå¥å®è¡
# ã³ãããæã®ãã§ãã¯ã®ã¿
uv run pre-commit run --hook-stage pre-commit
# ããã·ã¥æã®ãã§ãã¯ã®ã¿
uv run pre-commit run --hook-stage pre-push
# æåãã§ãã¯ã®ã¿
uv run pre-commit run --hook-stage manual
ç·æ¥æã®ã¹ããã
# ç·æ¥æã®ã¿äœ¿çšïŒæšå¥šããŸããïŒ
git commit -m "hotfix: ç·æ¥ä¿®æ£" --no-verify
ð§ èšå®ã®ã«ã¹ã¿ãã€ãº
åå¥ããŒã«ã®èšå®
- mypy:
pyproject.tomlã®[tool.mypy]ã»ã¯ã·ã§ã³ - black:
pyproject.tomlã®[tool.black]ã»ã¯ã·ã§ã³ - ruff:
pyproject.tomlã®[tool.ruff]ã»ã¯ã·ã§ã³ - isort:
pyproject.tomlã®[tool.isort]ã»ã¯ã·ã§ã³
Pre-commitèšå®
.pre-commit-config.yaml ã§ä»¥äžãã«ã¹ã¿ãã€ãºå¯èœïŒ
# ç¹å®ã®ãã¡ã€ã«ãé€å€
exclude: ^(tests/|examples/|archived_files/)
# ç¹å®ã®hookãç¡å¹å
# - id: mypy
# stages: [manual] # æåå®è¡ã®ã¿
# 倱ææã«å³åº§ã«åæ¢
fail_fast: true
ðš ãã©ãã«ã·ã¥ãŒãã£ã³ã°
ããããåé¡
-
mypyãšã©ãŒ
# åãšã©ãŒãä¿®æ£ããããäžæçã«ç¡èŠ # type: ignore ã³ã¡ã³ãã远å -
ãã©ãŒããããšã©ãŒ
# èªåä¿®æ£ãããå Žåãå€ã # å床ã³ããããè©Šè¡ git add . git commit -m "åãã¡ãã»ãŒãž" -
äŸåé¢ä¿ã®åé¡
# Pre-commitã®åã€ã³ã¹ããŒã« uv run pre-commit clean uv run pre-commit install
ããã©ãŒãã³ã¹æé©å
# ãã£ãã·ã¥ãã¯ãªã¢
uv run pre-commit clean
# ç¹å®ã®hookã®ã¿å®è¡
uv run pre-commit run --hook-stage manual mypy
â¡ ããã©ãŒãã³ã¹ç¹åŸŽ
é«éã³ããã
- ä¿®æ£ãã¡ã€ã«ã®ã¿ããã§ãã¯ïŒ
pass_filenames: trueïŒ - mypyã¯å€æŽããããã¡ã€ã«ã®ã¿ãåãã§ãã¯
- å¹³åã³ãããæé: 5-15ç§ïŒåŸæ¥ã®1/3以äžïŒ
å æ¬çããã·ã¥
- éããã§ãã¯ã¯ããã·ã¥æã«å®è¡
- CI/CDåã«å質ãä¿èšŒ
- ããŒã å šäœã§çµ±äžãããåè³ªåºæº
ð å質ã¡ããªã¯ã¹
Pre-commit hooksã«ãã以äžãä¿èšŒãããŸãïŒ
- â åå®å šæ§: mypy 100%ãã¹ïŒä¿®æ£ãã¡ã€ã«ïŒ
- â ã³ãŒãå質: ruff, flake8 100%ãã¹
- â ã»ãã¥ãªãã£: bandit, safety 100%ãã¹
- â ãã©ãŒããã: black, isort 100%çµ±äž
- â ããã¥ã¡ã³ã: pydocstyle Googleåœ¢åŒæºæ
ð¯ å©ç¹
- é«ééçº: ä¿®æ£ãã¡ã€ã«ã®ã¿ãã§ãã¯ã§åŸ æ©æéæå°å
- æ©æãšã©ãŒæ€åº: ã³ãããåã«åãšã©ãŒãçºèŠ
- äžè²«ããå質: ããŒã å šäœã§åãåºæº
- èªåä¿®æ£: å€ãã®åé¡ãèªåã§ä¿®æ£
- CI/CDå¹çå: äºåãã§ãã¯ã«ããCIæéççž®
- åŠç¿å¹æ: å質ã®é«ãã³ãŒãã®æžãæ¹ãåŠç¿
泚æ: ååã»ããã¢ããæã¯å šãã¡ã€ã«ã®ãã§ãã¯ã«æéããããå ŽåããããŸããããã®åŸã¯å€æŽããããã¡ã€ã«ã®ã¿ããã§ãã¯ãããããé«éã§ãã