Skip to content

Commit

Permalink
Merge pull request #3 from codebymikey/composer2-promise
Browse files Browse the repository at this point in the history
Composer 2 - installed library folders are empty
  • Loading branch information
codebymikey authored Feb 22, 2021
2 parents e3095c0 + 286b9d6 commit b58b669
Show file tree
Hide file tree
Showing 7 changed files with 341 additions and 21 deletions.
36 changes: 36 additions & 0 deletions .lando.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: drupal-libaries-installer

services:
app: &appserver
type: php:7.2
via: cli
composer_version: 1.10.20
xdebug: false
overrides:
environment:
PHP_IDE_CONFIG: "serverName=appserver"
XDEBUG_CONFIG: ""
XDEBUG_MODE: debug
config:
php: .php.ini
app2:
<<: *appserver
composer_version: 2

tooling:
composer: { service: app, cmd: /app/vendor/bin/composer, description: Run local Composer }
composer1: { service: app, cmd: /usr/local/bin/composer, description: Run Composer 1 }
composer2: { service: app2, cmd: /usr/local/bin/composer, description: Run Composer 2 }

xdebug-on:
description: Enable xdebug.
cmd:
- app: &xdebug_on docker-php-ext-enable xdebug 2>/dev/null && pkill -o -USR2 php-fpm && echo "Enabled xdebug"
- app2: *xdebug_on
user: root
xdebug-off:
description: Disable xdebug.
cmd:
- app: &xdebug_off rm -rf /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && pkill -o -USR2 php-fpm && echo "Disabled xdebug"
- app2: *xdebug_off
user: root
13 changes: 13 additions & 0 deletions .php.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[xdebug]
; https://xdebug.org/docs/all_settings
xdebug.show_exception_trace = 0
xdebug.max_nesting_level = 9999
xdebug.idekey = PHPSTORM
# For xdebug 3 - https://xdebug.org/docs/upgrade_guide
xdebug.mode = debug
; Start only when triggered.
xdebug.start_with_request = trigger
xdebug.client_host = host.docker.internal
xdebug.connect_timeout_ms = 200
xdebug.client_port = 9000
; xdebug.discover_client_host = false
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
1.4.1 / 2021-02-22
========================
* Add better Composer 2 support.

* Fix issue where libraries could not be downloaded on an empty cache, creating an empty folder instead.

Composer 2 introduces additional steps to [`DownloaderInterface`][composer-2-upgrade], which
needed integration as well as support for resolving the promises properly. [Additional reference][composer-2-download-support].
* Support parallel library downloads on Composer 2, while keeping existing synchronous download support on Composer 1.
* Fix issue with the plugin failing early if the plugin package is an `AliasPackage`.

1.4.0 / 2020-11-23
========================
* Add Composer 2 support.
Expand Down Expand Up @@ -38,4 +49,6 @@ definition for supporting:
========================
* Initial MVP plugin.

[composer-2-upgrade]: https://getcomposer.org/upgrade/UPGRADE-2.0.md
[composer-2-download-support]: https://github.com/composer/composer/issues/9209
[ckeditor-downloads]: https://github.com/balbuf/drupal-libraries-installer/issues/6
9 changes: 9 additions & 0 deletions example/project/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,12 @@
Demo root project integrating with Drupal libraries installer.

Update locally after committing by running `composer update zodiacmedia/drupal-libraries-installer`.

Or symlink to a copy of the current root project with:

