Легкість забезпечення якості коду: Останній посібник з pre-commit хуків на 2025 рік

Зміст

- Загальна інформація  
- Що таке Git hooks?  
- Чому використовувати pre-commit?  
 - Загальні випадки використання  
- Встановлення  

- Hooks  
 - 01 🔒 Безпека  
 - 02 🔍 Якість коду  
 - 🐍 Python  
 - 🟨 JavaScript та веб-інструменти  
 - ✅ Перевірка даних та конфігурацій  
 - 📝 Markdown  
 - 🐚 Shell  
 - 🐮 Makefile  
 - 📊 SQL код  
 - 📓 Notebooks  
 - 🖼️ Оптимізація зображень  
 - ✨ Додаткові типи файлів  
 - 03 📁 Файлова система  
 - 04 🌳 Якість Git  
 - 🪵 Обмеження репозиторію  
 - 🗒️ Стандарти повідомлень комітів  
 - 05 🧪 Швидкі тести (локальні)  

- Висновки  
 - Інші hooks, які варто розглянути  
 - Індивідуальні hooks  
 - Списки hooks  
 - Чого не вистачає?  
 - Комплексні hooks

Загальна інформація

Я займаюсь розробкою додатків з середньої школи, але перші справжні досвіди професійного програмування я здобув лише в другій половині бакалаврату. Це був вир нових концепцій — CI/CD, юніт-тестування, упаковка, управління залежностями, linting, форматування, схеми, бази даних, віддалені машини, хмарна інфраструктура, гілки Git, крім main тощо.

Цей потік інформації, у поєднанні з моїм зростаючим захопленням системним дизайном (і зростаючим розчаруванням через застарілі інструменти та неохайний код), спонукав мене заглибитися в сучасні практики розробки. Я направив цю енергію на створення GOTem (Gatlen’s Opinionated Template) — шаблону проекту, що об’єднує найкращі практики та найбільш надійні інструменти, які я вважаю найкращими. Це, можливо, трохи надмірно, але створення GOTem виконало дві функції: допомогло мені освоїти ці інструменти через практичний досвід і створило основу для майбутньої роботи, що відображає практики, які я відкривав. Це приємний побічний проект поряд із моїми звичайними обов’язками, який, сподіваюся, принесе новий погляд у дослідження в галузі безпеки ШІ — принаймні, поки ці навички не будуть автоматизовані. (✖﹏✖)

Під час цього процесу я закохався в pre-commit hooks — їх простота, потужність і чудова якість "налаштуй і забудь". На відміну від важчих рішень, як GitHub Actions, pre-commit hooks бездоганно інтегруються в щоденну розробку, залишаючись легкими. Вони особливо корисні для дослідницьких команд, які потребують забезпечення якості, але не хочуть бавитись з комплексними налаштуваннями CI/CD — ви можете налаштувати їх так, як вимагає ваш робочий процес.

Нижче ви знайдете мою ретельно відібрану колекцію pre-commit hooks, в основному (але не тільки) зосереджену на розробці Python. У той час як моя оригінальна документація містить детальні пояснення альтернатив та іншу інформацію, обмеження формату Medium змусили мене скоротити цей зміст. Для повної аргументації моїх виборів, перегляньте документацію GOTem’s Pre-Commit.

pic

Логотип Pre-Commit

Ця сторінка пояснює, що таке pre-commit hooks, чому їх використовують і яку конкретну вибірку я зробив для GOTem, щоб ваші проекти залишались чистими з кожним комітом. Файл конфігурації джерела можна знайти тут.

pic

Кінцевий результат

Що таке Git hooks?

Git hooks — це скрипти, які автоматично виконуються на певній стадії життєвого циклу Git. Найбільш часто використовуються pre-commit hooks, що запускаються перед тим, як коміт буде виконаний. Вони виступають як перша лінія захисту для якості коду, виконуючи такі функції:

  • Виявлення проблем із форматуванням
  • Знаходження потенційних загроз безпеці
  • Перевірка конфігурацій
  • Запуск швидких тестів
  • Впровадження командних стандартів

Чому використовувати pre-commit?

