From 34a8b96e529fe7284ae76dbc8987124b42f39ad9 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 2 Jun 2025 17:50:55 +0200 Subject: [PATCH 01/10] Bump Symfony 8 to PHP >= 8.4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index dda5575e..146fc200 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=8.2" + "php": ">=8.4" }, "autoload": { "psr-4": { "Symfony\\Component\\Process\\": "" }, From e364119194b3c853dd8c0ff0630098d26312a0c1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 3 Jun 2025 17:41:25 +0200 Subject: [PATCH 02/10] Remove deadcode after the bump to PHP >= 8.4 --- Tests/ProcessTest.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Tests/ProcessTest.php b/Tests/ProcessTest.php index 17f98a66..ef63f7a6 100644 --- a/Tests/ProcessTest.php +++ b/Tests/ProcessTest.php @@ -746,9 +746,6 @@ public function testProcessIsSignaledIfStopped() if ('\\' === \DIRECTORY_SEPARATOR) { $this->markTestSkipped('Windows does not support POSIX signals'); } - if (\PHP_VERSION_ID < 80300 && isset($_SERVER['GITHUB_ACTIONS'])) { - $this->markTestSkipped('Transient on GHA with PHP < 8.3'); - } $process = $this->getProcessForCode('sleep(32);'); $process->start(); @@ -1700,9 +1697,6 @@ public function testNotIgnoringSignal() if (!\function_exists('pcntl_signal')) { $this->markTestSkipped('pnctl extension is required.'); } - if (\PHP_VERSION_ID < 80300 && isset($_SERVER['GITHUB_ACTIONS'])) { - $this->markTestSkipped('Transient on GHA with PHP < 8.3'); - } $process = $this->getProcess(['sleep', '10']); From d22c732186c750da0021eb9fe5376057daf719cf Mon Sep 17 00:00:00 2001 From: Jack Worman Date: Tue, 3 Jun 2025 21:54:08 -0400 Subject: [PATCH 03/10] [Process] Improve typing for process callback --- PhpProcess.php | 3 +++ PhpSubprocess.php | 3 +++ Process.php | 41 +++++++++++++++++++++++++---------------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/PhpProcess.php b/PhpProcess.php index 0e7ff846..930f591f 100644 --- a/PhpProcess.php +++ b/PhpProcess.php @@ -55,6 +55,9 @@ public static function fromShellCommandline(string $command, ?string $cwd = null throw new LogicException(\sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class)); } + /** + * @param (callable('out'|'err', string):void)|null $callback + */ public function start(?callable $callback = null, array $env = []): void { if (null === $this->getCommandLine()) { diff --git a/PhpSubprocess.php b/PhpSubprocess.php index bdd4173c..8282f93c 100644 --- a/PhpSubprocess.php +++ b/PhpSubprocess.php @@ -78,6 +78,9 @@ public static function fromShellCommandline(string $command, ?string $cwd = null throw new LogicException(\sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class)); } + /** + * @param (callable('out'|'err', string):void)|null $callback + */ public function start(?callable $callback = null, array $env = []): void { if (null === $this->getCommandLine()) { diff --git a/Process.php b/Process.php index a8beb93d..d52db23a 100644 --- a/Process.php +++ b/Process.php @@ -51,6 +51,9 @@ class Process implements \IteratorAggregate public const ITER_SKIP_OUT = 4; // Use this flag to skip STDOUT while iterating public const ITER_SKIP_ERR = 8; // Use this flag to skip STDERR while iterating + /** + * @var \Closure('out'|'err', string)|null + */ private ?\Closure $callback = null; private array|string $commandline; private ?string $cwd; @@ -231,8 +234,8 @@ public function __clone() * The STDOUT and STDERR are also available after the process is finished * via the getOutput() and getErrorOutput() methods. * - * @param callable|null $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR + * @param (callable('out'|'err', string):void)|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR * * @return int The exit status code * @@ -257,6 +260,9 @@ public function run(?callable $callback = null, array $env = []): int * This is identical to run() except that an exception is thrown if the process * exits with a non-zero exit code. * + * @param (callable('out'|'err', string):void)|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * * @return $this * * @throws ProcessFailedException if the process didn't terminate successfully @@ -284,8 +290,8 @@ public function mustRun(?callable $callback = null, array $env = []): static * the output in real-time while writing the standard input to the process. * It allows to have feedback from the independent process during execution. * - * @param callable|null $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR + * @param (callable('out'|'err', string):void)|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR * * @throws ProcessStartFailedException When process can't be launched * @throws RuntimeException When process is already running @@ -395,8 +401,8 @@ public function start(?callable $callback = null, array $env = []): void * * Be warned that the process is cloned before being started. * - * @param callable|null $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR + * @param (callable('out'|'err', string):void)|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR * * @throws ProcessStartFailedException When process can't be launched * @throws RuntimeException When process is already running @@ -424,7 +430,8 @@ public function restart(?callable $callback = null, array $env = []): static * from the output in real-time while writing the standard input to the process. * It allows to have feedback from the independent process during execution. * - * @param callable|null $callback A valid PHP callback + * @param (callable('out'|'err', string):void)|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR * * @return int The exitcode of the process * @@ -471,6 +478,9 @@ public function wait(?callable $callback = null): int * from the output in real-time while writing the standard input to the process. * It allows to have feedback from the independent process during execution. * + * @param (callable('out'|'err', string):bool)|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * * @throws RuntimeException When process timed out * @throws LogicException When process is not yet started * @throws ProcessTimedOutException In case the timeout was reached @@ -1291,7 +1301,9 @@ private function getDescriptors(bool $hasCallback): array * The callbacks adds all occurred output to the specific buffer and calls * the user callback (if present) with the received output. * - * @param callable|null $callback The user defined PHP callback + * @param callable('out'|'err', string)|null $callback + * + * @return \Closure('out'|'err', string):bool */ protected function buildCallback(?callable $callback = null): \Closure { @@ -1299,14 +1311,11 @@ protected function buildCallback(?callable $callback = null): \Closure return fn ($type, $data): bool => null !== $callback && $callback($type, $data); } - $out = self::OUT; - - return function ($type, $data) use ($callback, $out): bool { - if ($out == $type) { - $this->addOutput($data); - } else { - $this->addErrorOutput($data); - } + return function ($type, $data) use ($callback): bool { + match ($type) { + self::OUT => $this->addOutput($data), + self::ERR => $this->addErrorOutput($data), + }; return null !== $callback && $callback($type, $data); }; From 7e90a5a07e2229e2adb51d4081931b441ea6ece7 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 9 Oct 2024 11:06:51 +0200 Subject: [PATCH 04/10] run tests using PHPUnit 11.5 --- phpunit.xml.dist | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 13bd3f83..c62cac13 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,10 +1,11 @@ @@ -18,7 +19,7 @@ - + ./ @@ -26,5 +27,9 @@ ./Tests ./vendor - + + + + + From 14f8bb0226586db04d71e5fc76a4e6f82fef9677 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 31 Jul 2025 14:36:46 +0200 Subject: [PATCH 05/10] replace PHPUnit annotations with attributes --- Tests/ExecutableFinderTest.php | 13 ++---- Tests/PhpSubprocessTest.php | 5 +- Tests/ProcessTest.php | 85 ++++++++++------------------------ 3 files changed, 30 insertions(+), 73 deletions(-) diff --git a/Tests/ExecutableFinderTest.php b/Tests/ExecutableFinderTest.php index cdc60a92..4ce80f15 100644 --- a/Tests/ExecutableFinderTest.php +++ b/Tests/ExecutableFinderTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Process\Tests; +use PHPUnit\Framework\Attributes\RunInSeparateProcess; use PHPUnit\Framework\TestCase; use Symfony\Component\Process\ExecutableFinder; @@ -110,9 +111,7 @@ public function testFindWithAddedSuffixes() $this->assertSamePath($fixturesDir.\DIRECTORY_SEPARATOR.$name.$suffix, $result); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testFindWithOpenBaseDir() { if ('\\' === \DIRECTORY_SEPARATOR) { @@ -136,9 +135,7 @@ public function testFindWithOpenBaseDir() } } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testFindBatchExecutableOnWindows() { if (\ini_get('open_basedir')) { @@ -169,9 +166,7 @@ public function testFindBatchExecutableOnWindows() $this->assertSamePath($target.'.BAT', $result); } - /** - * @runInSeparateProcess - */ + #[RunInSeparateProcess] public function testEmptyDirInPath() { putenv(\sprintf('PATH=%s%s', \dirname(\PHP_BINARY), \PATH_SEPARATOR)); diff --git a/Tests/PhpSubprocessTest.php b/Tests/PhpSubprocessTest.php index 3406e649..319e8a74 100644 --- a/Tests/PhpSubprocessTest.php +++ b/Tests/PhpSubprocessTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Process\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Process\PhpExecutableFinder; use Symfony\Component\Process\Process; @@ -25,9 +26,7 @@ public static function setUpBeforeClass(): void self::$phpBin = getenv('SYMFONY_PROCESS_PHP_TEST_BINARY') ?: ('phpdbg' === \PHP_SAPI ? 'php' : $phpBin->find()); } - /** - * @dataProvider subprocessProvider - */ + #[DataProvider('subprocessProvider')] public function testSubprocess(string $processClass, string $memoryLimit, string $expectedMemoryLimit) { $process = new Process([self::$phpBin, diff --git a/Tests/ProcessTest.php b/Tests/ProcessTest.php index 17f98a66..93ceed14 100644 --- a/Tests/ProcessTest.php +++ b/Tests/ProcessTest.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Process\Tests; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use PHPUnit\Framework\TestCase; use Symfony\Component\Process\Exception\InvalidArgumentException; use Symfony\Component\Process\Exception\LogicException; @@ -66,9 +69,7 @@ public function testInvalidCwd() $cmd->run(); } - /** - * @dataProvider invalidProcessProvider - */ + #[DataProvider('invalidProcessProvider')] public function testInvalidCommand(Process $process) { // An invalid command should not fail during start @@ -83,9 +84,7 @@ public static function invalidProcessProvider(): array ]; } - /** - * @group transient-on-windows - */ + #[Group('transient-on-windows')] public function testThatProcessDoesNotThrowWarningDuringRun() { @trigger_error('Test Error', \E_USER_NOTICE); @@ -123,9 +122,7 @@ public function testFloatAndNullTimeout() $this->assertNull($p->getTimeout()); } - /** - * @requires extension pcntl - */ + #[RequiresPhpExtension('pcntl')] public function testStopWithTimeoutIsActuallyWorking() { $p = $this->getProcess([self::$phpBin, __DIR__.'/NonStopableProcess.php', 30]); @@ -147,9 +144,7 @@ public function testStopWithTimeoutIsActuallyWorking() $this->assertLessThan(15, microtime(true) - $start); } - /** - * @group transient-on-windows - */ + #[Group('transient-on-windows')] public function testWaitUntilSpecificOutput() { $p = $this->getProcess([self::$phpBin, __DIR__.'/KillableProcessWithOutput.php']); @@ -233,9 +228,8 @@ public function testReadSupportIsDisabledWithoutCallback() /** * tests results from sub processes. - * - * @dataProvider responsesCodeProvider */ + #[DataProvider('responsesCodeProvider')] public function testProcessResponses($expected, $getter, $code) { $p = $this->getProcessForCode($code); @@ -246,9 +240,8 @@ public function testProcessResponses($expected, $getter, $code) /** * tests results from sub processes. - * - * @dataProvider pipesCodeProvider */ + #[DataProvider('pipesCodeProvider')] public function testProcessPipes($code, $size) { $expected = str_repeat(str_repeat('*', 1024), $size).'!'; @@ -262,9 +255,7 @@ public function testProcessPipes($code, $size) $this->assertEquals($expectedLength, \strlen($p->getErrorOutput())); } - /** - * @dataProvider pipesCodeProvider - */ + #[DataProvider('pipesCodeProvider')] public function testSetStreamAsInput($code, $size) { $expected = str_repeat(str_repeat('*', 1024), $size).'!'; @@ -319,9 +310,7 @@ public function testSetInputWhileRunningThrowsAnException() throw $e; } - /** - * @dataProvider provideInvalidInputValues - */ + #[DataProvider('provideInvalidInputValues')] public function testInvalidInput(array|object $value) { $process = $this->getProcess('foo'); @@ -340,9 +329,7 @@ public static function provideInvalidInputValues() ]; } - /** - * @dataProvider provideInputValues - */ + #[DataProvider('provideInputValues')] public function testValidInput(?string $expected, float|string|null $value) { $process = $this->getProcess('foo'); @@ -373,9 +360,7 @@ public static function chainedCommandsOutputProvider() ]; } - /** - * @dataProvider chainedCommandsOutputProvider - */ + #[DataProvider('chainedCommandsOutputProvider')] public function testChainedCommandsOutput($expected, $operator, $input) { $process = $this->getProcess(\sprintf('echo %s %s echo %s', $input, $operator, $input)); @@ -425,9 +410,7 @@ public function testFlushErrorOutput() $this->assertSame('', $p->getErrorOutput()); } - /** - * @dataProvider provideIncrementalOutput - */ + #[DataProvider('provideIncrementalOutput')] public function testIncrementalOutput($getOutput, $getIncrementalOutput, $uri) { $lock = tempnam(sys_get_temp_dir(), __FUNCTION__); @@ -949,9 +932,7 @@ public function testGetPidIsNullAfterRun() $this->assertNull($process->getPid()); } - /** - * @requires extension pcntl - */ + #[RequiresPhpExtension('pcntl')] public function testSignal() { $process = $this->getProcess([self::$phpBin, __DIR__.'/SignalListener.php']); @@ -966,9 +947,7 @@ public function testSignal() $this->assertEquals('Caught SIGUSR1', $process->getOutput()); } - /** - * @requires extension pcntl - */ + #[RequiresPhpExtension('pcntl')] public function testExitCodeIsAvailableAfterSignal() { $process = $this->getProcess('sleep 4'); @@ -995,9 +974,7 @@ public function testSignalProcessNotRunning() $process->signal(1); // SIGHUP } - /** - * @dataProvider provideMethodsThatNeedARunningProcess - */ + #[DataProvider('provideMethodsThatNeedARunningProcess')] public function testMethodsThatNeedARunningProcess($method) { $process = $this->getProcess('foo'); @@ -1019,9 +996,7 @@ public static function provideMethodsThatNeedARunningProcess() ]; } - /** - * @dataProvider provideMethodsThatNeedATerminatedProcess - */ + #[DataProvider('provideMethodsThatNeedATerminatedProcess')] public function testMethodsThatNeedATerminatedProcess($method) { $this->expectException(LogicException::class); @@ -1139,9 +1114,7 @@ public function testSetNullIdleTimeoutWhileOutputIsDisabled() $this->assertSame($process, $process->setIdleTimeout(null)); } - /** - * @dataProvider provideOutputFetchingMethods - */ + #[DataProvider('provideOutputFetchingMethods')] public function testGetOutputWhileDisabled($fetchMethod) { $p = $this->getProcessForCode('sleep(41);'); @@ -1225,9 +1198,7 @@ public static function pipesCodeProvider() return $codes; } - /** - * @dataProvider provideVariousIncrementals - */ + #[DataProvider('provideVariousIncrementals')] public function testIncrementalOutputDoesNotRequireAnotherCall($stream, $method) { $process = $this->getProcessForCode('$n = 0; while ($n < 3) { file_put_contents(\''.$stream.'\', $n, 1); $n++; usleep(1000); }', null, null, null, null); @@ -1495,9 +1466,7 @@ public function testGetCommandLine() $this->assertSame($expected, $p->getCommandLine()); } - /** - * @dataProvider provideEscapeArgument - */ + #[DataProvider('provideEscapeArgument')] public function testEscapeArgument($arg) { $p = new Process([self::$phpBin, '-r', 'echo $argv[1];', $arg]); @@ -1636,9 +1605,7 @@ public function testFailingProcessWithMultipleCallsToProcGetStatus() $this->assertSame(123, $process->getExitCode()); } - /** - * @group slow - */ + #[Group('slow')] public function testLongRunningProcessWithMultipleCallsToProcGetStatus() { $process = $this->getProcess('sleep 1 && echo "done" && php -r "exit(0);"'); @@ -1651,9 +1618,7 @@ public function testLongRunningProcessWithMultipleCallsToProcGetStatus() $this->assertSame(0, $process->getExitCode()); } - /** - * @group slow - */ + #[Group('slow')] public function testLongRunningProcessWithMultipleCallsToProcGetStatusError() { $process = $this->getProcess('sleep 1 && echo "failure" && php -r "exit(123);"'); @@ -1666,9 +1631,7 @@ public function testLongRunningProcessWithMultipleCallsToProcGetStatusError() $this->assertSame(123, $process->getExitCode()); } - /** - * @group transient-on-windows - */ + #[Group('transient-on-windows')] public function testNotTerminableInputPipe() { $process = $this->getProcess('echo foo'); From 71d3ef73806d7ff340f8a908f9fe49127399b4cd Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 4 Aug 2025 14:35:27 +0200 Subject: [PATCH 06/10] run tests with PHPUnit 12.1 on PHP >= 8.3 --- Tests/ExecutableFinderTest.php | 15 +++++---------- Tests/Fixtures/open_basedir.php | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 Tests/Fixtures/open_basedir.php diff --git a/Tests/ExecutableFinderTest.php b/Tests/ExecutableFinderTest.php index 4ce80f15..a605b161 100644 --- a/Tests/ExecutableFinderTest.php +++ b/Tests/ExecutableFinderTest.php @@ -14,6 +14,7 @@ use PHPUnit\Framework\Attributes\RunInSeparateProcess; use PHPUnit\Framework\TestCase; use Symfony\Component\Process\ExecutableFinder; +use Symfony\Component\Process\Process; /** * @author Chris Smith @@ -122,17 +123,11 @@ public function testFindWithOpenBaseDir() $this->markTestSkipped('Cannot test when open_basedir is set'); } - putenv('PATH='.\dirname(\PHP_BINARY)); - $initialOpenBaseDir = ini_set('open_basedir', \dirname(\PHP_BINARY).\PATH_SEPARATOR.'/'); - - try { - $finder = new ExecutableFinder(); - $result = $finder->find($this->getPhpBinaryName()); + $process = new Process([\PHP_BINARY, '-d', 'open_basedir='.\dirname(\PHP_BINARY).\PATH_SEPARATOR.'/', __DIR__.'/Fixtures/open_basedir.php']); + $process->run(); + $result = $process->getOutput(); - $this->assertSamePath(\PHP_BINARY, $result); - } finally { - ini_set('open_basedir', $initialOpenBaseDir); - } + $this->assertSamePath(\PHP_BINARY, $result); } #[RunInSeparateProcess] diff --git a/Tests/Fixtures/open_basedir.php b/Tests/Fixtures/open_basedir.php new file mode 100644 index 00000000..d86e66fa --- /dev/null +++ b/Tests/Fixtures/open_basedir.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require_once __DIR__.'/../../ExecutableFinder.php'; + +use Symfony\Component\Process\ExecutableFinder; + +putenv('PATH='.dirname(PHP_BINARY)); + +function getPhpBinaryName(): string +{ + return basename(PHP_BINARY, '\\' === DIRECTORY_SEPARATOR ? '.exe' : ''); +} + +echo (new ExecutableFinder())->find(getPhpBinaryName()); From f7f8c652703e1dd99c702cb39a196af39932c376 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Tue, 24 Jun 2025 13:39:09 +0100 Subject: [PATCH 07/10] Remove some implicit bool type juggling --- ExecutableFinder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ExecutableFinder.php b/ExecutableFinder.php index 6aa2d4d7..204558bc 100644 --- a/ExecutableFinder.php +++ b/ExecutableFinder.php @@ -63,13 +63,13 @@ public function find(string $name, ?string $default = null, array $extraDirs = [ } $dirs = array_merge( - explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')), + explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path') ?: ''), $extraDirs ); $suffixes = $this->suffixes; if ('\\' === \DIRECTORY_SEPARATOR) { - $pathExt = getenv('PATHEXT'); + $pathExt = getenv('PATHEXT') ?: ''; $suffixes = array_merge($suffixes, $pathExt ? explode(\PATH_SEPARATOR, $pathExt) : ['.exe', '.bat', '.cmd', '.com']); } $suffixes = '' !== pathinfo($name, \PATHINFO_EXTENSION) ? array_merge([''], $suffixes) : array_merge($suffixes, ['']); From 5517b388f434b10fa2b4ca9da1ddacca65b3b680 Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Sun, 10 Aug 2025 00:28:14 +0200 Subject: [PATCH 08/10] chore: heredoc indentation as of PHP 7.3 https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc --- Tests/PhpProcessTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Tests/PhpProcessTest.php b/Tests/PhpProcessTest.php index 111dc4c7..7cf1c7e5 100644 --- a/Tests/PhpProcessTest.php +++ b/Tests/PhpProcessTest.php @@ -22,8 +22,8 @@ public function testNonBlockingWorks() { $expected = 'hello world!'; $process = new PhpProcess(<<start(); $process->wait(); @@ -33,8 +33,8 @@ public function testNonBlockingWorks() public function testCommandLine() { $process = new PhpProcess(<<<'PHP' -getCommandLine(); @@ -55,8 +55,8 @@ public function testPassingPhpExplicitly() $expected = 'hello world!'; $script = <<run(); $this->assertEquals($expected, $process->getOutput()); @@ -67,8 +67,8 @@ public function testProcessCannotBeCreatedUsingFromShellCommandLine() static::expectException(LogicException::class); static::expectExceptionMessage('The "Symfony\Component\Process\PhpProcess::fromShellCommandline()" method cannot be called when using "Symfony\Component\Process\PhpProcess".'); PhpProcess::fromShellCommandline(<< Date: Sat, 9 Aug 2025 23:58:04 +0200 Subject: [PATCH 09/10] chore: PHP CS Fixer - restore PHP / PHPUnit rulesets --- Tests/ExecutableFinderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/ExecutableFinderTest.php b/Tests/ExecutableFinderTest.php index a605b161..0f5ef4c0 100644 --- a/Tests/ExecutableFinderTest.php +++ b/Tests/ExecutableFinderTest.php @@ -168,7 +168,7 @@ public function testEmptyDirInPath() try { touch('executable'); - chmod('executable', 0700); + chmod('executable', 0o700); $finder = new ExecutableFinder(); $result = $finder->find('executable'); From 410c833558ad2c2275abf96095b4fe2e40102105 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 14 Aug 2025 09:36:33 +0200 Subject: [PATCH 10/10] Replace __sleep/wakeup() by __(un)serialize() when BC isn't a concern --- Pipes/UnixPipes.php | 4 ++-- Pipes/WindowsPipes.php | 4 ++-- Process.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Pipes/UnixPipes.php b/Pipes/UnixPipes.php index 6f95a332..5fbab213 100644 --- a/Pipes/UnixPipes.php +++ b/Pipes/UnixPipes.php @@ -31,12 +31,12 @@ public function __construct( parent::__construct($input); } - public function __sleep(): array + public function __serialize(): array { throw new \BadMethodCallException('Cannot serialize '.__CLASS__); } - public function __wakeup(): void + public function __unserialize(array $data): void { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } diff --git a/Pipes/WindowsPipes.php b/Pipes/WindowsPipes.php index 116b8e30..f4ab195b 100644 --- a/Pipes/WindowsPipes.php +++ b/Pipes/WindowsPipes.php @@ -87,12 +87,12 @@ public function __construct( parent::__construct($input); } - public function __sleep(): array + public function __serialize(): array { throw new \BadMethodCallException('Cannot serialize '.__CLASS__); } - public function __wakeup(): void + public function __unserialize(array $data): void { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } diff --git a/Process.php b/Process.php index d52db23a..86a6d0b2 100644 --- a/Process.php +++ b/Process.php @@ -200,12 +200,12 @@ public static function fromShellCommandline(string $command, ?string $cwd = null return $process; } - public function __sleep(): array + public function __serialize(): array { throw new \BadMethodCallException('Cannot serialize '.__CLASS__); } - public function __wakeup(): void + public function __unserialize(array $data): void { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); }