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
Prefix all code bundled in PHAR distribution with unique namesspaces #3086
Conversation
Thanks for working on this @kambo-1st. I'll try to get back to PHP-Scoper this week and push a bit forward things there. Meanwhile don't hesitate to open issues on the repo for the problems encountered. I also highly recommend to have some e2e tests using the scoped PHAR if that's not the case trying out some cases relying on shared constants or interfaces. You have some examples on how I did it in PHP-Scoper itself. If you need to ping me directly the easiest way is Twitter/Slack |
@kambo-1st @theofidry Has there been progress? Thanks! |
I'm hacking on the ongoing issues on PHP-Scoper. However I don't think any of them are blockers to get a working isolated PHAR; just for the merge as you don't want something too ugly/brittle merged. For the rest sorry I'm not aware of any progress, maybe @kambo-1st was a bit busy last week :) |
@theofidry is right, there aren’t any blocking issues in PHP-Scoper for building working phar file (at least at this moment), but I indeed not happy about “proof of concept” solution proposed in this pull request. From my point of view humbug/php-scoper#192 will be need for the final version. In the meantime, I will prepare some e2e tests for the phar file, there is still a huge probability of some other issues. |
Codecov Report
@@ Coverage Diff @@
## master #3086 +/- ##
========================================
Coverage 81.5% 81.5%
Complexity 3412 3412
========================================
Files 137 137
Lines 9014 9014
========================================
Hits 7347 7347
Misses 1667 1667 Continue to review full report at Codecov.
|
@kambo-1st Thank you. I agree that we should wait for a release that includes humbug/php-scoper#192. |
Whilst humbug/php-scoper#192 is required for the final version, @kambo-1st found an acceptable workaround for now. So I would suggest to keep going on the progress as I suspect there is a lot more to do still |
4840beb
to
7a7a0c8
Compare
build/scoper.inc.php
Outdated
'PHP_Token', | ||
'PHP_TokenWithScope', | ||
'PHP_TokenWithScopeAndVisibility', | ||
'PHP_Token_ABSTRACT', |
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.
are those classes or constants?
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.
They are classes without any namespace.
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.
php-token-stream
unfortunately does not use namespaces.
@theofidry Would it be possible to add support for whitelisting classes using PHP_Token_*
or something along those lines?
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.
But do they need to be whitelisted?
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.
@sebastianbergmann that could be done. I opened humbug/php-scoper#227 for it
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.
@theofidry PHP_Token_* classes must be whitelisted, because they are instantiated dynamically (https://github.com/sebastianbergmann/php-token-stream/blob/711ca0c13c66f6b66c2ecb586e56415815034330/src/Token/Stream.php#L182). Prefixing break 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.
Maybe this could be fixed by having a patcher for this line instead?
build.xml
Outdated
@@ -50,6 +50,11 @@ | |||
<arg value="phpunit/php-invoker:^2.0"/> | |||
</exec> | |||
|
|||
<exec executable="${basedir}/build/tools/composer" taskname="composer"> |
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.
@theofidry Is php-scoper available as a PHAR? If so, @kambo-1st, I would prefer to have that PHAR in build/tools
and used here.
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 should. There was a problem with the last version so it didn't get a PHAR but that shouldn't happen anymore.
However I would recommend to switch to a PHAR at the last moment since it makes it much harder to debug/fix in the meantime.
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.
Sure, using Composer for the moment is fine until we are sure that 1) php-scoper can handle PHPUnit and 2) PHPUnit uses php-scoper correctly.
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 also prefer PHAR. But as @theofidry mentioned it wasn't available for latest version. When it will be available, i will use it.
I'm trying to prepare 0.9 which should provide some nice features:
Is there anything else that is blocking here or that could help? |
@kambo-1st What is the status here? Can you answer @theofidry's question? Thanks! |
1 similar comment
@kambo-1st What is the status here? Can you answer @theofidry's question? Thanks! |
Quick heads up: PHP-Scoper 0.9.1 has been tagged, it provides:
which should make all of your work easier :) |
Thank you, @theofidry. I hope to hear from @kambo-1st soon. Otherwise I'll have to look into this myself again. |
Sorry for keep you waiting. I'll look into it this week. |
Quick update, new features in scooper look promising, especially wildcards. At this moment I preparing some tests. |
I tried to follow up on this pull request and encountered an issue with php-scoper. The rest seems to work. |
429d533
to
47ecfd7
Compare
This reverts commit 47ecfd7.
@sebastianfeldmann Interesting issue, it seems, that this does not have any effect on the builded phar file, at least on the first sight. This is because there is still a proper alias defininition on the end of the file. \class_alias('PHPUnit\\PHPUnit_Framework_MockObject_MockObject', 'PHPUnit_Framework_MockObject_MockObject', \false); |
For me executing the PHAR fails instantly because the Mock class can not be found |
Should be better with https://github.com/humbug/php-scoper/releases/tag/0.11.1 |
I can't see any difference :( $whitelistClasses = [
'PHPUnit\*',
'SebastianBergmann\CodeCoverage\*',
'PharIo\*',
'PHP_Token*',
];
return [
'whitelist' => $whitelistClasses,
]; and <?php
namespace PHPUnit;
/**
* A PHP token.
*/
abstract class PHP_Token
{
...
}
\class_alias('PHPUnit\\PHP_Token', 'PHP_Token', \false); I'm not sure we are looking for the same issue. Can we agree, that with the given whitelist this class should not be prefixed with the |
Arg forgot to check if the whildcard works on global classes like that. That said I would argue you should be able to do without: the class aliasing should do the trick and doing without is really tricky |
I've had a very quick look and will try to dig into it more, but from what I see so far:
|
@theofidry Just out of curiosity: Why would, for the phar which uses a static require list, the |
For classes if you were to require all the files it wouldn’t be an issue,
but it would still be for functions (cf the PHPScoper doc I can’t link it
atm).
That said for now I’m trying to make it work outside the PHAR first once
it’s done it will be easy to tell where the proble comes from.
…On Sun 11 Nov 2018 at 14:38, Arne Blankerts ***@***.***> wrote:
@theofidry <https://github.com/theofidry> Just out of curiosity: Why
would, for the phar which uses a static require list, the
scoper-autoload.php be needed? And even if it wouldn't be a static
require list but an actual autoload being based on a classmap?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3086 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AE76gcOxGkmfBXby4zZW0fgf_uMjlhoBks5uuChUgaJpZM4TLqmm>
.
|
@sebastianfeldmann I did a PR with some fixes. There is some stuff to not merge but I would keep them for now and remove them later when everything is working. My process:
I released a new version of PHP-Scoper to fix a bug related to the whitelisting feature. From what I see most of the remaining failures are due to class strings incorrectly being scoped or not scoped, if you check the diff of my PR you will see what I mean. There might be one or two failures which requires a big more of digging than that but that should already be a solid start. Once this step is done, what is left is bundling it in the PHAR and ensuring the PHAR works as expected. |
@theofidry I'm still a bit confused.
|
I've added that doc entry for it, you might want to take a look: https://github.com/humbug/php-scoper/#implementation-insights
A few reasons:
Whereas always prefixing and appending class aliases when appropriate is very straightforward.
Because whitelisting a whole namespace is easier to achieve without breaking much stuff than selectively whitelisting some elements that way. But note that it has some limitations as well cf. namespace whitelisting I understand the feeling that always prefixing and adding a class alias feels weird, but whitelisting some elements just didn't work well enough. |
@sebastianfeldmann Not sure it matters, but |
That's good news. |
Is it really an issue though? As I said before: before shopping the PHAR
you need to make sure the scoping is done right and from what I see in the
tests there is still 1 or 2 cases that should be inspected.
The scoper-autoload.php file is in vendor next to the Composer autoload.php
…On Mon 19 Nov 2018 at 14:22, Sebastian Feldmann ***@***.***> wrote:
That's good news.
Our current issue is, that the PHP_Token* classes get prefixed by
php-scoper. And because of those classes getting created dynamically
those dynamic instantiations fail because of the wrong namespace.
php-scoper puts the right fallback class_alias statements in place but
because of the current php-ab autoloading the classes can't be loaded.
php-ab knows the classes by their new prefixed namespace, and if you
instantiate them with the original class names php-ab has no knowledge
about them and can't load the right file.
@theofidry <https://github.com/theofidry> was talking about using the
scoper-autoload.php file, but so far I'm not seeing this file anywhere.
I'll try to hardcode the original PHP_Token* classes into the PHAR
autoloader to make sure this is the only problem left to solve and if
that's the case try to figure out a good way to solve it.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3086 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AE76gVG97B8IrXao7UIW8PiZgScpYWUqks5uwrCYgaJpZM4TLqmm>
.
|
For the record: On top of that, the generated "autoload" is a static require list. That means, all files will be required even before one single line of other code is being executed. Any Or in other words: There's not autoloading in phar mode. Given that Or am I missing the point? ;) |
@theseer that was my understanding and it should make it easy. I was just pointing out that getting the scoping working outside the PHAR is needed first as it makes it easier to know where a potential issue might come from as well as allows to easily test the scoped code by running the (non-scoped) test suite against it |
@theseer the problem is/was, that @theofidry currently I'm creating the scoped files with this ant task <exec executable="${basedir}/build/tools/php-scoper" taskname="php-scoper">
<arg value="add-prefix" />
<arg value="--no-ansi" />
<arg value="--force" />
<arg value="--config" />
<arg path="${basedir}/build/scoper.inc.php" />
<arg value="--no-interaction" />
<arg value="--stop-on-failure" />
<arg value="--output-dir" />
<arg path="${basedir}/build/phar-scoped" />
<arg value="--prefix" />
<arg value="PHPUnit" />
<arg path="${basedir}/build/phar" />
</exec>
PHAR generation for PHPUnit works like this:
Now there is a 2.a where everything in With the command above no |
I've checked this morning, with the following configuration: scoper.inc.php<?php
declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return [
'whitelist-global-classes' => false,
'whitelist' => [
'PHPUnit\*',
'SebastianBergmann\CodeCoverage\*',
'PharIo\*',
'PHP_Token*',
'PHPUnit_Framework_MockObject_MockObject',
'MultiDependencyTest',
],
]; When I use the following script: compile.sh
Which in short scope the whole project except the tests, dump the autoloader and run the scoped PHPUnit agains the tests, it mostly works. There is one failure related to an extension relying on the So what is left is:
@sebastianfeldmann looks good to me, but I think you are missing dumping the autoloader: all the namespaces and everything changes so the Composer autoloader needs to be dumped again. PHP-Scoper could avoid that by either doing it itself (like I do in Box, but this is why I'm not keen to do it in PHP-Scoper, it is never a sure solution) or Scoper the autoloader itself (quite complex so I'm not really willing to do that) but meanwhile it is necessary otherwise the whole autoloading will be completely broken. |
I'm not sure I understand how that would be logically possible. As with autoloading this of course is a all or nothing approach. If not all units are defined and found at build time, the list will be incomplete. I guess, I'm just trying to figure out whether or not there's something I can change or even have to fix in Given that running php-scoper doesn't change anything but the names, no dependency changed. So if |
@theseer I can see one scenario when static sorting fails: in the case of circular dependencies. but that would require multiple classes defined in the same file. not sure if that's the case here. |
Afaik, PHP can't do resolve circular dependencies on this level. |
Does this topological sorting handles class aliasing? |
No. Good point. I guess that would require finding and "understanding" the class_alias function call. Currently the parser looks up class/interface/trait definitions as well as their extends, implements and uses. That's a problem, or is it? |
I think that could be the source of the issue since almost all whitelisted code get aliased. But since you are scanning the files first and operate a sorting, maybe adding support for the class aliasing wouldn't be too big of a deal? |
After being called out yesterday by @sebastianbergmann at the php user group Frankfurt I immediately after arriving at home sat down and made some checks I had only layed out in my head so far. So I rebased to the latest master. I used the created PHAR to run all phpunit 8 ready test suites on my machine (not much but some) and everything worked. When I run the phpunit test suite with the created phar file I get one error.
I'm not quite sure why exactly this one is crashing because the other tests in that class look quite similar. You can check by creating your own scoped phar by:
Note to myself: social pressure works ;) |
It was not my intention to "call you out" and "build up pressure". Quite the opposite: I wanted to you credit for the work you did. Sorry if I messed that up. I think it is time we closed this pull request and @sebastianfeldmann sends a new pull request with the current state of his work. This would make it a lot easier for me to work on this. |
Don't worry, you messed nothing up :) |
Superseded by #3575. |
This is a proof of concept for the #2015 it's by no means a final solution. For further detail please look at comments for #2015.