Pre-commit — це фреймворк, який дозволяє створювати ці Git hooks:

1.
Легко ділитись — Hooks визначаються в одному файлі YAML
2. Незалежність від мови — Працює з Python, JavaScript та іншими
3. Швидкість — Виконується лише на індексованих файлах і значно швидше за CI/CD
4. Забудькуватість — Члени команди не повинні запам'ятовувати інструменти забезпечення якості; hooks запускаються автоматично
5. Розширюваність — Велика екосистема готових до використання hooks

Pre-commit допомагає підтримувати якість коду, не уповільнюючи розробку. Хоча CI/CD пайплайни можуть займати кілька хвилин на виконання, pre-commit hooks дають миттєвий зворотний зв'язок прямо під час коміту. Попри свою назву, Pre-commit може встановлювати hooks на будь-якому етапі (наприклад: Використовуйте pre-push hook як більш витратний pre-commit для одночасного пушу кількох комітів).

Загальні випадки використання

Pre-commit може бути так строгим, як ви хочете, залежно від вашого проекту та компромісу між якістю та часом. Ось випадки, коли перевірки на рівні коміту більш доцільні, ніж на рівні pull-запиту:

  1. Linting/форматування коду та даних
  2. Перезбирання коду або документації
  3. Виконання міграцій бази даних
  4. Запобігання коміту секретів або великих файлів
  5. Вимога, щоб повідомлення комітів відповідали стандарту (наприклад, Commitizen)
  6. Запуск швидких тестів

Примітка: Husky — це альтернатива pre-commit для NodeJS.

Встановлення

Проекти, створені за допомогою GOTem, уже мають файл .pre-commit-config.yaml, налаштований як описано нижче. Якщо ви хочете створити свій власний, ви можете скористатися інструкціями тут.

Встановіть hooks за допомогою:

pre-commit install

Тепер ви побачите, як hooks виконуються після кожного коміту у вашому репозиторії.

Корисні команди:

# Тестувати hooks без коміту  
pre-commit run --all-files  

# Комітити без запуску hooks  
git commit --no-verify

Примітка: Будьте обережні з автоматичним оновленням pre-commit для неперевірених hooks через можливі загрози безпеці.

Hooks

Ця колекція пріоритетно обирає найкращі інструменти без зайвих повторів. Замість використання кількох перекриваючих інструментів, я вибрав найбільш ефективний варіант для кожного завдання. Наприклад:

  • Для linting коду Python використовується лише Ruff замість кількох окремих лінтерів
  • Для перевірки JSON/YAML/TOML використовуються спеціалізовані валідатори схем
  • Для сканування на безпеку використовується один всебічний інструмент

Усі hooks, позначені як # STRICT, за замовчуванням закоментовані і не рекомендовані для кожного проекту. (Наприклад: Лінтери стилю коду зазвичай потрібні для програмного забезпечення для виробництва, але не для дослідницьких проектів.)

01 🔒 Безпека

GitLeaks — швидкий, легкий сканер, що запобігає комітам секретів (паролів, API ключів, токенів) до вашого репозиторію.

Примітка: TruffleHog є більш комплексною, але складною альтернативою GitLeaks.

- repo:   
 rev: v8.22.1  
 hooks:  
 - id: gitleaks  
 name: "🔒 безпека · Виявлення захардкожених секретів"

02 🔍 Якість коду

Цей розділ охоплює інструменти для форматування коду, linting, перевірки типів та валідації схем для різних мов програмування та типів файлів. Були обрані найкращі інструменти, уникаючи зайвої функціональності.
Я обрав завантаження hook з віддалених репозиторіїв, а не локальними командами, щоб зробити файл більш портативним і здатним до самовстановлення.

🐍 Python

Ruff — швидкий, комплексний форматер і лінтер для Python, який замінює кілька традиційних інструментів (Black, Flake8, isort, pyupgrade, bandit, pydoclint, mccabe complexity та ін.). Хоча він ще не досяг 100% паритету з усіма цими інструментами, його швидкість та широка підтримка роблять його чудовим вибором як єдиний лінтер/форматер для Python:

