From 3bd874dde6eb1e639bff7c347766e75d6d755dc9 Mon Sep 17 00:00:00 2001 From: Imani Manyara Date: Sat, 3 Oct 2026 04:31:41 -0400 Subject: [PATCH] Make install work and read the config where it is registered Two defects stopped the package working at all. The shipped config named the hook command Simtabi\GitCommitChecker\Commands\PreCommitHookCommand, a namespace the package never had, so install aborted with "Class [...] not found". And both commands read the bare git-commit-checker key while the provider registers laranail.git-commit-checker. On an unpublished install, install iterated no hooks and the hook always reported itself disabled. The config now names the real class. Both commands read through one helper that prefers laranail.git-commit-checker and still honours a config published to the old bare path, as a deprecated fallback. The publish tag now writes config/laranail/git-commit-checker.php. Tests cover the class existing, the hook running when enabled and skipping when disabled at the registered key, and the legacy override. The class and enabled tests failed before the fix. The README gains its Quick start. --- CHANGELOG.md | 20 ++++++- README.md | 13 +++++ config/config.php | 2 +- src/Commands/Concerns/ReadsPackageConfig.php | 26 ++++++++++ src/Commands/InstallCommand.php | 8 +-- src/Commands/PreCommitHookCommand.php | 5 +- .../GitCommitCheckerServiceProvider.php | 2 +- tests/Feature/ConfigTest.php | 52 +++++++++++++++++++ 8 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 src/Commands/Concerns/ReadsPackageConfig.php create mode 100644 tests/Feature/ConfigTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index d9792c4..8f358c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -_Nothing yet._ +### Fixed + +- **`install` works.** The shipped config named the hook command + `Simtabi\GitCommitChecker\Commands\PreCommitHookCommand`, a namespace this package never had, + so `install` aborted with *"Class [...] not found"*. It now names + `Simtabi\Laranail\GitCommitChecker\Commands\PreCommitHookCommand`. +- **The config is read where the provider registers it.** Both commands read the bare + `git-commit-checker` key while the defaults live at `laranail.git-commit-checker`, so an + unpublished install iterated no hooks and the hook always reported itself disabled. + +### Deprecated + +- **A config published to `config/git-commit-checker.php`** is still honoured. Republish with + `--tag=laranail::git-commit-checker-config`, which now writes + `config/laranail/git-commit-checker.php`, and delete the old file. + +### Added + +- A `Quick start` section in the README. ## v0.1.0 diff --git a/README.md b/README.md index 9110bf4..7e8c0ce 100755 --- a/README.md +++ b/README.md @@ -16,6 +16,19 @@ Requires PHP `^8.4.1 || ^8.5` and Laravel `^13.0`. composer require laranail/git-commit-checker ``` +## Quick start + +```bash +# Write .git/hooks/pre-commit and, optionally, a pint.json preset +php artisan git-commit-checker:install + +# Every commit now runs Pint in --test mode over the changed PHP files; +# run the same check by hand without committing +php artisan git-commit-checker:pre-commit-hook +``` + +How the hook is wired is in [Architecture](docs/architecture.md); everything else is in the [documentation index](#documentation). + ## Documentation Full documentation is at diff --git a/config/config.php b/config/config.php index 48e499f..4ea6dd3 100644 --- a/config/config.php +++ b/config/config.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use Simtabi\GitCommitChecker\Commands\PreCommitHookCommand; +use Simtabi\Laranail\GitCommitChecker\Commands\PreCommitHookCommand; return [ 'enabled' => env('GIT_COMMIT_CHECKER_ENABLED', true), diff --git a/src/Commands/Concerns/ReadsPackageConfig.php b/src/Commands/Concerns/ReadsPackageConfig.php new file mode 100644 index 0000000..06b6ca9 --- /dev/null +++ b/src/Commands/Concerns/ReadsPackageConfig.php @@ -0,0 +1,26 @@ +laravel['config']; + + $root = $config->has('git-commit-checker.hooks') ? 'git-commit-checker' : 'laranail.git-commit-checker'; + + return $config->get("{$root}.{$key}", $default); + } +} diff --git a/src/Commands/InstallCommand.php b/src/Commands/InstallCommand.php index 2e22754..d17ee7e 100644 --- a/src/Commands/InstallCommand.php +++ b/src/Commands/InstallCommand.php @@ -9,11 +9,13 @@ use Illuminate\Console\ConfirmableTrait; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Attribute\AsCommand; +use Simtabi\Laranail\GitCommitChecker\Commands\Concerns\ReadsPackageConfig; #[AsCommand('git-commit-checker:install', 'Install "pre_commit" hook into your git.')] class InstallCommand extends Command { use ConfirmableTrait; + use ReadsPackageConfig; public function handle(): int { @@ -29,7 +31,7 @@ public function handle(): int return self::FAILURE; } - foreach ($this->laravel['config']->get('git-commit-checker.hooks') as $hook => $command) { + foreach ($this->packageConfig('hooks', []) as $hook => $command) { $this->install($hook, $command) ? $this->components->info("Hook [$hook] is installed successfully.") : $this->components->error("Unable to install hook [$hook]."); @@ -88,7 +90,7 @@ protected function generateHookScript(string $signature): string protected function generatePintConfiguration(string $path): void { - $presets = $this->laravel['config']->get('git-commit-checker.pint.presets', []); + $presets = $this->packageConfig('pint.presets', []); if (empty($presets)) { $this->components->error('Do not found a list of supported presets'); @@ -104,7 +106,7 @@ protected function generatePintConfiguration(string $path): void json_encode( $preset !== 'recommended' ? ['preset' => $preset] - : $this->laravel['config']->get('git-commit-checker.pint.recommended_preset'), + : $this->packageConfig('pint.recommended_preset'), JSON_PRETTY_PRINT, ) . PHP_EOL, )) { diff --git a/src/Commands/PreCommitHookCommand.php b/src/Commands/PreCommitHookCommand.php index 9ad23cc..48ddf65 100644 --- a/src/Commands/PreCommitHookCommand.php +++ b/src/Commands/PreCommitHookCommand.php @@ -11,13 +11,16 @@ use Illuminate\Console\Command; use Symfony\Component\Process\Process; use Symfony\Component\Console\Attribute\AsCommand; +use Simtabi\Laranail\GitCommitChecker\Commands\Concerns\ReadsPackageConfig; #[AsCommand('git-commit-checker:pre-commit-hook', 'Git hook before commit')] class PreCommitHookCommand extends Command { + use ReadsPackageConfig; + public function handle(): int { - if (! $this->laravel['config']->get('git-commit-checker.enabled')) { + if (! $this->packageConfig('enabled')) { $this->components->info('git-commit-hook is disabled. Skipped.'); return self::SUCCESS; diff --git a/src/Providers/GitCommitCheckerServiceProvider.php b/src/Providers/GitCommitCheckerServiceProvider.php index 7b5b27c..bbec619 100644 --- a/src/Providers/GitCommitCheckerServiceProvider.php +++ b/src/Providers/GitCommitCheckerServiceProvider.php @@ -21,7 +21,7 @@ public function boot() if ($this->app->runningInConsole()) { $this->publishes([ - __DIR__ . '/../../config/config.php' => config_path('git-commit-checker.php'), + __DIR__ . '/../../config/config.php' => config_path('laranail/git-commit-checker.php'), ], 'laranail::git-commit-checker-config'); $this->publishes([ diff --git a/tests/Feature/ConfigTest.php b/tests/Feature/ConfigTest.php new file mode 100644 index 0000000..8e5479c --- /dev/null +++ b/tests/Feature/ConfigTest.php @@ -0,0 +1,52 @@ +toBeArray()->not->toBeEmpty(); + + foreach ($hooks as $hook => $class) { + expect(class_exists($class))->toBeTrue("hook [$hook] names a class that does not exist: $class") + ->and(is_subclass_of($class, Command::class))->toBeTrue(); + } + + expect($hooks['pre-commit'])->toBe(PreCommitHookCommand::class); +}); + +/** + * Registered at `laranail.git-commit-checker`, read at the bare `git-commit-checker` key: unpublished, + * `enabled` was null, so the hook reported "disabled" and checked nothing, ever. + */ +it('runs the hook when enabled at the registered key', function (): void { + Config::set('laranail.git-commit-checker.enabled', true); + + $this->artisan('git-commit-checker:pre-commit-hook') + ->doesntExpectOutputToContain('is disabled'); +}); + +it('skips the hook when disabled at the registered key', function (): void { + Config::set('laranail.git-commit-checker.enabled', false); + + $this->artisan('git-commit-checker:pre-commit-hook') + ->expectsOutputToContain('is disabled') + ->assertSuccessful(); +}); + +/** An application that published the old bare config/git-commit-checker.php keeps its override. */ +it('still honours a config published to the old bare path', function (): void { + Config::set('git-commit-checker', array_replace(Config::get('laranail.git-commit-checker'), ['enabled' => false])); + Config::set('laranail.git-commit-checker.enabled', true); + + $this->artisan('git-commit-checker:pre-commit-hook') + ->expectsOutputToContain('is disabled'); +});