Skip to content

Commit 8e4b174

Browse files
feature #764 Copy peerDependencies to the root package.json (nicolas-grekas)
This PR was merged into the 1.12-dev branch. Discussion ---------- Copy peerDependencies to the root package.json As spotted in symfony/ux#93 /cc `@weaverryan` Commits ------- 0c79df1 Copy peerDependencies to the root package.json
2 parents 12be0e3 + 0c79df1 commit 8e4b174

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): bool
4144
$didAddLink = $this->addPackageJsonLink($packageName) || $didAddLink;
4245
}
4346

47+
$this->registerPeerDependencies($packagesNames);
48+
4449
// Register controllers and entrypoints in controllers.json
4550
$this->registerWebpackResources($packagesNames);
4651

@@ -106,11 +111,8 @@ private function registerWebpackResources(array $phpPackages)
106111
continue;
107112
}
108113

109-
if (!file_exists($packageJsonPath = $this->rootDir.'/vendor/'.$phpPackage.$assetsDir.'/package.json')) {
110-
continue;
111-
}
112-
113114
// Register in config
115+
$packageJsonPath = $this->rootDir.'/vendor/'.$phpPackage.$assetsDir.'/package.json';
114116
$packageJson = (new JsonFile($packageJsonPath))->read();
115117

116118
foreach ($packageJson['symfony']['controllers'] ?? [] as $controllerName => $defaultConfig) {
@@ -158,6 +160,41 @@ private function registerWebpackResources(array $phpPackages)
158160
file_put_contents($controllersJsonPath, json_encode($newControllersJson, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)."\n");
159161
}
160162

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

169206
return null;
170207
}
208+
209+
/**
210+
* @param ConstraintInterface[] $constraints
211+
*/
212+
private function compactConstraints(array $constraints): string
213+
{
214+
if (method_exists(Intervals::class, 'isSubsetOf')) {
215+
foreach ($constraints as $k1 => $constraint1) {
216+
foreach ($constraints as $k2 => $constraint2) {
217+
if ($k1 !== $k2 && Intervals::isSubsetOf($constraint1, $constraint2)) {
218+
unset($constraints[$k2]);
219+
}
220+
}
221+
}
222+
}
223+
224+
uksort($constraints, 'strnatcmp');
225+
226+
foreach ($constraints as $k => $constraint) {
227+
$constraints[$k] = \count($constraints) > 1 && false !== strpos($k, '|') ? '('.$k.')' : $k;
228+
}
229+
230+
return implode(',', $constraints);
231+
}
171232
}

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)