pic

Порівняння Ruff з конкурентами

Примітка: До того, як з’явився Ruff, проекти використовували кілька інструментів, таких як Black, isort, Flake8 і ін. Ruff об’єднує їх, забезпечуючи кращу швидкість та сучасні за замовчуванням налаштування.

- repo:   
 rev: v0.9.1  
 hooks:  
 - id: ruff-format  
 name: "🐍 python · Форматувати за допомогою Ruff"  
 # STRICT  
 - id: ruff  
 args: [--fix]

Pyright від Microsoft займається перевіркою типів Python:

  • Розширення для VSCode, але Pylance, стандартне розширення для Python, має вбудовану підтримку.
  • Це підтримуваний спільнотою pre-commit hook, схвалений Microsoft

Примітка: MyPy — оригінальний перевіряльник типів, але Pyright має кращу швидкість і додаткові можливості.

# STRICT  
- repo:   
 rev: v1.1.391  
 hooks:  
 - id: pyright  
 name: "🐍 python · Перевірка типів"

validate-pyproject спеціально перевіряє файл pyproject.toml. У майбутньому я також можу використовувати check-jsonschema для цієї перевірки.

- repo:   
 rev: v0.23  
 hooks:  
 - id: validate-pyproject  
 name: "🐍 python · Перевірка pyproject.toml"  
 additional_dependencies: ["validate-pyproject-schema-store[all]"]

🟨 JavaScript & Web Tools

Biome — сучасний, швидкий форматер і лінтер для екосистем JS/TS (JS[X], TS[X], JSON[C], CSS, GraphQL). Він має кращі за замовчуванням налаштування, ніж ESLint.

Примітка: ESLint/Prettier більш усталені, але повільніші; використовуйте їх, якщо потрібна підтримка конкретних плагінів чи фреймворків.

- repo:   
 rev: "v0.6.1"  
 hooks:  
 - id: biome-check  
 name: "🟨 javascript · Лінтинг, форматування та безпечні виправлення з Biome"  
 additional_dependencies: ["@biomejs/[email protected]"]

✅ Валідація даних і конфігурацій

check-jsonschema перевіряє різні конфігураційні файли за допомогою JSON Schema.
Він підтримує файли JSON, YAML та TOML, а також включає спеціалізовані валідатори, такі як TaskFile та GitHub Actions для перевірки.

- repo:   
 rev: 0.31.0  
 hooks:  
 - id: check-github-workflows  
 name: "🐙 github-actions · Перевірка gh workflow файлів"  
 args: ["--verbose"]  
 - id: check-taskfile  
 name: "✅ taskfile · Перевірка конфігурації Task"

📝 Markdown

mdformat для форматування Markdown з додатковими плагінами для GitHub-Flavored Markdown, форматування коду у стилі Ruff та підтримки frontmatter:

- repo:   
 rev: 0.7.21  
 hooks:  
 - id: mdformat  
 name: "📝 markdown · Форматування markdown"  
 additional_dependencies:  
 - mdformat-gfm # Підтримка GitHub-Flavored Markdown  
 - mdformat-ruff # Форматування коду Python  
 - mdformat-frontmatter # Підтримка YAML frontmatter  
 - ruff # Потрібно для mdformat-ruff

Markdownlint для лінтингу Markdown.

- repo:   
 rev: v0.12.0  
 hooks:  
 - id: markdownlint  
 name: "📝 markdown · Лінтинг markdown"

🐚 Shell

ShellCheck для лінтингу ваших shell-скриптів.

# STRICT  
- repo:   
 rev: v0.10.0.1  
 hooks:  
 - id: shellcheck  
 name: "🐚 shell · Лінтинг shell скриптів"

bashate перевіряє стиль коду вашого shell-скрипта.

# STRICT  
- repo:   
 rev: 2.1.1  
 hooks:  
 - id: bashate  
 name: "🐚 shell · Перевірка стилю коду shell скриптів"

🐮 Makefile

Checkmake для лінтингу вашого Makefile.

- repo:   
 rev: 0.2.2  
 hooks:  
 - id: checkmake  
 name: "🐮 Makefile · Лінтинг Makefile"

