Skip to content

Commit 4513721

Browse files
committed
- Add MakeHook command for creating new Git hooks based on stubs
- Add TODOs, implement logic and run the next hook in the chain for new Git hooks.
1 parent 45fdd97 commit 4513721

17 files changed

+355
-16
lines changed

src/Console/Commands/MakeHook.php

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<?php
2+
3+
namespace Igorsgm\GitHooks\Console\Commands;
4+
5+
use Igorsgm\GitHooks\Facades\GitHooks;
6+
use Illuminate\Console\Concerns\CreatesMatchingTest;
7+
use Illuminate\Console\GeneratorCommand;
8+
use Illuminate\Support\Str;
9+
use Symfony\Component\Console\Input\InputArgument;
10+
use Symfony\Component\Console\Input\InputOption;
11+
12+
class MakeHook extends GeneratorCommand
13+
{
14+
use CreatesMatchingTest;
15+
16+
/**
17+
* The console command name.
18+
*
19+
* @var string
20+
*/
21+
protected $name = 'git-hooks:make';
22+
23+
/**
24+
* The console command description.
25+
*
26+
* @var string
27+
*/
28+
protected $description = 'Create a new Hook';
29+
30+
/**
31+
* The type of class being generated.
32+
*
33+
* @var string
34+
*/
35+
protected $type = 'Git Hook';
36+
37+
/**
38+
* Execute the console command.
39+
*
40+
* @return bool|null
41+
*
42+
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
43+
*/
44+
public function handle()
45+
{
46+
$supportedHooks = GitHooks::getSupportedHooks();
47+
48+
if (! in_array($this->argument('hookType'), $supportedHooks)) {
49+
$this->getOutput()->writeln(sprintf(
50+
'<bg=red;fg=white> ERROR </> Invalid hook type. Valid types are: <comment>%s</comment>',
51+
implode(', ', $supportedHooks)
52+
));
53+
54+
return false;
55+
}
56+
57+
return parent::handle();
58+
}
59+
60+
/**
61+
* Replace the class name for the given stub.
62+
*
63+
* @param string $stub
64+
* @param string $name
65+
* @return string
66+
*/
67+
protected function replaceClass($stub, $name)
68+
{
69+
$stub = parent::replaceClass($stub, $name);
70+
71+
$hookName = Str::of($name)->classBasename()->snake()->replace('_', ' ')->title()->value();
72+
73+
return str_replace(['{{ hookName }}'], $hookName, $stub);
74+
}
75+
76+
/**
77+
* Get the stub file for the generator.
78+
*
79+
* @return string
80+
*/
81+
protected function getStub()
82+
{
83+
$relativePath = '/stubs/'.$this->argument('hookType').'-console.stub';
84+
85+
return file_exists($customPath = $this->laravel->basePath(trim($relativePath, '/')))
86+
? $customPath
87+
: __DIR__.$relativePath;
88+
}
89+
90+
/**
91+
* Get the default namespace for the class.
92+
*
93+
* @param string $rootNamespace
94+
* @return string
95+
*/
96+
protected function getDefaultNamespace($rootNamespace)
97+
{
98+
return $rootNamespace.'\Console\GitHooks';
99+
}
100+
101+
/**
102+
* Get the console command arguments.
103+
*
104+
* @return array
105+
*/
106+
protected function getArguments()
107+
{
108+
return [
109+
['hookType', InputArgument::REQUIRED, 'The type of the Git Hook', null, GitHooks::getSupportedHooks()],
110+
['name', InputArgument::REQUIRED, 'The name of the Git Hook'],
111+
];
112+
}
113+
114+
/**
115+
* Get the console command options.
116+
*
117+
* @return array
118+
*/
119+
protected function getOptions()
120+
{
121+
return [
122+
['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the Git Hook already exists'],
123+
];
124+
}
125+
126+
/**
127+
* Prompt for missing input arguments using the returned questions.
128+
*
129+
* @return array
130+
*/
131+
protected function promptForMissingArgumentsUsing()
132+
{
133+
$supportedHooks = implode(', ', GitHooks::getSupportedHooks());
134+
135+
return [
136+
'name' => 'What should the '.strtolower($this->type).' be named?',
137+
'hookType' => 'What type of the '.strtolower($this->type)."? Possible values: ($supportedHooks)",
138+
];
139+
}
140+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace {{ namespace }};
4+
5+
use Closure;
6+
use Igorsgm\GitHooks\Git\CommitMessage;
7+
use Igorsgm\GitHooks\Contracts\MessageHook;
8+
9+
class {{ class }} implements MessageHook
10+
{
11+
/**
12+
* Get the name of the hook.
13+
*/
14+
public function getName(): ?string
15+
{
16+
return '{{ hookName }}';
17+
}
18+
19+
/**
20+
* Execute the Hook.
21+
*
22+
* @param CommitMessage $message The commit message.
23+
* @param Closure $next The next hook in the chain to execute.
24+
* @return mixed|null
25+
*/
26+
public function handle(CommitMessage $message, Closure $next)
27+
{
28+
// TODO: Implement your commit msg hook logic here.
29+
30+
$currentMessage = $message->getMessage();
31+
// You can update commit message text
32+
$message->setMessage(str_replace('issue', 'fixed', $currentMessage));
33+
34+
// If you want to cancel the commit, you have to throw an exception.
35+
// i.e: throw new HookFailException();
36+
37+
// Run the next hook in the chain
38+
return $next($message);
39+
}
40+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace {{ namespace }};
4+
5+
use Closure;
6+
use Igorsgm\GitHooks\Git\Log;
7+
use Igorsgm\GitHooks\Contracts\PostCommitHook;
8+
9+
class {{ class }} implements PostCommitHook
10+
{
11+
/**
12+
* Get the name of the hook.
13+
*/
14+
public function getName(): ?string
15+
{
16+
return '{{ hookName }}';
17+
}
18+
19+
/**
20+
* Execute the Hook.
21+
*
22+
* @param Log $log
23+
* @param Closure $next The next hook in the chain to execute.
24+
* @return mixed|null
25+
*/
26+
public function handle(Log $log, Closure $next)
27+
{
28+
// TODO: Implement post commit hook logic here.
29+
30+
// You can interact with the commit log
31+
$hash = $log->getHash();
32+
$author = $log->getAuthor();
33+
$date = $log->getDate();
34+
$message = $log->getMessage();
35+
36+
// If you want to cancel the commit, you have to throw an exception.
37+
// i.e: throw new HookFailException();
38+
39+
// Run the next hook in the chain
40+
return $next($log);
41+
}
42+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace {{ namespace }};
4+
5+
use Closure;
6+
use Igorsgm\GitHooks\Git\ChangedFiles;
7+
use Igorsgm\GitHooks\Contracts\PreCommitHook;
8+
9+
class {{ class }} implements PreCommitHook
10+
{
11+
/**
12+
* Get the name of the hook.
13+
*/
14+
public function getName(): ?string
15+
{
16+
return '{{ hookName }}';
17+
}
18+
19+
/**
20+
* Execute the Hook.
21+
*
22+
* @param ChangedFiles $files The list of changed files to analyze.
23+
* @param Closure $next The next hook in the chain to execute.
24+
* @return mixed|null
25+
*/
26+
public function handle(ChangedFiles $files, Closure $next)
27+
{
28+
// TODO: Implement your pre commit hook logic here.
29+
30+
// If you want to cancel the commit, you have to throw an exception.
31+
// i.e: throw new HookFailException();
32+
33+
// Run the next hook in the chain
34+
return $next($files);
35+
}
36+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace {{ namespace }};
4+
5+
use Closure;
6+
use Igorsgm\GitHooks\Git\Log;
7+
use Igorsgm\GitHooks\Contracts\PrePushHook;
8+
9+
class {{ class }} implements PrePushHook
10+
{
11+
/**
12+
* Get the name of the hook.
13+
*/
14+
public function getName(): ?string
15+
{
16+
return '{{ hookName }}';
17+
}
18+
19+
/**
20+
* Execute the Hook.
21+
*
22+
* @param Log $log
23+
* @param Closure $next The next hook in the chain to execute.
24+
* @return mixed|null
25+
*/
26+
public function handle(Log $log, Closure $next)
27+
{
28+
// TODO: Implement pre push hook logic here.
29+
30+
// You can interact with the commit log
31+
$hash = $log->getHash();
32+
$author = $log->getAuthor();
33+
$date = $log->getDate();
34+
$message = $log->getMessage();
35+
36+
// If you want to cancel the commit, you have to throw an exception.
37+
// i.e: throw new HookFailException();
38+
39+
// Run the next hook in the chain
40+
return $next($log);
41+
}
42+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace {{ namespace }};
4+
5+
use Closure;
6+
use Igorsgm\GitHooks\Git\CommitMessage;
7+
use Igorsgm\GitHooks\Contracts\MessageHook;
8+
9+
class {{ class }} implements MessageHook
10+
{
11+
/**
12+
* Get the name of the hook.
13+
*/
14+
public function getName(): ?string
15+
{
16+
return '{{ hookName }}';
17+
}
18+
19+
/**
20+
* Execute the Hook.
21+
*
22+
* @param CommitMessage $message The commit message.
23+
* @param Closure $next The next hook in the chain to execute.
24+
* @return mixed|null
25+
*/
26+
public function handle(CommitMessage $message, Closure $next)
27+
{
28+
// TODO: Implement your prepare commit msg hook logic here.
29+
30+
$currentMessage = $message->getMessage();
31+
// You can update commit message text
32+
$message->setMessage(str_replace('issue', 'fixed', $currentMessage));
33+
34+
// If you want to cancel the commit, you have to throw an exception.
35+
// i.e: throw new HookFailException();
36+
37+
// Run the next hook in the chain
38+
return $next($message);
39+
}
40+
}

src/GitHooksServiceProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public function boot()
2424
\Igorsgm\GitHooks\Console\Commands\PrepareCommitMessage::class,
2525
\Igorsgm\GitHooks\Console\Commands\PostCommit::class,
2626
\Igorsgm\GitHooks\Console\Commands\PrePush::class,
27+
\Igorsgm\GitHooks\Console\Commands\MakeHook::class,
2728
]);
2829
}
2930
}

tests/Features/Commands/Hooks/BaseCodeAnalyzerPreCommitHookTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
use Igorsgm\GitHooks\Facades\GitHooks;
44
use Igorsgm\GitHooks\Git\ChangedFiles;
55
use Igorsgm\GitHooks\Tests\Fixtures\ConcreteBaseCodeAnalyzerFixture;
6-
use Igorsgm\GitHooks\Traits\GitHelper;
76

8-
uses(GitHelper::class);
97
beforeEach(function () {
108
$this->gitInit();
119
$this->initializeTempDirectory(base_path('temp'));

tests/Features/Commands/Hooks/BladeFormatterPreCommitHookTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
use Igorsgm\GitHooks\Console\Commands\Hooks\BladeFormatterPreCommitHook;
44
use Igorsgm\GitHooks\Facades\GitHooks;
5-
use Igorsgm\GitHooks\Traits\GitHelper;
65

7-
uses(GitHelper::class);
86
beforeEach(function () {
97
$this->gitInit();
108
$this->initializeTempDirectory(base_path('temp'));

tests/Features/Commands/Hooks/ESLintPreCommitHookTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
use Igorsgm\GitHooks\Console\Commands\Hooks\ESLintPreCommitHook;
44
use Igorsgm\GitHooks\Facades\GitHooks;
5-
use Igorsgm\GitHooks\Traits\GitHelper;
65

7-
uses(GitHelper::class);
86
beforeEach(function () {
97
$this->gitInit();
108
$this->initializeTempDirectory(base_path('temp'));

0 commit comments

Comments
 (0)