Skip to content

Commit b58b669

Browse files
authored
Merge pull request zodiacmedia#3 from codebymikey/composer2-promise
Composer 2 - installed library folders are empty
2 parents e3095c0 + 286b9d6 commit b58b669

File tree

7 files changed

+341
-21
lines changed

7 files changed

+341
-21
lines changed

.lando.yml

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: drupal-libaries-installer
2+
3+
services:
4+
app: &appserver
5+
type: php:7.2
6+
via: cli
7+
composer_version: 1.10.20
8+
xdebug: false
9+
overrides:
10+
environment:
11+
PHP_IDE_CONFIG: "serverName=appserver"
12+
XDEBUG_CONFIG: ""
13+
XDEBUG_MODE: debug
14+
config:
15+
php: .php.ini
16+
app2:
17+
<<: *appserver
18+
composer_version: 2
19+
20+
tooling:
21+
composer: { service: app, cmd: /app/vendor/bin/composer, description: Run local Composer }
22+
composer1: { service: app, cmd: /usr/local/bin/composer, description: Run Composer 1 }
23+
composer2: { service: app2, cmd: /usr/local/bin/composer, description: Run Composer 2 }
24+
25+
xdebug-on:
26+
description: Enable xdebug.
27+
cmd:
28+
- app: &xdebug_on docker-php-ext-enable xdebug 2>/dev/null && pkill -o -USR2 php-fpm && echo "Enabled xdebug"
29+
- app2: *xdebug_on
30+
user: root
31+
xdebug-off:
32+
description: Disable xdebug.
33+
cmd:
34+
- app: &xdebug_off rm -rf /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && pkill -o -USR2 php-fpm && echo "Disabled xdebug"
35+
- app2: *xdebug_off
36+
user: root

.php.ini

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[xdebug]
2+
; https://xdebug.org/docs/all_settings
3+
xdebug.show_exception_trace = 0
4+
xdebug.max_nesting_level = 9999
5+
xdebug.idekey = PHPSTORM
6+
# For xdebug 3 - https://xdebug.org/docs/upgrade_guide
7+
xdebug.mode = debug
8+
; Start only when triggered.
9+
xdebug.start_with_request = trigger
10+
xdebug.client_host = host.docker.internal
11+
xdebug.connect_timeout_ms = 200
12+
xdebug.client_port = 9000
13+
; xdebug.discover_client_host = false

CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
1.4.1 / 2021-02-22
2+
========================
3+
* Add better Composer 2 support.
4+
5+
* Fix issue where libraries could not be downloaded on an empty cache, creating an empty folder instead.
6+
7+
Composer 2 introduces additional steps to [`DownloaderInterface`][composer-2-upgrade], which
8+
needed integration as well as support for resolving the promises properly. [Additional reference][composer-2-download-support].
9+
* Support parallel library downloads on Composer 2, while keeping existing synchronous download support on Composer 1.
10+
* Fix issue with the plugin failing early if the plugin package is an `AliasPackage`.
11+
112
1.4.0 / 2020-11-23
213
========================
314
* Add Composer 2 support.
@@ -38,4 +49,6 @@ definition for supporting:
3849
========================
3950
* Initial MVP plugin.
4051

52+
[composer-2-upgrade]: https://getcomposer.org/upgrade/UPGRADE-2.0.md
53+
[composer-2-download-support]: https://github.com/composer/composer/issues/9209
4154
[ckeditor-downloads]: https://github.com/balbuf/drupal-libraries-installer/issues/6

example/project/README.md

+9
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,12 @@
33
Demo root project integrating with Drupal libraries installer.
44

55
Update locally after committing by running `composer update zodiacmedia/drupal-libraries-installer`.
6+
7+
Or symlink to a copy of the current root project with:
8+
9+
```bash
10+
# Enable "symlink-root-project" mode (--json requires composer 2).
11+
composer config --json extra.symlink-root-project true
12+
# Apply the symlink.
13+
composer update --lock
14+
```

example/project/composer.json

