Skip to content

Make packaged git hooks the source of truth #92

@coisa

Description

@coisa

Objective

Make resources/git-hooks the source of truth for Fast Forward Git hooks and keep git-hooks responsible for installing those packaged hooks into consumer repositories.

Current Limitation

The git-hooks command still carries GrumPHP initialization behavior, which makes the command do more than install the packaged hook files. That blurs ownership between GrumPHP-generated hooks and the hook templates maintained by this package.

Proposed Work

Refactor Git hook installation so the repository-maintained files in resources/git-hooks are the canonical hook templates. The command should copy those templates to the target hooks directory, apply executable permissions, and preserve the existing overwrite behavior.

Scope

  • Add missing packaged hook templates needed by the default hook set, including pre-commit and commit-msg.
  • Update packaged post-checkout and post-merge hooks to detect composer.json and composer.lock changes before running dependency refresh.
  • Expose useful hook context through DEVTOOLS_* environment variables in post-checkout and post-merge hooks.
  • Simplify GitHooksCommand so it only copies packaged hooks and sets executable permissions.
  • Update tests and documentation for the new hook installation behavior.

Non-goals

  • Changing grumphp.yml configuration or GrumPHP environment variables.
  • Updating composer.json metadata generation.
  • Replacing GrumPHP as the hook runner.
  • Reworking the full sync pipeline beyond the hook source-of-truth change.

Acceptance Criteria

Delivery Criteria

  • resources/git-hooks/pre-commit and resources/git-hooks/commit-msg are present as packaged hook templates.
  • post-checkout and post-merge run dependency refresh only when composer.json or composer.lock changed.
  • GitHooksCommand no longer runs GrumPHP initialization and only copies/chmods packaged hooks.
  • Existing source, target, no-overwrite, and executable permission behavior remains deterministic.
  • Tests cover the changed command behavior.
  • Documentation no longer references the removed --skip-grumphp-init option or GrumPHP initialization step.

Architectural / Isolation Criteria

  • MUST: The core logic MUST be isolated into dedicated classes or services instead of living inside command or controller entrypoints.
  • MUST: Responsibilities MUST be separated across input resolution, domain logic, processing or transformation, and output rendering when the change is non-trivial.
  • MUST: The command or controller layer MUST act only as an orchestrator.
  • MUST: The implementation MUST avoid tight coupling between core behavior and CLI or framework-specific I/O.
  • MUST: The design MUST allow future extraction or reuse with minimal changes.
  • MUST: The solution MUST remain extensible without requiring major refactoring for adjacent use cases.
  • MUST: Argument and option resolution MUST be validated separately from command execution logic.
  • MUST: Console formatting and rendering MUST stay separate from domain processing.
  • MUST: Exit behavior, error messaging, and generated output MUST remain deterministic and testable.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

Status

Released

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions