Problem
Currently, phpro/grumphp is installed as a direct dependency in composer.json. This approach can cause dependency resolution conflicts because:
- The direct dependency pulls in its full transitive dependency tree
- This can block versions of other packages during
composer install or composer update
- The locked versions may conflict with project-specific requirements in other repositories that consume this package
Additionally, the current GrumPHP configuration is limited to pre-commit hooks only, without handling branch-based dependency synchronization.
Proposal
Migrate from phpro/grumphp to phpro/grumphp-shim and enhance the git workflow integration to provide a more robust development experience:
- Switch to
grumphp-shim: Replace the direct phpro/grumphp dependency with phpro/grumphp-shim, which is a no-dependency metapackage that provides the GrumPHP executable without forcing specific dependency versions
- Add post-checkout hook: Ensure vendor dependencies reflect the correct state for the current branch after checkout
- Add post-merge hook: Re-install dependencies after merge operations to stay synchronized
Goals
Expected Behavior
After this change:
- Installing
fast-forward/dev-tools will no longer impose version constraints from phpro/grumphp transitive dependencies
- When switching branches, the post-checkout hook will check if
composer.lock changed and run composer install if needed
- After merging branches, the post-merge hook will ensure dependencies are up-to-date
- Pre-commit hooks continue to run
composer dev-tools validation before commits are allowed
Implementation Strategy
- Replace
phpro/grumphp with phpro/grumphp-shim in composer.json require section
- Update the
grumphp.yml configuration to include additional git hooks
- Add
stop_on_failure: true to maintain the current behavior
- Test the migration to ensure backward compatibility
composer.json changes
- "phpro/grumphp": "^2.19",
+ "phpro/grumphp-shim": "^0.1.0",
grumphp.yml enhancements
- Add
composer_checker_task (optional): Check if composer.json and composer.lock are synchronized
- Add git hook configuration for post-checkout and post-merge
- These hooks should:
- Check if
composer.lock was modified
- Run
composer install --no-interaction if needed
Additional Enhancements (Suggested)
The following enhancements could improve the GrumPHP integration beyond the core requirement:
| Enhancement |
Description |
Priority |
| Parallel task execution |
Run independent tasks in parallel for faster validation |
Low |
| Task caching |
Cache task results to speed up subsequent runs |
Medium |
| Enhanced emoji output |
Use emoji in console output for better visual feedback |
Low |
| Custom task configuration |
Allow repository-specific task overrides |
Medium |
Non-goals
- Does NOT change: The existing pre-commit validation behavior
- Does NOT add: New validation rules beyond what
dev-tools already provides
- Does NOT modify: The core plugin functionality of
dev-tools
Benefits
- Better dependency resolution: Eliminates version conflicts in downstream projects
- Synchronized vendor state: Ensures developers always have the correct dependencies for the current branch
- Improved DX: Automatic synchronization reduces manual intervention when switching contexts
Acceptance Criteria
Functional Criteria
Verification Commands
# Verify grumphp-shim is installed
composer show phpro/grumphp-shim
# Test pre-commit validation (should fail without --no-verify)
echo "invalid php" > /tmp/test.php
git add /tmp/test.php
# grumphp should catch this in pre-commit
# Verify git hooks are registered
cat .git/hooks/pre-commit | head -5
cat .git/hooks/post-checkout | head -5
cat .git/hooks/post-merge | head -5
Architectural / Isolation Criteria
- MUST: The GrumPHP configuration MUST be isolated in
grumphp.yml as a declarative configuration file.
- MUST: Any custom tasks or extensions MUST be implemented as separate classes in
src/GrumPHP/ following the existing namespace conventions.
- MUST: The implementation MUST allow GrumPHP to be disabled or overridden in consuming projects without breaking functionality.
Problem
Currently,
phpro/grumphpis installed as a direct dependency incomposer.json. This approach can cause dependency resolution conflicts because:composer installorcomposer updateAdditionally, the current GrumPHP configuration is limited to pre-commit hooks only, without handling branch-based dependency synchronization.
Proposal
Migrate from
phpro/grumphptophpro/grumphp-shimand enhance the git workflow integration to provide a more robust development experience:grumphp-shim: Replace the directphpro/grumphpdependency withphpro/grumphp-shim, which is a no-dependency metapackage that provides the GrumPHP executable without forcing specific dependency versionsGoals
phpro/grumphptransitive dependenciescomposer.lockafter branch switchesExpected Behavior
After this change:
fast-forward/dev-toolswill no longer impose version constraints fromphpro/grumphptransitive dependenciescomposer.lockchanged and runcomposer installif neededcomposer dev-toolsvalidation before commits are allowedImplementation Strategy
phpro/grumphpwithphpro/grumphp-shimincomposer.jsonrequire sectiongrumphp.ymlconfiguration to include additional git hooksstop_on_failure: trueto maintain the current behaviorcomposer.json changes
grumphp.yml enhancements
composer_checker_task(optional): Check ifcomposer.jsonandcomposer.lockare synchronizedcomposer.lockwas modifiedcomposer install --no-interactionif neededAdditional Enhancements (Suggested)
The following enhancements could improve the GrumPHP integration beyond the core requirement:
Non-goals
dev-toolsalready providesdev-toolsBenefits
Acceptance Criteria
Functional Criteria
phpro/grumphp-shimis installed instead ofphpro/grumphpcomposer dev-toolsbefore commits are acceptedcomposer installwhencomposer.lockchangescomposer installafter merge operationsVerification Commands
Architectural / Isolation Criteria
grumphp.ymlas a declarative configuration file.src/GrumPHP/following the existing namespace conventions.