📊 SQL Код

SQLFluff можна використовувати для лінтингу та автоматичної спроби виправити будь-які ваші *.sql файли.

- repo:   
 rev: 3.3.0  
 hooks:  
 - id: sqlfluff-fix  
 name: "📊 SQL · Спроба виправити порушення правил."  
 # STRICT  
 - id: sqlfluff-lint  
 name: "📊 SQL · Лінтинг SQL файлів"

📓 Ноутбуки

nbQA для забезпечення якості в Jupyter notebook, що дозволяє використовувати стандартні інструменти Python на ноутбуках.

Примітка: Ruff має нативну підтримку Jupyter Notebook, що робить деякі функції nbQA зайвими.

- repo:   
 rev: 1.9.1  
 hooks:  
 - id: nbqa  
 entry: nbqa mdformat  
 name: "📓 notebook · Форматування markdown клітинок"  
 args: ["--nbqa-md"]  
 types: [jupyter]  
 additional_dependencies:  
 - mdformat  
 - mdformat-gfm  
 - mdformat-ruff  
 - mdformat-frontmatter  
 - ruff  
 # STRICT  
 # TODO: Перевести на pyright  
 - id: nbqa-mypy  
 name: "📓 notebook · Перевірка типів клітинок"

🖼️ Оптимізація зображень

oxipng — оптимізатор PNG, написаний на Rust, з можливістю втратної та без втрат оптимізації.
(Вибір аргументів нижче дещо втрачає точність):

- repo:   
 rev: v9.1.3  
 hooks:  
 - id: oxipng  
 name: "🖼️ images · Оптимізація PNG файлів"  
 args: [  
 "-o", "4",  
 "--strip", "safe",  
 "--alpha"  
 ]

✨ Додаткові типи файлів

Prettier (HTML, YAML, CSS) займається форматуванням для різних типів файлів, не охоплених іншими інструментами. Хоча він може бути повільним, інколи викликає проблеми з форматуванням, що ламає код, і я особисто не люблю цей інструмент — він залишається стандартом для цих типів файлів.

Примітка: У майбутньому планується заміна Prettier на більш спеціалізовані інструменти для конкретних типів файлів.

- repo:   
 rev: v4.0.0-alpha.8  
 hooks:  
 - id: prettier  
 name: "✨ misc-files · Форматування різних веб-файлів"  
 types_or: [yaml, html, scss]  
 additional_dependencies:  
 - [email protected]

03 📁 Файлова система

Pre-commit hooks — це колекція хуків, керованих командою pre-commit. Ці хуки допомагають підтримувати чистоту репозиторіїв, запобігаючи загальним проблемам з файлами:

  • check-case-conflict - Запобігає проблемам на файлових системах з нечутливістю до регістру (Windows/MacOS)
  • check-symlinks & destroyed-symlinks - Підтримує цілісність символьних посилань
  • check-executables-have-shebangs - Забезпечує правильну конфігурацію скриптів
  • check-illegal-windows-names - Перевіряє файли, які не можна створити на Windows.
- repo:   
 rev: v5.0.0  
 hooks:  
 - id: check-executables-have-shebangs  
 name: "📁 filesystem/⚙️ exec · Перевірка наявності shebang"  
 - id: check-shebang-scripts-are-executable  
 name: "📁 filesystem/⚙️ exec · Перевірка прав доступу до скриптів"  
 - id: check-case-conflict  
 name: "📁 filesystem/📝 names · Перевірка чутливості до регістру"  
 - id: check-illegal-windows-names  
 name: "📁 filesystem/📝 names · Перевірка імен файлів для Windows"  
 - id: check-symlinks  
 name: "📁 filesystem/🔗 symlink · Перевірка правильності символьних посилань"  
 - id: destroyed-symlinks  
 name: "📁 filesystem/🔗 symlink · Виявлення зламаних символьних посилань"  
 # ... Більше нижче ...

04 🌳 Якість Git

🪵 Обмеження репозиторіїв

