Skip to content

Commit 0c79df1

Browse files
Copy peerDependencies to the root package.json
1 parent ff85b54 commit 0c79df1

File tree

4 files changed

+79
-4
lines changed

4 files changed

+79
-4
lines changed

src/PackageJsonSynchronizer.php

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
use Composer\Json\JsonFile;
1515
use Composer\Json\JsonManipulator;
16+
use Composer\Semver\Constraint\ConstraintInterface;
17+
use Composer\Semver\Intervals;
18+
use Composer\Semver\VersionParser;
1619

1720
/**
1821
* Synchronize package.json files detected in installed PHP packages with
@@ -41,6 +44,8 @@ public function synchronize(array $packagesNames)
4144
$this->addPackageJsonLink($packageName);
4245
}
4346

47+
$this->registerPeerDependencies($packagesNames);
48+
4449
// Register controllers and entrypoints in controllers.json
4550
$this->registerWebpackResources($packagesNames);
4651
}
@@ -98,11 +103,8 @@ private function registerWebpackResources(array $phpPackages)
98103
continue;
99104
}
100105

101-
if (!file_exists($packageJsonPath = $this->rootDir.'/vendor/'.$phpPackage.$assetsDir.'/package.json')) {
102-
continue;
103-
}
104-
105106
// Register in config
107+
$packageJsonPath = $this->rootDir.'/vendor/'.$phpPackage.$assetsDir.'/package.json';
106108
$packageJson = (new JsonFile($packageJsonPath))->read();
107109

108110
foreach ($packageJson['symfony']['controllers'] ?? [] as $controllerName => $defaultConfig) {
@@ -150,6 +152,41 @@ private function registerWebpackResources(array $phpPackages)
150152
file_put_contents($controllersJsonPath, json_encode($newControllersJson, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)."\n");
151153
}
152154

155+
public function registerPeerDependencies(array $phpPackages)
156+
{
157+
$peerDependencies = [];
158+
159+
foreach ($phpPackages as $phpPackage) {
160+
if (!$assetsDir = $this->resolveAssetsDir($phpPackage)) {
161+
continue;
162+
}
163+
164+
$packageJsonPath = $this->rootDir.'/vendor/'.$phpPackage.$assetsDir.'/package.json';
165+
$packageJson = (new JsonFile($packageJsonPath))->read();
166+
$versionParser = new VersionParser();
167+
168+
foreach ($packageJson['peerDependencies'] ?? [] as $peerDependency => $constraint) {
169+
$peerDependencies[$peerDependency][$constraint] = $versionParser->parseConstraints($constraint);
170+
}
171+
}
172+
173+
if (!$peerDependencies) {
174+
return;
175+
}
176+
177+
$manipulator = new JsonManipulator(file_get_contents($this->rootDir.'/package.json'));
178+
$content = json_decode($manipulator->getContents(), true);
179+
$devDependencies = $content['devDependencies'] ?? [];
180+
181+
foreach ($peerDependencies as $peerDependency => $constraints) {
182+
$devDependencies[$peerDependency] = $this->compactConstraints($constraints);
183+
}
184+
uksort($devDependencies, 'strnatcmp');
185+
$manipulator->addMainKey('devDependencies', $devDependencies);
186+
187+
file_put_contents($this->rootDir.'/package.json', $manipulator->getContents());
188+
}
189+
153190
private function resolveAssetsDir(string $phpPackage)
154191
{
155192
foreach (['/assets', '/Resources/assets'] as $subdir) {
@@ -160,4 +197,28 @@ private function resolveAssetsDir(string $phpPackage)
160197

161198
return null;
162199
}
200+
201+
/**
202+
* @param ConstraintInterface[] $constraints
203+
*/
204+
private function compactConstraints(array $constraints): string
205+
{
206+
if (method_exists(Intervals::class, 'isSubsetOf')) {
207+
foreach ($constraints as $k1 => $constraint1) {
208+
foreach ($constraints as $k2 => $constraint2) {
209+
if ($k1 !== $k2 && Intervals::isSubsetOf($constraint1, $constraint2)) {
210+
unset($constraints[$k2]);
211+
}
212+
}
213+
}
214+
}
215+
216+
uksort($constraints, 'strnatcmp');
217+
218+
foreach ($constraints as $k => $constraint) {
219+
$constraints[$k] = \count($constraints) > 1 && false !== strpos($k, '|') ? '('.$k.')' : $k;
220+
}
221+
222+
return implode(',', $constraints);
223+
}
163224
}

tests/Fixtures/packageJson/vendor/symfony/existing-package/Resources/assets/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,9 @@
1010
}
1111
}
1212
}
13+
},
14+
"peerDependencies": {
15+
"@hotcookies": "^1.1|^2",
16+
"@hotdogs": "^2"
1317
}
1418
}

tests/Fixtures/packageJson/vendor/symfony/new-package/assets/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,8 @@
1010
}
1111
},
1212
"entrypoints": ["admin.js"]
13+
},
14+
"peerDependencies": {
15+
"@hotcookies": "^1.1"
1316
}
1417
}

tests/PackageJsonSynchronizerTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Flex\Tests;
1313

14+
use Composer\Semver\Intervals;
1415
use PHPUnit\Framework\TestCase;
1516
use Symfony\Component\Filesystem\Filesystem;
1617
use Symfony\Flex\PackageJsonSynchronizer;
@@ -70,6 +71,8 @@ public function testSynchronizeExistingPackage()
7071
[
7172
'name' => 'symfony/fixture',
7273
'devDependencies' => [
74+
'@hotcookies' => '^1.1|^2',
75+
'@hotdogs' => '^2',
7376
'@symfony/existing-package' => 'file:vendor/symfony/existing-package/Resources/assets',
7477
'@symfony/stimulus-bridge' => '^1.0.0',
7578
'stimulus' => '^1.1.1',
@@ -111,6 +114,8 @@ public function testSynchronizeNewPackage()
111114
'{
112115
"name": "symfony/fixture",
113116
"devDependencies": {
117+
"@hotcookies": "'.(method_exists(Intervals::class, 'isSubsetOf') ? '^1.1' : '^1.1,(^1.1|^2)').'",
118+
"@hotdogs": "^2",
114119
"@symfony/existing-package": "file:vendor/symfony/existing-package/Resources/assets",
115120
"@symfony/new-package": "file:vendor/symfony/new-package/assets",
116121
"@symfony/stimulus-bridge": "^1.0.0",
@@ -161,6 +166,8 @@ public function testArrayFormattingHasNotChanged()
161166
'{
162167
"name": "symfony/fixture",
163168
"devDependencies": {
169+
"@hotcookies": "^1.1|^2",
170+
"@hotdogs": "^2",
164171
"@symfony/existing-package": "file:vendor/symfony/existing-package/Resources/assets",
165172
"@symfony/stimulus-bridge": "^1.0.0",
166173
"stimulus": "^1.1.1"

0 commit comments

Comments
 (0)