cihispano / git-hooks
Automated Git Hooks for CodeIgniter 4 projects with PHPStan, PHP CS Fixer, and quality checks
Requires
- php: ^8.1
Requires (Dev)
- codeigniter/coding-standard: ^1.8
- friendsofphp/php-cs-fixer: ^3.90
- mikey179/vfsstream: ^1.6
- phpstan/phpstan: ^2
- phpunit/phpunit: ^10.5
- slevomat/coding-standard: ^8.28
- squizlabs/php_codesniffer: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-09-24 02:26:35 UTC
README
Automated Git Hooks for CodeIgniter 4 projects. This package ensures your code meets the highest quality standards by running automated checks before every commit.
β¨ Features
- π PHP Syntax Check - Validates PHP syntax (lint) on all staged files.
- π PHPStan Analysis - Performs deep static analysis to find potential bugs (Level 10).
- π PHP_CodeSniffer - Validates PSR-12 compliance and coding standards.
- π¨ PHP CS Fixer - Automatically formats code to follow defined styles.
- π― Smart Scope - Only analyzes staged files to keep your workflow fast.
- π Native ANSI Output - Beautiful, colorful console feedback with icons (respects
NO_COLOR). - π§ Zero Config - Works out of the box with sensible defaults for CI4.
πΊοΈ Roadmap
Planned, not yet available:
- Extended
git-hooks.json- Tool toggles (phpstan,phpcs,php_cs_fixer,phpunit),commit_msgoverrides (min_length,max_length,types), and a tool/config allowlist to decide which project configuration files andvendor/binbinaries the hooks may run (trust gate for SEC-001). - PHP-based hooks - Replace the current shell scripts with PHP bootstrap scripts that delegate to the package classes.
NO_COLORin shell hooks - Make the installed shell hooks honorNO_COLOR(today it is respected by the installer/uninstaller console output, not by the hook scripts).
See docs/CONFIGURATION.md for the configuration schema and defaults.
π Requirements
- PHP 8.1 to 8.4
- Git 2.0 or higher
- Composer 2.0 or higher
Compatibility policy
- Runtime compatibility: the package is supported on PHP 8.1 through 8.4.
- Development dependency resolution:
composer.lockis generated withconfig.platform.php=8.1.0. - CI validation: tests and static analysis run on PHP 8.1, 8.2, 8.3, and 8.4 in both GitHub Actions and GitLab CI.
- Coding style checks (
composer sniffandcomposer cs) run on PHP 8.1 to keep formatter and sniffer output aligne with the minimum supported runtime. - When running
composer cson PHP newer than 8.1, PHP CS Fixer may show a warning. This is expected; use PHP 8.1 locally if you want warning-free style checks.
π¦ Installation
Install the package as a development dependency:
composer require --dev cihispano/git-hooks
Then install the hooks into the current repository:
composer install-hooks
The hooks are not installed automatically on
composer install/update; runcomposer install-hooksonce per repository (and again after updating the package) to install or refresh them. Usecomposer uninstall-hooksto remove them.
Install Location
Hooks are copied to the repository's hooks directory, resolved in the following order:
git -C <directory> rev-parse --git-path hooksβ always preferred, so git decides the location for worktrees, submodules, andcore.hooksPath.- Manual fallback that parses
.git(directory orgitdir:file) and linked-worktreecommondirfiles.
The hooks source is always read from the installed package root, so the install works
identically whether the package lives at the project root or under vendor/.
π Usage
Once installed, the hooks work automatically.
pre-commit
Every time you commit code, the pre-commit hook will:
- β
Check PHP syntax on all staged
.phpfiles - β Verify formatting with PHP CS Fixer (if installed)
- β Check PSR-12 compliance with PHP_CodeSniffer (if installed)
- β Run PHPStan analysis (if installed)
commit-msg
The commit-msg hook validates the first line of your commit message:
- β Minimum 10 characters
- β Maximum 100 characters
- β Conventional Commits format
See docs/CONVENTIONAL_COMMITS.md for examples and guidance.
pre-push
Before pushing, the pre-push hook runs a full-project validation:
- β PHPUnit, if available in the target project
- β Full PHPStan analysis
This repository ships its own PHPUnit suite for the package itself. The installed pre-push hook is also
designed for consumer projects and will run PHPUnit there when it is available. If PHPUnit is not installed
in the target project, the hook skips that step and continues with the remaining checks.
Example Output
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CiHispano: Running Centralized Quality Checks
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[1/4] Checking PHP syntax...
β Syntax is valid
[2/4] Validating code style...
β Coding style verified
[3/4] Sniffing code standards...
β Standards check passed
[4/4] Running static analysis...
β Static analysis completed
β All checks passed! Proceeding with commit.
When a Check Fails
If any check fails, the commit will be blocked:
[2/4] Validating code style...
β Style violations found.
Fix the issues and try again:
# Fix code style automatically
composer cs:fix
# Stage the fixed files
git add .
# Try committing again
git commit -S -m "Your message"
π οΈ Configuration
Project configuration (git-hooks.json)
An optional git-hooks.json file in the project root controls installer behavior:
{
"auto_install": false,
"build_dir": "build"
}
auto_install(bool, defaultfalse): install hooks automatically oncomposer install/update. Without it (or withfalse), usecomposer install-hooksexplicitly.build_dir(string, defaultbuild): QA cache directory (PHPStan, PHP CS Fixer, PHPUnit).composer init-hooksgenerates the file with defaults.- Invalid JSON or wrong value types fail loudly β no silent fallback.
In consumer projects, automatic installation requires wiring the composer events in the project's own
composer.json(scripts do not propagate from dependencies):"post-install-cmd": "CiHispano\\ComposerScripts::postInstall"(andpost-update-cmd).
Skipping Hooks (Not Recommended)
If you need to commit without running the hooks:
git commit --no-verify -m "Emergency fix"
β οΈ Warning: Only use this in emergencies. Your code should always pass the quality checks.
Uninstalling Hooks
To remove the Git hooks:
composer uninstall-hooks
Customizing the Hooks
The hooks are located in your repository's hooks directory (usually .git/hooks/, but
git-first resolution honors core.hooksPath and worktrees) after installation. You can
modify them if needed, but keep in mind they will be overwritten when you update the package.
π Trust boundary
The hooks execute repository-controlled code with your user's privileges:
pre-commitruns the QA tools fromvendor/bin(php-cs-fixer,phpcs,phpstan) against the staged files, using the project's own configs when present (.php-cs-fixer(.dist).php,phpcs.xml(.dist),phpstan.neon(.dist),phpunit.xml(.dist)).pre-pushruns the project's PHPUnit suite and a full PHPStan analysis.
A malicious config file or vendor/bin tool in a checked-out branch can therefore run
code on every developer's machine at the next commit/push. Install these hooks only
in repositories you already trust β the repo config overrides the package defaults by
design, and the trust model is documented in
docs/INSTALLATION.md.
For the 0.1.0 line this is documentation only; a git-hooks.json allowlist to gate which
configs and binaries the hooks may run is planned (see Roadmap).
π Composer Scripts
This package provides the following Composer scripts:
{
"scripts": {
"install-hooks": "CiHispano\\ComposerScripts::install",
"uninstall-hooks": "CiHispano\\ComposerScripts::uninstall",
"analyze": "@php -d xdebug.mode=off -d xdebug.log= vendor/bin/phpstan analyze --verbose",
"check:all": [
"@analyze",
"@sniff",
"@cs",
"@test"
],
"clear:cache": [
"@php -r \"if (file_exists('build/.php-cs-fixer.cache')) unlink('build/.php-cs-fixer.cache');\"",
"@php -r \"if (file_exists('build/phpstan.cache')) unlink('build/phpstan.cache');\"",
"@php -r \"echo 'Cache cleared successfully' . PHP_EOL;\""
],
"cs": "@php -d xdebug.mode=off -d xdebug.log= vendor/bin/php-cs-fixer fix --ansi --verbose --dry-run --diff",
"cs:fix": "@php -d xdebug.mode=off -d xdebug.log= vendor/bin/php-cs-fixer fix --ansi --verbose --diff",
"reset": [
"@php scripts/reset.php",
"@composer install --no-interaction --optimize-autoloader"
],
"sniff": "@php -d xdebug.mode=off -d xdebug.log= vendor/bin/phpcs",
"sniff:fix": "@php -d xdebug.mode=off -d xdebug.log= vendor/bin/phpcbf",
"style": "@cs:fix",
"test": "@php -d xdebug.mode=off -d xdebug.log= vendor/bin/phpunit --configuration phpunit.xml.dist --colors=always",
"test:coverage": "@php -d xdebug.mode=coverage -d xdebug.start_with_request=yes vendor/bin/phpunit --configuration phpunit.xml.dist --colors=always --coverage-text --coverage-html build/coverage"
}
}
Add these to your composer.json to access them easily:
composer install-hooks
composer uninstall-hooks
composer analyze
composer check:all
composer clear:cache
composer sniff
composer cs
composer cs:fix
composer sniff:fix
composer style
composer reset
composer test
composer test:coverage
composer resetremoves installed dependencies and QA cache artifacts (vendor/,build/,.php-cs-fixer.cache,.phpunit.result.cache) and reinstalls everything from scratch, keepingcomposer.lockfor reproducible validation. Run it before validating each feature, fix, or bug.
π§ Integration with Existing Projects
With PHPStan
Add PHPStan to your project:
composer require --dev phpstan/phpstan
Create phpstan.neon:
parameters:
level: max
paths:
- app
With PHP CS Fixer
Add PHP CS Fixer to your project:
composer require --dev friendsofphp/php-cs-fixer
Create .php-cs-fixer.dist.php:
<?php
use PhpCsFixer\Config;
use PhpCsFixer\Finder;
$finder = Finder::create()
->in(__DIR__ . '/app')
->name('*.php');
return (new Config())
->setRules([
'@PSR12' => true,
'array_syntax' => ['syntax' => 'short'],
])
->setFinder($finder);
π€ Contributing
Contributions are welcome! Please feel free to submit a pull request or merge request.
Development Setup
# Clone the repository
git clone https://github.com/cihispano/git-hooks.git
cd git-hooks
# Install dependencies
composer install
# Run all active quality checks
composer check:all
# Or run them individually
composer analyze
composer sniff
composer cs
composer test
# Fix code style
composer cs:fix
# Generate coverage locally
composer test:coverage
Test Suite
composer analyzecomposer sniffcomposer cscomposer test
For a full local validation pass, run composer check:all. If you want an HTML
coverage report, run composer test:coverage and open the generated files under
build/coverage/.
π Changelog
Please see CHANGELOG for more information on what has changed recently.
π Security
If you discover any security-related issues, please email security@cihispano.org instead of using the issue tracker.
π License
The MIT License (MIT). Please see License File for more information.
π₯ Credits
π Support
If you find this package helpful, please consider:
- β Starring the repository
- π Reporting bugs
- π‘ Suggesting new features
- π Improving documentation
- π Contributing code
π Related Packages
- codeigniter4/framework - The CodeIgniter 4 framework
- phpstan/phpstan - PHP Static Analysis Tool
- friendsofphp/php-cs-fixer - PHP Coding Standards Fixer
Made with β€οΈ for the CodeIgniter community