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
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
"clue/ndjson-react": "^1.3",
"composer/pcre": "^3.4",
"composer/xdebug-handler": "^3.0.5",
"entropy/entropy": "^0.4",
"entropy/entropy": "^0.4.6",
"fidry/cpu-core-counter": "^1.3",
"friendsofphp/php-cs-fixer": "^3.95.5",
"friendsofphp/php-cs-fixer": "^3.95.10",
"nette/utils": "^4.1",
"react/child-process": "^0.6.7",
"react/event-loop": "^1.6",
Expand All @@ -37,7 +37,7 @@
"rector/jack": "^1.0",
"rector/rector": "^2.4",
"rector/type-perfect": "^2.1",
"symplify/phpstan-rules": "^14.11",
"symplify/phpstan-rules": "^14.12",
"symplify/vendor-patches": "^11.5",
"tomasvotruba/class-leak": "^2.1.7",
"tomasvotruba/type-coverage": "^2.2",
Expand Down
12 changes: 12 additions & 0 deletions packages/coding-standard/src/Fixer/LineLength/LineLengthFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@
/**
* @see \Symplify\CodingStandard\Tests\Fixer\LineLength\LineLengthFixer\LineLengthFixerTest
* @see \Symplify\CodingStandard\Tests\Fixer\LineLength\LineLengthFixer\ConfiguredLineLengthFixerTest
*
* @implements ConfigurableFixerInterface<
* array{
* self::LINE_LENGTH?: int,
* self::BREAK_LONG_LINES?: bool,
* self::INLINE_SHORT_LINES?: bool
* }, array{
* self::LINE_LENGTH: int,
* self::BREAK_LONG_LINES: bool,
* self::INLINE_SHORT_LINES: bool
* }
* >
*/
final class LineLengthFixer extends AbstractSymplifyFixer implements ConfigurableFixerInterface
{
Expand Down
59 changes: 12 additions & 47 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
parameters:
level: 8

# reportUnmatchedIgnoredErrors: false

# requires exact closure types
checkMissingCallableSignature: true

# symplify - see https://github.com/symplify/phpstan-rules#usage
symplify:
pathStrings: true

paths:
- packages
- src
Expand All @@ -23,6 +14,10 @@ parameters:
- '*/Source/*'
- '*/Fixture/*'

# see https://github.com/symplify/phpstan-rules#usage
symplify:
pathStrings: true

# see https://github.com/tomasVotruba/unused-public
unused_public:
methods: true
Expand All @@ -32,23 +27,20 @@ parameters:
# see https://github.com/TomasVotruba/type-coverage
type_coverage:
return: 99
param: 94.4
param: 99
property: 99

bootstrapFiles:
- tests/bootstrap.php

treatPhpDocTypesAsCertain: true
errorFormat: symplify
treatPhpDocTypesAsCertain: false

ignoreErrors:
# set above
-
path: src/Parallel/Application/ParallelFileProcessor.php
message: '#Cannot call method (.*?)\(\) on Symplify\\EasyCodingStandard\\Parallel\\ValueObject\\ProcessPool\|null#'

# @todo revisit: split return into typed file_diffs/coding_standard_errors buckets
- '#Method Symplify\\EasyCodingStandard\\Application\\SingleFileProcessor\:\:processFilePath\(\) should return array\{file_diffs\?\: array<Symplify\\EasyCodingStandard\\ValueObject\\Error\\FileDiff>, coding_standard_errors\?\: array<Symplify\\EasyCodingStandard\\SniffRunner\\ValueObject\\Error\\CodingStandardError>\} but returns array<(.*?), array<Symplify\\EasyCodingStandard\\SniffRunner\\ValueObject\\Error\\CodingStandardError\|Symplify\\EasyCodingStandard\\ValueObject\\Error\\FileDiff>>#'

# false positive on custom config tets
# on purpose to override a config
-
message: '#Missing call to parent\:\:setUp\(\) method#'
paths:
Expand All @@ -57,43 +49,16 @@ parameters:
- tests/Skipper/SkipCriteriaResolver/SkippedPathsResolver/SkippedPathsResolverTest.php
- src/Testing/PHPUnit/AbstractCheckerTestCase.php

# testing instance of on purpose
-
message: '#Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf#'
path: tests/*

# overly detailed
- '#PHPDoc tag @var with type string\|false is not subtype of native type non\-empty\-string\|false#'

# array validation on purpose
- '#Call to static method Webmozart\\Assert\\Assert\:\:allString\(\) with (non-empty-array|list|array)<string> will always evaluate to true#'
- '#Call to static method Webmozart\\Assert\\Assert\:\:allIsArray\(\) with array<class\-string<PHP_CodeSniffer\\Sniffs\\Sniff\|PhpCsFixer\\Fixer\\FixerInterface>, array<mixed>> will always evaluate to true#'

# hack to autoload contants
# intentional: hack to autoload contants
- '#Call to new PHP_CodeSniffer\\Util\\Tokens\(\) on a separate line has no effect#'

# php version condition
-
identifier: smaller.alwaysFalse
path: src/Configuration/ConfigInitializer.php

# false positive
-
identifier: offsetAssign.dimType
path: src/Console/Output/JsonOutputFormatter.php

# coding-standard: runtime-defined PHP_CodeSniffer/php-cs-fixer token constants
- '#Constant T_OPEN_CURLY_BRACKET|T_START_NOWDOC not found#'

# coding-standard: php-cs-fixer interface generics intentionally left unspecified
- '#Class (.*?) implements generic interface PhpCsFixer\\Fixer\\ConfigurableFixerInterface but does not specify its types\: TFixerInputConfig, TFixerComputedConfig#'

# coding-standard: intentional cross-version condition
-
message: '#Comparison operation ">\=" between int<\d+, \d+> and (.*?) is always true#'
path: packages/coding-standard/src/TokenAnalyzer/DocblockRelatedParamNamesResolver.php

# coding-standard: intentional null removal
-
message: '#Parameter \#1 \$array \(array<int, PhpCsFixer\\Tokenizer\\Token>\) to function array_filter does not contain falsy values, the array will always stay the same#'
path: packages/coding-standard/src/TokenRunner/Traverser/TokenReverser.php
identifier: smaller.alwaysFalse
path: src/Configuration/ConfigInitializer.php
2 changes: 1 addition & 1 deletion src/Console/Output/JsonOutputFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public function createJsonContent(ErrorAndDiffResult $errorAndDiffResult, bool $
}

/**
* @return array{totals: array{errors: int, diffs: int}, files: string[]}
* @return array{totals: array{errors: int, diffs: int}, files: array<string, array<string, list<array<string, mixed>>>>}
*/
private function createBaseErrorsJson(ErrorAndDiffResult $errorAndDiffResult): array
{
Expand Down
42 changes: 25 additions & 17 deletions src/Parallel/Application/ParallelFileProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,12 @@
*
* https://github.com/phpstan/phpstan-src/commit/b84acd2e3eadf66189a64fdbc6dd18ff76323f67#diff-7f625777f1ce5384046df08abffd6c911cfbb1cfc8fcb2bdeaf78f337689e3e2R150
*/
final class ParallelFileProcessor
final readonly class ParallelFileProcessor
{
private const int SYSTEM_ERROR_LIMIT = 50;

private ProcessPool|null $processPool = null;

public function __construct(
private readonly WorkerCommandLineFactory $workerCommandLineFactory,
private WorkerCommandLineFactory $workerCommandLineFactory,
) {
}

Expand Down Expand Up @@ -70,24 +68,32 @@ public function check(
$systemErrors = [];

$tcpServer = new TcpServer('127.0.0.1:0', $streamSelectLoop);
$this->processPool = new ProcessPool($tcpServer);
$processPool = new ProcessPool($tcpServer);

$tcpServer->on(ReactEvent::CONNECTION, function (ConnectionInterface $connection) use (&$jobs): void {
$tcpServer->on(ReactEvent::CONNECTION, function (ConnectionInterface $connection) use (
&$jobs,
$processPool
): void {
$inDecoder = new Decoder($connection, true, 512, 0, 4 * 1024 * 1024);
$outEncoder = new Encoder($connection);

$inDecoder->on(ReactEvent::DATA, function (array $data) use (&$jobs, $inDecoder, $outEncoder): void {
$inDecoder->on(ReactEvent::DATA, function (array $data) use (
&$jobs,
$inDecoder,
$outEncoder,
$processPool
): void {
$action = $data[ReactCommand::ACTION];
if ($action !== Action::HELLO) {
return;
}

$processIdentifier = $data[Option::PARALLEL_IDENTIFIER];
$parallelProcess = $this->processPool->getProcess($processIdentifier);
$parallelProcess = $processPool->getProcess($processIdentifier);
$parallelProcess->bindConnection($inDecoder, $outEncoder);

if ($jobs === []) {
$this->processPool->quitProcess($processIdentifier);
$processPool->quitProcess($processIdentifier);
return;
}

Expand All @@ -112,13 +118,14 @@ public function check(
$handleErrorCallable = function (Throwable $throwable) use (
&$systemErrors,
&$systemErrorsCount,
&$reachedSystemErrorsCountLimit
&$reachedSystemErrorsCountLimit,
$processPool
): void {
$systemErrors[] = new SystemError($throwable->getLine(), $throwable->getMessage(), $throwable->getFile());

++$systemErrorsCount;
$reachedSystemErrorsCountLimit = true;
$this->processPool->quitAll();
$processPool->quitAll();
};

$timeoutInSeconds = SimpleParameterProvider::getIntParameter(Option::PARALLEL_TIMEOUT_IN_SECONDS);
Expand Down Expand Up @@ -161,7 +168,8 @@ function (array $json) use (
$postFileCallback,
&$systemErrorsCount,
&$reachedInternalErrorsCountLimit,
$processIdentifier
$processIdentifier,
$processPool
): void {
// decode arrays to objects
foreach ($json[Bridge::SYSTEM_ERRORS] as $jsonError) {
Expand All @@ -186,11 +194,11 @@ function (array $json) use (
$systemErrorsCount += $json[Bridge::SYSTEM_ERRORS_COUNT];
if ($systemErrorsCount >= self::SYSTEM_ERROR_LIMIT) {
$reachedInternalErrorsCountLimit = true;
$this->processPool->quitAll();
$processPool->quitAll();
}

if ($jobs === []) {
$this->processPool->quitProcess($processIdentifier);
$processPool->quitProcess($processIdentifier);
return;
}

Expand All @@ -205,8 +213,8 @@ function (array $json) use (
$handleErrorCallable,

// 3. callable on exit
function ($exitCode, string $stdErr) use (&$systemErrors, $processIdentifier): void {
$this->processPool->tryQuitProcess($processIdentifier);
function ($exitCode, string $stdErr) use (&$systemErrors, $processIdentifier, $processPool): void {
$processPool->tryQuitProcess($processIdentifier);
if ($exitCode === ExitCode::SUCCESS) {
return;
}
Expand All @@ -219,7 +227,7 @@ function ($exitCode, string $stdErr) use (&$systemErrors, $processIdentifier): v
}
);

$this->processPool->attachProcess($processIdentifier, $parallelProcess);
$processPool->attachProcess($processIdentifier, $parallelProcess);
}

$streamSelectLoop->run();
Expand Down
1 change: 0 additions & 1 deletion src/Skipper/FileSystem/FnMatchPathNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public function normalizeForFnmatch(string $path): string
}

if (\str_contains($path, '..')) {
/** @var string|false $realPath */
$realPath = realpath($path);
if ($realPath === false) {
return '';
Expand Down
3 changes: 1 addition & 2 deletions src/Skipper/RealpathMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ final class RealpathMatcher
{
public function match(string $matchingPath, string $filePath): bool
{
/** @var string|false $realPathMatchingPath */
/** @var non-empty-string|false $realPathMatchingPath */
$realPathMatchingPath = realpath($matchingPath);
if ($realPathMatchingPath === false) {
return false;
}

/** @var string|false $realpathFilePath */
$realpathFilePath = realpath($filePath);
if ($realpathFilePath === false) {
return false;
Expand Down
2 changes: 0 additions & 2 deletions tests/SniffRunner/File/FileFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Symplify\EasyCodingStandard\Tests\SniffRunner\File;

use PHP_CodeSniffer\Files\File as PhpCodeSnifferFile;
use PHP_CodeSniffer\Fixer;
use Symplify\EasyCodingStandard\SniffRunner\File\FileFactory;
use Symplify\EasyCodingStandard\SniffRunner\ValueObject\File;
Expand All @@ -20,7 +19,6 @@ public function test(): void
$file = $fileFactory->createFromFile($filePath);

$this->assertInstanceOf(File::class, $file);
$this->assertInstanceOf(PhpCodeSnifferFile::class, $file);
$this->assertInstanceOf(Fixer::class, $file->fixer);
$this->assertSame($filePath, $file->getFilename());
}
Expand Down
Loading