Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[Process] Allow writing portable "prepared" command lines#24763
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
[Process] Allow writing portable "prepared" command lines#24763
Uh oh!
There was an error while loading.Please reload this page.
Conversation
2db2948 to2c23e96Compare| $options =array('suppress_errors' =>true); | ||
| if ('\\' !==DIRECTORY_SEPARATOR) { |
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:
$windows ='\\' ===DIRECTORY_SEPARATOR;$this->replacePlaceholder($commandline,$windows ?array('!','!') :array('$',''));if ($windows) {
| privatefunctionreplacePlaceholder($commandLine,$toReplace) | ||
| { | ||
| if (preg_match('/\{([a-zA-Z0-9]*?)\}/',$commandLine)) { |
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.
Either this test is useless (because{ or} chars are replaced) or the following line is buggy (because{ and} are replaced regardless that they match the previous regex).
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.
From what I understand, it's buggy. Only placeholders like{foo} must be replaced.{} should not match,echo '{{foo}' should returnecho '{value' too.
Something like this should do the trick:
if (!preg_match_all('/\{([a-zA-Z0-9]+?)\}/',$commandLine,$matches)) {return$commandLine;}$patterns =$replacements =array();foreach ($matchesas$match) {$patterns[] =sprintf('/{%s}/',$match[1]);$replacements[] =sprintf('%s%s%s',$toReplace[0],$match[1],$toReplace[1]);}returnpreg_replace($patterns,$replacements,$commandLine);
(I've not tested it, but you got the idea)
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 understand and will modify according to the exemple
e8973b5 to0bf646cCompareSimperfit commentedOct 31, 2017
done@dunglas |
Simperfit commentedOct 31, 2017
Status: Needs Review |
0bf646c toc6c730cCompare| privatefunctionreplacePlaceholder($commandLine,$toReplace) | ||
| { | ||
| if (!preg_match_all('/\{([a-zA-Z0-9]+?)\}/',$commandLine,$matches)) { |
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 think this could be replaced by a single call to preg_replace
the pattern is missing the underscore also
| if ('\\' ===DIRECTORY_SEPARATOR) { | ||
| $windows ='\\' ===DIRECTORY_SEPARATOR; | ||
| $commandline =$this->replacePlaceholder($commandline,$windows ?array('!','!') :array('$','')); |
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.
the "$toReplace" should be moved inside the method, there is no reason to leak this outside of the method I think
nicolas-grekas commentedNov 1, 2017
Someone proposed to fail when a var was used, but not provided when calling. Is that something that would be possible? |
Simperfit commentedNov 1, 2017
I need to figure out, but I don't see anything that would make it not possible. |
ca1a267 to51f6947CompareSimperfit commentedNov 7, 2017
Comments addressed and new throw added. |
51f6947 to0dda934Compare| $patterns[] =sprintf('/{%s}/',$match[0]); | ||
| $replacements[] =sprintf('%s%s%s',$toReplace[0],$match[0],$toReplace[1]); | ||
| if (isset($env[$match[0]])) { | ||
| $isInEnv =true; |
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.
Shouldn't you store unused placeholders to display a nice error message likeThe placeholders "foo", "bar" doesn't exist?
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 can do that, that's a good idea.
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.
Any update?
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.
updated
0dda934 toe596524Compare| } | ||
| if (!empty($env)) { | ||
| thrownewInvalidArgumentException(sprintf('Placeholder%s "%s" doesn\'t exist.',count($env) >1 ?'s' :'',implode(',',array_keys($env)))); |
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.
If you make the distinction between singular and plural for "placeholder/s", you should probably do the same for "doesn't/don't" too.
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.
done
e596524 to4bf2bb3Compare4bf2bb3 toc49cbb6CompareSimperfit commentedFeb 19, 2018
Doc PR has been added. |
dunglas commentedFeb 19, 2018
Thanks@Simperfit. |
…nes (Simperfit)This PR was merged into the 4.1-dev branch.Discussion----------[Process] Allow writing portable "prepared" command lines| Q | A| ------------- | ---| Branch? | 4.1| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets |#23778| License | MIT| Doc PR |symfony/symfony-docs#9295This give the opportunity to create process commands that allow to changes only the values instead of changing the code.Commits-------d1e4f48 [Process] Allow writing portable "prepared" command lines
Tobion commentedFeb 25, 2018 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
I don't agree with this implementation. The new syntax is very specific to the Symfony process now and not suited within the a general Process class. This logic should be split out into some sort of ProcessBuilder that returns the final command line that you then pass to the Process. |
nicolas-grekas commentedFeb 25, 2018 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@Tobion you can think of this as SQL prepared statements. Note that the Process component doesn't provide any mean to escape shell arguments anymore, exactly like you should not use any for SQL drivers. And also because it is just impossible to properly escape shell arguments (same for SQL btw, when taking portability into account). |
Tobion commentedFeb 25, 2018
PDO provides different methods for prepared statements to separate concerns. Exactly what I'm asking for. |
nicolas-grekas commentedFeb 25, 2018 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
I'm really not convinced that a different design would provide anything better sorry. |
malarzm commentedFeb 28, 2018
Late to the game, but isn't this a BC break for folks using something like |
Tobion commentedFeb 28, 2018
There are probably bc breaks here. that is also why I don't agree with using the same api for this because you cannot control it anymore. |
nicolas-grekas commentedFeb 28, 2018 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Nobody echoes like that (they do |
Tobion commentedFeb 28, 2018
I would expect that I can run a command with the process component the same way it works on the shell. This is not possible anymore and you have to think and know about Process special behavior now (in addition to correct escaping). |
nicolas-grekas commentedFeb 28, 2018
do you have a real-life example? |
malarzm commentedFeb 28, 2018
This is rather bold statement. Also I'm not talking about escaping, in my example the user would want to have plain IMO if you're not willing to revert the feature there should be a feature flag turned off by default in 4.x and switched to on in 5.x. |
nicolas-grekas commentedFeb 28, 2018
@malarzm you were asking about BC break. I explained why I think the collision is more theoretical than practical IMHO. |
Tobion commentedFeb 28, 2018
|
nicolas-grekas commentedFeb 28, 2018 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@Tobion sure, but this a constructed example... |
Tobion commentedFeb 28, 2018
It's not about if it's real example or not. It's about expectations. Why am I not allowed to run a process that works with the process component? The job of the process component is it make it easier to run processes from PHP, not harder with edge cases that don't work and behave unexpected. |
javiereguiluz commentedFeb 28, 2018
I think Tobias has a point here. Suddenly, your Symfony app can't run commands that contain |
nicolas-grekas commentedFeb 28, 2018
OK, see#26344 |
…e "prepared" command lines (Simperfit)" (nicolas-grekas)This PR was merged into the 4.1-dev branch.Discussion----------Revert "feature#24763 [Process] Allow writing portable "prepared" command lines (Simperfit)"| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets | -| License | MIT| Doc PR | -This reverts commit1364089, reversingchanges made toe043478.As discussed in#24763 and#26344This doens't revert the possibility to use prepared command lines. They just won't be *portable* anymore, unless special care is taken by "userland".Ie the placeholders need to be shell-dependent: use eg `echo "$FOO"` on *nix (the double quotes *are* important), and `echo !FOO!` on Windows (no double quotes there).Commits-------6a98bfa Revert "feature#24763 [Process] Allow writing portable "prepared" command lines (Simperfit)"
…nes (Simperfit)This PR was merged into the 4.4 branch.Discussion----------[Process] Allow writing portable "prepared" command lines| Q | A| ------------- | ---| Branch? | 4.4| Bug fix? | no| New feature? | yes <!-- please update src/**/CHANGELOG.md files -->| BC breaks? | no <!-- seehttps://symfony.com/bc -->| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->| Tests pass? | yes <!-- please add some, will be required by reviewers -->| Fixed tickets |#23778 <!-- #-prefixed issue number(s), if any -->| License | MIT| Doc PR |symfony/symfony-docs#11802 <!-- required for new features -->Hey here, it's me, again !I've talked with@nicolas-grekas and he gave me a new way of writing this feature that will not be a problem for people using things like {{ toto }} since we are using the linux style of using envvar, the replaced arguments is only replaced when using windows.This should not break anything and work as expected!see#24763This makes `"$FOO"` work seamlessly on Linux and on Windows to reference an env var (that can be provided when calling e.g. the "run" method)Commits-------3f8354f [Process] Allow writing portable "prepared" command lines
Uh oh!
There was an error while loading.Please reload this page.
This give the opportunity to create process commands that allow to changes only the values instead of changing the code.