Skip to content

Commit 39634d2

Browse files
committed
wip
1 parent d0fbf47 commit 39634d2

File tree

6 files changed

+260
-55
lines changed

6 files changed

+260
-55
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"larastan/larastan": "^2.0|^3.0",
3535
"laravel/pint": "^1.2",
3636
"mockery/mockery": "^1.6.1",
37-
"nunomaduro/phpinsights": "^2.12",
37+
"nunomaduro/phpinsights": "^2.13",
3838
"orchestra/testbench": "^v8.0|^v9.0|^v10.0",
3939
"pestphp/pest": "^2.0|^3.0",
4040
"pestphp/pest-plugin-laravel": "^2.0|^3.0",

phpinsights.php

Lines changed: 205 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,224 @@
22

33
declare(strict_types=1);
44

5+
use NunoMaduro\PhpInsights\Domain\Insights\ForbiddenDefineFunctions;
6+
use NunoMaduro\PhpInsights\Domain\Insights\ForbiddenFinalClasses;
7+
use NunoMaduro\PhpInsights\Domain\Insights\ForbiddenNormalClasses;
8+
use NunoMaduro\PhpInsights\Domain\Insights\ForbiddenPrivateMethods;
9+
use NunoMaduro\PhpInsights\Domain\Insights\ForbiddenTraits;
10+
use NunoMaduro\PhpInsights\Domain\Metrics\Architecture\Classes;
11+
use NunoMaduro\PhpInsights\Domain\Metrics\Code\Code;
12+
use NunoMaduro\PhpInsights\Domain\Metrics\Style\Style;
13+
use PhpCsFixer\Fixer\Alias\ArrayPushFixer;
14+
use PhpCsFixer\Fixer\Alias\BacktickToShellExecFixer;
15+
use PhpCsFixer\Fixer\Alias\MbStrFunctionsFixer;
16+
use PhpCsFixer\Fixer\CastNotation\ModernizeTypesCastingFixer;
17+
use PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer;
18+
use PhpCsFixer\Fixer\ClassNotation\OrderedInterfacesFixer;
19+
use PhpCsFixer\Fixer\ClassNotation\OrderedTraitsFixer;
20+
use PhpCsFixer\Fixer\ClassNotation\ProtectedToPrivateFixer;
21+
use PhpCsFixer\Fixer\ClassNotation\SelfAccessorFixer;
22+
use PhpCsFixer\Fixer\ClassNotation\SelfStaticAccessorFixer;
23+
use PhpCsFixer\Fixer\ClassNotation\VisibilityRequiredFixer;
24+
use PhpCsFixer\Fixer\ClassUsage\DateTimeImmutableFixer;
25+
use PhpCsFixer\Fixer\ControlStructure\NoSuperfluousElseifFixer;
26+
use PhpCsFixer\Fixer\ControlStructure\NoUselessElseFixer;
27+
use PhpCsFixer\Fixer\Import\FullyQualifiedStrictTypesFixer;
28+
use PhpCsFixer\Fixer\Operator\NewWithParenthesesFixer;
29+
use PhpCsFixer\Fixer\Operator\NotOperatorWithSuccessorSpaceFixer;
30+
use PhpCsFixer\Fixer\Strict\DeclareStrictTypesFixer;
31+
use PhpCsFixer\Fixer\Strict\StrictComparisonFixer;
32+
use SlevomatCodingStandard\Sniffs\Commenting\UselessFunctionDocCommentSniff;
33+
use SlevomatCodingStandard\Sniffs\ControlStructures\DisallowEmptySniff;
34+
use SlevomatCodingStandard\Sniffs\ControlStructures\DisallowYodaComparisonSniff;
35+
use SlevomatCodingStandard\Sniffs\Namespaces\AlphabeticallySortedUsesSniff;
36+
use SlevomatCodingStandard\Sniffs\TypeHints\DeclareStrictTypesSniff;
37+
use SlevomatCodingStandard\Sniffs\TypeHints\DisallowMixedTypeHintSniff;
38+
use SlevomatCodingStandard\Sniffs\TypeHints\ParameterTypeHintSniff;
39+
use SlevomatCodingStandard\Sniffs\TypeHints\PropertyTypeHintSniff;
40+
use SlevomatCodingStandard\Sniffs\TypeHints\ReturnTypeHintSniff;
41+
542
return [
43+
44+
/*
45+
|--------------------------------------------------------------------------
46+
| Default Preset
47+
|--------------------------------------------------------------------------
48+
|
49+
| This option controls the default preset that will be used by PHP Insights
50+
| to make your code reliable, simple, and clean. However, you can always
51+
| adjust the `Metrics` and `Insights` below in this configuration file.
52+
|
53+
| Supported: "default", "laravel", "symfony", "magento2", "drupal", "wordpress"
54+
|
55+
*/
56+
657
'preset' => 'laravel',
58+
59+
/*
60+
|--------------------------------------------------------------------------
61+
| IDE
62+
|--------------------------------------------------------------------------
63+
|
64+
| This options allow to add hyperlinks in your terminal to quickly open
65+
| files in your favorite IDE while browsing your PhpInsights report.
66+
|
67+
| Supported: "textmate", "macvim", "emacs", "sublime", "phpstorm",
68+
| "atom", "vscode".
69+
|
70+
| If you have another IDE that is not in this list but which provide an
71+
| url-handler, you could fill this config with a pattern like this:
72+
|
73+
| myide://open?url=file://%f&line=%l
74+
|
75+
*/
76+
77+
'ide' => null,
78+
79+
/*
80+
|--------------------------------------------------------------------------
81+
| Configuration
82+
|--------------------------------------------------------------------------
83+
|
84+
| Here you may adjust all the various `Insights` that will be used by PHP
85+
| Insights. You can either add, remove or configure `Insights`. Keep in
86+
| mind, that all added `Insights` must belong to a specific `Metric`.
87+
|
88+
*/
89+
790
'exclude' => [
891
'src/Console/Commands/',
992
'src/HooksPipeline.php',
1093
'src/Git/Log.php',
94+
'tests/Files/*WithFixableIssues.php',
95+
'tests/TestCase.php',
1196
],
97+
1298
'add' => [
13-
// ExampleMetric::class => [
14-
// ExampleInsight::class,
15-
// ]
99+
Classes::class => [
100+
ForbiddenFinalClasses::class,
101+
],
102+
Code::class => [
103+
// Rules from pint.json that enhance code quality
104+
ArrayPushFixer::class,
105+
BacktickToShellExecFixer::class,
106+
DateTimeImmutableFixer::class,
107+
DeclareStrictTypesFixer::class,
108+
FullyQualifiedStrictTypesFixer::class,
109+
MbStrFunctionsFixer::class,
110+
ModernizeTypesCastingFixer::class,
111+
OrderedClassElementsFixer::class,
112+
OrderedInterfacesFixer::class,
113+
OrderedTraitsFixer::class,
114+
ProtectedToPrivateFixer::class,
115+
SelfAccessorFixer::class,
116+
SelfStaticAccessorFixer::class,
117+
StrictComparisonFixer::class,
118+
VisibilityRequiredFixer::class,
119+
],
120+
Style::class => [
121+
// Style rules from pint.json
122+
NoSuperfluousElseifFixer::class,
123+
NoUselessElseFixer::class,
124+
],
16125
],
126+
17127
'remove' => [
18-
SlevomatCodingStandard\Sniffs\Classes\ForbiddenPublicPropertySniff::class,
19-
SlevomatCodingStandard\Sniffs\ControlStructures\DisallowEmptySniff::class,
20-
SlevomatCodingStandard\Sniffs\TypeHints\DisallowMixedTypeHintSniff::class,
21-
SlevomatCodingStandard\Sniffs\Classes\SuperfluousExceptionNamingSniff::class,
22-
SlevomatCodingStandard\Sniffs\Functions\FunctionLengthSniff::class,
23-
SlevomatCodingStandard\Sniffs\Commenting\DocCommentSpacingSniff::class,
24-
NunoMaduro\PhpInsights\Domain\Sniffs\ForbiddenSetterSniff::class,
25-
NunoMaduro\PhpInsights\Domain\Insights\CyclomaticComplexityIsHigh::class,
26-
NunoMaduro\PhpInsights\Domain\Insights\ForbiddenNormalClasses::class,
27-
NunoMaduro\PhpInsights\Domain\Insights\ForbiddenTraits::class,
28-
PHP_CodeSniffer\Standards\Generic\Sniffs\Commenting\TodoSniff::class,
29-
PHP_CodeSniffer\Standards\Generic\Sniffs\Files\LineLengthSniff::class,
30-
PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\ScopeClosingBraceSniff::class,
31-
PHP_CodeSniffer\Standards\PEAR\Sniffs\WhiteSpace\ScopeClosingBraceSniff::class,
32-
PHP_CodeSniffer\Standards\PSR12\Sniffs\Classes\ClassInstantiationSniff::class,
33-
PhpCsFixer\Fixer\Basic\BracesFixer::class,
34-
PhpCsFixer\Fixer\ClassNotation\ClassDefinitionFixer::class,
35-
PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer::class,
36-
PhpCsFixer\Fixer\Operator\NewWithBracesFixer::class,
128+
AlphabeticallySortedUsesSniff::class,
129+
DeclareStrictTypesSniff::class, // We use DeclareStrictTypesFixer from PHP-CS-Fixer instead
130+
DisallowEmptySniff::class, // Allow using empty() function
131+
DisallowMixedTypeHintSniff::class,
132+
ForbiddenDefineFunctions::class,
133+
ForbiddenNormalClasses::class,
134+
ForbiddenTraits::class,
135+
ParameterTypeHintSniff::class,
136+
PropertyTypeHintSniff::class,
137+
ReturnTypeHintSniff::class,
138+
UselessFunctionDocCommentSniff::class,
139+
NewWithParenthesesFixer::class, // Disabled as per pint.json
140+
NotOperatorWithSuccessorSpaceFixer::class, // Disabled as per pint.json
141+
DisallowYodaComparisonSniff::class, // Allow normal comparisons
37142
],
143+
38144
'config' => [
39-
// ExampleInsight::class => [
40-
// 'key' => 'value',
41-
// ],
145+
ForbiddenPrivateMethods::class => [
146+
'title' => 'The usage of private methods is not idiomatic in Laravel.',
147+
],
148+
OrderedClassElementsFixer::class => [
149+
'order' => [
150+
'use_trait',
151+
'case',
152+
'constant',
153+
'constant_public',
154+
'constant_protected',
155+
'constant_private',
156+
'property_public',
157+
'property_protected',
158+
'property_private',
159+
'construct',
160+
'destruct',
161+
'magic',
162+
'phpunit',
163+
'method_abstract',
164+
'method_public_static',
165+
'method_public',
166+
'method_protected_static',
167+
'method_protected',
168+
'method_private_static',
169+
'method_private',
170+
],
171+
'sort_algorithm' => 'none',
172+
],
173+
DeclareStrictTypesFixer::class => [
174+
'strict_types' => true,
175+
],
176+
FullyQualifiedStrictTypesFixer::class => [
177+
'import_symbols' => true,
178+
],
42179
],
180+
181+
/*
182+
|--------------------------------------------------------------------------
183+
| Requirements
184+
|--------------------------------------------------------------------------
185+
|
186+
| Here you may define a level you want to reach per `Insights` category.
187+
| When a score is lower than the minimum level defined, then an error
188+
| code will be returned. This is optional and individually defined.
189+
|
190+
*/
191+
43192
'requirements' => [
44-
'min-quality' => 100,
45-
'min-complexity' => 0,
46-
'min-architecture' => 100,
47-
'min-style' => 100,
193+
'min-quality' => 90,
194+
'min-complexity' => 90,
195+
'min-architecture' => 80,
196+
'min-style' => 90,
197+
'disable-security-check' => false,
48198
],
199+
200+
/*
201+
|--------------------------------------------------------------------------
202+
| Threads
203+
|--------------------------------------------------------------------------
204+
|
205+
| Here you may adjust how many threads (core) PHPInsights can use to perform
206+
| the analysis. This is optional, don't provide it and the tool will guess
207+
| the max core number available. It accepts null value or integer > 0.
208+
|
209+
*/
210+
211+
'threads' => null,
212+
213+
/*
214+
|--------------------------------------------------------------------------
215+
| Timeout
216+
|--------------------------------------------------------------------------
217+
| Here you may adjust the timeout (in seconds) for PHPInsights to run before
218+
| a ProcessTimedOutException is thrown.
219+
| This accepts an int > 0. Default is 60 seconds, which is the default value
220+
| of Symfony's setTimeout function.
221+
|
222+
*/
223+
224+
'timeout' => 60,
49225
];

