Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[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

Conversation

@Simperfit
Copy link
Contributor

@SimperfitSimperfit commentedOct 31, 2017
edited
Loading

QA
Branch?4.1
Bug fix?no
New feature?yes
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed tickets#23778
LicenseMIT
Doc PRsymfony/symfony-docs#9295

This give the opportunity to create process commands that allow to changes only the values instead of changing the code.

jean-pasqualini, theofidry, twifty, sstok, and Koc reacted with thumbs up emoji
@SimperfitSimperfitforce-pushed thefeature/allow-writing-prepared-command-line branch 3 times, most recently from2db2948 to2c23e96CompareOctober 31, 2017 07:05
@chalasrchalasr added this to the4.1 milestoneOct 31, 2017

$options =array('suppress_errors' =>true);

if ('\\' !==DIRECTORY_SEPARATOR) {
Copy link
Member

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) {

Simperfit reacted with thumbs up emoji

privatefunctionreplacePlaceholder($commandLine,$toReplace)
{
if (preg_match('/\{([a-zA-Z0-9]*?)\}/',$commandLine)) {
Copy link
Member

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).

Copy link
Member

@dunglasdunglasOct 31, 2017
edited
Loading

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)

Copy link
ContributorAuthor

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

dunglas reacted with thumbs up emoji
@SimperfitSimperfitforce-pushed thefeature/allow-writing-prepared-command-line branch 2 times, most recently frome8973b5 to0bf646cCompareOctober 31, 2017 13:12
@Simperfit
Copy link
ContributorAuthor

done@dunglas

@Simperfit
Copy link
ContributorAuthor

Status: Needs Review

@SimperfitSimperfitforce-pushed thefeature/allow-writing-prepared-command-line branch from0bf646c toc6c730cCompareNovember 1, 2017 07:03

privatefunctionreplacePlaceholder($commandLine,$toReplace)
{
if (!preg_match_all('/\{([a-zA-Z0-9]+?)\}/',$commandLine,$matches)) {

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('$',''));

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
Copy link
Member

Someone proposed to fail when a var was used, but not provided when calling. Is that something that would be possible?

@Simperfit
Copy link
ContributorAuthor

I need to figure out, but I don't see anything that would make it not possible.

@SimperfitSimperfitforce-pushed thefeature/allow-writing-prepared-command-line branch 2 times, most recently fromca1a267 to51f6947CompareNovember 7, 2017 07:43
@Simperfit
Copy link
ContributorAuthor

Comments addressed and new throw added.

@SimperfitSimperfitforce-pushed thefeature/allow-writing-prepared-command-line branch from51f6947 to0dda934CompareNovember 7, 2017 07:50
$patterns[] =sprintf('/{%s}/',$match[0]);
$replacements[] =sprintf('%s%s%s',$toReplace[0],$match[0],$toReplace[1]);
if (isset($env[$match[0]])) {
$isInEnv =true;
Copy link
Member

@dunglasdunglasNov 8, 2017
edited
Loading

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?

Copy link
ContributorAuthor

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Any update?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

updated

@SimperfitSimperfitforce-pushed thefeature/allow-writing-prepared-command-line branch from0dda934 toe596524CompareDecember 1, 2017 17:49
}

if (!empty($env)) {
thrownewInvalidArgumentException(sprintf('Placeholder%s "%s" doesn\'t exist.',count($env) >1 ?'s' :'',implode(',',array_keys($env))));
Copy link
Member

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.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

done

@SimperfitSimperfitforce-pushed thefeature/allow-writing-prepared-command-line branch frome596524 to4bf2bb3CompareDecember 7, 2017 09:23
@SimperfitSimperfitforce-pushed thefeature/allow-writing-prepared-command-line branch from4bf2bb3 toc49cbb6CompareDecember 16, 2017 04:52
@Simperfit
Copy link
ContributorAuthor

Doc PR has been added.

@dunglas
Copy link
Member

Thanks@Simperfit.

@dunglasdunglas merged commitd1e4f48 intosymfony:masterFeb 19, 2018
dunglas added a commit that referenced this pull requestFeb 19, 2018
…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
Copy link
Contributor

Tobion commentedFeb 25, 2018
edited
Loading

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.
Why should the process class know about this syntax? It's not its responsiblity.

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedFeb 25, 2018
edited
Loading

@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).
Like PHP PDO handles prepared statements directly, it can also be legit to make Process handle "prepared" command lines, to provide portability across OSes for shell placeholders (esp.${FOO} vs!FOO! on Windows, which you can still use if you really don't want to use the Symfony placeholders btw).

@Tobion
Copy link
Contributor

PDO provides different methods for prepared statements to separate concerns. Exactly what I'm asking for.

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedFeb 25, 2018
edited
Loading

I'm really not convinced that a different design would provide anything better sorry.
This change is the last of a series of moves that turn Process into a properly handled abstraction of command lines and escaping of arguments (which should never have been exposed to userland, like sql arguments.)

sstok reacted with thumbs up emoji

@SimperfitSimperfit deleted the feature/allow-writing-prepared-command-line branchFebruary 26, 2018 08:51
@malarzm
Copy link
Contributor

Late to the game, but isn't this a BC break for folks using something likeecho "{{ some_var }} foo bar" >> something.j2 where they expect{{ some_var }} to be echoed to a file?

@Tobion
Copy link
Contributor

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
Copy link
Member

nicolas-grekas commentedFeb 28, 2018
edited
Loading

Nobody echoes like that (they dofile_put_contents() instead)
You need to take escaping into consideration when thinking about this.
We already forced ppl tonot escape values on their own (there is no way to do this in 4.0)
So either they doescapeshellargs() on their own, which is totally broken and unsupported.
When done properly, either ppl use the array-way to define command lines, thus cannot use placeholders, either they use env vars already, but the non portable OS-dependent style. - there is no other way for dynamic values.
Last possibility: ppl inject static values that they escaped/wrote themselves (that's your example), which I really don't expect to collide in practice.
All in all, I think this means dynamic values cannot collide in any supported way, and static values are really unlikely to collide.

@Tobion
Copy link
Contributor

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
Copy link
Member

do you have a real-life example?

@malarzm
Copy link
Contributor

Nobody echoes like that (they do file_put_contents() instead)

This is rather bold statement. Also I'm not talking about escaping, in my example the user would want to have plain{{ some_var }} foo bar appended to thesomething.j2 file ({{ some_var }} is valid syntax for j2). In 4.0 it would work, in 4.1 it'd be an exception.

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
Copy link
Member

@malarzm you were asking about BC break. I explained why I think the collision is more theoretical than practical IMHO.

@Tobion
Copy link
Contributor

echo "My template {{ var }}" | bin/console lint:twig kboom

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedFeb 28, 2018
edited
Loading

@Tobion sure, but this a constructed example...
In a real app, you'll do (in 4.0, on Linux):
(new Process('echo $TWIG | bin/console lint:twig'))->run(null, array('TWIG' => 'My template {{ var }}');
as there is no other way to inject a value (and running a command to lint a static string is not something "real", you might agree :) )

@Tobion
Copy link
Contributor

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.

malarzm, jvasseur, and sstok reacted with thumbs up emoji

@javiereguiluz
Copy link
Member

I think Tobias has a point here. Suddenly, your Symfony app can't run commands that contain{{ ... }} (unless you update your code) Of course it's not super common to include{{ ... }} in your commands but I don't think it's impossible at all.

@nicolas-grekas
Copy link
Member

OK, see#26344

nicolas-grekas added a commit to nicolas-grekas/symfony that referenced this pull requestMar 2, 2018
…red" command lines (Simperfit)"This reverts commit1364089, reversingchanges made toe043478.
fabpot added a commit that referenced this pull requestMar 5, 2018
…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)"
@fabpotfabpot mentioned this pull requestMay 7, 2018
fabpot added a commit that referenced this pull requestJun 26, 2019
…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
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@xabbuhxabbuhxabbuh left review comments

@dunglasdunglasdunglas approved these changes

@nicolas-grekasnicolas-grekasnicolas-grekas approved these changes

Assignees

No one assigned

Projects

None yet

Milestone

4.1

Development

Successfully merging this pull request may close these issues.

9 participants

@Simperfit@nicolas-grekas@dunglas@Tobion@malarzm@javiereguiluz@xabbuh@chalasr@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp