-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Process][Console] deprecated defining commands as strings #27821
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
ce7d6df
to
73fe4d6
Compare
this does not running things like |
and for anyone asking, |
UPGRADE-4.2.md
Outdated
* Deprecated the `setHorizontalBorderChar()` method in favor of the `setDefaultCrossingChars()` method in `TableStyle`. | ||
* Deprecated the `getHorizontalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`. | ||
* Deprecated the `setVerticalBorderChar()` method in favor of the `setVerticalBorderChars()` method in `TableStyle`. | ||
* Deprecated the `getVerticalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
already part of UPGRADE-4.1, to revert?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted
73fe4d6
to
ab1794f
Compare
|
ab1794f
to
8524a7a
Compare
Cool, thanks for working on that! I think it clearly reduces the chance of an accidental mistake. Now you can only pass an array and you have to explicitly ask the |
532a7d3
to
534e35c
Compare
UPGRADE-4.2.md
Outdated
------- | ||
|
||
* Deprecated passing a command as a string to `ProcessHelper::run()`, | ||
pass it the command as an array of arguments instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass the command
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also add a word about the new withShell()
method (as passing an array of arguments is not always possible, perhaps mention the cases where using withShell()
is "valid"?).
------- | ||
|
||
* Deprecated the `Process::setCommandline()` and the `PhpProcess::setPhpBinary()` methods. | ||
* Deprecated passing commands as strings when creating a `Process` instance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
@@ -21,6 +21,18 @@ Console | |||
* Removed the `getHorizontalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`. | |||
* Removed the `setVerticalBorderChar()` method in favor of the `setVerticalBorderChars()` method in `TableStyle`. | |||
* Removed the `getVerticalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`. | |||
* The `ProcessHelper::run()` method takes the command as an array of arguments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
4.2.0 | ||
----- | ||
|
||
* allowed passing commands as `array($process, 'ENV_VAR' => 'value')` to `ProcessHelper::run()` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
@@ -330,7 +330,7 @@ private function resolveCommands($value) | |||
throw new \LogicException('Resolving commands requires the Symfony Process component.'); | |||
} | |||
|
|||
$process = new Process('echo '.$matches[0]); | |||
$process = \method_exists(Process::class, 'withShell') ? Process::withShell('echo '.$matches[0]) : new Process('echo '.$matches[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about adding a comment to not forget simplifying this piece of code again in 5.0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we'll have many places to clean up like this when preparing 5.0, we will spot it with the usual grep method_exists
@@ -163,6 +167,23 @@ public function __construct($commandline, string $cwd = null, array $env = null, | |||
$this->pty = false; | |||
} | |||
|
|||
/** | |||
* @param string $command The command line to pass to the shell of the OS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add a description explaining the "valid" use cases for using this method.
I don't like the Also, what's the reasoning behind the deprecation of Process::setCommandline() and PhpProcess::setPhpBinary()? Thanks! |
I agree with @javiereguiluz here. If you're not into processes that much it's hard to understand. Not sure how to name it though. Maybe we should start by trying to define the difference in 1 sentence. That could help us to come up with a good name? |
Maybe take some inspiration from symfony/symfony-docs#9988 recently?
They are abstraction leaks. A process should not be mutable for these settings. They completely defeat the as |
|
If we don't want to explain all the internal details of using these "shell commands", maybe we can rename $result = (new Process(['ls', '-al']))->getOutput();
$result = (Process::asString('ls -al'))->getOutput(); |
This would render the whole idea kind of useless. Because then we can also just keep everything as is and accept both, an array and a string. People will just update and ask themselves why the constructor is now an array and just modify and use |
@Toflar can you please explain to me the difference between them, or the consequences of using this shell things vs the other thing? Imagine that I'm not a tech person, so the explanation is a simple as possible. That way we'll be able to find the right name. Thanks! |
I'm struggling with finding a good name myself. I basically raised this issue because @nicolas-grekas tweetet about the difference saying something like "did you know you can pass process arguments as an array?". I checked his linked docs PR (symfony/symfony-docs#9988) and I just noticed that the docs are nice but there's room for improvement code-wise. Right now, the Process component does just happily accept both, an array or a string as constructor argument. When you pass it as a string, the arguments are not escaped and passed on to the shell as is. This means you as a developer can benefit from additional features such as stream redirections but you are also responsible to use the correct syntax and escape everything needed yourself which is dependent on the underlying OS. So e.g. if you develop on Windows and deploy to Linux, your command might fail. And my argument was that in 90% of all cases, the commands are likely rather simple and don't need any special shell feature. Or in other words: 90% of all our devs want to pass an array not a string. I just feel like that with this PR we can protect devs from some unforeseen compatibility issues which is something worth working towards imho 😄 |
@javiereguiluz The fact that the shell is there is the reason why we can use e.g. So, when using the array syntax, conceptually, you do not use a shell. Escaping becomes a foreign concept (and thus saying is "there is no need to escape" builds on no ground - there is nothing to escape for or against.) PS: even when defining command in the shell's language, people should still NOT escape strings themselves. This is very very similar to prepared statements: you do NOT want to escape your SQL parameters yourself because that's actually impossible to achieve in a portable and secure way. Instead, you use placeholders in prepared statements and bind the values when executing. That's exactly what ppl should do for commands also, and what https://github.com/symfony/symfony-docs/pull/9988/files#diff-2e6951f193acece85d23e18380939b51R122 explains. I hope this help understand the reasons for this PR. |
@Toflar @nicolas-grekas your comments were perfectly clear. Thanks! I propose other names then: $result = (new Process(['ls', '-al']))->getOutput();
$result = (Process::raw('ls -al'))->getOutput();
$result = (Process::rawCommand('ls -al'))->getOutput();
$result = (Process::unescaped('ls -al'))->getOutput();
$result = (Process::unescapedCommand('ls -al'))->getOutput(); |
|
It's not really about escaping then, so I'd go with |
I don't care about the method name length. My concern is that |
IMHO, |
@@ -44,9 +46,22 @@ public function run(OutputInterface $output, $cmd, $error = null, callable $call | |||
$formatter = $this->getHelperSet()->get('debug_formatter'); | |||
|
|||
if ($cmd instanceof Process) { | |||
$process = $cmd; | |||
} else { | |||
$cmd = array($cmd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why wrapping the Process object in an array, to unwrap it after that ? this looks really weird.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to normalize the data structure and simplify the following lines
$process = new Process($cmd); | ||
$cmd = array(); | ||
} elseif (($cmd[0] ?? null) instanceof Process) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is no adding support for passing an array with a Process as first argument (and other stuff after that). does it actually make sense ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See PR description:
Allowed passing commands as array($process, 'ENV_VAR' => 'value') to ProcessHelper::run()
534e35c
to
345f004
Compare
Thanks @fabpot, comments addressed. |
345f004
to
d769679
Compare
d769679
to
8895bc1
Compare
* @param string $command The command line to pass to the shell of the OS | ||
* @param string|null $cwd The working directory or null to use the working dir of the current PHP process | ||
* @param array|null $env The environment variables or null to use the same environment as the current PHP process | ||
* @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
null
is part of mixed
:)
Thank you @nicolas-grekas. |
…ings (nicolas-grekas) This PR was merged into the 4.2-dev branch. Discussion ---------- [Process][Console] deprecated defining commands as strings | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #27796 | License | MIT | Doc PR | - * Added the `Process::fromShellCommandline()` static constructor to define shell command-lines * Allowed passing commands as `array($process, 'ENV_VAR' => 'value')` to `ProcessHelper::run()` * Deprecated passing commands as strings when creating a `Process` instance. * Deprecated the `Process::setCommandline()` and the `PhpProcess::setPhpBinary()` methods. * Deprecated passing a command as a string to `ProcessHelper::run()`, pass it the command as an array of arguments instead. * Made the `ProcessHelper` class final Commits ------- 8895bc1 [Process][Console] deprecated defining commands as strings
This PR was merged into the master branch. Discussion ---------- Update doc for Process v4.2 Follows symfony/symfony#27821 Fixes #10299 Commits ------- 3a0a450 Update doc for Process v4.2
…tion (derrabus) This PR was merged into the 6.4 branch. Discussion ---------- [Console] Remove `Process::fromShellCommandline()` detection | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | no | New feature? | no | Deprecations? | no | Tickets | N/A | License | MIT | Doc PR | N/A This method exists since #27821 (Symfony 4.2) Commits ------- 12ee32d [Console] Remove Process::fromShellCommandline() detection
Process::fromShellCommandline()
static constructor to define shell command-linesarray($process, 'ENV_VAR' => 'value')
toProcessHelper::run()
Process
instance.Process::setCommandline()
and thePhpProcess::setPhpBinary()
methods.ProcessHelper::run()
, pass it the command as an array of arguments instead.ProcessHelper
class final