Pre-commit hooks знову, цього разу для захисту гілок, що обмежують небажані дії.

  • forbid-new-submodules - Запобігає додаванню нових git субмодулів (репозиторій у репозиторії). (На мою думку, git субмодулі — це цілком нормальна практика, але)
  • check-merge-conflict - Запобігає коміту незрозумілих конфліктів злиття
  • no-commit-to-branch - Захищає основні гілки від прямого коміту (Захисти гілок GitHub доступний тільки для членів Enterprise (на жаль))
  • check-added-large-files - Запобігає коміту файлів більше 5000KB (Git Large File Storage (LFS) або Data Version Control (DVC) слід використовувати замість цього)
- repo:   
 rev: v5.0.0  
 hooks:  
 # ... Інші вище ...  
 - id: check-merge-conflict  
 name: "🌳 git · Виявлення маркерів конфлікту"  
 - id: forbid-new-submodules  
 name: "🌳 git · Запобігання створенню субмодулів"  
 - id: no-commit-to-branch  
 name: "🌳 git · Захист основних гілок"  
 args: ["--branch", "main", "--branch", "master"]  
 - id: check-added-large-files  
 name: "🌳 git · Блокування великих файлів для коміту"  
 args: ['--maxkb=5000']

🗒️ Стандарти повідомлень комітів

Commitizen забезпечує високоякісні стандартизовані повідомлення комітів, що дозволяє автоматично генерувати зміни в журналах та використовувати семантичне версіонування.

Примітка: Commitizen надає інтерфейс командного рядка для стандартизованих комітів, з альтернативами, такими як czg для AI-згенерованих комітів.

default_install_hook_types:  
 - pre-commit  
 - commit-msg  
repos:  
# ... інші хуки ...
- repo:   
 rev: v4.1.0  
 hooks:  
 - id: commitizen  
 name: "🌳 git · Перевірка повідомлення коміту"  
 stages: [commit-msg]

Якщо ви хочете використовувати commitizen з налаштуванням cz-conventional-gitmoji, додайте additional_dependencies: [cz-conventional-gitmoji] до вашої конфігурації:

default_install_hook_types:  
 - pre-commit  
 - commit-msg  
repos:  
# ... інші хуки ...  
 - repo:   
 rev: v4.1.0  
 hooks:  
 - id: commitizen  
 name: "🌳 git · Перевірка повідомлення коміту"  
 stages: [commit-msg]  
 additional_dependencies: [cz-conventional-gitmoji] # НОВЕ

І не забудьте вказати commitizen використовувати цей пресет у вашому файлі pyproject.toml:

[tool.commitizen]  
name = "cz_gitmoji"

05 🧪 Швидкі тести (Локально)

Хоча детальні тести можуть бути занадто повільними для pre-commit хука, корисно запускати швидкі локальні тести, щоб виявити несподівані помилки у вашому коді, перш ніж ви зробите 10 комітів і будете невпевнені, який саме з них зламав ваш код.

Приклад нижче використовує pytest. Перший хук перевіряє, чи не містять тести синтаксичних помилок і чи можуть бути успішно зібрані. Це має завжди проходити.

Другий хук запускає всі швидкі тести pytests, використовуючи мій власний параметр pytest, який використовує можливість pytest-timeout, про яку ви можете прочитати тут

- repo: local  
 hooks:  
 - id: pytest-collect  
 name: 🧪 test · Перевірка форматування тестів  
 entry: ./.venv/bin/pytest tests  
 language: system  
 types: [python]  
 args: ["--collect-only"]  
 pass_filenames: false  
 always_run: true  
 # STRICT  
 - id: pytest-fast  
 name: 🧪 test · Запуск швидких тестів  
 entry: ./.venv/bin/pytest tests  
 language: system  
 types: [python]  
 args: ["--max-timeout=3"]  
 pass_filenames: false  
 always_run: true

Висновок

Це далеко не вичерпний список чудових хуків. Ви можете вибирати та комбінувати їх на свій розсуд.
Хуки не існують для всіх інструментів, тому, якщо ви хочете запустити такі інструменти, ви завжди можете використовувати локальний хук:

