Skip to content
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

vendor/bin/doctrine-module only works if it's a symlink #729

Closed
bitwombat opened this issue Aug 22, 2021 · 12 comments · Fixed by #735
Closed

vendor/bin/doctrine-module only works if it's a symlink #729

bitwombat opened this issue Aug 22, 2021 · 12 comments · Fixed by #735
Labels
Milestone

Comments

@bitwombat
Copy link

$ doctrine-module orm:generate-proxies
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 4

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 4
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 4

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 4

This happens because Composer detects it's running in WSL2 and copies files into vendor/bin/ for some reason. The logic in vendor/bin/doctrine-module expects __DIR__ to be ../doctrine-module/bin, which it is when vendor/bin/doctrine-module is a symlink (ie. it gets followed).

A workaround is to configure Composer to always make symlinks:

    "config": {
        "bin-compat": "symlink"
    },

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.

@TomHAnderson
Copy link
Member

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.

@bitwombat
Copy link
Author

bitwombat commented Aug 24, 2021

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.

@TomHAnderson
Copy link
Member

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.

@bitwombat
Copy link
Author

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.

include('doctrine-module.php');

@TomHAnderson
Copy link
Member

Can you duplicate it without manually moving it? Can composer put it in the bin dir as a non-symlink?

@bitwombat
Copy link
Author

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.

@CardboardAgent
Copy link

Don't know if it is actually the same but I do believe this is at least similar to doctrine/orm#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?

@bitwombat
Copy link
Author

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.

@TomHAnderson
Copy link
Member

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?

@driehle
Copy link
Member

driehle commented Oct 17, 2021

@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');.

@bitwombat
Copy link
Author

"Composer automatically creates a proxy file"

Yeah, you lost me.

I was using composer 2.1.5.

@driehle
Copy link
Member

driehle commented Oct 18, 2021

Good, then I suggest we use include(__DIR__ . '/doctrine-module.php');. I'll create a PR in a second.

driehle added a commit to driehle/DoctrineModule that referenced this issue Oct 18, 2021
@driehle driehle added the Bug label Oct 18, 2021
@driehle driehle added this to the 4.1.3 milestone Oct 18, 2021
driehle added a commit that referenced this issue Oct 18, 2021
fix #729: fixed include path in bin/doctrine-module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants