From 6249c197f215cc2b3ce9cf5e9d29bf6694b7e55b Mon Sep 17 00:00:00 2001 From: mrmishmash Date: Sat, 19 Oct 2024 23:52:39 +0200 Subject: [PATCH 1/3] Adds 'parallel' option support to phpcs task. --- doc/tasks/phpcs.md | 8 ++++ src/Task/Phpcs.php | 74 +++++++++++++++++++++++++++++++++++- test/Unit/Task/PhpcsTest.php | 18 ++++++++- 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/doc/tasks/phpcs.md b/doc/tasks/phpcs.md index 3ffc2cf8..f3f08a9b 100644 --- a/doc/tasks/phpcs.md +++ b/doc/tasks/phpcs.md @@ -31,6 +31,7 @@ grumphp: triggered_by: [php] exclude: [] show_sniffs_error_path: true + parallel: null ``` **standard** @@ -136,6 +137,13 @@ A list of rules that should not be checked. Leave this option blank to run all c Displays the sniff that triggered the error, allowing you to more easily find the specific rules with their namespaces. +**parallel** + +*Default: null* + +Determines the number of processes that phpcs / phpcbf will use when running. Pass a positive integer for multiple +processes. You can also pass the string 'auto' and it will use the number of cores / vCPUs your machine supports. + ## Framework presets ### Symfony 2 diff --git a/src/Task/Phpcs.php b/src/Task/Phpcs.php index c16320b3..4521060e 100644 --- a/src/Task/Phpcs.php +++ b/src/Task/Phpcs.php @@ -18,6 +18,7 @@ use GrumPHP\Task\Context\RunContext; use Symfony\Component\Console\Exception\CommandNotFoundException; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Process\Exception\ProcessFailedException; use Symfony\Component\Process\Process; /** @@ -47,7 +48,8 @@ public static function getConfigurableOptions(): ConfigOptionsResolver 'report' => 'full', 'report_width' => null, 'exclude' => [], - 'show_sniffs_error_path' => true + 'show_sniffs_error_path' => true, + 'parallel' => null, ]); $resolver->addAllowedTypes('standard', ['array', 'null', 'string']); @@ -64,6 +66,7 @@ public static function getConfigurableOptions(): ConfigOptionsResolver $resolver->addAllowedTypes('report_width', ['null', 'int']); $resolver->addAllowedTypes('exclude', ['array']); $resolver->addAllowedTypes('show_sniffs_error_path', ['bool']); + $resolver->addAllowedTypes('parallel', ['null', 'int', 'string']); return ConfigOptionsResolver::fromOptionsResolver($resolver); } @@ -161,7 +164,76 @@ private function addArgumentsFromConfig( $arguments->addOptionalCommaSeparatedArgument('--ignore=%s', $config['ignore_patterns']); $arguments->addOptionalCommaSeparatedArgument('--exclude=%s', $config['exclude']); $arguments->addOptionalArgument('-s', $config['show_sniffs_error_path']); + $arguments->addOptionalArgument('--parallel=%s', $this->getParallelValue($config['parallel'])); return $arguments; } + + protected function getParallelValue(string|int|null $option): ?int + { + if ($option === null) { + return null; + } + + if (is_string($option)) { + if ($option === 'auto') { + return $this->getNumberOfCpuCores() ?? 1; + } + + throw new \InvalidArgumentException( + sprintf("When option 'parallel' is a string it can only be 'auto', got '%s'", $option) + ); + } + + if ($option < 1) { + throw new \InvalidArgumentException( + sprintf("When option 'parallel' is an integer it must be greater than zero, got %d", $option) + ); + } + + return $option; + } + + /** + * @return int|null + */ + protected function getNumberOfCpuCores(): ?int + { + try { + if (strncasecmp(PHP_OS, 'WIN', 3) === 0) { + $process = new Process(['wmic', 'cpu', 'get', 'NumberOfCores']); + } + + if (strncasecmp(PHP_OS, 'Linux', 5) === 0 || strncasecmp(PHP_OS, 'Darwin', 6) === 0) { + $process = new Process(['nproc']); + } + + if (!isset($process)) { + return null; + } + + $process->run(); + + if (!$process->isSuccessful()) { + throw new ProcessFailedException($process); + } + + $output = $process->getOutput(); + + if (strncasecmp(PHP_OS, 'WIN', 3) === 0) { + $lines = explode("\n", trim($output)); + foreach ($lines as $line) { + $cores = (int) trim($line); + if ($cores > 0) { + return $cores; + } + } + return null; + } + + return (int) trim($output); + } catch (\Exception) { + return null; + } + } } diff --git a/test/Unit/Task/PhpcsTest.php b/test/Unit/Task/PhpcsTest.php index 45c36cb1..b2e6b3f2 100644 --- a/test/Unit/Task/PhpcsTest.php +++ b/test/Unit/Task/PhpcsTest.php @@ -49,7 +49,8 @@ public function provideConfigurableOptions(): iterable 'report' => 'full', 'report_width' => null, 'exclude' => [], - 'show_sniffs_error_path' => true + 'show_sniffs_error_path' => true, + 'parallel' => null, ] ]; } @@ -357,6 +358,21 @@ public function provideExternalTaskRuns(): iterable $this->expectFileList('hello.php'.PHP_EOL.'hello2.php'), ] ]; + yield 'parallel' => [ + [ + 'parallel' => 4, + ], + $this->mockContext(RunContext::class, ['hello.php', 'hello2.php']), + 'phpcs', + [ + '--extensions=php', + '--report=full', + '-s', + '--parallel=4', + '--report-json', + $this->expectFileList('hello.php'.PHP_EOL.'hello2.php'), + ] + ]; } private function expectFileList(string $expectedContents): callable From 721865085caf0a5c06f6e6f0b7116ed465ff71f5 Mon Sep 17 00:00:00 2001 From: mrmishmash Date: Sun, 20 Oct 2024 10:19:08 +0200 Subject: [PATCH 2/3] Remove auto detection of CPU cores in Phpcs task. --- doc/tasks/phpcs.md | 3 +- src/Task/Phpcs.php | 71 +--------------------------------------------- 2 files changed, 2 insertions(+), 72 deletions(-) diff --git a/doc/tasks/phpcs.md b/doc/tasks/phpcs.md index f3f08a9b..a2b4dc0c 100644 --- a/doc/tasks/phpcs.md +++ b/doc/tasks/phpcs.md @@ -141,8 +141,7 @@ Displays the sniff that triggered the error, allowing you to more easily find th *Default: null* -Determines the number of processes that phpcs / phpcbf will use when running. Pass a positive integer for multiple -processes. You can also pass the string 'auto' and it will use the number of cores / vCPUs your machine supports. +Determines the number of processes that phpcs / phpcbf will use when running. Defaults to a single process. ## Framework presets diff --git a/src/Task/Phpcs.php b/src/Task/Phpcs.php index 4521060e..46bc5b5c 100644 --- a/src/Task/Phpcs.php +++ b/src/Task/Phpcs.php @@ -18,7 +18,6 @@ use GrumPHP\Task\Context\RunContext; use Symfony\Component\Console\Exception\CommandNotFoundException; use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Process\Exception\ProcessFailedException; use Symfony\Component\Process\Process; /** @@ -164,76 +163,8 @@ private function addArgumentsFromConfig( $arguments->addOptionalCommaSeparatedArgument('--ignore=%s', $config['ignore_patterns']); $arguments->addOptionalCommaSeparatedArgument('--exclude=%s', $config['exclude']); $arguments->addOptionalArgument('-s', $config['show_sniffs_error_path']); - $arguments->addOptionalArgument('--parallel=%s', $this->getParallelValue($config['parallel'])); + $arguments->addOptionalArgument('--parallel=%s', $config['parallel']); return $arguments; } - - protected function getParallelValue(string|int|null $option): ?int - { - if ($option === null) { - return null; - } - - if (is_string($option)) { - if ($option === 'auto') { - return $this->getNumberOfCpuCores() ?? 1; - } - - throw new \InvalidArgumentException( - sprintf("When option 'parallel' is a string it can only be 'auto', got '%s'", $option) - ); - } - - if ($option < 1) { - throw new \InvalidArgumentException( - sprintf("When option 'parallel' is an integer it must be greater than zero, got %d", $option) - ); - } - - return $option; - } - - /** - * @return int|null - */ - protected function getNumberOfCpuCores(): ?int - { - try { - if (strncasecmp(PHP_OS, 'WIN', 3) === 0) { - $process = new Process(['wmic', 'cpu', 'get', 'NumberOfCores']); - } - - if (strncasecmp(PHP_OS, 'Linux', 5) === 0 || strncasecmp(PHP_OS, 'Darwin', 6) === 0) { - $process = new Process(['nproc']); - } - - if (!isset($process)) { - return null; - } - - $process->run(); - - if (!$process->isSuccessful()) { - throw new ProcessFailedException($process); - } - - $output = $process->getOutput(); - - if (strncasecmp(PHP_OS, 'WIN', 3) === 0) { - $lines = explode("\n", trim($output)); - foreach ($lines as $line) { - $cores = (int) trim($line); - if ($cores > 0) { - return $cores; - } - } - return null; - } - - return (int) trim($output); - } catch (\Exception) { - return null; - } - } } From 05745243b92a5c8a8fba480a710bd5496a02cdee Mon Sep 17 00:00:00 2001 From: mrmishmash Date: Sun, 20 Oct 2024 10:22:39 +0200 Subject: [PATCH 3/3] Remove 'string' as possible type for parallel option. --- src/Task/Phpcs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Task/Phpcs.php b/src/Task/Phpcs.php index 46bc5b5c..8d3c1812 100644 --- a/src/Task/Phpcs.php +++ b/src/Task/Phpcs.php @@ -65,7 +65,7 @@ public static function getConfigurableOptions(): ConfigOptionsResolver $resolver->addAllowedTypes('report_width', ['null', 'int']); $resolver->addAllowedTypes('exclude', ['array']); $resolver->addAllowedTypes('show_sniffs_error_path', ['bool']); - $resolver->addAllowedTypes('parallel', ['null', 'int', 'string']); + $resolver->addAllowedTypes('parallel', ['null', 'int']); return ConfigOptionsResolver::fromOptionsResolver($resolver); }