Incompatibility with wikimedia/composer-merge-plugin
lpalgarvio opened this issue · 1 comments
Hello
Theres an incompatibility with wikimedia/composer-merge-plugin, a composer plugin used to merge in memory other composer.json files when issued install/update, including the extras key (where we have the drupal-libraries key). This normally involves at least composer.json and composer.local.json.
https://github.com/wikimedia/composer-merge-plugin
EDIT: There's a similar behavior with drupal-libraries-installer-plugin:
https://github.com/mnsami/composer-custom-directory-installer
mnsami/composer-custom-directory-installer#16
What happens is basically drupal-libraries-installer-plugin does not pick this merge.
If you place a print_r or file_put_contents in composer-merge-plugin/src/Merga/ExtraPackage.php in function mergeExtra, you will notice that the merge does happen. But after drupal-libraries-installer-plugin is run, so it never catches the merge.
Also, by using non-assoc array for libraries in drupal-libraries['libraries'], even if the merge would happen before, these would get replaced, as they are indexed numerically. Which i was noticing with my print_r/file_put_contents in composer-merge-plugin/src/Merga/ExtraPackage.php, function mergeExtra.
Therefor, the array must be built like this, with an associative array (indexed by keys):
{
"extra": {
"drupal-libraries": {
"libraries": {
"components/backbone": {
"name": "backbone",
"package": "components/backbone"
},
"ckeditor/ckeditor": {
"name": "ckeditor",
"package": "ckeditor/ckeditor"
}
}
}
}
Then it is fine for a merge.
For simplicity, you can from here eventually turn it into this:
{
"extra": {
"drupal-libraries": {
"libraries": {
"components/backbone": "backbone",
"ckeditor/ckeditor": "ckeditor"
}
}
}
}
Thus removing the need for an extra level in the array.
So i did this fix in my json files and now they are merging.
However, drupal-libraries-installer-plugin still does not catch it.
I researched a bit and couldn't find a way to prioritize/give weight/re-order plugin execution.
Having this in this specific order is not enough:
"require": {
"wikimedia/composer-merge-plugin": "~1.3",
"cweagans/composer-patches": "~1.3",
"composer/installers": "~1.0",
"robloach/component-installer": "~0.2",
"derhasi/composer-preserve-paths": "~0.1",
"davidbarratt/drupal-structure": "~1.0@alpha",
"drupal/drupal-library-installer-plugin": "~0.3",
"drupal/drupal": "7.*"
},
So i researched further.
I tried ProcessExecutor (use Composer\Util\ProcessExecutor)
Combined with EventSubscriberInterface (use Composer\EventDispatcher\EventSubscriberInterface), function getSubscribedEvents.
(and use Composer\Installer\PackageEvents and use Composer\Script\ScriptEvents).
For that i used events:
ScriptEvents::PRE_INSTALL_CMD
ScriptEvents::PRE_UPDATE_CMD
ScriptEvents::POST_INSTALL_CMD
ScriptEvents::POST_UPDATE_CMD
PackageEvents::PRE_PACKAGE_INSTALL
PackageEvents::PRE_PACKAGE_UPDATE
PackageEvents::POST_PACKAGE_INSTALL
PackageEvents::POST_PACKAGE_UPDATE
I got it to load drupal-libraries-installer-plugin and with a print_r/file_put_contents in DrupalLibraryInstaller function __construct, i was finally seeing the new picked merged json, with all the missing libraries.
However this would only happen on POST events.
Essentially voiding the use of getInstallPath.
I tried moving code around, functions, etc, but i could not manage to get it working.
I also tried adding the merge plugin to the autoloader and requirements of drupal-libraries-installer-plugin in composer.json, but it had no effect, and still launched drupal-libraries-installer-plugin first, to my understanding and frustration.
Do you have any ideas?
Here's a hacked version of your plugin demonstrating what i tried.
I took ideas from cweagans/composer-patches.