src/GitHooksServiceProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@ public function register(): void
3939
// Automatically apply the package configuration
4040
$this->mergeConfigFrom(__DIR__.'/../config/git-hooks.php', 'laravel-git-hooks');
4141

42-
$this->app->singleton('laravel-git-hooks', fn () => new GitHooks);
42+
$this->app->singleton('laravel-git-hooks', fn () => new GitHooks());
4343
}
4444
}

src/Traits/WithAutoFix.php

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,11 @@ trait WithAutoFix
1616

1717
public function suggestAutoFixOrExit(): bool
1818
{
19-
$hasFixerCommand = !empty($this->fixerCommand());
20-
21-
if ($hasFixerCommand) {
22-
if (config('git-hooks.automatically_fix_errors')) {
23-
$this->command->getOutput()->writeln(
24-
sprintf('<bg=green;fg=white> AUTOFIX </> <fg=green> %s Running Autofix</>', $this->getName())
25-
);
26-
if ($this->autoFixFiles()) {
27-
return true;
28-
}
29-
} elseif ($this->shouldAttemptAutofix() && $this->autoFixFiles()) {
30-
return true;
31-
}
19+
if ($this->tryAutoFix()) {
20+
return true;
3221
}
3322

34-
$this->markPipelineFailed();
35-
36-
if (config('git-hooks.stop_at_first_analyzer_failure')) {
37-
throw new HookFailException;
38-
}
23+
$this->handleAnalyzerFailure();
3924

4025
return false;
4126
}
@@ -79,6 +64,47 @@ protected function handleFixFailure(string $filePath, mixed $process): void
7964
}
8065
}
8166