- repo: local  
 hooks:  
 - id: make-lint  
 name: Запустити 'make lint'  
 entry: make  
 args: ["lint"]  
 language: system

остаточний файл .pre-commit-config.yaml

exclude: |  
 (?x)^(  
 .*\{\{.*\}\}.*| # Виключити файли з змінними cookiecutter  
 docs/site/.*| # Виключити зкомпільовані файли mkdocs  
 \.history/.*| # Виключити файли історії  
 .*cache.*/.*| # Виключити каталоги кешу  
 .*venv.*/.*| # Виключити каталоги віртуальних середовищ  
 )$  
fail_fast: true  
default_language_version:  
 python: python3.12  
default_install_hook_types:  
 - pre-commit  
 - commit-msg  
repos:  
 #  
 # Документація тут:  
 # https://gatlenculp.github.io/gatlens-opinionated-template/precommit/  
 #  
 # ---------------------------------------------------------------------------- #  
 # 🔄 Pre-Commit Hooks #  
 # ---------------------------------------------------------------------------- #  

 # ----------------------------- 🔒 Інструменти безпеки ---------------------------- #  

 - repo: https://github.com/gitleaks/gitleaks  
 rev: v8.22.1  
 hooks:  
 - id: gitleaks  
 name: "🔒 безпека · Виявлення хардкодованих секретів"  

 # --------------------------- 🔍 Інструменти для якості коду -------------------------- #  

 ### Інструменти для Python ###  
 - repo: https://github.com/astral-sh/ruff-pre-commit  
 rev: v0.9.1  
 hooks:  
 - id: ruff-format  
 name: "🐍 python · Форматування з Ruff"  
 # STRICT  
 # - id: ruff  
 # name: "🐍 python · Лінтинг та безпечне автозміщення з Ruff"  
 # args: [--fix]  

 # STRICT  
 # - repo: https://github.com/RobertCraigie/pyright-python  
 # rev: v1.1.391  
 # hooks:  
 # - id: pyright  
 # name: "🐍 python · Перевірка типів"  

 - repo: https://github.com/abravalheri/validate-pyproject  
 rev: v0.23  
 hooks:  
 - id: validate-pyproject  
 name: "🐍 python · Перевірка pyproject.toml"  
 additional_dependencies: ["validate-pyproject-schema-store[all]"]  

 ### Інструменти для Javascript та веб-розробки ###  
 - repo: https://github.com/biomejs/pre-commit  
 rev: "v0.6.1"  
 hooks:  
 - id: biome-check  
 name: "🟨 javascript · Лінтинг, форматування та безпечні виправлення з Biome"  
 additional_dependencies: ["@biomejs/[email protected]"]  

 ### Перевірка даних та конфігурацій ###  
 - repo: https://github.com/python-jsonschema/check-jsonschema  
 rev: 0.31.0  
 hooks:  
 - id: check-github-workflows  
 name: "🐙 github-actions · Перевірка gh workflow файлів"  
 args: ["--verbose"]  
 - id: check-taskfile  
 name: "✅ taskfile · Перевірка конфігурації Task"  

 ### Markdown ###  
 - repo: https://github.com/hukkin/mdformat  
 rev: 0.7.21  
 hooks:  
 - id: mdformat  
 name: "📝 markdown · Форматування markdown"  
 additional_dependencies:  
 - mdformat-gfm  
 - mdformat-ruff  
 - mdformat-frontmatter  
 - ruff  

 # STRICT  
 # - repo: https://github.com/markdownlint/markdownlint  
 # rev: v0.12.0  
 # hooks:  
 # - id: markdownlint  
 # name: "📝 markdown · Лінтинг markdown"  

 ### Shell ###  

 # STRICT  
 # - repo: https://github.com/shellcheck-py/shellcheck-py  
 # rev: v0.10.0.1  
 # hooks:  
 # - id: shellcheck  
 # name: "🐚 shell · Лінтинг shell скриптів"  

 # STRICT  
 # - repo: https://github.com/openstack/bashate  
 # rev: 2.1.1  
 # hooks:  
 # - id: bashate  
 # name: "🐚 shell · Перевірка стилю коду shell скриптів"  

 ### Makefile ###  
 - repo: https://github.com/mrtazz/checkmake.git  
 rev: 0.2.2  
 hooks:  
 - id: checkmake  
 name: "🐮 Makefile · Лінтинг Makefile"  

 ### SQL ###  

 - repo: https://github.com/sqlfluff/sqlfluff  
 rev: 3.3.0  
 hooks:  
 - id: sqlfluff-fix  
 name: "📊 SQL · Спроба виправити порушення правил."  
 # STRICT  
 # - id: sqlfluff-lint  
 # name: "📊 SQL · Лінтинг SQL файлів коду"  

 ### Ноутбуки ###  
 - repo: https://github.com/nbQA-dev/nbQA  
 rev: 1.9.1  
 hooks:  
 - id: nbqa  
 entry: nbqa mdformat  
 name: "📓 notebook · Форматування markdown клітинок"  
 args: ["--nbqa-md"]  
 types: [jupyter]  
 additional_dependencies:
