deployer
deployer copied to clipboard
PHPStan and PHPUnit tests fail because of autoloader issues in deployer
- Deployer version: v7.0.0-rc.8
- Deployment OS: Ubuntu
In our recipe we are using PHPStan and PHPUnit (amongst others) to test our recipe. When we started migrating to Deployer 7 our tests could not be executed anymore because of "Autoloader issues" It looks they are related to the fact Deployer only ships the Phar file itself in its releases (and not the files in src/ anymore)
PHPStan e.g throws:
------ ---------------------------------------------------------------------
Line tests/UrlMapperTest.php
------ ---------------------------------------------------------------------
91 Class Deployer\Exception\Exception not found.
💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
------ ---------------------------------------------------------------------
------ ---------------------------------------------------------------------
Line src/samples/magento2/deploy.php
------ ---------------------------------------------------------------------
18 Function set not found.
💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
21 Function set not found.
💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
24 Function set not found.
💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
33 Function set not found.
💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
------ ---------------------------------------------------------------------
Where PHPUnit will throw
PHPUnit\Framework\Exception: Class "Deployer\Exception\Exception" does not exist
including vendor/autoload.php, like suggested in #3070 e.g
require_once __DIR__ . '/../vendor/autoload.php';
does not do the trick
I already tried stuff like adding the phar file to composer's autoloader section but that did not work out (also not sure if that is even possible)
What did work though was adding a hard reference in composer.jsons autoload section to a deployer/deployer package outside of my project I am working on. e.g
"autoload": {
"files": [
"/home/rutger/packages/deployer/vendor/autoload.php"
]
}
But this of course will not work in CI/CD
I get the feeling this is a bug in Deployer 7, or some documentation on how to use autoloading this is missing. I hope something can be done about this.
For the record, PHPstorm has no issues finding the references inside the phar file, also the code just executes just fine It's the lack of ability to running PHPStan and PHPunit tests that is the issues here.
Upvote & Fund
- We're using Polar.sh so you can upvote and help fund this issue.
- We receive the funding once the issue is completed & confirmed by you.
- Thank you in advance for helping prioritize & fund our backlog.
Well, Deployer comes as a single phar archive. Not sure how to enable phpstan with it.
Maybe exclude deploy.php?
@antonmedv Thanks for the quick reply It's not just deploy.php, its our entire recipe which also holds a bunch of "normal classes" e.g
<?php
declare(strict_types=1);
namespace Some\Namespace;
use Deployer\Exception\Exception;
use function Deployer\get;
use function Deployer\run;
use function Deployer\writeln;
Class SomeClass
{
}
So excluding is not really an option here
For now, we a requiring deployer/deployer "from source" to work around the issue, but we'd really like to just require a stable tag/version and make sure the autoloader can find the classes inside the phar
I'm not sure if that is even possible though, so maybe this issue should be a "question" after all on how to get this resolved Maybe there is a trick to add an extra autloload.php file to the official release that points to the files in the phar?
I found https://github.com/composer/composer/issues/5036#issuecomment-467761062, and although such an approach works for our PHPUnit classes it does not for PHPStan
Via that threat I discovered "phive" (https://github.com/phar-io/phive) which might be of help (but need to test it myself)
@antonmedv
Could you please (re)consider to re-add the source to the releases?
N.B. I think it would make sense to distribute the phar without any (Composer) dependencies. Wasn't this also what https://github.com/deployphp/distribution was for?
Distributing it (only) as a phar via this composer package still has the downside of the dependencies in the composer.json/composer.lock file
If I look at e.g https://github.com/netz98/n98-magerun2#installation I see that they do NOT promote installing the phar via composer, but instead as a direct download. It is still an option to require it as composer (dev) dependency though
Yes, I think it is ok to add source back. With bundled bin.
I ran into a similar problem just now. I built a wrapper around Deployer and my CI started shouting at me because of missing Classes.
I see that you remove the require and autoload blocks from the composer.json on release. That means other packages can never depend on this package.
I assume this is done for performance reasons when running just the phar?
I could work around this by adding the dependencies and autoloading back on the consumer end when the sources are back in the release but that seems like a bad idea ...
Any ideas how to work around this?
I played around with this a bit more today and came up with the following ... well, I guess it's still a workaround:
Create a bootstrap file for PHPUnit (can be used for Psalm, PHPStan, ...):
require_once __DIR__ . '/../vendor/autoload.php';
\Phar::loadPhar(__DIR__ . '/../deployer.phar');
require_once 'phar://deployer.phar/vendor/autoload.php';
I also created a symlink to the acutal Phar wit a .phar extension in my package root. Mostly to make PHPStorm play nice since it only indexes Phars if they actually have the .phar extension. Added benefit is that I can easily update the path to the actual phar.
This might cause collisions with other packages in case I ever add a package as dependency that already exists in the phar but ... guess the risk is ok for now.
Not ideal, I'd be really happy if there was a "proper" dev package with all the sources and autoloading intact and a distro package that only contains the phar.
But as long as it works ...
Not ideal, I'd be really happy if there was a "proper" dev package with all the sources and autoloading intact and a distro package that only contains the phar.
I think we can create something like this.
Since I saw the source was added back again I gave this a second try At first glance it did not seem to work out, most likely as no autoload section was specified in Deployer's composer.json
For now I managed to move on again by adding this to our own recipe (which requires deployer/deployer:^7)
"autoload": {
"psr-4": {
"Deployer\\": "vendor/deployer/deployer/src",
}
},
It feels kind of hacky but at least we can move on now :)
-- edit --
Seems like the explicit auto-loading of "vendor/deployer/deployer/src/functions.php" made phpstan work, but it broke the recipe as it auto-loaded it twice. So, I removed that line from composer.json (also from the examle here) and replaced with a bootstrap file in my phpstan.neon instead
parameters:
bootstrapFiles:
- vendor/deployer/deployer/src/functions.php