Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

## <a name="documentation"></a>Documentation

Full documentation is at
Expand Down
2 changes: 1 addition & 1 deletion config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
26 changes: 26 additions & 0 deletions src/Commands/Concerns/ReadsPackageConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Simtabi\Laranail\GitCommitChecker\Commands\Concerns;

/**
* One place that knows where this package's configuration lives.
*
* The provider registers it at `laranail.git-commit-checker`. Until 2026-10 the commands read the
* bare `git-commit-checker` key instead, so an unpublished install saw null everywhere: `install`
* iterated over nothing and the hook reported itself disabled. A config published before then landed
* at the bare `config/git-commit-checker.php` and is still honoured (deprecated), so an application
* that already overrode it keeps its override.
*/
trait ReadsPackageConfig
{
protected function packageConfig(string $key, mixed $default = null): mixed
{
$config = $this->laravel['config'];

$root = $config->has('git-commit-checker.hooks') ? 'git-commit-checker' : 'laranail.git-commit-checker';

return $config->get("{$root}.{$key}", $default);
}
}
8 changes: 5 additions & 3 deletions src/Commands/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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].");
Expand Down Expand Up @@ -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');
Expand All @@ -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,
)) {
Expand Down
5 changes: 4 additions & 1 deletion src/Commands/PreCommitHookCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/Providers/GitCommitCheckerServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down
52 changes: 52 additions & 0 deletions tests/Feature/ConfigTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Config;
use Simtabi\Laranail\GitCommitChecker\Commands\PreCommitHookCommand;

/**
* The shipped config named `Simtabi\GitCommitChecker\Commands\PreCommitHookCommand`, a namespace this
* package never had, so `install` aborted with "Class [...] not found" on every hook.
*/
it('names hook commands that exist', function (): void {
$hooks = Config::get('laranail.git-commit-checker.hooks');

expect($hooks)->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');
});
Loading