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: 1 addition & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Memory limit for PHPStan and Rector is `1G` (already set in composer scripts).

## Architecture

- `src/Config/ECSConfig.php` — Illuminate container subclass, low-level rule registration (`rule()`, `ruleWithConfiguration()`, `sets()`, `import()`). Auto-tags Sniff/FixerInterface/OutputFormatterInterface bindings.
- `src/Config/ECSConfig.php` — `Entropy\Container\Container` subclass, low-level rule registration (`rule()`, `ruleWithConfiguration()`, `sets()`, `import()`). Auto-tags Sniff/FixerInterface/OutputFormatterInterface bindings.
- `src/Configuration/ECSConfigBuilder.php` — fluent user-facing API (`withRules`, `withSets`, `withPreparedSets`, `withPhpCsFixerSets`, `withSpacesLevel`, …). Returned by `ECSConfig::configure()`. `__invoke(ECSConfig)` flushes the builder state into the container.
- `config/set/common/*.php` — prepared rule sets (spaces, arrays, namespaces, docblock, etc.); each returns a closure consumed by `ECSConfig::import()`.
- `src/Config/Level/` — gradual-adoption levels (e.g. `SpacesLevel`). Each level class exposes `RULES` (ordered safest → most invasive) and optionally `RULE_CONFIGURATIONS`.
Expand All @@ -50,10 +50,6 @@ Memory limit for PHPStan and Rector is `1G` (already set in composer scripts).
- Don't introduce new comments unless they explain a non-obvious why; well-named identifiers should carry meaning.
- Don't add backwards-compat shims, dead re-exports, or features that aren't required by the task.

## Patched dependency

`illuminate/container` is patched via `patches/illuminate-container-container-php.patch` (cweagans/composer-patches). Don't update the package without re-checking the patch.

## Don't

