Issue with generated autoload_static.php on Windows
Using standard laravel composer.json, diagnose is all ok.
When updating the $prefixDirsPsr4 array in autoload_static.php contains the wrong entry for 'App\'. Rather than a relative directory it uses an absolute path containing the windows drive letter. Strangely, the base install of laravel via composer works fine but this bug only shows on subsequent updates.
I can manually fix this by replacing 'W:\\ with __DIR__ . '/../..' .'.
'App\\' =>
array (
0 => 'W:\\/app',
)
should be
'App\\' =>
array (
0 => __DIR__ . '/../..' .'/app',
)
composer.json
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"require": {
"php": ">=5.6.4",
"laravel/framework": "5.4.*",
"laravel/tinker": "~1.0"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "~5.7"
},
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"post-root-package-install": [
"php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"php artisan key:generate"
],
"post-install-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postInstall",
"php artisan optimize"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"php artisan optimize"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true
}
}
Update: It seems that this is possibly caused by the Windows drive mapped to the root folder of the laravel app. I mapped the W: drive to the parent folder and the updates now work.
I am fairly confident we had a similar issue reported in the past. Not sure if it has been closed or resolved yet. I'll try and see if I can find it..
Can you provide more information about the paths involved btw? Root dir, mapped drive path, full absolute paths, which relative path from where to where (provide their absolute source and destination), etc?
Hopefully this helps.
Absolute path: \\server\websites\laravel\...{laravel composer.json}...
Mapping drive letter (W:) to \\server\websites\laravel\... has issues when generating autoload_static.php.
Mapping drive letter (W:) to \\server\websites\... then CD to laravel works.
I think there was an issue similar to this when your project directory had a name equal to one of your vendor directories. Can you try renaming laravel to something unique (non-vendor) and then map your drive back again to your project directory, see if that has any effect?
If it has no effect, then it would seem more related to the fact that the root directory is a mapped directory.
@curry684 you remember anything similar to this?
I used laravel as an example folder name but the actual folder has a different name.
Which suggests there is a problem with the root directory being mapped.
Oh ok. :-(
@alcohol think you're referring to https://github.com/composer/composer/issues/6108, it had a different cause in the end but it also pointed to issues with shortest path detection. I can't really reproduce it as I no longer have a Windows dev environment, doing everything in Ubuntu VM nowadays.
What seems to be happening is that, because the project is itself rooted in such a short folder (W:\app in this case) the Composer code decides an absolute path is shorter than ..\...\..\, which is technically correct but not quite practical.
Just tested some things with findShortestPath and it doesn't seem to be causing this. Next possible culprit would be https://github.com/composer/composer/blob/master/src/Composer/Autoload/AutoloadGenerator.php#L866:
if (empty($installPath)) {
$installPath = strtr(getcwd(), '\\', '/');
}
That's the part where the autoload prefixes are made relative to eachother, and this line fallbacks to an absolute path if the shared path component is empty I think, which would be the case if installing the project in a drive root.
@alcohol were you thinking of #5564?
Possibly. It has been quite a few days since I looked at this issue.
The issue still exists : With a Slim Framework app mounted as a Windows drive letter, the drive letter ends up in autoload_static.php for app paths added via psr-4. When mounting the project's parent folder to a drive letter, everythink works as expected.
I would like to add that it is not easy to arrive here, for people unfamiliar with Composer and autoloading. This is a significant barrier.
Closing as nobody cared to fix it in these many years, if it is still applicable do tell and I will reopen.
@dg0yt if you still have a repro case please do tell how it can be reproduced with all steps and all paths involved (symlink target/source, where composer is run, etc.). Then maybe there's a chance I can do something about it.
The issue still exists.
How to reproduce:
Latest version Composer for windows: https://getcomposer.org/download/
composer.json:
{
"name": "cotonti/cotonti",
"description": "Cotonti CMF",
"homepage": "https://www.cotonti.com/",
"license": "BSD 3-Clause",
"support": {
"source": "https://github.com/Cotonti/Cotonti",
"wiki": "https://www.cotonti.com/docs/"
},
"config": {
"vendor-dir": "lib"
},
"require": {
"php": ">=5.6",
"ext-gd": "*",
"ext-mbstring": "*",
"ext-json": "*",
"ext-hash": "*",
"ext-pdo": "*",
"league/flysystem": "^3.0",
"platformcommunity/flysystem-bunnycdn": "^3.0",
"league/flysystem-path-prefixing": "^3.3"
},
"autoload": {
"classmap": ["system/", "lib/cssmin.php", "lib/jsmin.php"],
"psr-4": {
"cot\\modules\\": "modules/",
"cot\\plugins\\": "plugins/",
"cot\\": "system/",
"": ["lib/"]
}
}
}
Run
> composer update
lib/composer/autoload_static.php contains:
public static $fallbackDirsPsr4 = array (
0 => 'C:\\OpenServerData\\domains\\lily-software.loc\\public_html\\lib',
);
Should be:
public static $fallbackDirsPsr4 = array (
0 => DIR . '/../..' . '/lib',
);
Ok reopening then.. What's the path you executed this in?
@Alex300 a 👍🏻 is not an answer to my question. I need to know the path you executed composer in to be able to try and reproduce.
Sorry. I exeuted it from directory C:\OpenServerData\domains\lily-software.loc\public_html. composer.json is in this dir too.
Little bit confused as to why you renamed vendor to lib and then also added lib to the autoload psr4 configuration?
Any chance you could get us some debugging output showing the values of these lines?
https://github.com/composer/composer/blob/main/src/Composer/Autoload/AutoloadGenerator.php#L1147-L1155
The "easiest" way to do this would be to run composer from source (git clone) instead of a phar binary.
Little bit confused as to why you renamed vendor to lib and then also added lib to the autoload psr4 configuration?
lib is the standard Cotonti folder for third-party libraries. That why I added it to the autoload psr4 configuration.
One of Cotonti developers asked to not leave the vendor directory in the root of the project. So I make lib also vendor dir.
Is this not a good idea?
Any chance you could get us some debugging output showing the values of these lines?
Will try
Is this not a good idea?
No, it's definitely not. The vendor folder is not "yours", and managed solely by Composer. Hacking into that structure will definitely cause serious problems. If anything, you should let Composer manage its vendor folder and use lib as a path repository if you can - it will install the packages into vendor then itself.
Looking at that site it seems like a very old and outdated project which had some kind of Composer support "tacked on" as an afterthought, while still polling on the frontpage how many people are using PHP 7 already, which was released on December 3rd 2015 little over 8 years ago. Its autoload configuration is downright broken and it seems to ship its own compiled Composer autoloader.
I would recommend migrating your project to a modern and supported framework like Symfony or Laravel.
That's a bit harsh maybe. It looks like @Alex300 is a big contributor to Cotonti. Maybe he is simply trying to modernize the framework/application? The way support for Composer was added does raise several questions. I get the impression it is not quite fully understood how Composer works and what Composer best practices are. But those are all things that could be addressed and/or answered. All of that is besides the point of this issue though. So lets stick to what is important, which is figuring out if there is a bug in the code that creates the autoload_static.php file or not :-)
Didn't see @Alex300 is in practice the sole maintainer of the project. Given what he is trying to do with mounting an entire folder in the root namespace, this is bound to cause grave issues and conflicts, as is committing a compiled autoloader to that same folder.
Mounting lib as a path repository instead as I suggested would probably fix and prevent many issues and allow you to use it as a module system of sorts, which I think is the intended result. Would require a lot of tweaking still to get working correctly.
No, it's definitely not. The vendor folder is not "yours", and managed solely by Composer. Hacking into that structure will definitely cause serious problems.
Ok, I see. So I will add lib/vendor directory and will fix composer.josn:
"config": {
"vendor-dir": "lib/vendor"
},
Or is it preferable to leave the vendor folder in the project root?
Thank you for advice
Any chance you could get us some debugging output showing the values of these lines?
I'll try to do it in the next few days
Maybe he is simply trying to modernize the framework/application?
Yes indeed
Any chance you could get us some debugging output showing the values of these lines?
$vendorPathCode: string(24) " => __DIR__ . '/..' . '/"
$vendorPharPathCode: string(36) " => 'phar://' . __DIR__ . '/..' . '/"
$appBaseDirCode: string(27) " => __DIR__ . '/../..' . '/"
$appBaseDirPharCode: string(39) " => 'phar://' . __DIR__ . '/../..' . '/"
$absoluteVendorPathCode: string(64) " => 'C:\\OpenServerData\\domains\\cotonti.loc\\public_html\\lib/"
$absoluteVendorPharPathCode: string(71) " => 'phar://C:\\OpenServerData\\domains\\cotonti.loc\\public_html\\lib/"
$absoluteAppBaseDirCode: string(59) " => 'C:\\OpenServerData\\domains\\cotonti.loc\\public_html/"
$absoluteAppBaseDirPharCode: string(66) " => 'phar://C:\\OpenServerData\\domains\\cotonti.loc\\public_html/"
Ok, I see. So I will add lib/vendor directory and will fix composer.josn:
So, after debugging vars above, I set vendor to lib/vendor directory and the error disappeared
"config": {
"vendor-dir": "lib/vendor"
},