```bash
# Enable "symlink-root-project" mode (--json requires composer 2).
composer config --json extra.symlink-root-project true
# Apply the symlink.
composer update --lock
```
25 changes: 25 additions & 0 deletions example/project/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,38 @@
"zodiacmedia/drupal-libraries-installer": "*@dev",
"zodiacmedia/drupal-libraries-installer-demo-dependency": "*@dev"
},
"require-dev": {
"composer/composer": "^1.10"
},
"autoload": {
"classmap": [
"scripts/composer/ScriptHandler.php"
]
},
"scripts": {
"preSymlinkMainProject": "ExampleDrupalLibrariesProject\\composer\\ScriptHandler::preInstall",
"symlinkMainProject": "ExampleDrupalLibrariesProject\\composer\\ScriptHandler::postInstall",
"pre-install-cmd": [
"@preSymlinkMainProject"
],
"pre-update-cmd": [
"@preSymlinkMainProject"
],
"post-install-cmd": [
"@symlinkMainProject"
],
"post-update-cmd": [
"@symlinkMainProject"
]
},
"config": {
"preferred-install": "source",
"classmap-authoritative": true,
"prepend-autoloader": false,
"optimize-autoloader": true
},
"extra": {
"symlink-root-project": false,
"installer-paths": {
"web/libraries/ckeditor/{$name}": [
"vendor:drupal-library_ckeditor"
Expand Down
128 changes: 128 additions & 0 deletions example/project/scripts/composer/ScriptHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

namespace ExampleDrupalLibrariesProject\composer;

use Composer\Script\Event;
use Composer\Util\Filesystem;
use Composer\Util\Platform;

/**
* The drupal-libraries-installer example project script handler.
*
* Attempts to symlink to the parent repository during development when
* "extra.symlink-root-project" is true.
*
* Mainly useful for testing certain behaviours without having to duplicate
* code or commit every time in order for composer to pull it in.
*
* Composer restricts symlinking to a path containing the current project.
* So we have to handle it manually with some hacky code.
*
* It's definitely not adviced as you could accidentally discard changes in
* your root project during an install/update if the appropriate event hooks
* are not triggered.
*/
class ScriptHandler {

protected const PACKAGE_NAME = 'zodiacmedia/drupal-libraries-installer';

/**
* Attempt to prepare for the post install/update.
*
* @param \Composer\Script\Event $event
* The composer event.
*/
public static function preInstall(Event $event) {
$composer = $event->getComposer();
$root_package = $composer->getPackage();
$locker = $composer->getLocker();
// Always attempt to clean up if:
// - the lock file is not present.
// - the lock file is outdated.
// - in the pre-update hook.
$originating_event = $event->getOriginatingEvent();
$originating_event_name = $originating_event ? $originating_event->getName() : NULL;
$needs_updating = $originating_event_name === 'pre-update-cmd' || !$locker->isLocked() || !$locker->isFresh();
$should_symlink = empty($root_package->getExtra()['symlink-root-project']);
if ($needs_updating || $should_symlink) {
// Don't symlink the root project. Attempt to remove any existing symlink.
$filesystem = new Filesystem();
$destination = static::getPackageDestination();
$destination = $filesystem->normalizePath($destination);

$is_junction = $filesystem->isJunction($destination);
$is_symlink = is_link($destination);
if ($is_junction || $is_symlink) {
$io = $event->getIO();
if ($is_junction) {
$io->writeError(sprintf('Removing existing junction for <info>%s</info>', static::PACKAGE_NAME));
}
elseif ($is_symlink) {
$io->writeError(sprintf('Removing existing symlink for <info>%s</info>', static::PACKAGE_NAME));
}
$filesystem->removeDirectory($destination);
}
}
}

/**
* Attempt to symlink to the parent repository during development.
*
* @param \Composer\Script\Event $event
* The composer event.
*/
public static function postInstall(Event $event) {
$root_package = $event->getComposer()->getPackage();
if (empty($root_package->getExtra()['symlink-root-project'])) {
// Do nothing.
return;
}

$io = $event->getIO();
$filesystem = new Filesystem();
$link = implode(DIRECTORY_SEPARATOR, ['..', '..', '..', '..']);
$destination = static::getPackageDestination();
$destination = $filesystem->normalizePath($destination);
if (Platform::isWindows()) {
if (!$filesystem->isJunction($destination)) {
$io->writeError(sprintf('Creating junction for <info>%s</info>', static::PACKAGE_NAME));
$filesystem->removeDirectory($destination);
$filesystem->junction($link, $destination);
}
}
else {
if (!$filesystem->isSymlinkedDirectory($destination)) {
$io->writeError(sprintf('Creating symlink for <info>%s</info>', static::PACKAGE_NAME));
// Attempt to remove the existing directory.
$filesystem->removeDirectory($destination);
if (!static::createSymlink($link, $destination)) {
throw new \RuntimeException(sprintf('Failed to create a symlink for "%s"', static::PACKAGE_NAME));
}
}
}
}

/**
* Returns the destination package directory.
*/
protected static function getPackageDestination() {
return implode(DIRECTORY_SEPARATOR, [
getcwd(),
'vendor',
'zodiacmedia',
'drupal-libraries-installer',
]);
}

/**
* Creates a symlink to the root project.
*/
protected static function createSymlink($target, $link) {
if (!function_exists('symlink')) {
return FALSE;
}

return @symlink($target, $link);
}

}
Loading

0 comments on commit b58b669

Please sign in to comment.