8000 [Process][Console] deprecated defining commands as strings · symfony/symfony@73fe4d6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 73fe4d6

Browse files
[Process][Console] deprecated defining commands as strings
1 parent f27c3a8 commit 73fe4d6

File tree

11 files changed

+179
-48
lines changed
  • Dotenv
  • Process
  • 11 files changed

    +179
    -48
    lines changed

    UPGRADE-4.2.md

    Lines changed: 37 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -11,6 +11,27 @@ Config
    1111

    1212
    * Deprecated constructing a `TreeBuilder` without passing root node information.
    1313

    14+
    Console
    15+
    -------
    16+
    17+
    * Deprecated the `setCrossingChar()` method in favor of the `setDefaultCrossingChar()` method in `TableStyle`.
    18+
    * Deprecated the `setHorizontalBorderChar()` method in favor of the `setDefaultCrossingChars()` method in `TableStyle`.
    19+
    * Deprecated the `getHorizontalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`.
    20+
    * Deprecated the `setVerticalBorderChar()` method in favor of the `setVerticalBorderChars()` method in `TableStyle`.
    21+
    * Deprecated the `getVerticalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`.
    22+
    * Deprecated passing a command as a string to `ProcessHelper::run()`,
    23+
    pass it the command as an array of arguments instead.
    24+
    25+
    Before:
    26+
    ```php
    27+
    $processHelper->run($output, 'ls -l');
    28+
    ```
    29+
    30+
    After:
    31+
    ```php
    32+
    $processHelper->run($output, array('ls', '-l'));
    33+
    ```
    34+
    1435
    DoctrineBridge
    1536
    --------------
    1637

    @@ -37,6 +58,22 @@ Form
    3758
    {% endfor %}
    3859
    ```
    3960

    61+
    Process
    62+
    -------
    63+
    64+
    * Deprecated the `Process::setCommandline()` and the `PhpProcess::setPhpBinary()` methods.
    65+
    * Deprecated passing commands as strings when creating a `Process` instance.
    66+
    67+
    Before:
    68+
    ```php
    69+
    $process = new Process('ls -l');
    70+
    ```
    71+
    72+
    After:
    73+
    ```php
    74+
    $process = new Process(array('ls', '-l'));
    75+
    ```
    76+
    4077
    Security
    4178
    --------
    4279

    UPGRADE-5.0.md

    Lines changed: 28 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -21,6 +21,18 @@ Console
    2121
    * Removed the `getHorizontalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`.
    2222
    * Removed the `setVerticalBorderChar()` method in favor of the `setVerticalBorderChars()` method in `TableStyle`.
    2323
    * Removed the `getVerticalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`.
    24+
    * The `ProcessHelper::run()` method takes the command as an array of arguments.
    25+
    26+
    Before:
    27+
    ```php
    28+
    $processHelper->run($output, 'ls -l');
    29+
    ```
    30+
    31+
    After:
    32+
    ```php
    33+
    $processHelper->run($output, array('ls', '-l'));
    34+
    ```
    35+
    2436

    2537
    DependencyInjection
    2638
    -------------------
    @@ -78,6 +90,22 @@ HttpFoundation
    7890
    * The `getClientSize()` method of the `UploadedFile` class has been removed.
    7991
    * The `getSession()` method of the `Request` class throws an exception when session is null.
    8092

    93+
    Process
    94+
    -------
    95+
    96+
    * Removed the `Process::setCommandline()` and the `PhpProcess::setPhpBinary()` methods.
    97+
    * Commands must be defined as arrays when creating a `Process` instance.
    98+
    99+
    Before:
    100+
    ```php
    101+
    $process = new Process('ls -l');
    102+
    ```
    103+
    104+
    After:
    105+
    ```php
    106+
    $process = new Process(array('ls', '-l'));
    107+
    ```
    108+
    81109
    Security
    82110
    --------
    83111

    src/Symfony/Component/Console/CHANGELOG.md

    Lines changed: 8 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1,6 +1,14 @@
    11
    CHANGELOG
    22
    =========
    33

    4+
    4.2.0
    5+
    -----
    6+
    7+
    * allowed passing commands as `array($process, 'ENV_VAR' => 'value')` to `ProcessHelper::run()`
    8+
    * deprecated passing a command as a string to `ProcessHelper::run()`,
    9+
    pass it the command as an array of its arguments instead
    10+
    * made the `ProcessHelper` class final
    11+
    412
    4.1.0
    513
    -----
    614

    src/Symfony/Component/Console/Helper/ProcessHelper.php

    Lines changed: 24 additions & 9 deletions
    Original file line numberDiff line numberDiff line change
    @@ -20,18 +20,20 @@
    2020
    * The ProcessHelper class provides helpers to run external processes.
    2121
    *
    2222
    * @author Fabien Potencier <fabien@symfony.com>
    23+
    *
    24+
    * @final since Symfony 4.2
    2325
    */
    2426
    class ProcessHelper extends Helper
    2527
    {
    2628
    /**
    2729
    * Runs an external process.
    2830
    *
    29-
    * @param OutputInterface $output An OutputInterface instance
    30-
    * @param string|array|Process $cmd An instance of Process or an array of arguments to escape and run or a command to run
    31-
    * @param string|null $error An error message that must be displayed if something went wrong
    32-
    * @param callable|null $callback A PHP callback to run whenever there is some
    33-
    * output available on STDOUT or STDERR
    34-
    * @param int $verbosity The threshold for verbosity
    31+
    * @param OutputInterface $output An OutputInterface instance
    32+
    * @param array|Process $cmd An instance of Process or an array of the command and arguments
    33+
    * @param string|null $error An error message that must be displayed if something went wrong
    34+
    * @param callable|null $callback A PHP callback to run whenever there is some
    35+
    * output available on STDOUT or STDERR
    36+
    * @param int $verbosity The threshold for verbosity
    3537
    *
    3638
    * @return Process The process that ran
    3739
    */
    @@ -44,9 +46,22 @@ public function run(OutputInterface $output, $cmd, $error = null, callable $call
    4446
    $formatter = $this->getHelperSet()->get('debug_formatter');
    4547

    4648
    if ($cmd instanceof Process) {
    47-
    $process = $cmd;
    48-
    } else {
    49+
    $cmd = array($cmd);
    50+
    }
    51+
    52+
    if (!\is_array($cmd)) {
    53+
    @trigger_error(sprintf('Passing a command as a string to "%s()" is deprecated since Symfony 4.2, pass it the command as an array of arguments instead.', __METHOD__), E_USER_DEPRECATED);
    54+
    $cmd = array(\method_exists(Process::class, 'withShell') ? Process::withShell($cmd) : new Process($cmd));
    55+
    }
    56+
    57+
    if (\is_string($cmd[0] ?? null)) {
    4958
    $process = new Process($cmd);
    59+
    $cmd = array();
    60+
    } elseif (($cmd[0] ?? null) instanceof Process) {
    61+
    $process = $cmd[0];
    62+
    unset($cmd[0]);
    63+
    } else {
    64+
    throw new \InvalidArgumentException(sprintf('Invalid command provided to "%s()": the command should an array whose first is element is either the path to the binary to run of a "Process" object.', __METHOD__));
    5065
    }
    5166

    5267
    if ($verbosity <= $output->getVerbosity()) {
    @@ -57,7 +72,7 @@ public function run(OutputInterface $output, $cmd, $error = null, callable $call
    5772
    $callback = $this->wrapCallback($output, $process, $callback);
    5873
    }
    5974

    60-
    $process->run($callback);
    75+
    $process->run($callback, $cmd);
    6176

    6277
    if ($verbosity <= $output->getVerbosity()) {
    6378
    $message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run successfully', $process->getExitCode());

    src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php

    Lines changed: 17 additions & 2 deletions
    Original file line numberDiff line numberDiff line change
    @@ -25,6 +25,10 @@ class ProcessHelperTest extends TestCase
    2525
    */
    2626
    public function testVariousProcessRuns($expected, $cmd, $verbosity, $error)
    2727
    {
    28+
    if (\is_string($cmd)) {
    29+
    $cmd = \method_exists(Process::class, 'withShell') ? Process::withShell($cmd) : new Process($cmd);
    30+
    }
    31+
    2832
    $helper = new ProcessHelper();
    2933
    $helper->setHelperSet(new HelperSet(array(new DebugFormatterHelper())));
    3034
    $output = $this->getOutputStream($verbosity);
    @@ -41,7 +45,7 @@ public function testPassedCallbackIsExecuted()
    4145
    $executed = false;
    4246
    $callback = function () use (&$executed) { $executed = true; };
    4347

    44-
    $helper->run($output, 'php -r "echo 42;"', null, $callback);
    48+
    $helper->run($output, array('php', '-r', 'echo 42;'), null, $callback);
    4549
    $this->assertTrue($executed);
    4650
    }
    4751

    @@ -81,12 +85,21 @@ public function provideCommandsAndOutput()
    8185
    OUT out message
    8286
    RES 252 Command did not run successfully
    8387

    88+
    EOT;
    89+
    90+
    $PHP = '\\' === \DIRECTORY_SEPARATOR ? '!PHP!' : '"$PHP"';
    91+
    $successOutputPhp = <<<EOT
    92+
    RUN php -r $PHP
    93+
    OUT 42
    94+
    RES Command ran successfully
    95+
    8496
    EOT;
    8597

    8698
    $errorMessage = 'An error occurred';
    8799
    $args = new Process(array('php', '-r', 'echo 42;'));
    88100
    $args = $args->getCommandLine();
    89101
    $successOutputProcessDebug = str_replace("'php' '-r' 'echo 42;'", $args, $successOutputProcessDebug);
    102+
    $withShell = \method_exists(Process::class, 'withShell') ? array(Process::class, 'withShell') : function ($cmd) { return new Process($cmd); };
    90103

    91104
    return array(
    92105
    array('', 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERBOSE, null),
    @@ -100,7 +113,9 @@ public function provideCommandsAndOutput()
    100113
    array($syntaxErrorOutputVerbose.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, $errorMessage),
    101114
    array($syntaxErrorOutputDebug.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(500000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, $errorMessage),
    102115
    array($successOutputProcessDebug, array('php', '-r', 'echo 42;'), StreamOutput::VERBOSITY_DEBUG, null),
    103-
    array($successOutputDebug, new Process('php -r "echo 42;"'), StreamOutput::VERBOSITY_DEBUG, null),
    116+
    array($successOutputDebug, $withShell('php -r "echo 42;"'), StreamOutput::VERBOSITY_DEBUG, null),
    117+
    array($successOutputProcessDebug, array(new Process(array('php', '-r', 'echo 42;'))), StreamOutput::VERBOSITY_DEBUG, null),
    118+
    array($successOutputPhp, array($withShell('php -r '.$PHP), 'PHP' => 'echo 42;'), StreamOutput::VERBOSITY_DEBUG, null),
    104119
    );
    105120
    }
    106121

    src/Symfony/Component/Dotenv/Dotenv.php

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -330,7 +330,7 @@ private function resolveCommands($value)
    330330
    throw new \LogicException('Resolving commands requires the Symfony Process component.');
    331331
    }
    332332

    333-
    $process = new Process('echo '.$matches[0]);
    333+
    $process = \method_exists(Process::class, 'withShell') ? Process::withShell('echo '.$matches[0]) : new Process('echo '.$matches[0]);
    334334
    $process->inheritEnvironmentVariables(true);
    335335
    $process->setEnv($this->values);
    336336
    try {

    src/Symfony/Component/Process/CHANGELOG.md

    Lines changed: 7 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1,6 +1,13 @@
    11
    CHANGELOG
    22
    =========
    33

    4+
    4.2.0
    5+
    -----
    6+
    7+
    * added the `Process::withShell()` static constructor to define shell command-lines
    8+
    * deprecated passing a command as string when creating a `Process` instance
    9+
    * deprecated the `Process::setCommandline()` and the `PhpProcess::setPhpBinary()` methods
    10+
    411
    4.1.0
    512
    -----
    613

    src/Symfony/Component/Process/PhpProcess.php

    Lines changed: 7 additions & 2 deletions
    Original file line numberDiff line numberDiff line change
    @@ -29,11 +29,12 @@ class PhpProcess extends Process
    2929
    * @param string|null $cwd The working directory or null to use the working dir of the current PHP process
    3030
    * @param array|null $env The environment variables or null to use the same environment as the current PHP process
    3131
    * @param int $timeout The timeout in seconds
    32+
    * @param array|null $php Path to the PHP binary to use with any additional arguments
    3233
    */
    33-
    public function __construct(string $script, string $cwd = null, array $env = null, int $timeout = 60)
    34+
    public function __construct(string $script, string $cwd = null, array $env = null, int $timeout = 60, array $php = null)
    3435
    {
    3536
    $executableFinder = new PhpExecutableFinder();
    36-
    if (false === $php = $executableFinder->find(false)) {
    37+
    if (false === $php = $php ?? $executableFinder->find(false)) {
    3738
    $php = null;
    3839
    } else {
    3940
    $php = array_merge(array($php), $executableFinder->findArguments());
    @@ -51,9 +52,13 @@ public function __construct(string $script, string $cwd = null, array $env = nul
    5152

    5253
    /**
    5354
    * Sets the path to the PHP binary to use.
    55+
    *
    56+
    * @deprecated since Symfony 4.2, use the $php argument of the constructor instead.
    5457
    */
    5558
    public function setPhpBinary($php)
    5659
    {
    60+
    @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the $php argument of the constructor instead.', __METHOD__), E_USER_DEPRECATED);
    61+
    5762
    $this->setCommandLine($php);
    5863
    }
    5964

    src/Symfony/Component/Process/Process.php

    Lines changed: 32 additions & 7 deletions
    < 97AE td data-grid-cell-id="diff-edd51b05bf438c7cdca442e25d68f41dd0a51952a69fa0c5fa912dc31d833ef4-145-145-0" data-selected="false" role="gridcell" style="background-color:var(--bgColor-default);text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative diff-line-number-neutral left-side">145
    Original file line numberDiff line numberDiff line change
    @@ -129,21 +129,25 @@ class Process implements \IteratorAggregate
    129129
    );
    130130

    131131
    /**
    132-
    * @param string|array $commandline The command line to run
    133-
    * @param string|null $cwd The working directory or null to use the working dir of the current PHP process
    134-
    * @param array|null $env The environment variables or null to use the same environment as the current PHP process
    135-
    * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input
    136-
    * @param int|float|null $timeout The timeout in seconds or null to disable
    132+
    * @param array $command The command to run and its arguments listed as separate entries
    133+
    * @param string|null $cwd The working directory or null to use the working dir of the current PHP process
    134+
    * @param array|null $env The environment variables or null to use the same environment as the current PHP process
    135+
    * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input
    136+
    * @param int|float|null $timeout The timeout in seconds or null to disable
    137137
    *
    138138
    * @throws RuntimeException When proc_open is not installed
    139139
    */
    140-
    public function __construct($commandline, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
    140+
    public function __construct($command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
    141141
    {
    142142
    if (!function_exists('proc_open')) {
    143143
    throw new RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.');
    144144
    }
    145

    146-
    $this->commandline = $commandline;
    146+
    if (!\is_array($command)) {
    147+
    @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::withShell()" constructor if you need features provided by the shell.', __CLASS__), E_USER_DEPRECATED);
    148+
    }
    149+
    150+
    $this->commandline = $command;
    147151
    $this->cwd = $cwd;
    148152

    149153
    // on Windows, if the cwd changed via chdir(), proc_open defaults to the dir where PHP was started
    @@ -163,6 +167,23 @@ public function __construct($commandline, string $cwd = null, array $env = null,
    163167
    $this->pty = false;
    164168
    }
    165169

    170+
    /**
    171+
    * @param string $command The command line to pass to the shell of the OS
    172+
    * @param string|null $cwd The working directory or null to use the working dir of the current PHP process
    173+
    * @param array|null $env The environment variables or null to use the same environment as the current PHP process
    174+
    * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input
    175+
    * @param int|float|null $timeout The timeout in seconds or null to disable
    176+
    *
    177+
    * @throws RuntimeException When proc_open is not installed
    178+
    */
    179+
    public static function withShell(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
    180+
    {
    181+
    $process = new static(array(), $cwd, $env, $input, $timeout);
    182+
    $process->commandline = $command;
    183+
    184+
    return $process;
    185+
    }
    186+
    166187
    public function __destruct()
    167188
    {
    168189
    $this->stop(0);
    @@ -892,9 +913,13 @@ public function getCommandLine()
    892913
    * @param string|array $commandline The command to execute
    893914
    *
    894915
    * @return self The current Process instance
    916+
    *
    917+
    * @deprecated since Symfony 4.2.
    895918
    */
    896919
    public function setCommandLine($commandline)
    897920
    {
    921+
    @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
    922+
    898923
    $this->commandline = $commandline;
    899924

    900925
    return $this;

    src/Symfony/Component/Process/Tests/ProcessFailedExceptionTest.php

    Lines changed: 7 additions & 7 deletions
    Original file line numberDiff line numberDiff line change
    @@ -24,7 +24,7 @@ class ProcessFailedExceptionTest extends TestCase
    2424
    */
    2525
    public function testProcessFailedExceptionThrowsException()
    2626
    {
    27-
    $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful'))->setConstructorArgs(array('php'))->getMock();
    27+
    $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful'))->setConstructorArgs(array(array('php')))->getMock();
    2828
    $process->expects($this->once())
    2929
    ->method('isSuccessful')
    3030
    ->will($this->returnValue(true));
    @@ -52,7 +52,7 @@ public function testProcessFailedExceptionPopulatesInformationFromProcessOutput(
    5252
    $errorOutput = 'FATAL: Unexpected error';
    5353
    $workingDirectory = getcwd();
    5454

    55-
    $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'getOutput', 'getErrorOutput', 'getExitCode', 'getExitCodeText', 'isOutputDisabled', 'getWorkingDirectory'))->setConstructorArgs(array($cmd))->getMock();
    55+
    $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'getOutput', 'getErrorOutput', 'getExitCode', 'getExitCodeText', 'isOutputDisabled', 'getWorkingDirectory'))->setConstructorArgs(array(array($cmd)))->getMock();
    5656
    $process->expects($this->once())
    5757
    ->method('isSuccessful')
    5858
    ->will($this->returnValue(false));
    @@ -84,8 +84,8 @@ public function testProcessFailedExceptionPopulatesInformationFromProcessOutput(
    8484
    $exception = new ProcessFailedException($process);
    8585

    8686
    $this->assertEquals(
    87-
    "The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}\n\nOutput:\n================\n{$output}\n\nError Output:\n================\n{$errorOutput}",
    88-
    $exception->getMessage()
    87+
    "The command \"\"$cmd\"\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}\n\nOutput:\n================\n{$output}\n\nError Output:\n================\n{$errorOutput}",
    88+
    str_replace("'php'", '"php"', $exception->getMessage())
    8989
    );
    9090
    }
    9191

    @@ -100,7 +100,7 @@ public function testDisabledOutputInFailedExceptionDoesNotPopulateOutput()
    100100
    $exitText = 'General error';
    101101
    $workingDirectory = getcwd();
    102102

    103-
    $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput', 'getWorkingDirectory'))->setConstructorArgs(array($cmd))->getMock();
    103+
    $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput', 'getWorkingDirectory'))->setConstructorArgs(array(array($cmd)))->getMock();
    104104
    $process->expects($this->once())
    105105
    ->method('isSuccessful')
    106106
    ->will($this->returnValue(false));
    @@ -130,8 +130,8 @@ public function testDisabledOutputInFailedExceptionDoesNotPopulateOutput()
    130130
    $exception = new ProcessFailedException($process);
    131131

    132132
    $this->assertEquals(
    133-
    "The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}",
    134-
    $exception->getMessage()
    133+
    "The command \"\"$cmd\"\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}",
    134+
    str_replace("'php'", '"php"', $exception->getMessage())
    135135
    );
    136136
    }
    137137
    }

    0 commit comments

    Comments
     (0)
    0