Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
Add "executable" option to server:run console command#23721
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
Uh oh!
There was an error while loading.Please reload this page.
Conversation
| thrownew \InvalidArgumentException(sprintf('Port "%s" is not valid.',$this->port)); | ||
| } | ||
| $this->executable =$executable; |
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 welcome any suggestions on how to validate this. Usingis_executable would only work for full paths. And this can be anything fromxdebug (from my original issue) to/usr/bin/php7_custom_build -c /custom/php.ini.
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.
For now the command would just fail on the higher layer (inWebServer::run)
| $finder =newPhpExecutableFinder(); | ||
| if (false ===$executable =$finder->find()) { | ||
| thrownew \RuntimeException('Unable to find the PHP executable.'); | ||
| } |
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'd move this logic to WebServerConfig constructor now that it holds an executable.
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.
Moved
| $env, | ||
| $input->getArgument('addressport'), | ||
| $input->getOption('router'), | ||
| $input->getOption('executable') |
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.
Is in your oppinion "executable" correct name for what it holds? (e.g.:php orphp -c /path/to/ini or/usr/bin/custom_php). Other options I considered were "command" (although that clashes with Symfony command) or "binary" (which is usually the file itself, not the whole 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 believeexecutable andbinary in this scenario are synonyms. Bash calls itcommand, in my mind it makes a bit more sense (even though the command will be the whole string that the Process will run).
85061fb tocde9568Comparetomasfejfar commentedJul 31, 2017
I added a test for WebServerConfig class. In first commit the test is added for the existing implementation. Then a change commit adds the "executable" parameter and tests that it works as expected. I still couldn't properly test whether the code works as a whole (see first message) and would very much welcome any suggestions on how to do it. |
be96c77 to011d1dbComparefabpot commentedAug 1, 2017
Instead of adding an option for an edge case, I propose to be able to configure the executable via an env var. |
fernandocarletti commentedAug 1, 2017
I was working on the very same issue, but I came with a different approach:3.4...xurumelous:feature/cli-settings-server I did not change the |
tomasfejfar commentedAug 2, 2017
@fabpot that makes sense. I'll try to update the code asap. @xurumelous yes, I thought about that as well. It's actually what most people use when debugging CLI apps. But it would not work for my case. If you look at#22101 - my exact use cases is xdebug wrapper for the php binary. What's great about it is that you have centralized configuration and all you need to know is that you need to call |
fernandocarletti commentedAug 2, 2017
@tomasfejfar Yes, it makes sense. Are you making the change for the env variable? If you need help you can count on me. I really need to be able to set xdebug.remote_port per project. Right now I'm basically doing it manually, getting the command the |
tomasfejfar commentedAug 2, 2017
This implementation should allow you to set the executable to If you could do the change for the env variable and send a PR from your fork to this branch, that would be great. I'll probably not have time for it this week. Did you manage to test your changes somehow? How did you approach it? I've coded the whole thing without ever running it because I couldn't get it to work (as noted in the first post) :( |
tomasfejfar commentedAug 2, 2017 • 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.
@fabpot what about setting the executable as a parameter and pulling it from the DI? I would prefer changing |
fernandocarletti commentedAug 2, 2017
@tomasfejfar I believe I'll have time for this later today or tomorrow night. I tested in the vendor folder. I ran composer with I thought you have tested it, so I did not mention one issue before, I'll comment on the line I'm talking about. |
| $executable =$config->getExecutable(); | ||
| $process =newProcess(array($binary,'-S',$config->getAddress(),$config->getRouter())); | ||
| $process =newProcess(array($executable,'-S',$config->getAddress(),$config->getRouter())); |
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 believe we should "explode"$executable string. Depending on how the Process class is escaping the array, the first one will be the command name, see the example:
$'echo -e test'bash:echo -e test:command not found
If you pass a whole string as the command, it will be interpreted as its name. I did not test it, but I believe it will do the same in the end.
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.
Oh, yes... definitely. Thanks.
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 not as simple as it seems. Consider following executable:php -dmemory_limit=16M -dzend_extension="C:\Program Files\some_extension.dll". If I were to split this with spaces, it would break around theProgram Files part. And parsing CLI arguments is way over the scope of this PR IMHO. I've googled for some ready-made solutions and everything is in the ballpark of hundred lines of code.
I tried to repurpose\Symfony\Component\Console\Input\StringInput for this, but it feels very hacky and I needed to add new public method to it.
See50fda23
Tested with php index.php s:r --docroot web\ --executable "php -dmemory_limit=512M -dinclude_path=\"c:\Program Files\""
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 suggestions welcome
a990d3c to8970e9fComparetomasfejfar commentedAug 7, 2017
I kept the various commits to allow easy revert if some of them are not OK. Tested on Windows: Works as expected. All green. Ready for review. |
tomasfejfar commentedAug 15, 2017
Can I do anything else to move this forward? |
tomasfejfar commentedAug 21, 2017
Any update on this? |
| $executable =$config->getExecutable(); | ||
| // we need to separate the executable from the rest of the string as StringInput won't handle it | ||
| $firstPartOfCommand =explode('',$executable)[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 a path with a space in it?
| $executable =null; | ||
| $envExecutable =getenv('SYMFONY_SERVER_EXECUTABLE'); | ||
| if ($envExecutable !==false) { |
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.
should befalse !== $envExecutable
| $executable =$envExecutable; | ||
| } | ||
| if ($executable ===null) { |
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.
Yoda-style as well
| $this->arguments[$arg->getName()] =$arg->isArray() ?array($token) :$token; | ||
| // if last argument isArray(), append token to last argument | ||
| // if last argument isArray(), append token to last argument |
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.
should be reverted (fabbot false positive)
| $this->arguments[$arg->getName()][] =$token; | ||
| // unexpected argument | ||
| // unexpected argument |
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.
should be reverted (fabbot false positive)
nicolas-grekas left a comment
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.
@tomasfejfar: the current logic is broken, because it implicitly mixes escaped and unescaped command line arguments (this previous comment hints it.) Instead, what aboutnot allowing command line args in the new env var? That would require you to create a small shell wrapper to add them there, thus make everything else much simpler.
If you really want to push args in the env var, the logic needs to consider that:
- the env var is already shell-safe and doesn't need further escaping
- the added args need to be escaped
- the concatenated string needs to be prefixed by "exec" on Linux, to not break signalling the child process.
Escaping should be done in a similar way as done here:
https://github.com/symfony/symfony/blob/3.4/src/Symfony/Component/Process/ProcessBuilder.php#L270-L273
nicolas-grekas commentedSep 26, 2017
Oh btw, if you follow this path, what about putting that env var in PhpExecutableFinder? |
nicolas-grekas commentedOct 8, 2017
Moving to 4.1. Rebase on master might be needed, where PHP 7.1 features can be used btw. |
8970e9f tof14fde3Comparef14fde3 tob5ff2baCompare…_BINARY` env var (nicolas-grekas)This PR was merged into the 4.1-dev branch.Discussion----------[Process] Make `PhpExecutableFinder` look for the `PHP_BINARY` env var| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets |#22101| License | MIT| Doc PR | -I think this is enough to fix the linked issue and thus replace#23721.ping@tomasfejfar FYICommits-------4bd01f2 [Process] Make `PhpExecutableFinder` look for the `PHP_BINARY` env var
The PR adds the "executable" option to
server:runcommand to allow running server with custom executable (as inbin\console server:run --executable="php -c /path/to/ini")I'm having a hard time testing this. The webserver bundle does not have any tests. I tried to add the symfony repo locally to my other project to test it, but I got:
Any pointers welcome.