Closed bitwombat closed 2 years ago
In order to correct this, we'll need someone with access to WSL2 and a vested interest in correcting it. Know anyone? I'm sure that may come across as smart-assed but that's really who would be best to submit a PR on this.
Hi Tom - Have enjoyed Doctrine for years, so would like to try to contribute. I'm not familiar with the codebase but could help by testing.
If that's not useful, I'll be able to have a crack at it in a few weeks.
I hope I didn't come across as short. In retrospect, I was worried I did.
This enhancement doesn't NEED WSL2 but would benefit from a user who can duplicate the issue. I'm worried the issue isn't duplicatable on standard *nix distributions.
Not short! You included a caveat anyway :) Plus, as saints, open source maintainers get extra leeway and benefit of the doubt.
I just duplicated it on my Ubuntu setup.
$ rm vendor/bin/doctrine-module
$ cp vendor/doctrine/doctrine-module/bin/doctrine-module vendor/bin
$ doctrine-module
PHP Warning: include(doctrine-module.php): failed to open stream: No such file or directory in /app/platform/product-app/vendor/bin/doctrine-module on line 3
Warning: include(doctrine-module.php): failed to open stream: No such file or directory in /app/platform/product-app/vendor/bin/doctrine-module on line 3
PHP Warning: include(): Failed opening 'doctrine-module.php' for inclusion (include_path='.:/usr/local/lib/php') in /app/platform/product-app/vendor/bin/doctrine-module on line 3
Warning: include(): Failed opening 'doctrine-module.php' for inclusion (include_path='.:/usr/local/lib/php') in /app/platform/product-app/vendor/bin/doctrine-module on line 3
It looks to me like a simple "include failed because I'm not in the dir I thought I was in".
I'm fibbing a little - I'm running PHP inside a docker container. But I don't think that's contributing, since the include is path-less, and the doctrine-module.php
file is not in vendor/bin, so that's what's making the include fail.
Can you duplicate it without manually moving it? Can composer put it in the bin dir as a non-symlink?
Doesn't look like it: https://getcomposer.org/doc/06-config.md#bin-compat
The manual/composer part doesn't really matter. Doctrine-module can't load if it's not a symlink, unlike the other inhabitants of vendor/bin/
. This seems to be due to its direct include, instead of relying on autoload.
Don't know if it is actually the same but I do believe this is at least similar to https://github.com/doctrine/orm/issues/8563 where changing bin/doctrine
to
#!/usr/bin/env php
<?php
include(__DIR__ . '/doctrine.php');
Solved the issue.
Changing bin/doctrine-module
to
#!/usr/bin/env php
<?php
include(__DIR__ . '/doctrine-module.php');
Fixes the issue in my case, though I did not invest any time trying to recreate the environment described here (setting up symlinks). I am using WSL2, though the application is running in a docker container.
@bitwombat could you perhaps try this solution in your setup?
That didn't work.
Because composer is copying vendor/doctrine/doctrine-module/bin
into vendor/bin
, it has to be:
include(__DIR__ . '/../doctrine/doctrine-module/bin/doctrine-module.php');
Taking a sample of my vendor/bin
dir, I see that doctrine
and doctrine-dbal
both do this too, as well as codecept
. But phpmd
, phpcs
, codecept
and laminas-development-mode
all load autoload and then new
something, which would be robust to them being symlinks or copied in.
I appreciate your investigation into this windows issue. Since you have examples of working bin dir code, how about putting in a PR with the modified doctrine-module?
@bitwombat Could it be that you are using an old version of composer? For me with composer 2.1.8 the solution with __DIR__
works on WSL2. No need for bin-compat: symlink
. This is the same settings as it is used in doctrine/orm.
Composer automatically creates a proxy file. For doctrine/orm, i.e. for vendor/bin/doctrine
this looks like this:
#!/usr/bin/env php
<?php
/**
* Proxy PHP file generated by Composer
*
* This file includes the referenced bin path (../doctrine/orm/bin/doctrine) using eval to remove the shebang if present
*
* @generated
*/
$binPath = realpath(__DIR__ . "/" . '../doctrine/orm/bin/doctrine');
$contents = file_get_contents($binPath);
$contents = preg_replace('{^#!/.+\r?\n<\?(php)?}', '', $contents, 1, $replaced);
if ($replaced) {
$contents = strtr($contents, array(
'__FILE__' => var_export($binPath, true),
'__DIR__' => var_export(dirname($binPath), true),
));
eval($contents);
exit(0);
}
include $binPath;
I think for DoctrineModule we should go the same way, i.e. changing it to include(__DIR__ . '/doctrine-module.php');
.
"Composer automatically creates a proxy file"
Yeah, you lost me.
I was using composer 2.1.5.
Good, then I suggest we use include(__DIR__ . '/doctrine-module.php');
. I'll create a PR in a second.
This happens because Composer detects it's running in WSL2 and copies files into
vendor/bin/
for some reason. The logic invendor/bin/doctrine-module
expects__DIR__
to be../doctrine-module/bin
, which it is whenvendor/bin/doctrine-module
is a symlink (ie. it gets followed).A workaround is to configure Composer to always make symlinks:
I don't believe this is a composer issue.
doctrine-module
should not be relying on symlink resolution to../doctrine-module/bin/doctrine-module
in order to work. Other vendor/bin files seem to work by loading autoload.php and newing an object.