67+
private function tryAutoFix(): bool
68+
{
69+
if (!$this->canAutoFix()) {
70+
return false;
71+
}
72+
73+
if (config('git-hooks.automatically_fix_errors')) {
74+
return $this->performAutomaticFix();
75+
}
76+
77+
return $this->performInteractiveFix();
78+
}
79+
80+
private function canAutoFix(): bool
81+
{
82+
return !empty($this->fixerCommand());
83+
}
84+
85+
private function performAutomaticFix(): bool
86+
{
87+
$this->command->getOutput()->writeln(
88+
sprintf('<bg=green;fg=white> AUTOFIX </> <fg=green> %s Running Autofix</>', $this->getName())
89+
);
90+
91+
return $this->autoFixFiles();
92+
}
93+
94+
private function performInteractiveFix(): bool
95+
{
96+
return $this->shouldAttemptAutofix() && $this->autoFixFiles();
97+
}
98+
99+
private function handleAnalyzerFailure(): void
100+
{
101+
$this->markPipelineFailed();
102+
103+
if (config('git-hooks.stop_at_first_analyzer_failure')) {
104+
throw new HookFailException();
105+
}
106+
}
107+
82108
private function shouldAttemptAutofix(): bool
83109
{
84110
// In test environment, skip Terminal check

src/Traits/WithPipeline.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,14 @@ protected function finishHookConsoleTask(): Closure
8080
// Erase the line
8181
$this->output->write("\x1B[2K");
8282
} else {
83-
$this->output->writeln(''); // Make sure we first close the previous line
83+
// Make sure we first close the previous line
84+
$this->output->writeln('');
8485
}
8586

8687
$taskTitle = $this->getHookTaskTitle($this->hookExecuting);
8788

88-
$this->output->writeln(
89-
"{$taskTitle}: ".($success ? '<info>✔</info>' : '<error>failed</error>')
90-
);
89+
$status = $success ? '<info>✔</info>' : '<error>failed</error>';
90+
$this->output->writeln("{$taskTitle}: {$status}");
9191

9292
$this->hookExecuting = null;
9393
};

src/Traits/WithPipelineFailCheck.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ protected function markPipelineFailed(): void
1212
{
1313
$tmpFile = $this->getPipelineFailedTempFile();
1414
if (touch($tmpFile) === false) {
15-
throw new HookFailException;
15+
throw new HookFailException();
1616
}
1717
}
1818

@@ -34,6 +34,9 @@ protected function clearPipelineFailed(): void
3434

3535
protected function getPipelineFailedTempFile(): string
3636
{
37-
return sys_get_temp_dir().DIRECTORY_SEPARATOR.'githooks-pipeline-fail-'.getmypid();
37+
$tempDir = sys_get_temp_dir();
38+
$pid = getmypid();
39+
40+
return "{$tempDir}/githooks-pipeline-fail-{$pid}";
3841
}
3942
}

0 commit comments

Comments
 (0)