composer icon indicating copy to clipboard operation
composer copied to clipboard

Issue with generated autoload_static.php on Windows

Open mistajolly opened this issue 9 years ago • 26 comments

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',
        )

mistajolly avatar Mar 13 '17 10:03 mistajolly

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

mistajolly avatar Mar 13 '17 10:03 mistajolly

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.

mistajolly avatar Mar 13 '17 13:03 mistajolly

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

alcohol avatar Mar 14 '17 09:03 alcohol

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?

alcohol avatar Mar 14 '17 09:03 alcohol

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.

mistajolly avatar Mar 14 '17 09:03 mistajolly

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?

alcohol avatar Mar 14 '17 10:03 alcohol

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.

mistajolly avatar Mar 14 '17 10:03 mistajolly

Oh ok. :-(

alcohol avatar Mar 14 '17 10:03 alcohol

@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.

curry684 avatar Mar 14 '17 10:03 curry684

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.

curry684 avatar Mar 14 '17 10:03 curry684

@alcohol were you thinking of #5564?

janpapenbrock avatar Mar 27 '17 20:03 janpapenbrock

Possibly. It has been quite a few days since I looked at this issue.

alcohol avatar Mar 28 '17 07:03 alcohol

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.

dg0yt avatar Jan 23 '21 09:01 dg0yt

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.

Seldaek avatar May 15 '22 11:05 Seldaek

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',
);

Alex300 avatar Oct 28 '23 11:10 Alex300

Ok reopening then.. What's the path you executed this in?

Seldaek avatar Oct 28 '23 11:10 Seldaek

@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.

Seldaek avatar Dec 18 '23 10:12 Seldaek

Sorry. I exeuted it from directory C:\OpenServerData\domains\lily-software.loc\public_html. composer.json is in this dir too.

Alex300 avatar Dec 18 '23 11:12 Alex300

Little bit confused as to why you renamed vendor to lib and then also added lib to the autoload psr4 configuration?

alcohol avatar Dec 18 '23 13:12 alcohol

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.

alcohol avatar Dec 18 '23 13:12 alcohol

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

Alex300 avatar Dec 20 '23 06:12 Alex300

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.

curry684 avatar Dec 20 '23 07:12 curry684

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 :-)

alcohol avatar Dec 20 '23 08:12 alcohol

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.

curry684 avatar Dec 20 '23 08:12 curry684

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

Alex300 avatar Dec 21 '23 13:12 Alex300

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"
},

Alex300 avatar Dec 24 '23 13:12 Alex300