phpro/grumphp
GrumPHP is a Composer plugin that installs Git hooks to run quality checks on every commit. It executes configured tasks like tests and linters, blocks failing commits, and helps teams enforce coding standards and best practices automatically.
## Getting Started
### Minimal Setup for Laravel
1. **Installation**
```bash
composer require --dev phpro/grumphp
GrumPHP auto-configures git hooks. Verify with:
composer grumphp:run
Basic Configuration
Create grumphp.yml in your Laravel project root:
grumphp:
tasks:
phpcs:
standard: PSR12
phpmd:
rulesets: ["cleancode", "codesize", "controversial", "design", "naming", "unusedcode"]
phpunit: ~
First Use Case Run GrumPHP manually to test:
composer grumphp:run
Or trigger via git commit (hooks enabled by default).
Task Integration with Laravel Features
artisan:test):
tasks:
artisan:
commands: ["test"]
args: ["--env=testing"]
.env in GrumPHP:
environment:
variables:
APP_ENV: "{{ env('APP_ENV') }}"
Parallel Task Execution
Leverage Laravel’s queue system for heavy tasks (e.g., phpstan):
parallel:
enabled: true
max_workers: 4 # Match Laravel queue workers
Task Dependencies Chain tasks like Laravel’s service providers:
tasks:
phpcs:
triggered_by: ["phpmd"]
Custom Tasks
Create a Laravel-specific task (e.g., laravel:routes):
// app/GrumPHP/Task/LaravelRoutesTask.php
namespace App\GrumPHP\Task;
use GrumPHP\Task\Task;
class LaravelRoutesTask extends Task {
public function run() {
$routes = app()->routes->getRoutes();
// Custom logic...
}
}
Register in grumphp.yml:
tasks:
app:laravel:routes: ~
CI/CD Integration Use GrumPHP in Laravel Forge/Laravel Envoyer:
# .github/workflows/ci.yml
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: composer grumphp:run --strict
Git Hook Conflicts
composer grumphp:git:deinit before deploying, then reinitialize post-deploy:
composer grumphp:git:init
Environment Variables
.env vars not passed to tasks.grumphp.yml:
environment:
files: [".env"]
Task Caching
phpstan) using Laravel’s cache:
tasks:
phpstan:
cache: true
cache_file: ~/.cache/grumphp/phpstan.laravel.cache
Debugging Fixer Issues
fix_by_default: true may auto-fix Laravel’s APP_KEY or DB configs.fixer:
enabled: true
fix_by_default: false
exclude_files: ["config/app.php", "config/database.php"]
Parallel Execution Quirks
parallel:
enabled: false
Task Event Listeners
ModelSaved) to trigger GrumPHP:
// app/Providers/AppServiceProvider.php
public function boot() {
event(new \GrumPHP\Runner\Event\RunnerEvent());
}
Strict Mode for CI
--strict in CI to fail builds:
composer grumphp:run --strict
Laravel Mix/Valet Conflicts
php path conflicts with GrumPHP’s EXEC_GRUMPHP_COMMAND.git_hook_variables:
EXEC_GRUMPHP_COMMAND: "/usr/local/bin/php"
Task Prioritization
priority to run critical tasks first (e.g., phpunit before phpcs):
tasks:
phpunit:
priority: 100
Laravel Debugbar Integration
// app/Providers/AppServiceProvider.php
use GrumPHP\Runner\Event\RunnerEvent;
public function boot() {
event(new RunnerEvent());
\Debugbar::info('GrumPHP Results', $this->grumphpResults);
}
Excluding Vendor Files
vendor/ by default.tasks:
phpcs:
exclude: ["vendor/**"]
Custom Artisan Commands
grumphp:custom command in Laravel:
php artisan make:command GrumPHPRun
Extend GrumPHP\Console\Command\RunCommand.Windows-Specific Issues
EXEC_GRUMPHP_COMMAND:
git_hook_variables:
EXEC_GRUMPHP_COMMAND: "wsl php"
Laravel Sail/Docker
git_hook_variables:
EXEC_GRUMPHP_COMMAND: "sail grumphp:run"
Task Result Storage
// After RunnerEvent::complete
\App\Models\GrumPHPResult::create([
'output' => $event->getOutput(),
'status' => $event->isSuccessful() ? 'passed' : 'failed',
]);
---
How can I help you explore Laravel packages today?