- Don't bypass `phpstan`, `rector`, or `check-cs` with skip comments unless the user asks for it.
Expand Down
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@
],
"require": {
"php": ">=8.4",
"clue/ndjson-react": "^1.3",
"composer/pcre": "^3.4",
"composer/xdebug-handler": "^3.0.5",
"entropy/entropy": "^0.4",
"fidry/cpu-core-counter": "^1.3",
"friendsofphp/php-cs-fixer": "^3.95.5",
"nette/utils": "^4.1",
"react/child-process": "^0.6.7",
"react/event-loop": "^1.6",
"react/socket": "^1.17",
"sebastian/diff": "^9.0",
"squizlabs/php_codesniffer": "^4.0.1",
"symfony/finder": "^7.4",
"symplify/easy-parallel": "dev-main",
"webmozart/assert": "^2.4"
},
"require-dev": {
Expand Down
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ parameters:
# set above
-
path: src/Parallel/Application/ParallelFileProcessor.php
message: '#Cannot call method (.*?)\(\) on Symplify\\EasyParallel\\ValueObject\\ProcessPool\|null#'
message: '#Cannot call method (.*?)\(\) on Symplify\\EasyCodingStandard\\Parallel\\ValueObject\\ProcessPool\|null#'

- '#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>>#'

Expand Down
4 changes: 2 additions & 2 deletions src/Application/EasyCodingStandardApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
use Symplify\EasyCodingStandard\FileSystem\StaticRelativeFilePathHelper;
use Symplify\EasyCodingStandard\Finder\SourceFinder;
use Symplify\EasyCodingStandard\Parallel\Application\ParallelFileProcessor;
use Symplify\EasyCodingStandard\Parallel\CpuCoreCountProvider;
use Symplify\EasyCodingStandard\Parallel\ScheduleFactory;
use Symplify\EasyCodingStandard\Parallel\ValueObject\Bridge;
use Symplify\EasyCodingStandard\SniffRunner\ValueObject\Error\CodingStandardError;
use Symplify\EasyCodingStandard\Utils\ParametersMerger;
use Symplify\EasyCodingStandard\ValueObject\Configuration;
use Symplify\EasyCodingStandard\ValueObject\Error\FileDiff;
use Symplify\EasyCodingStandard\ValueObject\Error\SystemError;
use Symplify\EasyCodingStandard\ValueObject\Option;
use Symplify\EasyParallel\CpuCoreCountProvider;
use Symplify\EasyParallel\ScheduleFactory;

final readonly class EasyCodingStandardApplication
{
Expand Down
4 changes: 2 additions & 2 deletions src/Console/Command/WorkerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
use Symplify\EasyCodingStandard\Console\ExitCode;
use Symplify\EasyCodingStandard\Console\Output\ConsoleOutputFormatter;
use Symplify\EasyCodingStandard\MemoryLimitter;
use Symplify\EasyCodingStandard\Parallel\Enum\Action;
use Symplify\EasyCodingStandard\Parallel\Enum\ReactCommand;
use Symplify\EasyCodingStandard\Parallel\WorkerRunner;
use Symplify\EasyParallel\Enum\Action;
use Symplify\EasyParallel\Enum\ReactCommand;

/**
* Inspired at: https://github.com/phpstan/phpstan-src/commit/9124c66dcc55a222e21b1717ba5f60771f7dda92
Expand Down
16 changes: 8 additions & 8 deletions src/Parallel/Application/ParallelFileProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@
use React\Socket\TcpServer;
use Symplify\EasyCodingStandard\Console\ExitCode;
use Symplify\EasyCodingStandard\DependencyInjection\SimpleParameterProvider;
use Symplify\EasyCodingStandard\Parallel\CommandLine\WorkerCommandLineFactory;
use Symplify\EasyCodingStandard\Parallel\Enum\Action;
use Symplify\EasyCodingStandard\Parallel\Enum\Content;
use Symplify\EasyCodingStandard\Parallel\Enum\ReactCommand;
use Symplify\EasyCodingStandard\Parallel\Enum\ReactEvent;
use Symplify\EasyCodingStandard\Parallel\ValueObject\Bridge;
use Symplify\EasyCodingStandard\Parallel\ValueObject\ParallelProcess;
use Symplify\EasyCodingStandard\Parallel\ValueObject\ProcessPool;
use Symplify\EasyCodingStandard\Parallel\ValueObject\Schedule;
use Symplify\EasyCodingStandard\SniffRunner\ValueObject\Error\CodingStandardError;
use Symplify\EasyCodingStandard\ValueObject\Configuration;
use Symplify\EasyCodingStandard\ValueObject\Error\FileDiff;
use Symplify\EasyCodingStandard\ValueObject\Error\SystemError;
use Symplify\EasyCodingStandard\ValueObject\Option;
use Symplify\EasyParallel\CommandLine\WorkerCommandLineFactory;
use Symplify\EasyParallel\Enum\Action;
use Symplify\EasyParallel\Enum\Content;
use Symplify\EasyParallel\Enum\ReactCommand;
use Symplify\EasyParallel\Enum\ReactEvent;
use Symplify\EasyParallel\ValueObject\ParallelProcess;
use Symplify\EasyParallel\ValueObject\ProcessPool;
use Symplify\EasyParallel\ValueObject\Schedule;
use Throwable;

/**
Expand Down
86 changes: 86 additions & 0 deletions src/Parallel/CommandLine/WorkerCommandLineFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

declare(strict_types=1);

namespace Symplify\EasyCodingStandard\Parallel\CommandLine;

final class WorkerCommandLineFactory
{
private const string OPTION_DASHES = '--';

/**
* @param array<string, bool|string|null> $workerOptionValues option name => value, mirrored to the worker process
* @param string[] $paths
*/
public function create(
string $baseScript,
string $workerCommandName,
?string $projectConfigFile,
array $workerOptionValues,
array $paths,
string $identifier,
int $port
): string {
$processCommandArray = [escapeshellarg(PHP_BINARY), escapeshellarg($baseScript), $workerCommandName];

if ($projectConfigFile !== null) {
$processCommandArray[] = '--config';
$processCommandArray[] = escapeshellarg($projectConfigFile);
}

foreach ($this->mirrorCommandOptions($workerOptionValues) as $processCommandOption) {
$processCommandArray[] = $processCommandOption;
}

// for TCP local server
$processCommandArray[] = '--port';
$processCommandArray[] = (string) $port;

$processCommandArray[] = '--identifier';
$processCommandArray[] = escapeshellarg($identifier);

foreach ($paths as $path) {
$processCommandArray[] = escapeshellarg($path);
}

// set json output
$processCommandArray[] = '--output-format';
$processCommandArray[] = escapeshellarg('json');

return implode(' ', $processCommandArray);
}

/**
* @param array<string, bool|string|null> $workerOptionValues
* @return string[]
*/
private function mirrorCommandOptions(array $workerOptionValues): array
{
$processCommandOptions = [];

foreach ($workerOptionValues as $optionName => $optionValue) {
// skip clutter
if ($optionValue === null) {
continue;
}

if (is_bool($optionValue)) {
if ($optionValue) {
$processCommandOptions[] = self::OPTION_DASHES . $optionName;
}

continue;
}

if ($optionName === 'memory-limit') {
// does not accept -1 as value without assign
$processCommandOptions[] = '--' . $optionName . '=' . $optionValue;
} else {
$processCommandOptions[] = self::OPTION_DASHES . $optionName;
$processCommandOptions[] = escapeshellarg($optionValue);
}
}

return $processCommandOptions;
}
}
15 changes: 15 additions & 0 deletions src/Parallel/Contract/SerializableInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Symplify\EasyCodingStandard\Parallel\Contract;

use JsonSerializable;

interface SerializableInterface extends JsonSerializable
{
/**
* @param array<string, mixed> $json
*/
public static function decode(array $json): self;
}
23 changes: 23 additions & 0 deletions src/Parallel/CpuCoreCountProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Symplify\EasyCodingStandard\Parallel;

use Fidry\CpuCoreCounter\CpuCoreCounter;
use Fidry\CpuCoreCounter\NumberOfCpuCoreNotFound;

final class CpuCoreCountProvider
{
private const int DEFAULT_CORE_COUNT = 2;

public function provide(): int
{
try {
return new CpuCoreCounter()
->getCount();
} catch (NumberOfCpuCoreNotFound) {
return self::DEFAULT_CORE_COUNT;
}
}
}
14 changes: 14 additions & 0 deletions src/Parallel/Enum/Action.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Symplify\EasyCodingStandard\Parallel\Enum;

final class Action
{
public const string HELLO = 'hello';

public const string MAIN = 'main';

public const string RESULT = 'result';
}
12 changes: 12 additions & 0 deletions src/Parallel/Enum/Content.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Symplify\EasyCodingStandard\Parallel\Enum;

final class Content
{
public const string RESULT = 'result';

public const string FILES = 'files';
}
12 changes: 12 additions & 0 deletions src/Parallel/Enum/ReactCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Symplify\EasyCodingStandard\Parallel\Enum;

final class ReactCommand
{
public const string ACTION = 'action';

public const string IDENTIFIER = 'identifier';
}
16 changes: 16 additions & 0 deletions src/Parallel/Enum/ReactEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Symplify\EasyCodingStandard\Parallel\Enum;

final class ReactEvent
{
public const string EXIT = 'exit';

public const string DATA = 'data';

public const string ERROR = 'error';

public const string CONNECTION = 'connection';
}
11 changes: 11 additions & 0 deletions src/Parallel/Exception/ParallelShouldNotHappenException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Symplify\EasyCodingStandard\Parallel\Exception;

use Exception;

final class ParallelShouldNotHappenException extends Exception
{
}
30 changes: 30 additions & 0 deletions src/Parallel/ScheduleFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Symplify\EasyCodingStandard\Parallel;

use Symplify\EasyCodingStandard\Parallel\ValueObject\Schedule;
use Webmozart\Assert\Assert;

/**
* Used from
* https://github.com/phpstan/phpstan-src/blob/9124c66dcc55a222e21b1717ba5f60771f7dda92/src/Parallel/Scheduler.php
*/
final class ScheduleFactory
{
/**
* @param array<string> $files
*/
public function create(int $cpuCores, int $jobSize, int $maxNumberOfProcesses, array $files): Schedule
{
Assert::positiveInteger($jobSize);

$jobs = array_chunk($files, $jobSize);
$numberOfProcesses = min(count($jobs), $cpuCores);

$numberOfProcesses = min($maxNumberOfProcesses, $numberOfProcesses);

return new Schedule($numberOfProcesses, $jobs);
}
}
Loading
Loading