- mdformat  
 - mdformat-gfm  
 - mdformat-ruff  
 - mdformat-frontmatter  
 - ruff  
 # STRICT  
 # TODO: Перевести на pyright  
 - id: nbqa-mypy  
 name: "📓 notebook · Перевірка типів клітинок"  

 ### PNG зображення ###  
 - repo: https://github.com/shssoichiro/oxipng  
 rev: v9.1.3  
 hooks:  
 - id: oxipng  
 name: "🖼️ images · Оптимізація PNG файлів"  
 args: ["-o", "4", "--strip", "safe", "--alpha"]  

 ### Додаткові типи файлів ###  
 - repo: https://github.com/pre-commit/mirrors-prettier  
 rev: v4.0.0-alpha.8  
 hooks:  
 - id: prettier  
 name: "✨ misc-files · Форматування інших веб-файлів"  
 types_or: [yaml, html, scss]  
 additional_dependencies:  
 - [email protected]  

 # ---------------------------- 📁 Інструменти файлової системи --------------------------- #  

 - repo: https://github.com/pre-commit/pre-commit-hooks  
 rev: v5.0.0  
 hooks:  
 # Перевірки файлової системи  
 - id: check-executables-have-shebangs  
 name: "📁 filesystem/⚙️ exec · Перевірка наявності shebang"  
 - id: check-shebang-scripts-are-executable  
 name: "📁 filesystem/⚙️ exec · Перевірка прав доступу до скриптів"  
 - id: check-case-conflict  
 name: "📁 filesystem/📝 names · Перевірка чутливості до регістру"  
 - id: check-illegal-windows-names  
 name: "📁 filesystem/📝 names · Перевірка імен файлів Windows"  
 - id: check-symlinks  
 name: "📁 filesystem/🔗 symlink · Перевірка валідності символьних посилань"  
 - id: destroyed-symlinks  
 name: "📁 filesystem/🔗 symlink · Виявлення зламаних символьних посилань"  
 # ------------------------------- 🌳 Інструменти Git ------------------------------- #  
 - id: check-merge-conflict  
 name: "🌳 git · Виявлення маркерів конфліктів"  
 - id: forbid-new-submodules  
 name: "🌳 git · Запобігання створенню підмодулів"  
 - id: no-commit-to-branch  
 name: "🌳 git · Захист основних гілок"  
 args: ["--branch", "main", "--branch", "master"]  
 - id: check-added-large-files  
 name: "🌳 git · Блокування великих файлів у комітах"  
 args: ["--maxkb=5000"]  

 # ---------------------------------------------------------------------------- #  
 # 📝 Хуки для повідомлень комітів #  
 # ---------------------------------------------------------------------------- #  
 #  
 # --------------------------- ✍️ Якість повідомлень комітів -------------------------- #  

 ### Стандарти повідомлень комітів ###  
 - repo: https://github.com/commitizen-tools/commitizen  
 rev: v4.1.0  
 hooks:  
 - id: commitizen  
 name: "🌳 git · Перевірка повідомлення коміту"  
 stages: [commit-msg]  
 additional_dependencies: [cz-conventional-gitmoji]  

 # ---------------------------------------------------------------------------- #  
 # 🧪 Швидкі тести (локально) #  
 # ---------------------------------------------------------------------------- #  

 - repo: local  
 hooks:  
 - id: pytest-collect  
 name: 🧪 test · Перевірка форматування тестів  
 entry: ./.venv/bin/pytest tests  
 language: system  
 types: [python]  
 args: ["--collect-only"]  
 pass_filenames: false  
 always_run: true  
 # STRICT  
 - id: pytest-fast  
 name: 🧪 test · Запуск швидких тестів  
 entry: ./.venv/bin/pytest tests  
 language: system  
 types: [python]  
 args: ["--max-timeout=3"]  
 pass_filenames: false  
 always_run: true

