Skip to content

Commit

Permalink
Added support for more parameters including docker support
Browse files Browse the repository at this point in the history
  • Loading branch information
cradu committed Apr 10, 2024
1 parent c82dffd commit 472ed8a
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 10 deletions.
71 changes: 70 additions & 1 deletion config/git-hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@
| The following variables are used to store the paths to bin executables for
| various code analyzer dependencies used in your Laravel application.
| This configuration node allows you to set up the paths for these executables.
| Here you can also specify the path to the configuration files they use to customize their behavior
| Here you can also specify the path to the configuration files they use to customize their behavior.
| Each analyzer can be configured to run inside Docker on a specific container.
|
*/
'code_analyzers' => [
Expand All @@ -173,34 +174,46 @@
'config' => env('LARAVEL_PINT_CONFIG'),
'preset' => env('LARAVEL_PINT_PRESET', 'laravel'),
'file_extensions' => env('LARAVEL_PINT_FILE_EXTENSIONS', '/\.php$/'),
'run_in_docker' => env('LARAVEL_PINT_RUN_IN_DOCKER', false),
'docker_container' => env('LARAVEL_PINT_DOCKER_CONTAINER', ''),
],
'php_code_sniffer' => [
'phpcs_path' => env('PHPCS_PATH', 'vendor/bin/phpcs'),
'phpcbf_path' => env('PHPCBF_PATH', 'vendor/bin/phpcbf'),
'config' => env('PHPCS_STANDARD_CONFIG', 'phpcs.xml'),
'file_extensions' => env('PHPCS_FILE_EXTENSIONS', '/\.php$/'),
'run_in_docker' => env('LARAVEL_PHPCS_RUN_IN_DOCKER', false),
'docker_container' => env('LARAVEL_PHPCS_DOCKER_CONTAINER', ''),
],
'larastan' => [
'path' => env('LARASTAN_PATH', 'vendor/bin/phpstan'),
'config' => env('LARASTAN_CONFIG', 'phpstan.neon'),
'additional_params' => env('LARASTAN_ADDITIONAL_PARAMS', '--xdebug'),
'run_in_docker' => env('LARAVEL_LARASTAN_RUN_IN_DOCKER', false),
'docker_container' => env('LARAVEL_LARASTAN_DOCKER_CONTAINER', ''),
],
'blade_formatter' => [
'path' => env('BLADE_FORMATTER_PATH', 'node_modules/.bin/blade-formatter'),
'config' => env('BLADE_FORMATTER_CONFIG', '.bladeformatterrc.json'),
'file_extensions' => env('BLADE_FORMATTER_FILE_EXTENSIONS', '/\.blade\.php$/'),
'run_in_docker' => env('BLADE_FORMATTER_RUN_IN_DOCKER', false),
'docker_container' => env('BLADE_FORMATTER_DOCKER_CONTAINER', ''),
],
'prettier' => [
'path' => env('PRETTIER_PATH', 'node_modules/.bin/prettier'),
'config' => env('PRETTIER_CONFIG', '.prettierrc.json'),
'additional_params' => env('PRETTIER_ADDITIONAL_PARAMS', ''),
'file_extensions' => env('PRETTIER_FILE_EXTENSIONS', '/\.(jsx?|tsx?|vue)$/'),
'run_in_docker' => env('PRETTIER_RUN_IN_DOCKER', false),
'docker_container' => env('PRETTIER_DOCKER_CONTAINER', ''),
],
'eslint' => [
'path' => env('ESLINT_PATH', 'node_modules/.bin/eslint'),
'config' => env('ESLINT_CONFIG', '.eslintrc.js'),
'additional_params' => env('ESLINT_ADDITIONAL_PARAMS', ''),
'file_extensions' => env('ESLINT_FILE_EXTENSIONS', '/\.(jsx?|tsx?|vue)$/'),
'run_in_docker' => env('ESLINT_RUN_IN_DOCKER', false),
'docker_container' => env('ESLINT_DOCKER_CONTAINER', ''),
],
],

Expand All @@ -221,4 +234,60 @@
|
*/
'artisan_path' => base_path('artisan'),

/*
|--------------------------------------------------------------------------
| Output errors
|--------------------------------------------------------------------------
|
| This configuration option allows you output any errors encountered
| during execution directly for easy debug.
|
*/
'output_errors' => false,

/*
|--------------------------------------------------------------------------
| Automatically fix errors
|--------------------------------------------------------------------------
|
| This configuration option allows you to configure the git hooks to
| automatically run the fixer without any CLI prompt.
|
*/
'automatically_fix_errors' => false,

/*
|--------------------------------------------------------------------------
| Automatically re-run analyzer after autofix
|--------------------------------------------------------------------------
|
| This configuration option allows you to configure the git hooks to
| automatically re-run the analyzer command after autofix.
| The git hooks will not fail in case the re-run is succesful.
|
*/
'rerun_analyzer_after_autofix' => false,

