1313
1414use Composer \Json \JsonFile ;
1515use Composer \Json \JsonManipulator ;
16- use Composer \Semver \Constraint \ConstraintInterface ;
17- use Composer \Semver \Intervals ;
18- use Composer \Semver \VersionParser ;
1916use Seld \JsonLint \ParsingException ;
2017
2118/**
@@ -40,14 +37,17 @@ public function shouldSynchronize(): bool
4037
4138 public function synchronize (array $ phpPackages ): bool
4239 {
43- // Remove all links and add again only the existing packages
4440 try {
45- $ didAddLink = $ this -> removePackageJsonLinks (( new JsonFile ( $ this ->rootDir .'/package.json ' ))-> read ( ));
41+ JsonFile:: parseJson ( file_get_contents ( $ this ->rootDir .'/package.json ' ));
4642 } catch (ParsingException $ e ) {
4743 // if package.json is invalid (possible during a recipe upgrade), we can't update the file
4844 return false ;
4945 }
5046
47+ $ didChangePackageJson = $ this ->removeObsoletePackageJsonLinks ();
48+
49+ $ dependencies = [];
50+
5151 foreach ($ phpPackages as $ k => $ phpPackage ) {
5252 if (\is_string ($ phpPackage )) {
5353 // support for smooth upgrades from older flex versions
@@ -56,22 +56,29 @@ public function synchronize(array $phpPackages): bool
5656 'keywords ' => ['symfony-ux ' ],
5757 ];
5858 }
59- $ didAddLink = $ this ->addPackageJsonLink ($ phpPackage ) || $ didAddLink ;
59+
60+ foreach ($ this ->resolvePackageDependencies ($ phpPackage ) as $ dependency => $ constraint ) {
61+ $ dependencies [$ dependency ][$ phpPackage ['name ' ]] = $ constraint ;
62+ }
6063 }
6164
62- $ this ->registerPeerDependencies ( $ phpPackages ) ;
65+ $ didChangePackageJson = $ this ->registerDependencies ( $ dependencies ) || $ didChangePackageJson ;
6366
6467 // Register controllers and entrypoints in controllers.json
6568 $ this ->registerWebpackResources ($ phpPackages );
6669
67- return $ didAddLink ;
70+ return $ didChangePackageJson ;
6871 }
6972
70- private function removePackageJsonLinks ( array $ packageJson ): bool
73+ private function removeObsoletePackageJsonLinks ( ): bool
7174 {
72- $ didRemoveLink = false ;
73- $ jsDependencies = $ packageJson ['dependencies ' ] ?? [];
74- $ jsDevDependencies = $ packageJson ['devDependencies ' ] ?? [];
75+ $ didChangePackageJson = false ;
76+
77+ $ manipulator = new JsonManipulator (file_get_contents ($ this ->rootDir .'/package.json ' ));
78+ $ content = json_decode ($ manipulator ->getContents (), true );
79+
80+ $ jsDependencies = $ content ['dependencies ' ] ?? [];
81+ $ jsDevDependencies = $ content ['devDependencies ' ] ?? [];
7582
7683 foreach (['dependencies ' => $ jsDependencies , 'devDependencies ' => $ jsDevDependencies ] as $ key => $ packages ) {
7784 foreach ($ packages as $ name => $ version ) {
@@ -82,39 +89,78 @@ private function removePackageJsonLinks(array $packageJson): bool
8289 continue ;
8390 }
8491
85- $ manipulator = new JsonManipulator (file_get_contents ($ this ->rootDir .'/package.json ' ));
86- $ manipulator ->removeSubNode ('devDependencies ' , $ name );
87- file_put_contents ($ this ->rootDir .'/package.json ' , $ manipulator ->getContents ());
88- $ didRemoveLink = true ;
92+ $ manipulator ->removeSubNode ($ key , $ name );
93+ $ didChangePackageJson = true ;
8994 }
9095 }
9196
92- return $ didRemoveLink ;
97+ file_put_contents ($ this ->rootDir .'/package.json ' , $ manipulator ->getContents ());
98+
99+ return $ didChangePackageJson ;
93100 }
94101
95- private function addPackageJsonLink ( array $ phpPackage ): bool
102+ private function resolvePackageDependencies ( $ phpPackage ): array
96103 {
104+ $ dependencies = [];
105+
97106 if (!$ packageJson = $ this ->resolvePackageJson ($ phpPackage )) {
98- return false ;
107+ return $ dependencies ;
99108 }
100109
101- $ manipulator = new JsonManipulator (file_get_contents ($ this ->rootDir .'/package.json ' ));
102- $ manipulator ->addSubNode ('devDependencies ' , '@ ' .$ phpPackage ['name ' ], 'file: ' .substr ($ packageJson ->getPath (), 1 + \strlen ($ this ->rootDir ), -13 ));
110+ $ dependencies ['@ ' .$ phpPackage ['name ' ]] = 'file: ' .substr ($ packageJson ->getPath (), 1 + \strlen ($ this ->rootDir ), -13 );
111+
112+ foreach ($ packageJson ->read ()['peerDependencies ' ] ?? [] as $ peerDependency => $ constraint ) {
113+ $ dependencies [$ peerDependency ] = $ constraint ;
114+ }
115+
116+ return $ dependencies ;
117+ }
103118
119+ private function registerDependencies (array $ flexDependencies ): bool
120+ {
121+ $ didChangePackageJson = false ;
122+
123+ $ manipulator = new JsonManipulator (file_get_contents ($ this ->rootDir .'/package.json ' ));
104124 $ content = json_decode ($ manipulator ->getContents (), true );
105125
106- $ devDependencies = $ content ['devDependencies ' ];
107- uksort ($ devDependencies , 'strnatcmp ' );
108- $ manipulator ->addMainKey ('devDependencies ' , $ devDependencies );
126+ foreach ($ flexDependencies as $ dependency => $ constraints ) {
127+ if (1 !== \count ($ constraints ) && 1 !== \count (array_count_values ($ constraints ))) {
128+ // If the flex packages have a colliding peer dependency, leave the resolution to the user
129+ continue ;
130+ }
131+
132+ $ constraint = array_shift ($ constraints );
109133
110- $ newContents = $ manipulator ->getContents ();
111- if ($ newContents === file_get_contents ($ this ->rootDir .'/package.json ' )) {
112- return false ;
134+ $ parentNode = isset ($ content ['dependencies ' ][$ dependency ]) ? 'dependencies ' : 'devDependencies ' ;
135+ if (!isset ($ content [$ parentNode ][$ dependency ])) {
136+ $ content ['devDependencies ' ][$ dependency ] = $ constraint ;
137+ $ didChangePackageJson = true ;
138+ } elseif ($ constraint !== $ content [$ parentNode ][$ dependency ]) {
139+ $ content [$ parentNode ][$ dependency ] = $ constraint ;
140+ $ didChangePackageJson = true ;
141+ }
113142 }
114143
115- file_put_contents ($ this ->rootDir .'/package.json ' , $ newContents );
144+ if ($ didChangePackageJson ) {
145+ if (isset ($ content ['dependencies ' ])) {
146+ $ manipulator ->addMainKey ('dependencies ' , $ content ['dependencies ' ]);
147+ }
148+
149+ if (isset ($ content ['devDependencies ' ])) {
150+ $ devDependencies = $ content ['devDependencies ' ];
151+ uksort ($ devDependencies , 'strnatcmp ' );
152+ $ manipulator ->addMainKey ('devDependencies ' , $ devDependencies );
153+ }
154+
155+ $ newContents = $ manipulator ->getContents ();
156+ if ($ newContents === file_get_contents ($ this ->rootDir .'/package.json ' )) {
157+ return false ;
158+ }
159+
160+ file_put_contents ($ this ->rootDir .'/package.json ' , $ manipulator ->getContents ());
161+ }
116162
117- return true ;
163+ return $ didChangePackageJson ;
118164 }
119165
120166 private function registerWebpackResources (array $ phpPackages )
@@ -151,7 +197,7 @@ private function registerWebpackResources(array $phpPackages)
151197 continue ;
152198 }
153199
154- // Otherwise, the package exists: merge new config with uer config
200+ // Otherwise, the package exists: merge new config with user config
155201 $ previousConfig = $ previousControllersJson ['controllers ' ][$ name ][$ controllerName ];
156202
157203 $ config = [];
@@ -180,39 +226,6 @@ private function registerWebpackResources(array $phpPackages)
180226 file_put_contents ($ controllersJsonPath , json_encode ($ newControllersJson , \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES )."\n" );
181227 }
182228
183- public function registerPeerDependencies (array $ phpPackages )
184- {
185- $ peerDependencies = [];
186-
187- foreach ($ phpPackages as $ phpPackage ) {
188- if (!$ packageJson = $ this ->resolvePackageJson ($ phpPackage )) {
189- continue ;
190- }
191-
192- $ versionParser = new VersionParser ();
193-
194- foreach ($ packageJson ->read ()['peerDependencies ' ] ?? [] as $ peerDependency => $ constraint ) {
195- $ peerDependencies [$ peerDependency ][$ constraint ] = $ versionParser ->parseConstraints ($ constraint );
196- }
197- }
198-
199- if (!$ peerDependencies ) {
200- return ;
201- }
202-
203- $ manipulator = new JsonManipulator (file_get_contents ($ this ->rootDir .'/package.json ' ));
204- $ content = json_decode ($ manipulator ->getContents (), true );
205- $ devDependencies = $ content ['devDependencies ' ] ?? [];
206-
207- foreach ($ peerDependencies as $ peerDependency => $ constraints ) {
208- $ devDependencies [$ peerDependency ] = $ this ->compactConstraints ($ constraints );
209- }
210- uksort ($ devDependencies , 'strnatcmp ' );
211- $ manipulator ->addMainKey ('devDependencies ' , $ devDependencies );
212-
213- file_put_contents ($ this ->rootDir .'/package.json ' , $ manipulator ->getContents ());
214- }
215-
216229 private function resolvePackageJson (array $ phpPackage ): ?JsonFile
217230 {
218231 $ packageDir = $ this ->rootDir .'/ ' .$ this ->vendorDir .'/ ' .$ phpPackage ['name ' ];
@@ -233,28 +246,4 @@ private function resolvePackageJson(array $phpPackage): ?JsonFile
233246
234247 return null ;
235248 }
236-
237- /**
238- * @param ConstraintInterface[] $constraints
239- */
240- private function compactConstraints (array $ constraints ): string
241- {
242- if (method_exists (Intervals::class, 'isSubsetOf ' )) {
243- foreach ($ constraints as $ k1 => $ constraint1 ) {
244- foreach ($ constraints as $ k2 => $ constraint2 ) {
245- if ($ k1 !== $ k2 && Intervals::isSubsetOf ($ constraint1 , $ constraint2 )) {
246- unset($ constraints [$ k2 ]);
247- }
248- }
249- }
250- }
251-
252- uksort ($ constraints , 'strnatcmp ' );
253-
254- foreach ($ constraints as $ k => $ constraint ) {
255- $ constraints [$ k ] = \count ($ constraints ) > 1 && false !== strpos ($ k , '| ' ) ? '( ' .$ k .') ' : $ k ;
256- }
257-
258- return implode (', ' , $ constraints );
259- }
260249}
0 commit comments