+25
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,38 @@
2626
"zodiacmedia/drupal-libraries-installer": "*@dev",
2727
"zodiacmedia/drupal-libraries-installer-demo-dependency": "*@dev"
2828
},
29+
"require-dev": {
30+
"composer/composer": "^1.10"
31+
},
32+
"autoload": {
33+
"classmap": [
34+
"scripts/composer/ScriptHandler.php"
35+
]
36+
},
37+
"scripts": {
38+
"preSymlinkMainProject": "ExampleDrupalLibrariesProject\\composer\\ScriptHandler::preInstall",
39+
"symlinkMainProject": "ExampleDrupalLibrariesProject\\composer\\ScriptHandler::postInstall",
40+
"pre-install-cmd": [
41+
"@preSymlinkMainProject"
42+
],
43+
"pre-update-cmd": [
44+
"@preSymlinkMainProject"
45+
],
46+
"post-install-cmd": [
47+
"@symlinkMainProject"
48+
],
49+
"post-update-cmd": [
50+
"@symlinkMainProject"
51+
]
52+
},
2953
"config": {
3054
"preferred-install": "source",
3155
"classmap-authoritative": true,
3256
"prepend-autoloader": false,
3357
"optimize-autoloader": true
3458
},
3559
"extra": {
60+
"symlink-root-project": false,
3661
"installer-paths": {
3762
"web/libraries/ckeditor/{$name}": [
3863
"vendor:drupal-library_ckeditor"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php
2+
3+
namespace ExampleDrupalLibrariesProject\composer;
4+
5+
use Composer\Script\Event;
6+
use Composer\Util\Filesystem;
7+
use Composer\Util\Platform;
8+
9+
/**
10+
* The drupal-libraries-installer example project script handler.
11+
*
12+
* Attempts to symlink to the parent repository during development when
13+
* "extra.symlink-root-project" is true.
14+
*
15+
* Mainly useful for testing certain behaviours without having to duplicate
16+
* code or commit every time in order for composer to pull it in.
17+
*
18+
* Composer restricts symlinking to a path containing the current project.
19+
* So we have to handle it manually with some hacky code.
20+
*
21+
* It's definitely not adviced as you could accidentally discard changes in
22+
* your root project during an install/update if the appropriate event hooks
23+
* are not triggered.
24+
*/
25+
class ScriptHandler {
26+
27+
protected const PACKAGE_NAME = 'zodiacmedia/drupal-libraries-installer';
28+
29+
/**
30+
* Attempt to prepare for the post install/update.
31+
*
32+
* @param \Composer\Script\Event $event
33+
* The composer event.
34+
*/
35+
public static function preInstall(Event $event) {
36+
$composer = $event->getComposer();
37+
$root_package = $composer->getPackage();
38+
$locker = $composer->getLocker();
39+
// Always attempt to clean up if:
40+
// - the lock file is not present.
41+
// - the lock file is outdated.
42+
// - in the pre-update hook.
43+
$originating_event = $event->getOriginatingEvent();
44+
$originating_event_name = $originating_event ? $originating_event->getName() : NULL;
45+
$needs_updating = $originating_event_name === 'pre-update-cmd' || !$locker->isLocked() || !$locker->isFresh();
46+
$should_symlink = empty($root_package->getExtra()['symlink-root-project']);
47+
if ($needs_updating || $should_symlink) {
48+
// Don't symlink the root project. Attempt to remove any existing symlink.
49+
$filesystem = new Filesystem();
50+
$destination = static::getPackageDestination();
51+
$destination = $filesystem->normalizePath($destination);
52+
53+
$is_junction = $filesystem->isJunction($destination);
54+
$is_symlink = is_link($destination);
55+
if ($is_junction || $is_symlink) {
56+
$io = $event->getIO();
57+
if ($is_junction) {
58+
$io->writeError(sprintf('Removing existing junction for <info>%s</info>', static::PACKAGE_NAME));
59+
}
60+
elseif ($is_symlink) {
61+
$io->writeError(sprintf('Removing existing symlink for <info>%s</info>', static::PACKAGE_NAME));
62+
}
63+
$filesystem->removeDirectory($destination);
64+
}
65+
}
66+
}
67+
68+
/**
69+
* Attempt to symlink to the parent repository during development.
70+
*
71+
* @param \Composer\Script\Event $event
72+
* The composer event.
73+
*/
74+
public static function postInstall(Event $event) {
75+
$root_package = $event->getComposer()->getPackage();
76+
if (empty($root_package->getExtra()['symlink-root-project'])) {
77+
// Do nothing.
78+
return;
79+
}
80+
81+
$io = $event->getIO();
82+
$filesystem = new Filesystem();
83+
$link = implode(DIRECTORY_SEPARATOR, ['..', '..', '..', '..']);
84+
$destination = static::getPackageDestination();
85+
$destination = $filesystem->normalizePath($destination);
86+
if (Platform::isWindows()) {
87+
if (!$filesystem->isJunction($destination)) {
88+
$io->writeError(sprintf('Creating junction for <info>%s</info>', static::PACKAGE_NAME));
89+
$filesystem->removeDirectory($destination);
90+
$filesystem->junction($link, $destination);
91+
}
92+
}
93+
else {
94+
if (!$filesystem->isSymlinkedDirectory($destination)) {
95+
$io->writeError(sprintf('Creating symlink for <info>%s</info>', static::PACKAGE_NAME));
96+
// Attempt to remove the existing directory.
97+
$filesystem->removeDirectory($destination);
98+
if (!static::createSymlink($link, $destination)) {
99+
throw new \RuntimeException(sprintf('Failed to create a symlink for "%s"', static::PACKAGE_NAME));
100+
}
101+
}
102+
}
103+
}
104+
105+
/**
106+
* Returns the destination package directory.
107+
*/
108+
protected static function getPackageDestination() {
109+
return implode(DIRECTORY_SEPARATOR, [
110+
getcwd(),
111+
'vendor',
112+
'zodiacmedia',
113+
'drupal-libraries-installer',
114+
]);
115+
}
116+
117+
/**
118+
* Creates a symlink to the root project.
119+
*/
120+
protected static function createSymlink($target, $link) {
121+
if (!function_exists('symlink')) {
122+
return FALSE;
123+
}
124+
125+
return @symlink($target, $link);
126+
}
127+
128+
}

0 commit comments

Comments
 (0)