From b00928670cedc76c0444c0f3c1cd64c1d6b7fd78 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 28 May 2019 14:18:42 +0200 Subject: [PATCH 01/26] updated version to 5.0 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e0174de7..9dcdd6de 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "5.0-dev" } } } From bf59d6c6f51cf35eb0413807d3f4e90aa44603d4 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 28 May 2019 15:10:17 +0200 Subject: [PATCH 02/26] Bump Symfony 5.0 to PHP 7.2 --- Tests/ExecutableFinderTest.php | 3 --- composer.json | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Tests/ExecutableFinderTest.php b/Tests/ExecutableFinderTest.php index 6d69a77e..65d5451a 100644 --- a/Tests/ExecutableFinderTest.php +++ b/Tests/ExecutableFinderTest.php @@ -132,9 +132,6 @@ public function testFindProcessInOpenBasedir() $this->assertSamePath(PHP_BINARY, $result); } - /** - * @requires PHP 5.4 - */ public function testFindBatchExecutableOnWindows() { if (ini_get('open_basedir')) { diff --git a/composer.json b/composer.json index 9dcdd6de..cfccd283 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": "^7.1.3" + "php": "^7.2.9" }, "autoload": { "psr-4": { "Symfony\\Component\\Process\\": "" }, From 828774541181d2b90640873de86db0341542ab24 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 8 Jun 2019 16:53:56 +0200 Subject: [PATCH 03/26] Remove deprecated code paths that trigger a runtime notice --- CHANGELOG.md | 7 +++++++ PhpProcess.php | 12 ------------ Process.php | 24 +----------------------- 3 files changed, 8 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31d06385..db7e98b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ CHANGELOG ========= +5.0.0 +----- + + * removed `PhpProcess::setPhpBinary()` + * `Process` must be instantiated with a command array, use `Process::fromShellCommandline()` when the command should be parsed by the shell + * removed `Process::setCommandLine()` + 4.2.0 ----- diff --git a/PhpProcess.php b/PhpProcess.php index 126d9b75..63f9caff 100644 --- a/PhpProcess.php +++ b/PhpProcess.php @@ -49,18 +49,6 @@ public function __construct(string $script, string $cwd = null, array $env = nul parent::__construct($php, $cwd, $env, $script, $timeout); } - /** - * Sets the path to the PHP binary to use. - * - * @deprecated since Symfony 4.2, use the $php argument of the constructor instead. - */ - public function setPhpBinary($php) - { - @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the $php argument of the constructor instead.', __METHOD__), E_USER_DEPRECATED); - - $this->setCommandLine($php); - } - /** * {@inheritdoc} */ diff --git a/Process.php b/Process.php index 5e3993d7..3926983a 100644 --- a/Process.php +++ b/Process.php @@ -137,16 +137,12 @@ class Process implements \IteratorAggregate * * @throws RuntimeException When proc_open is not installed */ - public function __construct($command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) + public function __construct(array $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) { if (!\function_exists('proc_open')) { throw new LogicException('The Process class relies on proc_open, which is not available on your PHP installation.'); } - if (!\is_array($command)) { - @trigger_error(sprintf('Passing a command as string when creating a "%s" instance is deprecated since Symfony 4.2, pass it as an array of its arguments instead, or use the "Process::fromShellCommandline()" constructor if you need features provided by the shell.', __CLASS__), E_USER_DEPRECATED); - } - $this->commandline = $command; $this->cwd = $cwd; @@ -965,24 +961,6 @@ public function getCommandLine() return \is_array($this->commandline) ? implode(' ', array_map([$this, 'escapeArgument'], $this->commandline)) : $this->commandline; } - /** - * Sets the command line to be executed. - * - * @param string|array $commandline The command to execute - * - * @return self The current Process instance - * - * @deprecated since Symfony 4.2. - */ - public function setCommandLine($commandline) - { - @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); - - $this->commandline = $commandline; - - return $this; - } - /** * Gets the process timeout (max. runtime). * From 802a854486c65e22d8dff38363a909e35976dc9e Mon Sep 17 00:00:00 2001 From: dFayet Date: Tue, 11 Jun 2019 12:13:09 +0200 Subject: [PATCH 04/26] Replace @return annotation by return type in final classes --- Process.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Process.php b/Process.php index 3926983a..9a418645 100644 --- a/Process.php +++ b/Process.php @@ -246,7 +246,7 @@ public function run(callable $callback = null, array $env = []): int * * @final */ - public function mustRun(callable $callback = null, array $env = []) + public function mustRun(callable $callback = null, array $env = []): object { if (0 !== $this->run($callback, $env)) { throw new ProcessFailedException($this); @@ -367,7 +367,7 @@ public function start(callable $callback = null, array $env = []) * * @final */ - public function restart(callable $callback = null, array $env = []) + public function restart(callable $callback = null, array $env = []): object { if ($this->isRunning()) { throw new RuntimeException('Process is already running'); From 308af6779ce81311778c3c0ee199010dc3604c9b Mon Sep 17 00:00:00 2001 From: Philippe Segatori Date: Sat, 29 Jun 2019 00:45:38 +0200 Subject: [PATCH 05/26] [Process] [5.0] Replace docblocks by type-hints --- ExecutableFinder.php | 6 ++---- PhpExecutableFinder.php | 4 +--- Pipes/PipesInterface.php | 2 +- Pipes/UnixPipes.php | 2 +- Pipes/WindowsPipes.php | 2 +- Process.php | 24 ++++++++---------------- ProcessUtils.php | 2 +- 7 files changed, 15 insertions(+), 27 deletions(-) diff --git a/ExecutableFinder.php b/ExecutableFinder.php index cb4345e7..aa52cf36 100644 --- a/ExecutableFinder.php +++ b/ExecutableFinder.php @@ -31,10 +31,8 @@ public function setSuffixes(array $suffixes) /** * Adds new possible suffix to check for executable. - * - * @param string $suffix */ - public function addSuffix($suffix) + public function addSuffix(string $suffix) { $this->suffixes[] = $suffix; } @@ -48,7 +46,7 @@ public function addSuffix($suffix) * * @return string|null The executable path or default value */ - public function find($name, $default = null, array $extraDirs = []) + public function find(string $name, string $default = null, array $extraDirs = []) { if (ini_get('open_basedir')) { $searchPath = array_merge(explode(PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs); diff --git a/PhpExecutableFinder.php b/PhpExecutableFinder.php index 461ea131..bd0eaf43 100644 --- a/PhpExecutableFinder.php +++ b/PhpExecutableFinder.php @@ -29,11 +29,9 @@ public function __construct() /** * Finds The PHP executable. * - * @param bool $includeArgs Whether or not include command arguments - * * @return string|false The PHP executable path or false if it cannot be found */ - public function find($includeArgs = true) + public function find(bool $includeArgs = true) { if ($php = getenv('PHP_BINARY')) { if (!is_executable($php)) { diff --git a/Pipes/PipesInterface.php b/Pipes/PipesInterface.php index 52bbe76b..b8e6d267 100644 --- a/Pipes/PipesInterface.php +++ b/Pipes/PipesInterface.php @@ -44,7 +44,7 @@ public function getFiles(); * * @return string[] An array of read data indexed by their fd */ - public function readAndWrite($blocking, $close = false); + public function readAndWrite(bool $blocking, bool $close = false); /** * Returns if the current state has open file handles or pipes. diff --git a/Pipes/UnixPipes.php b/Pipes/UnixPipes.php index 875ee6ab..ae81b565 100644 --- a/Pipes/UnixPipes.php +++ b/Pipes/UnixPipes.php @@ -89,7 +89,7 @@ public function getFiles() /** * {@inheritdoc} */ - public function readAndWrite($blocking, $close = false) + public function readAndWrite(bool $blocking, bool $close = false) { $this->unblock(); $w = $this->write(); diff --git a/Pipes/WindowsPipes.php b/Pipes/WindowsPipes.php index f44f33b4..b6bfc571 100644 --- a/Pipes/WindowsPipes.php +++ b/Pipes/WindowsPipes.php @@ -126,7 +126,7 @@ public function getFiles() /** * {@inheritdoc} */ - public function readAndWrite($blocking, $close = false) + public function readAndWrite(bool $blocking, bool $close = false) { $this->unblock(); $w = $this->write(); diff --git a/Process.php b/Process.php index 71a4aa7a..92fd775f 100644 --- a/Process.php +++ b/Process.php @@ -495,7 +495,7 @@ public function getPid() * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed * @throws RuntimeException In case of failure */ - public function signal($signal) + public function signal(int $signal) { $this->doSignal($signal, true); @@ -897,7 +897,7 @@ public function getStatus() * * @return int The exit-code of the process */ - public function stop($timeout = 10, $signal = null) + public function stop(float $timeout = 10, int $signal = null) { $timeoutMicro = microtime(true) + $timeout; if ($this->isRunning()) { @@ -1028,13 +1028,11 @@ public function setIdleTimeout($timeout) /** * Enables or disables the TTY mode. * - * @param bool $tty True to enabled and false to disable - * * @return self The current Process instance * * @throws RuntimeException In case the TTY mode is not supported */ - public function setTty($tty) + public function setTty(bool $tty) { if ('\\' === \DIRECTORY_SEPARATOR && $tty) { throw new RuntimeException('TTY mode is not supported on Windows platform.'); @@ -1062,13 +1060,11 @@ public function isTty() /** * Sets PTY mode. * - * @param bool $bool - * * @return self */ - public function setPty($bool) + public function setPty(bool $bool) { - $this->pty = (bool) $bool; + $this->pty = $bool; return $this; } @@ -1102,11 +1098,9 @@ public function getWorkingDirectory() /** * Sets the current working directory. * - * @param string $cwd The new working directory - * * @return self The current Process instance */ - public function setWorkingDirectory($cwd) + public function setWorkingDirectory(string $cwd) { $this->cwd = $cwd; @@ -1185,11 +1179,9 @@ public function setInput($input) /** * Sets whether environment variables will be inherited or not. * - * @param bool $inheritEnv - * * @return self The current Process instance */ - public function inheritEnvironmentVariables($inheritEnv = true) + public function inheritEnvironmentVariables(bool $inheritEnv = true) { if (!$inheritEnv) { throw new InvalidArgumentException('Not inheriting environment variables is not supported.'); @@ -1316,7 +1308,7 @@ protected function buildCallback(callable $callback = null) * * @param bool $blocking Whether to use a blocking read call */ - protected function updateStatus($blocking) + protected function updateStatus(bool $blocking) { if (self::STATUS_STARTED !== $this->status) { return; diff --git a/ProcessUtils.php b/ProcessUtils.php index 2f9c4be4..5b6879ae 100644 --- a/ProcessUtils.php +++ b/ProcessUtils.php @@ -39,7 +39,7 @@ private function __construct() * * @throws InvalidArgumentException In case the input is not valid */ - public static function validateInput($caller, $input) + public static function validateInput(string $caller, $input) { if (null !== $input) { if (\is_resource($input)) { From 980c1042d3a1776a7097d42ee498a114608af9c2 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 19 Jul 2019 10:49:41 +0200 Subject: [PATCH 06/26] remove deprecated inheritEnvironmentVariables() method --- CHANGELOG.md | 1 + Process.php | 18 ------------------ 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09109e8d..eca3141f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 5.0.0 ----- + * removed `Process::inheritEnvironmentVariables()` * removed `PhpProcess::setPhpBinary()` * `Process` must be instantiated with a command array, use `Process::fromShellCommandline()` when the command should be parsed by the shell * removed `Process::setCommandLine()` diff --git a/Process.php b/Process.php index 7a32b2ad..c3d5753e 100644 --- a/Process.php +++ b/Process.php @@ -1176,24 +1176,6 @@ public function setInput($input) return $this; } - /** - * Sets whether environment variables will be inherited or not. - * - * @return self The current Process instance - * - * @deprecated since Symfony 4.4, env variables are always inherited - */ - public function inheritEnvironmentVariables(bool $inheritEnv = true) - { - @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.4, env variables are always inherited.', __METHOD__), E_USER_DEPRECATED); - - if (!$inheritEnv) { - throw new InvalidArgumentException('Not inheriting environment variables is not supported.'); - } - - return $this; - } - /** * Performs a check between the timeout definition and the time the process started. * From 6a848c8e1c2aaecc6f7a13e8859e213c4f3d6a09 Mon Sep 17 00:00:00 2001 From: Karoly Gossler Date: Fri, 9 Aug 2019 15:40:51 +0200 Subject: [PATCH 07/26] added `Process::getLastOutputTime()` method --- CHANGELOG.md | 3 ++- Process.php | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eca3141f..9ff05cf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ CHANGELOG 4.4.0 ----- -* deprecated `Process::inheritEnvironmentVariables()`: env variables are always inherited. + * deprecated `Process::inheritEnvironmentVariables()`: env variables are always inherited. + * added `Process::getLastOutputTime()` method 4.2.0 ----- diff --git a/Process.php b/Process.php index 1815888f..00dafcec 100644 --- a/Process.php +++ b/Process.php @@ -954,6 +954,16 @@ public function addErrorOutput(string $line) fseek($this->stderr, $this->incrementalErrorOutputOffset); } + /** + * Gets the last output time in seconds + * + * @return float|null The last output time in seconds or null if it isn't started + */ + public function getLastOutputTime(): ?float + { + return $this->lastOutputTime; + } + /** * Gets the command line to be executed. * From c61ffc1169fb029403fcde45586768f76623e431 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 18 Aug 2019 10:23:14 +0200 Subject: [PATCH 08/26] fixed CS --- Process.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Process.php b/Process.php index 500e5d33..b49d391a 100644 --- a/Process.php +++ b/Process.php @@ -949,7 +949,7 @@ public function addErrorOutput(string $line) } /** - * Gets the last output time in seconds + * Gets the last output time in seconds. * * @return float|null The last output time in seconds or null if it isn't started */ From e5d790034989f09a1737ac8825209a482d7d7d09 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Wed, 14 Aug 2019 01:26:41 +0200 Subject: [PATCH 09/26] Added more parameter type declarations. --- Process.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Process.php b/Process.php index 2f6cc944..db9e7a27 100644 --- a/Process.php +++ b/Process.php @@ -602,7 +602,7 @@ public function getIncrementalOutput() * * @return \Generator */ - public function getIterator($flags = 0) + public function getIterator(int $flags = 0) { $this->readPipesForOutput(__FUNCTION__, false); @@ -995,13 +995,11 @@ public function getIdleTimeout() * * To disable the timeout, set this value to null. * - * @param int|float|null $timeout The timeout in seconds - * * @return $this * * @throws InvalidArgumentException if the timeout is negative */ - public function setTimeout($timeout) + public function setTimeout(?float $timeout) { $this->timeout = $this->validateTimeout($timeout); @@ -1009,18 +1007,16 @@ public function setTimeout($timeout) } /** - * Sets the process idle timeout (max. time since last output). + * Sets the process idle timeout (max. time since last output) in seconds. * * To disable the timeout, set this value to null. * - * @param int|float|null $timeout The timeout in seconds - * * @return $this * * @throws LogicException if the output is disabled * @throws InvalidArgumentException if the timeout is negative */ - public function setIdleTimeout($timeout) + public function setIdleTimeout(?float $timeout) { if (null !== $timeout && $this->outputDisabled) { throw new LogicException('Idle timeout can not be set while the output is disabled.'); @@ -1048,7 +1044,7 @@ public function setTty(bool $tty) throw new RuntimeException('TTY mode requires /dev/tty to be read/writable.'); } - $this->tty = (bool) $tty; + $this->tty = $tty; return $this; } From 9dd6e2e8cbe4b867b6bdf7f74383ed8c0473fd2f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 17 Nov 2019 19:31:35 +0100 Subject: [PATCH 10/26] updated version to 5.1 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index cfccd283..b8083ebd 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "5.1-dev" } } } From 110f98bed214a007eb440c7bb14088fed96f847f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 18 Nov 2019 18:27:11 +0100 Subject: [PATCH 11/26] Allow PHP ^7.2.5 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index cfccd283..2a6d3a94 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": "^7.2.9" + "php": "^7.2.5" }, "autoload": { "psr-4": { "Symfony\\Component\\Process\\": "" }, From 55bebe44b76b82d618e9eeea83f6562ad03a1a67 Mon Sep 17 00:00:00 2001 From: Dominik Piekarski Date: Tue, 11 Feb 2020 13:33:01 +0100 Subject: [PATCH 12/26] [Process] Add getter for process starttime --- CHANGELOG.md | 5 +++++ Process.php | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ff05cf4..3f3a0202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +5.1.0 +----- + + * added `Process::getStartTime()` to retrieve the start time of the process as float + 5.0.0 ----- diff --git a/Process.php b/Process.php index 69ccc084..456f2eb3 100644 --- a/Process.php +++ b/Process.php @@ -1208,6 +1208,18 @@ public function checkTimeout() } } + /** + * @throws LogicException in case process is not started + */ + public function getStartTime(): float + { + if (!$this->isStarted()) { + throw new LogicException('Start time is only available after process start.'); + } + + return $this->starttime; + } + /** * Returns whether TTY is supported on the current operating system. */ From db5d570fa068cc10f3cbee2c708e7c4880033078 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 3 Mar 2020 20:07:47 +0100 Subject: [PATCH 13/26] Leverage PHP8's get_debug_type() --- Pipes/AbstractPipes.php | 2 +- composer.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Pipes/AbstractPipes.php b/Pipes/AbstractPipes.php index 92076efb..83dc2625 100644 --- a/Pipes/AbstractPipes.php +++ b/Pipes/AbstractPipes.php @@ -103,7 +103,7 @@ protected function write(): ?array } elseif (!isset($this->inputBuffer[0])) { if (!\is_string($input)) { if (!is_scalar($input)) { - throw new InvalidArgumentException(sprintf('%s yielded a value of type "%s", but only scalars and stream resources are supported.', \get_class($this->input), \gettype($input))); + throw new InvalidArgumentException(sprintf('%s yielded a value of type "%s", but only scalars and stream resources are supported.', get_debug_type($this->input), get_debug_type($input))); } $input = (string) $input; } diff --git a/composer.json b/composer.json index 79c657a9..fa703a0b 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": "^7.2.5" + "php": "^7.2.5", + "symfony/polyfill-php80": "^1.15" }, "autoload": { "psr-4": { "Symfony\\Component\\Process\\": "" }, From 509ba166ae24c2227227c8ad54a3916bbd137422 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 16 May 2020 14:09:30 +0200 Subject: [PATCH 14/26] updated version to 5.2 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index fa703a0b..12d5b029 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-master": "5.2-dev" } } } From a9bb93b437c4ebb719ff46e33623aaa2139514cd Mon Sep 17 00:00:00 2001 From: Andrei O Date: Wed, 8 Jul 2020 00:04:30 +0300 Subject: [PATCH 15/26] [Process] allow setting options esp. "create_new_console" to detach a subprocess --- CHANGELOG.md | 7 ++++++ Process.php | 38 ++++++++++++++++++++++++---- Tests/CreateNewConsoleTest.php | 45 ++++++++++++++++++++++++++++++++++ Tests/ThreeSecondProcess.php | 14 +++++++++++ 4 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 Tests/CreateNewConsoleTest.php create mode 100644 Tests/ThreeSecondProcess.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f3a0202..31b9ee6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ CHANGELOG ========= +5.2.0 +----- + + * added `Process::setOptions()` to set `Process` specific options + * added option `create_new_console` to allow a subprocess to continue + to run after the main script exited, both on Linux and on Windows + 5.1.0 ----- diff --git a/Process.php b/Process.php index e1efb9cc..5dd38c4b 100644 --- a/Process.php +++ b/Process.php @@ -71,6 +71,7 @@ class Process implements \IteratorAggregate private $incrementalErrorOutputOffset = 0; private $tty = false; private $pty; + private $options = ['suppress_errors' => true, 'bypass_shell' => true]; private $useFileHandles = false; /** @var PipesInterface */ @@ -196,7 +197,11 @@ public static function fromShellCommandline(string $command, string $cwd = null, public function __destruct() { - $this->stop(0); + if ($this->options['create_new_console'] ?? false) { + $this->processPipes->close(); + } else { + $this->stop(0); + } } public function __clone() @@ -303,10 +308,7 @@ public function start(callable $callback = null, array $env = []) $commandline = $this->replacePlaceholders($commandline, $env); } - $options = ['suppress_errors' => true]; - if ('\\' === \DIRECTORY_SEPARATOR) { - $options['bypass_shell'] = true; $commandline = $this->prepareWindowsCommandLine($commandline, $env); } elseif (!$this->useFileHandles && $this->isSigchildEnabled()) { // last exit code is output on the fourth pipe and caught to work around --enable-sigchild @@ -332,7 +334,7 @@ public function start(callable $callback = null, array $env = []) throw new RuntimeException(sprintf('The provided cwd "%s" does not exist.', $this->cwd)); } - $this->process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $options); + $this->process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options); if (!\is_resource($this->process)) { throw new RuntimeException('Unable to launch a new process.'); @@ -1220,6 +1222,32 @@ public function getStartTime(): float return $this->starttime; } + /** + * Defines options to pass to the underlying proc_open(). + * + * @see https://php.net/proc_open for the options supported by PHP. + * + * Enabling the "create_new_console" option allows a subprocess to continue + * to run after the main process exited, on both Windows and *nix + */ + public function setOptions(array $options) + { + if ($this->isRunning()) { + throw new RuntimeException('Setting options while the process is running is not possible.'); + } + + $defaultOptions = $this->options; + $existingOptions = ['blocking_pipes', 'create_process_group', 'create_new_console']; + + foreach ($options as $key => $value) { + if (!\in_array($key, $existingOptions)) { + $this->options = $defaultOptions; + throw new LogicException(sprintf('Invalid option "%s" passed to "%s()". Supported options are "%s".', $key, __METHOD__, implode('", "', $existingOptions))); + } + $this->options[$key] = $value; + } + } + /** * Returns whether TTY is supported on the current operating system. */ diff --git a/Tests/CreateNewConsoleTest.php b/Tests/CreateNewConsoleTest.php new file mode 100644 index 00000000..4d43fb8d --- /dev/null +++ b/Tests/CreateNewConsoleTest.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Process\Process; + +/** + * @author Andrei Olteanu + */ +class CreateNewConsoleTest extends TestCase +{ + public function testOptionCreateNewConsole() + { + $this->expectNotToPerformAssertions(); + try { + $process = new Process(['php', __DIR__.'/ThreeSecondProcess.php']); + $process->setOptions(['create_new_console' => true]); + $process->disableOutput(); + $process->start(); + } catch (\Exception $e) { + $this->fail($e); + } + } + + public function testItReturnsFastAfterStart() + { + // The started process must run in background after the main has finished but that can't be tested with PHPUnit + $startTime = microtime(true); + $process = new Process(['php', __DIR__.'/ThreeSecondProcess.php']); + $process->setOptions(['create_new_console' => true]); + $process->disableOutput(); + $process->start(); + $this->assertLessThan(3000, $startTime - microtime(true)); + } +} diff --git a/Tests/ThreeSecondProcess.php b/Tests/ThreeSecondProcess.php new file mode 100644 index 00000000..e483b4b9 --- /dev/null +++ b/Tests/ThreeSecondProcess.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +echo 'Worker started'; +sleep(3); +echo 'Worker done'; From e8749eb40a4743d7cb24507a4ff5db6e3306180c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 12 Aug 2021 15:32:19 +0200 Subject: [PATCH 16/26] Cleanup more `@return` annotations --- ExecutableFinder.php | 2 +- PhpExecutableFinder.php | 4 ++-- Process.php | 42 ++++++++++++++++++++--------------------- ProcessUtils.php | 2 +- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/ExecutableFinder.php b/ExecutableFinder.php index feee4ad4..5914b4cd 100644 --- a/ExecutableFinder.php +++ b/ExecutableFinder.php @@ -44,7 +44,7 @@ public function addSuffix(string $suffix) * @param string|null $default The default to return if no executable is found * @param array $extraDirs Additional dirs to check into * - * @return string|null The executable path or default value + * @return string|null */ public function find(string $name, string $default = null, array $extraDirs = []) { diff --git a/PhpExecutableFinder.php b/PhpExecutableFinder.php index e4f03f76..ec24f911 100644 --- a/PhpExecutableFinder.php +++ b/PhpExecutableFinder.php @@ -29,7 +29,7 @@ public function __construct() /** * Finds The PHP executable. * - * @return string|false The PHP executable path or false if it cannot be found + * @return string|false */ public function find(bool $includeArgs = true) { @@ -85,7 +85,7 @@ public function find(bool $includeArgs = true) /** * Finds the PHP executable arguments. * - * @return array The PHP executable arguments + * @return array */ public function findArguments() { diff --git a/Process.php b/Process.php index a541cd66..a20b0f78 100644 --- a/Process.php +++ b/Process.php @@ -569,7 +569,7 @@ public function isOutputDisabled() /** * Returns the current output of the process (STDOUT). * - * @return string The process output + * @return string * * @throws LogicException in case the output has been disabled * @throws LogicException In case the process is not started @@ -591,7 +591,7 @@ public function getOutput() * In comparison with the getOutput method which always return the whole * output, this one returns the new output since the last call. * - * @return string The process output since the last call + * @return string * * @throws LogicException in case the output has been disabled * @throws LogicException In case the process is not started @@ -685,7 +685,7 @@ public function clearOutput() /** * Returns the current error output of the process (STDERR). * - * @return string The process error output + * @return string * * @throws LogicException in case the output has been disabled * @throws LogicException In case the process is not started @@ -708,7 +708,7 @@ public function getErrorOutput() * whole error output, this one returns the new error output since the last * call. * - * @return string The process error output since the last call + * @return string * * @throws LogicException in case the output has been disabled * @throws LogicException In case the process is not started @@ -776,7 +776,7 @@ public function getExitCodeText() /** * Checks if the process ended successfully. * - * @return bool true if the process ended successfully, false otherwise + * @return bool */ public function isSuccessful() { @@ -855,7 +855,7 @@ public function getStopSignal() /** * Checks if the process is currently running. * - * @return bool true if the process is currently running, false otherwise + * @return bool */ public function isRunning() { @@ -871,7 +871,7 @@ public function isRunning() /** * Checks if the process has been started with no regard to the current state. * - * @return bool true if status is ready, false otherwise + * @return bool */ public function isStarted() { @@ -881,7 +881,7 @@ public function isStarted() /** * Checks if the process is terminated. * - * @return bool true if process is terminated, false otherwise + * @return bool */ public function isTerminated() { @@ -895,7 +895,7 @@ public function isTerminated() * * The status is one of: ready, started, terminated. * - * @return string The current process status + * @return string */ public function getStatus() { @@ -972,7 +972,7 @@ public function addErrorOutput(string $line) /** * Gets the last output time in seconds. * - * @return float|null The last output time in seconds or null if it isn't started + * @return float|null */ public function getLastOutputTime(): ?float { @@ -982,7 +982,7 @@ public function getLastOutputTime(): ?float /** * Gets the command line to be executed. * - * @return string The command to execute + * @return string */ public function getCommandLine() { @@ -990,9 +990,9 @@ public function getCommandLine() } /** - * Gets the process timeout (max. runtime). + * Gets the process timeout in seconds (max. runtime). * - * @return float|null The timeout in seconds or null if it's disabled + * @return float|null */ public function getTimeout() { @@ -1000,9 +1000,9 @@ public function getTimeout() } /** - * Gets the process idle timeout (max. time since last output). + * Gets the process idle timeout in seconds (max. time since last output). * - * @return float|null The timeout in seconds or null if it's disabled + * @return float|null */ public function getIdleTimeout() { @@ -1071,7 +1071,7 @@ public function setTty(bool $tty) /** * Checks if the TTY mode is enabled. * - * @return bool true if the TTY mode is enabled, false otherwise + * @return bool */ public function isTty() { @@ -1103,7 +1103,7 @@ public function isPty() /** * Gets the working directory. * - * @return string|null The current working directory or null on failure + * @return string|null */ public function getWorkingDirectory() { @@ -1131,7 +1131,7 @@ public function setWorkingDirectory(string $cwd) /** * Gets the environment variables. * - * @return array The current environment variables + * @return array */ public function getEnv() { @@ -1168,7 +1168,7 @@ public function setEnv(array $env) /** * Gets the Process input. * - * @return resource|string|\Iterator|null The Process input + * @return resource|string|\Iterator|null */ public function getInput() { @@ -1321,7 +1321,7 @@ private function getDescriptors(): array * * @param callable|null $callback The user defined PHP callback * - * @return \Closure A PHP closure + * @return \Closure */ protected function buildCallback(callable $callback = null) { @@ -1504,7 +1504,7 @@ private function resetProcessData() * @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants) * @param bool $throwException Whether to throw exception in case signal failed * - * @return bool True if the signal was sent successfully, false otherwise + * @return bool * * @throws LogicException In case the process is not running * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed diff --git a/ProcessUtils.php b/ProcessUtils.php index 3be7e61a..6cc7a610 100644 --- a/ProcessUtils.php +++ b/ProcessUtils.php @@ -35,7 +35,7 @@ private function __construct() * @param string $caller The name of method call that validates the input * @param mixed $input The input to validate * - * @return mixed The validated input + * @return mixed * * @throws InvalidArgumentException In case the input is not valid */ From a3ab47968ef2cc5124efc4f1b6b4e7a61b85a543 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 24 Aug 2021 18:27:03 +0200 Subject: [PATCH 17/26] Add some missing return types to internal/final classes --- Pipes/UnixPipes.php | 5 +---- Pipes/WindowsPipes.php | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/Pipes/UnixPipes.php b/Pipes/UnixPipes.php index 58a8da07..5a0e9d47 100644 --- a/Pipes/UnixPipes.php +++ b/Pipes/UnixPipes.php @@ -35,10 +35,7 @@ public function __construct(?bool $ttyMode, bool $ptyMode, $input, bool $haveRea parent::__construct($input); } - /** - * @return array - */ - public function __sleep() + public function __sleep(): array { throw new \BadMethodCallException('Cannot serialize '.__CLASS__); } diff --git a/Pipes/WindowsPipes.php b/Pipes/WindowsPipes.php index 69768f3d..bca84f57 100644 --- a/Pipes/WindowsPipes.php +++ b/Pipes/WindowsPipes.php @@ -88,10 +88,7 @@ public function __construct($input, bool $haveReadSupport) parent::__construct($input); } - /** - * @return array - */ - public function __sleep() + public function __sleep(): array { throw new \BadMethodCallException('Cannot serialize '.__CLASS__); } From b076aa9be226405545de739ef6711f6141651700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Sun, 3 Oct 2021 17:40:55 +0200 Subject: [PATCH 18/26] Fix "can not" spelling --- Process.php | 12 ++++++------ Tests/ProcessTest.php | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Process.php b/Process.php index a20b0f78..aa9b1c7a 100644 --- a/Process.php +++ b/Process.php @@ -530,7 +530,7 @@ public function disableOutput() throw new RuntimeException('Disabling output while the process is running is not possible.'); } if (null !== $this->idleTimeout) { - throw new LogicException('Output can not be disabled while an idle timeout is set.'); + throw new LogicException('Output cannot be disabled while an idle timeout is set.'); } $this->outputDisabled = true; @@ -814,7 +814,7 @@ public function getTermSignal() $this->requireProcessIsTerminated(__FUNCTION__); if ($this->isSigchildEnabled() && -1 === $this->processInformation['termsig']) { - throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.'); + throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal cannot be retrieved.'); } return $this->processInformation['termsig']; @@ -1038,7 +1038,7 @@ public function setTimeout(?float $timeout) public function setIdleTimeout(?float $timeout) { if (null !== $timeout && $this->outputDisabled) { - throw new LogicException('Idle timeout can not be set while the output is disabled.'); + throw new LogicException('Idle timeout cannot be set while the output is disabled.'); } $this->idleTimeout = $this->validateTimeout($timeout); @@ -1155,7 +1155,7 @@ public function getEnv() */ public function setEnv(array $env) { - // Process can not handle env values that are arrays + // Process cannot handle env values that are arrays $env = array_filter($env, function ($value) { return !\is_array($value); }); @@ -1189,7 +1189,7 @@ public function getInput() public function setInput($input) { if ($this->isRunning()) { - throw new LogicException('Input can not be set while the process is running.'); + throw new LogicException('Input cannot be set while the process is running.'); } $this->input = ProcessUtils::validateInput(__METHOD__, $input); @@ -1514,7 +1514,7 @@ private function doSignal(int $signal, bool $throwException): bool { if (null === $pid = $this->getPid()) { if ($throwException) { - throw new LogicException('Can not send signal on a non running process.'); + throw new LogicException('Cannot send signal on a non running process.'); } return false; diff --git a/Tests/ProcessTest.php b/Tests/ProcessTest.php index 70b8e051..411cb815 100644 --- a/Tests/ProcessTest.php +++ b/Tests/ProcessTest.php @@ -276,7 +276,7 @@ public function testLiveStreamAsInput() public function testSetInputWhileRunningThrowsAnException() { $this->expectException(LogicException::class); - $this->expectExceptionMessage('Input can not be set while the process is running.'); + $this->expectExceptionMessage('Input cannot be set while the process is running.'); $process = $this->getProcessForCode('sleep(30);'); $process->start(); try { @@ -938,7 +938,7 @@ public function testExitCodeIsAvailableAfterSignal() public function testSignalProcessNotRunning() { $this->expectException(LogicException::class); - $this->expectExceptionMessage('Can not send signal on a non running process.'); + $this->expectExceptionMessage('Cannot send signal on a non running process.'); $process = $this->getProcess('foo'); $process->signal(1); // SIGHUP } @@ -1057,7 +1057,7 @@ public function testEnableOrDisableOutputAfterRunDoesNotThrowException() public function testDisableOutputWhileIdleTimeoutIsSet() { $this->expectException(LogicException::class); - $this->expectExceptionMessage('Output can not be disabled while an idle timeout is set.'); + $this->expectExceptionMessage('Output cannot be disabled while an idle timeout is set.'); $process = $this->getProcess('foo'); $process->setIdleTimeout(1); $process->disableOutput(); @@ -1066,7 +1066,7 @@ public function testDisableOutputWhileIdleTimeoutIsSet() public function testSetIdleTimeoutWhileOutputIsDisabled() { $this->expectException(LogicException::class); - $this->expectExceptionMessage('timeout can not be set while the output is disabled.'); + $this->expectExceptionMessage('timeout cannot be set while the output is disabled.'); $process = $this->getProcess('foo'); $process->disableOutput(); $process->setIdleTimeout(1); From 6bacc79268fb8a2fac52c9f66afe5e041220233f Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Wed, 3 Nov 2021 10:24:47 +0100 Subject: [PATCH 19/26] Add generic types to traversable implementations --- InputStream.php | 4 +++- Process.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/InputStream.php b/InputStream.php index 4f8f7133..240665f3 100644 --- a/InputStream.php +++ b/InputStream.php @@ -17,6 +17,8 @@ * Provides a way to continuously write to the input of a Process until the InputStream is closed. * * @author Nicolas Grekas + * + * @implements \IteratorAggregate */ class InputStream implements \IteratorAggregate { @@ -67,7 +69,7 @@ public function isClosed() } /** - * @return \Traversable + * @return \Traversable */ #[\ReturnTypeWillChange] public function getIterator() diff --git a/Process.php b/Process.php index aa9b1c7a..c6868828 100644 --- a/Process.php +++ b/Process.php @@ -27,6 +27,8 @@ * * @author Fabien Potencier * @author Romain Neutron + * + * @implements \IteratorAggregate */ class Process implements \IteratorAggregate { @@ -618,7 +620,7 @@ public function getIncrementalOutput() * @throws LogicException in case the output has been disabled * @throws LogicException In case the process is not started * - * @return \Generator + * @return \Generator */ #[\ReturnTypeWillChange] public function getIterator(int $flags = 0) From e8f02d0795d3852e2e0169dc7660786e9de30859 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 23 Nov 2021 15:18:55 +0100 Subject: [PATCH 20/26] [Messenger][Process] Add SensioLabs as a backer to the README --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index afce5e45..8777de4a 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,17 @@ Process Component The Process component executes commands in sub-processes. +Sponsor +------- + +The Process component for Symfony 5.4/6.0 is [backed][1] by [SensioLabs][2]. + +As the creator of Symfony, SensioLabs supports companies using Symfony, with an +offering encompassing consultancy, expertise, services, training, and technical +assistance to ensure the success of web application development projects. + +Help Symfony by [sponsoring][3] its development! + Resources --------- @@ -11,3 +22,7 @@ Resources * [Report issues](https://github.com/symfony/symfony/issues) and [send Pull Requests](https://github.com/symfony/symfony/pulls) in the [main Symfony repository](https://github.com/symfony/symfony) + +[1]: https://symfony.com/backers +[2]: https://sensiolabs.com +[3]: https://symfony.com/sponsor From c5ba874c9b636dbccf761e22ce750e88ec3f55e1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 1 Jan 2023 09:32:19 +0100 Subject: [PATCH 21/26] Bump license year to 2023 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 88bf75bb..00837045 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From f7f1cf1595bc176da3ed5dda597e2168d44ff786 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 24 Jan 2023 15:02:24 +0100 Subject: [PATCH 22/26] Update license years (last time) --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 00837045..0138f8f0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2023 Fabien Potencier +Copyright (c) 2004-present Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 4019350bf7a212e95aea39395bf0de278db01253 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Wed, 14 Dec 2022 15:42:16 +0100 Subject: [PATCH 23/26] Migrate to `static` data providers using `rector/rector` --- Tests/ProcessTest.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Tests/ProcessTest.php b/Tests/ProcessTest.php index 1646bcb9..790167fc 100644 --- a/Tests/ProcessTest.php +++ b/Tests/ProcessTest.php @@ -301,7 +301,7 @@ public function testInvalidInput($value) $process->setInput($value); } - public function provideInvalidInputValues() + public static function provideInvalidInputValues() { return [ [[]], @@ -319,7 +319,7 @@ public function testValidInput($expected, $value) $this->assertSame($expected, $process->getInput()); } - public function provideInputValues() + public static function provideInputValues() { return [ [null, null], @@ -328,7 +328,7 @@ public function provideInputValues() ]; } - public function chainedCommandsOutputProvider() + public static function chainedCommandsOutputProvider() { if ('\\' === \DIRECTORY_SEPARATOR) { return [ @@ -422,7 +422,7 @@ public function testIncrementalOutput($getOutput, $getIncrementalOutput, $uri) fclose($h); } - public function provideIncrementalOutput() + public static function provideIncrementalOutput() { return [ ['getOutput', 'getIncrementalOutput', 'php://stdout'], @@ -957,7 +957,7 @@ public function testMethodsThatNeedARunningProcess($method) $process->{$method}(); } - public function provideMethodsThatNeedARunningProcess() + public static function provideMethodsThatNeedARunningProcess() { return [ ['getOutput'], @@ -988,7 +988,7 @@ public function testMethodsThatNeedATerminatedProcess($method) throw $e; } - public function provideMethodsThatNeedATerminatedProcess() + public static function provideMethodsThatNeedATerminatedProcess() { return [ ['hasBeenSignaled'], @@ -1093,7 +1093,7 @@ public function testGetOutputWhileDisabled($fetchMethod) $p->{$fetchMethod}(); } - public function provideOutputFetchingMethods() + public static function provideOutputFetchingMethods() { return [ ['getOutput'], @@ -1130,7 +1130,7 @@ public function testTermSignalTerminatesProcessCleanly() $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException'); } - public function responsesCodeProvider() + public static function responsesCodeProvider() { return [ // expected output / getter / code to execute @@ -1140,7 +1140,7 @@ public function responsesCodeProvider() ]; } - public function pipesCodeProvider() + public static function pipesCodeProvider() { $variations = [ 'fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);', @@ -1183,7 +1183,7 @@ public function testIncrementalOutputDoesNotRequireAnotherCall($stream, $method) $process->stop(); } - public function provideVariousIncrementals() + public static function provideVariousIncrementals() { return [ ['php://stdout', 'getIncrementalOutput'], @@ -1449,7 +1449,7 @@ public function testRawCommandLine() $this->assertSame($expected, str_replace('Standard input code', '-', $p->getOutput())); } - public function provideEscapeArgument() + public static function provideEscapeArgument() { yield ['a"b%c%']; yield ['a"b^c^']; From 3f3ab88c5592914a2b80bb3d9f594919367144a1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 16 Feb 2023 10:33:00 +0100 Subject: [PATCH 24/26] CS fix --- Process.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Process.php b/Process.php index 14e17774..871522de 100644 --- a/Process.php +++ b/Process.php @@ -617,10 +617,10 @@ public function getIncrementalOutput() * * @param int $flags A bit field of Process::ITER_* flags * + * @return \Generator + * * @throws LogicException in case the output has been disabled * @throws LogicException In case the process is not started - * - * @return \Generator */ #[\ReturnTypeWillChange] public function getIterator(int $flags = 0) From d4ce417ebcb0b7d090b4c178ed6d3accc518e8bd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 21 Feb 2023 17:34:40 +0100 Subject: [PATCH 25/26] Fix phpdocs in components --- Process.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Process.php b/Process.php index 871522de..b47ecca1 100644 --- a/Process.php +++ b/Process.php @@ -910,7 +910,7 @@ public function getStatus() * Stops the process. * * @param int|float $timeout The timeout in seconds - * @param int $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9) + * @param int|null $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9) * * @return int|null The exit-code of the process or null if it's not running */ From 4b850da0cc3a2a9181c1ed407adbca4733dc839b Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Mon, 6 Mar 2023 21:48:01 +0100 Subject: [PATCH 26/26] [Tests] Replace `setMethods()` by `onlyMethods()` and `addMethods()` --- Tests/ProcessFailedExceptionTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/ProcessFailedExceptionTest.php b/Tests/ProcessFailedExceptionTest.php index d6d7bfb0..259ffd63 100644 --- a/Tests/ProcessFailedExceptionTest.php +++ b/Tests/ProcessFailedExceptionTest.php @@ -25,7 +25,7 @@ class ProcessFailedExceptionTest extends TestCase */ public function testProcessFailedExceptionThrowsException() { - $process = $this->getMockBuilder(Process::class)->setMethods(['isSuccessful'])->setConstructorArgs([['php']])->getMock(); + $process = $this->getMockBuilder(Process::class)->onlyMethods(['isSuccessful'])->setConstructorArgs([['php']])->getMock(); $process->expects($this->once()) ->method('isSuccessful') ->willReturn(true); @@ -49,7 +49,7 @@ public function testProcessFailedExceptionPopulatesInformationFromProcessOutput( $errorOutput = 'FATAL: Unexpected error'; $workingDirectory = getcwd(); - $process = $this->getMockBuilder(Process::class)->setMethods(['isSuccessful', 'getOutput', 'getErrorOutput', 'getExitCode', 'getExitCodeText', 'isOutputDisabled', 'getWorkingDirectory'])->setConstructorArgs([[$cmd]])->getMock(); + $process = $this->getMockBuilder(Process::class)->onlyMethods(['isSuccessful', 'getOutput', 'getErrorOutput', 'getExitCode', 'getExitCodeText', 'isOutputDisabled', 'getWorkingDirectory'])->setConstructorArgs([[$cmd]])->getMock(); $process->expects($this->once()) ->method('isSuccessful') ->willReturn(false); @@ -97,7 +97,7 @@ public function testDisabledOutputInFailedExceptionDoesNotPopulateOutput() $exitText = 'General error'; $workingDirectory = getcwd(); - $process = $this->getMockBuilder(Process::class)->setMethods(['isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput', 'getWorkingDirectory'])->setConstructorArgs([[$cmd]])->getMock(); + $process = $this->getMockBuilder(Process::class)->onlyMethods(['isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput', 'getWorkingDirectory'])->setConstructorArgs([[$cmd]])->getMock(); $process->expects($this->once()) ->method('isSuccessful') ->willReturn(false);