-
-
Notifications
You must be signed in to change notification settings - Fork 101
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
Restart the process with a different configuration #91
Restart the process with a different configuration #91
Conversation
I see you're bundling XdebugHandler (under a different name). Is there a reason to not use |
So far it's an experiment so I'm trying to assess what I really need first and then how I can integrate an existing solution. However looking at
There is also a slightly different case with https://github.com/infection/infection. @johnstevenson your input could be welcomed here. IMO it would a great addition to have xdebug-handler (but then the name may require to change) being able to handle those cases properly. From afar the work done doesn't look trivial and has a few platform adjustments that I would be more than happy to not have to figure out |
ping @johnstevenson. Sorry I thought I pinged you initially but somehow I typed |
Could you outline exactly what you want to achieve, please. |
Mostly allowing to tweak other settings than xdebug: in the case of Box for example, we also need to set the |
Okay, so you want to restart the process in two scenarios: when xdebug is enabled and/or if I cannot really understand what the inflection code you have used brings to the party, other than to completely confuse things by splitting the code up (and consequently miss out some important stuff, like actually storing the original inis in the environment so that PHP_INI_SCAN_DIR can be restored). I'm just glad they didn't attribute it to me :) Having said that, though, this stuff can be surprisingly tricky to get one's head round. I suggest that you start off by trying https://packagist.org/packages/composer/xdebug-handler This is a lot more robust now (in terms of testing a variety of ini environments) and it also provides all current ini settings to the restarted process, so command-line overrides are available. To tweak other ini stuff, just call Alternatively you could update your entry points to call Hope this helps. |
5001a0d
to
7c510d5
Compare
Sorry I didn't push my PoC yesterday... That would have helped I think.
AFAIK the case with Infection is slightly different: when run Infection runs the tests once with coverage enabled (so it does require xdebug) and then generate mutants and will run the tests again for them. This second part should be run without. It does store and restore the original inis, it's however named differently.
Well the point is to avoid that :) So I've just pushed a PoC using So the status is the following: I've got something working right now. I however would like to leverage Would you mind taking a look at it and tell me if those changes look acceptable to you? If they are I'll do the PRs accordinly. |
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.
Sorry but this is all to specific to your use case
src/Php/PhpSettingsHandler.php
Outdated
class PhpSettingsHandler | ||
{ | ||
// MODIFIED | ||
const SUFFIX_ALLOW = '_ALLOW_INITIAL_SETTINGS'; |
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 would be bc break
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.
yeah, I changed it to match more what I had but I think we can keep it unchanged that's ok
src/Php/PhpSettingsHandler.php
Outdated
* | ||
* @throws RuntimeException If a parameter is invalid | ||
*/ | ||
final public function __construct($envPrefix, $colorOption = '', LoggerInterface $logger = 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.
This breaks the tests
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.
Yep. I kinda prefer to have the logger in the constructor as IMO there is no reason to rely on a setter here and this allows a cleaner form:
(new XdebugHandler(..., $logger))->check();
// as opposed to
$handler = new XdebugHandler(...);
$handler->setLogger($logger);
$handler->check();
unset($handler);
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.
No, it breaks the tests by making the constructor final
!
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 that, we can remove it it's unnecessary :P Sorry I didn't actually try the implementation against the test yet I just manually tried it
src/Php/PhpSettingsHandler.php
Outdated
|
||
// MODIFIED | ||
// renamed $this->loaded to $this->restart | ||
$this->restart = $this->shouldRestart(); |
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 original variable is a string containing the xdebug version or empty
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.
yes, but now the purpose would be more needs to restart or not so a boolean would make more sense. Note though that I assume you always want to disable xdebug on restart in the whole thing, it's just that we are also changing other stuff.
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.
It won't make any sense to folks who want to know (and report) the version (like Composer for example)
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 second restart
variable then? That way we can keep the current usage for loaded
but the actual reloading is defined by the state of the boolean value restart
src/Php/PhpSettingsHandler.php
Outdated
$this->restart = $this->shouldRestart(); | ||
|
||
if (null !== $logger) { | ||
$this->setLogger($logger); |
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's this got to do with any of this?
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 #91 (comment). I can live without that though
src/Php/PhpSettingsHandler.php
Outdated
*/ | ||
protected function shouldRestart() | ||
{ | ||
return extension_loaded('xdebug') || in_array(ini_get('phar.readonly'), ['1', 'On'], 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.
Should be the xdebug version or an empty string
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.
As per #91 (comment)
src/Php/PhpSettingsHandler.php
Outdated
private function writeTmpIni(array $iniFiles) | ||
{ | ||
// MODIFIED | ||
if (!$this->tmpIni = tempnam(sys_get_temp_dir(), $this->envPrefix.'_')) { |
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.
Identifiable tmp files can be a security risk, which is why we stopped doing something similar. Is there a specific reason you need this?
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 I see. Well my train of though is that I wanted to be able to identify them to double check they were removed properly or something. Since it's for security reasons though we can disregard that change completely
I made a handful of comments (I didn't review it all).
Sure, but it seems an awful lot of work when you could just add a few characters to your |
@johnstevenson thanks for the review. So what do you think about it? If you wish to keep
And with your review, actually I think that's the only elements really required. The rest is nitpicks I can live with if it allows me to re-use Also note that I added a logging entry for the restart command:
Which I think could be added without any problem too
Because what people will do is:
That's it, and it should work. Sure it's not a requirement but it's a better DX to just make sure that works out of the box. That enough was not good enough of a reason however. Another reason is that when using PHP-Scoper (see https://github.com/humbug/box/blob/master/doc/configuration.md#compactors-compactors), a lot of processing will be done relying on nikic/PHP-Parser. And this one is horribly slow if xdebug is used so disabling xdebug is almost a requirement here and it is more awkward to do at the user level |
Hey, thanks for the PRs. I just knocked you up a quick way to extend it, as it is at the moment: use Composer\XdebugHandler\XdebugHandler;
class Restarter extends XdebugHandler
{
private $refClass;
public function __construct($logger)
{
parent::__construct('box', '--ansi');
$this->setLogger($logger);
if (ini_get('phar.readonly')) {
$this->init();
}
}
protected function restart($command)
{
if ($this->refClass) {
$prop = $this->refClass->getProperty('tmpIni');
$prop->setAccessible(true);
$this->updateIni($prop->getValue($this));
}
parent::restart($command);
}
private function init()
{
$this->refClass = new \ReflectionClass('Composer\XdebugHandler\XdebugHandler');
$prop = $this->refClass->getProperty('loaded');
$prop->setAccessible(true);
if (!$loaded = $prop->getValue($this)) {
$prop->setValue($this, 'forced-restart');
}
}
private function updateIni($tmpIni)
{
$content = file_get_contents($tmpIni);
$content .= 'phar.readonly = 0'.PHP_EOL;
file_put_contents($tmpIni, $content);
}
} As you surmised, I want to keep the library as unchanged as possible (because everything is there for a very real purpose). However, I think it could be useful if it was more easily extendable, so I'm sure we'll get somewhere in the end. |
Thanks @johnstevenson. I do like your solution, but what about composer/xdebug-handler#45? It would make it possible more easily without having to resort to reflection on private properties |
Check for the PHP configuration when starting box and restart the process with xdebug disabled and `phar.readonly` turned off. Closes box-project#5
7c510d5
to
c40139a
Compare
Many thanks for the help @johnstevenson! I'm still having issues within PHPUnit i.e. if I allow the restart during the tests, it fails with a weird error:
This is happening for the tests in CompileTest. If I jumped to it, remove
This scenario is weird enough so I'll just drop it as it is for now, but in case you encounter this kind of issue or have an idea, there's an easy reproducer here |
Hey thanks. I'll have a play with this later and see what is happening. |
Ah, it's a chdir issue. Use |
Not exactly off the mark but rather how to guess which is the main script to use? |
The outline would be helpful ( especially as I'm drinking beer now) |
Ok I found the issue, indeed it's a chdir issue & I get a different error with PhpStorm because they have their
Now I can try to hack that last bit to make sure it point to the right script. However:
Also I realise I actually don't want a restart: I need xdebug for the right coverage anyway... So my real issue is actually sebastianbergmann/phpunit#3047. So I don't think there is anything to fix on XdebugHandler side in the end... That said this report might help you for a weird case if that ever happens^^
🍻 I'm actually passing on that one as I drank the whole week & day... But enjoy yours! |
Well, php tries to run its binary as a script which I guess results in that output.
You can check for |
I think it's easier to do by setting |
Sure, but it's either going to be your main box script (or something else). But the override variable in the PhpUnit config would be neat as well. |
No description provided.