Інші хуки, які варто розглянути

Ось деякі інші хуки, які я не додав, але розглядав би для додавання!

Індивідуальні хуки

  • buildbuf — Лінтер для Protobuf
  • Clang — Лінтер для C++
  • gitlint — Альтернатива commitlint, можливо, навіть краща.
  • typos або codespell — Знаходить поширені помилки в коді та документації.
    Один блог віддає перевагу Typos перед codespell, оскільки він знаходить більше помилок (і, ймовірно, має підтримку для VSCode?)
  • yamllint — Лінтер для YAML
  • yamlfmt — Форматувач YAML від Google
  • actionlint — Лінтер для файлів GitHub Actions, можливо, кращий перевіряльник, ніж той, що обраний зараз.
  • uv pre-commits — Колекція pre-commit хуків для uv від Astral
  • Vulture або Deadcode — Виявляє невикористовуваний код у Python
  • sync-pre-commit-deps — Синхронізація залежностей pre-commit хуків на основі інших встановлених хуків (для уникнення встановлення кількох версій, припускаю).

Списки хуків

  • featured hooks від команди pre-commit
  • first-party hooks від команди pre-commit (деякі з них використано в цьому посібнику).
  • Megalinter’s Supported Linters — Не всі з них можуть мати pre-commit хуки, але все одно це чудова колекція інструментів для QA!
  • (Більше, але вам доведеться знайти їх самостійно :P)

Чого не вистачає?

  • Оптимізатори для файлів більше ніж тільки для PNG (JPG, GIF тощо)
  • Перевірка на ненормативну лексику (Ви будете здивовані кількістю нецензурної лексики в проектах з друзями). Це можна можливо зробити за допомогою GitLeaks
  • … Цей список може бути безкінечним …

Енсамбль хуків (Лінтери, форматувальники тощо)

Я трохи перегнув палицю, вибираючи свої улюблені форматувальники, лінтери тощо. Це може призвести до необхідності підтримувати більше хуків, ніж це варто. В списку моїх задач — подивитися на енсамбль лінтерів та форматувальників, таких як Megalinter та Superlinter, що значно зменшить кількість роботи з підтримкою QA коду і надасть підтримку для мов, не шукаючи кілька хуків для кожної з них. Вони також мають перевагу в кращій інтеграції з іншими інструментами CI/CD, попередньо зібраними контейнерами та скануванням на безпеку.

🦙 MegaLinter аналізує 50 мов, 22 формати, 21 формат інструментів, надмірне копіювання, орфографічні помилки та проблеми безпеки у вихідному коді вашого репозиторію за допомогою GitHub Action, інших інструментів CI або локально.

Мене трохи турбує, що ці енсамбль лінтери можуть стати додатковим неприємним програмним забезпеченням, яке треба вивчити та налаштувати, що може відштовхнути невеликі команди від їх використання. Крім того, це програмне забезпечення може не підтримувати ваші улюблені лінтери — деякі з яких згадані в цьому посібнику, такі як Biomejs та mdformat. Я впевнений, що список доступних інструментів можна розширити, хоча я не зовсім впевнений, скільки зусиль потрібно для цього.

Перекладено з: Effortless Code Quality: The Ultimate Pre-Commit Hooks Guide for 2025

Leave a Reply

Your email address will not be published. Required fields are marked *