13
13
14
14
use Composer \Json \JsonFile ;
15
15
use Composer \Json \JsonManipulator ;
16
+ use Composer \Semver \Constraint \ConstraintInterface ;
17
+ use Composer \Semver \Intervals ;
18
+ use Composer \Semver \VersionParser ;
16
19
17
20
/**
18
21
* Synchronize package.json files detected in installed PHP packages with
@@ -41,6 +44,8 @@ public function synchronize(array $packagesNames): bool
41
44
$ didAddLink = $ this ->addPackageJsonLink ($ packageName ) || $ didAddLink ;
42
45
}
43
46
47
+ $ this ->registerPeerDependencies ($ packagesNames );
48
+
44
49
// Register controllers and entrypoints in controllers.json
45
50
$ this ->registerWebpackResources ($ packagesNames );
46
51
@@ -106,11 +111,8 @@ private function registerWebpackResources(array $phpPackages)
106
111
continue ;
107
112
}
108
113
109
- if (!file_exists ($ packageJsonPath = $ this ->rootDir .'/vendor/ ' .$ phpPackage .$ assetsDir .'/package.json ' )) {
110
- continue ;
111
- }
112
-
113
114
// Register in config
115
+ $ packageJsonPath = $ this ->rootDir .'/vendor/ ' .$ phpPackage .$ assetsDir .'/package.json ' ;
114
116
$ packageJson = (new JsonFile ($ packageJsonPath ))->read ();
115
117
116
118
foreach ($ packageJson ['symfony ' ]['controllers ' ] ?? [] as $ controllerName => $ defaultConfig ) {
@@ -158,6 +160,41 @@ private function registerWebpackResources(array $phpPackages)
158
160
file_put_contents ($ controllersJsonPath , json_encode ($ newControllersJson , \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES )."\n" );
159
161
}
160
162
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
+
161
198
private function resolveAssetsDir (string $ phpPackage )
162
199
{
163
200
foreach (['/assets ' , '/Resources/assets ' ] as $ subdir ) {
@@ -168,4 +205,28 @@ private function resolveAssetsDir(string $phpPackage)
168
205
169
206
return null ;
170
207
}
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
+ }
171
232
}
0 commit comments