/*
|--------------------------------------------------------------------------
| Stop at first analyzer failure
|--------------------------------------------------------------------------
|
| This configuration option allows you to configure the git hooks to
| stop (or not) at the first analyzer failure encountered.
|
*/
'stop_at_first_analyzer_failure' => true,

/*
|--------------------------------------------------------------------------
| Debug commands
|--------------------------------------------------------------------------
|
| This configuration option allows you to configure the git hooks to
| display the commands that are executed (usually for debug purpose).
|
*/
'debug_commands' => false,
];
111 changes: 102 additions & 9 deletions src/Console/Commands/Hooks/BaseCodeAnalyzerPreCommitHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ abstract class BaseCodeAnalyzerPreCommitHook
* @var array
*/
protected $filesBadlyFormattedPaths = [];

/**
* Run tool in docker
*
* @var bool
*/
protected $runInDocker = false;

/**
* Docker container on which to run
*
* @var string
*/
protected $dockerContainer = '';

public function __construct()
{
Expand Down Expand Up @@ -109,9 +123,15 @@ protected function analizeCommittedFiles($commitFiles)
}

$filePath = $file->getFilePath();
$command = $this->analyzerCommand().' '.$filePath;
$command = $this->dockerCommand($this->analyzerCommand().' '.$filePath);

$isProperlyFormatted = $this->runCommands($command)->isSuccessful();
$process = $this->runCommands($command);

if (config('git-hooks.debug_commands')) {
$this->command->getOutput()->write(PHP_EOL . ' <bg=yellow;fg=white> DEBUG </> Executed command: ' . $process->getCommandLine() . PHP_EOL);
}

$isProperlyFormatted = $process->isSuccessful();

if (! $isProperlyFormatted) {
if (empty($this->filesBadlyFormattedPaths)) {
Expand All @@ -122,6 +142,11 @@ protected function analizeCommittedFiles($commitFiles)
sprintf('<fg=red> %s Failed:</> %s', $this->getName(), $filePath)
);
$this->filesBadlyFormattedPaths[] = $filePath;

if (config('git-hooks.output_errors')) {
$this->command->newLine();
$this->command->getOutput()->write($process->getOutput());
}
}
}

Expand Down Expand Up @@ -217,14 +242,29 @@ protected function suggestAutoFixOrExit(): bool
{
$hasFixerCommand = ! empty($this->fixerCommand());

if ($hasFixerCommand && Terminal::hasSttyAvailable() &&
$this->command->confirm('Would you like to attempt to correct files automagically?') &&
$this->autoFixFiles()
) {
return true;
if ($hasFixerCommand) {
if (config('git-hooks.automatically_fix_errors')) {
$this->command->getOutput()->writeln(
sprintf('<bg=green;fg=white> AUTOFIX </> <fg=green> %s Running Autofix</>', $this->getName())
);
if ($this->autoFixFiles()) {
return true;
}
} else {
if (Terminal::hasSttyAvailable() &&
$this->command->confirm('Would you like to attempt to correct files automagically?') &&
$this->autoFixFiles()
) {
return true;
}
}
}

throw new HookFailException();
if (config('git-hooks.stop_at_first_analyzer_failure')) {
throw new HookFailException();
}

return false;
}

/**
Expand All @@ -238,7 +278,15 @@ protected function suggestAutoFixOrExit(): bool
private function autoFixFiles(): bool
{
foreach ($this->filesBadlyFormattedPaths as $key => $filePath) {
$wasProperlyFixed = $this->runCommands($this->fixerCommand().' '.$filePath)->isSuccessful();
$fixerCommand = $this->dockerCommand($this->fixerCommand().' '.$filePath);
$process = $this->runCommands($fixerCommand);

if (config('git-hooks.rerun_analyzer_after_autofix')) {
$command = $this->dockerCommand($this->analyzerCommand().' '.$filePath);
$process = $this->runCommands($command);
}

$wasProperlyFixed = $process->isSuccessful();

if ($wasProperlyFixed) {
$this->runCommands('git add '.$filePath);
Expand All @@ -250,6 +298,11 @@ private function autoFixFiles(): bool
$this->command->getOutput()->writeln(
sprintf('<fg=red> %s Autofix Failed:</> %s', $this->getName(), $filePath)
);

if (config('git-hooks.output_errors')) {
$this->command->newLine();
$this->command->getOutput()->write($process->getOutput());
}
}

return empty($this->filesBadlyFormattedPaths);
Expand Down Expand Up @@ -303,4 +356,44 @@ public function getFixerExecutable(): string
{
return $this->fixerExecutable;
}

/**
* @return BaseCodeAnalyzerPreCommitHook
*/
public function setRunInDocker($runInDocker)
{
$this->runInDocker = (bool)$runInDocker;

return $this;
}

public function getRunInDocker(): bool
{
return $this->runInDocker;
}

/**
* @param string $dockerContainer
* @return BaseCodeAnalyzerPreCommitHook
*/
public function setDockerContainer($dockerContainer)
{
$this->dockerContainer = $dockerContainer;

return $this;
}

public function getDockerContainer(): string
{
return $this->dockerContainer;
}

private function dockerCommand(string $command): string
{
if (!$this->runInDocker || empty($this->dockerContainer)) {
return $command;
}

return 'docker exec ' . escapeshellarg($this->dockerContainer) . ' sh -c ' . escapeshellarg($command);
}
}
2 changes: 2 additions & 0 deletions src/Console/Commands/Hooks/BladeFormatterPreCommitHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public function handle(ChangedFiles $files, Closure $next)

