Files

89 lines
4.7 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
# =============================================================================
# tools/git-hooks/pre-commit.sh — нативная замена lefthook-движка
# =============================================================================
# Зачем: lefthook 2.1.x виснет при `git commit` на этой Windows-машine
# (путь с кириллицей + пробелом: "C:\моя\проекты\портал crm\Документация").
# Сами проверки отрабатывают и проходят, но движок lefthook не завершается
# и плодит node-зомби (см. CHANGELOG / memory feedback_environment q.107+).
# Заменено 23.05.2026 по решению заказчика «свой простой скрипт».
#
# Этот скрипт зеркалит pre-commit джобы lefthook.yml, но:
# - вызывает инструменты напрямую (node <entry>, не npx → нет зомби-обёрток)
# - НЕ модифицирует index (нет git add / git stash / --fix) → нет конфликта
# за .git/index.lock с родительским git commit (корень зависаний lefthook)
# - имеет явный exit-код, ничего не висит
#
# Источник истины КОНФИГУРАЦИИ проверок — lefthook.yml (для CI/Linux, где
# lefthook работает штатно). Этот скрипт — локальная Windows-реализация.
#
# Bypass (как у lefthook): LEFTHOOK=0 git commit ...
# =============================================================================
[ "$LEFTHOOK" = "0" ] && exit 0
ROOT="$(git rev-parse --show-toplevel)"
cd "$ROOT" || exit 1
STAGED=$(git diff --cached --name-only --diff-filter=ACM)
[ -z "$STAGED" ] && exit 0
FAIL=0
note() { printf '\n[pre-commit] %s\n' "$1"; }
# 1. gitleaks — секреты / ПДн / токены в staged (§5.2). Нативный exe.
note "gitleaks (secrets)"
./bin/gitleaks.exe protect --staged --config .gitleaks.toml --no-banner || { note "gitleaks FAILED"; FAIL=1; }
# 2+3. markdownlint + cspell на staged .md (исключая вендоренные скилы).
# Без --fix: pre-commit не модифицирует файлы. Авто-fix — `npm run lint:md:fix`.
MD=$(printf '%s\n' "$STAGED" | grep -E '\.md$' | grep -vE '^\.claude/skills/(mermaid|ccpm|data-scientist|marketingskills)/')
if [ -n "$MD" ]; then
note "markdownlint"
node node_modules/markdownlint-cli2/markdownlint-cli2-bin.mjs $MD || { note "markdownlint FAILED — запусти 'npm run lint:md:fix'"; FAIL=1; }
note "cspell"
node node_modules/cspell/bin.mjs --no-progress --no-summary --no-gitignore $MD || { note "cspell FAILED — добавь слово в cspell-words.txt или поправь"; FAIL=1; }
fi
# 4. Stylelint на staged .html (CSS в прототипах).
HTML=$(printf '%s\n' "$STAGED" | grep -E '\.html$')
if [ -n "$HTML" ]; then
note "stylelint"
node node_modules/stylelint/bin/stylelint.mjs $HTML || { note "stylelint FAILED"; FAIL=1; }
fi
# 5. Pint (--test, без авто-fix) на staged app/**/*.php.
# NB: Larastan УБРАН из pre-commit 23.05.2026 — он анализирует весь проект через
# phpstan-baseline.neon, который дрейфит от параллельных Claude-сессий и устаревшего
# ide-helper (ImportLog @mixin и т.п.) → блокирует несвязанные коммиты сотнями
# ignore.unmatched. Larastan остаётся в lefthook.yml (CI/Linux) + ручной `composer stan`
# перед push. pint (форматирование, не baseline-зависим) остаётся.
PHP=$(printf '%s\n' "$STAGED" | grep -E '^app/.*\.php$')
if [ -n "$PHP" ]; then
PHP_REL=$(printf '%s\n' "$PHP" | sed 's#^app/##')
note "pint --test"
( cd app && php vendor/bin/pint --test $PHP_REL ) || { note "pint FAILED — запусти 'cd app && composer pint'"; FAIL=1; }
fi
# 7. squawk на staged *.sql (миграции PostgreSQL).
SQL=$(printf '%s\n' "$STAGED" | grep -E '\.sql$')
if [ -n "$SQL" ]; then
note "squawk"
./bin/squawk.exe $SQL || { note "squawk FAILED"; FAIL=1; }
fi
# 8. ESLint на staged app/resources/js/**/*.{ts,vue}.
VUE=$(printf '%s\n' "$STAGED" | grep -E '^app/resources/js/.*\.(ts|vue)$')
if [ -n "$VUE" ]; then
VUE_REL=$(printf '%s\n' "$VUE" | sed 's#^app/##')
note "eslint"
( cd app && node node_modules/eslint/bin/eslint.js $VUE_REL ) || { note "eslint FAILED"; FAIL=1; }
fi
if [ "$FAIL" = "1" ]; then
note "ОТКЛОНЕНО — проверки не пройдены (см. выше). Обход: LEFTHOOK=0 git commit ..."
exit 1
fi
note "OK — все проверки пройдены"
exit 0