composer/installers

Composer 1 vs 2: Adds extra sites/ directory for Drupal 7 installation

paul-m opened this issue · 3 comments

Thanks in advance for any effort at all on this. :-)

I use composer-installers to put Drupal stuff where it belongs. See my minimal composer.json below for an example of how this works.

Using Composer 1, this works as expected: Drupal core is placed in docroot/ without any problem.

Using Composer 2, everything works as expected again, except for one extra bit of path is inserted to docroot/sites/sites/. It should only be docroot/sites/.

This doesn't make a lot of sense because the whole package should just be placed within the custom directory. This is the only directory that has any special cases... Other directories within drupal/drupal are not misplaced.

This issue only happens with custom path configurations for both drupal-core and drupal-module. I would expect that if there were a problem, it would be with one overwriting the other, not adding a bonus directory.

% composer show composer/installers | grep versions
versions : * v1.10.0
% composer --version
Composer version 2.0.11 2021-02-24 14:57:23

composer.json:

{
    "name": "foo/bar",
    "type": "project",
    "config": {
        "sort-packages": true,
        "platform": {
            "php": "7.3"
        }
    },
    "require": {
        "composer/installers": "@stable",
        "drupal/ctools": "1.17",
        "drupal/drupal": "7.78"
    },
    "extra": {
        "installer-paths": {
            "docroot": [
                "type:drupal-core"
            ],
            "docroot/sites/all/modules/contrib/{$name}": [
                "type:drupal-module"
            ]
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "repositories": {
        "drupal": {
            "type": "composer",
            "url": "https://packages.drupal.org/7"
        }
    }
}

Ok this is in fact a problem in Composer itself and not related to the paths. It's merely triggered by your custom paths because that creates an intersection of two packages being installed in the same directories.

In Composer 1 it worked fine because things happened more sequentially, so it installs drupal/drupal first, then puts drupal/ctools in the docroot/sites/all/modules/contrib/... dir and all is well.

What happens in Composer 2 due to the parallelisation of installs is something like this:

  • It prepares installation for drupal/drupal so docroot gets created
  • It prepares installation for drupal/ctools, so docroot/sites/all/modules/contrib gets created
  • It now extracts the drupal/drupal archive into docroot, but as the dir exists we have to move all the contents one by one, which is fine until it reaches the sites dir, which exists already due to the step above. That made rename() put the drupal/drupal's sites directory inside docroot/sites/, so you end up with the duplicated ../sites/sites here.

Anyway should be fixed with latest Composer snapshot, and the next 2.0 release will include the fix.

Can confirm: composer selfupdate --snapshot cures this.

I hope 2.0.12 gets released soon. :-)

It's out now