return $this->setFileExtensions(config('git-hooks.code_analyzers.blade_formatter.file_extensions'))
->setAnalyzerExecutable(config('git-hooks.code_analyzers.blade_formatter.path'), true)
->setRunInDocker(config('git-hooks.code_analyzers.blade_formatter.run_in_docker'))
->setDockerContainer(config('git-hooks.code_analyzers.blade_formatter.docker_container'))
->handleCommittedFiles($files, $next);
}

Expand Down
2 changes: 2 additions & 0 deletions src/Console/Commands/Hooks/ESLintPreCommitHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public function handle(ChangedFiles $files, Closure $next)

return $this->setFileExtensions(config('git-hooks.code_analyzers.eslint.file_extensions'))
->setAnalyzerExecutable(config('git-hooks.code_analyzers.eslint.path'), true)
->setRunInDocker(config('git-hooks.code_analyzers.eslint.run_in_docker'))
->setDockerContainer(config('git-hooks.code_analyzers.eslint.docker_container'))
->handleCommittedFiles($files, $next);
}

Expand Down
2 changes: 2 additions & 0 deletions src/Console/Commands/Hooks/LarastanPreCommitHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public function handle(ChangedFiles $files, Closure $next)
$this->configParam = $this->configParam();

return $this->setAnalyzerExecutable(config('git-hooks.code_analyzers.larastan.path'))
->setRunInDocker(config('git-hooks.code_analyzers.larastan.run_in_docker'))
->setDockerContainer(config('git-hooks.code_analyzers.larastan.docker_container'))
->handleCommittedFiles($files, $next);
}

Expand Down
2 changes: 2 additions & 0 deletions src/Console/Commands/Hooks/PHPCodeSnifferPreCommitHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public function handle(ChangedFiles $files, Closure $next)
return $this->setFileExtensions(config('git-hooks.code_analyzers.php_code_sniffer.file_extensions'))
->setAnalyzerExecutable(config('git-hooks.code_analyzers.php_code_sniffer.phpcs_path'))
->setFixerExecutable(config('git-hooks.code_analyzers.php_code_sniffer.phpcbf_path'))
->setRunInDocker(config('git-hooks.code_analyzers.php_code_sniffer.run_in_docker'))
->setDockerContainer(config('git-hooks.code_analyzers.php_code_sniffer.docker_container'))
->handleCommittedFiles($files, $next);
}

Expand Down
2 changes: 2 additions & 0 deletions src/Console/Commands/Hooks/PintPreCommitHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public function handle(ChangedFiles $files, Closure $next)

return $this->setFileExtensions(config('git-hooks.code_analyzers.laravel_pint.file_extensions'))
->setAnalyzerExecutable(config('git-hooks.code_analyzers.laravel_pint.path'), true)
->setRunInDocker(config('git-hooks.code_analyzers.laravel_pint.run_in_docker'))
->setDockerContainer(config('git-hooks.code_analyzers.laravel_pint.docker_container'))
->handleCommittedFiles($files, $next);
}

Expand Down
2 changes: 2 additions & 0 deletions src/Console/Commands/Hooks/PrettierPreCommitHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public function handle(ChangedFiles $files, Closure $next)

return $this->setFileExtensions(config('git-hooks.code_analyzers.prettier.file_extensions'))
->setAnalyzerExecutable(config('git-hooks.code_analyzers.prettier.path'), true)
->setRunInDocker(config('git-hooks.code_analyzers.prettier.run_in_docker'))
->setDockerContainer(config('git-hooks.code_analyzers.prettier.docker_container'))
->handleCommittedFiles($files, $next);
}

Expand Down
7 changes: 7 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ public function defineEnvironment($app)
'pre-push' => [],
'code_analyzers' => [],
'artisan_path' => base_path('artisan'),
'output_errors' => false,
'automatically_fix_errors' => false,
'rerun_analyzer_after_autofix' => false,
'stop_at_first_analyzer_failure' => true,
'debug_commands' => false,
'run_in_docker' => false,
'docker_command' => '',
]);

$this->config = $app['config'];
Expand Down

0 comments on commit 472ed8a

Please sign in to comment.