@@ -21,7 +21,7 @@ class MagentoComposerApplication
21
21
{
22
22
23
23
const COMPOSER_WORKING_DIR = '--working-dir ' ;
24
-
24
+
25
25
/**
26
26
* Path to Composer home directory
27
27
*
@@ -121,8 +121,144 @@ public function runComposerCommand(array $commandParams, $workingDir = null)
121
121
);
122
122
}
123
123
124
- //TODO: parse output based on command
125
-
126
124
return $ this ->consoleOutput ->fetch ();
127
125
}
126
+
127
+ /**
128
+ * Runs composer update --dry-run command
129
+ *
130
+ * @param array $packages
131
+ * @param string|null $workingDir
132
+ * @return string
133
+ */
134
+ public function runUpdateDryRun ($ packages , $ workingDir = null )
135
+ {
136
+ try {
137
+ $ output = $ this ->runComposerCommand (
138
+ ['command ' => 'update ' , '--dry-run ' => true ],
139
+ $ workingDir
140
+ );
141
+ } catch (\RuntimeException $ e ) {
142
+
143
+ $ errorMessage = $ this ->generateAdditionalErrorMessage ($ e ->getMessage (), $ packages );
144
+
145
+ throw new \RuntimeException ($ errorMessage . PHP_EOL . $ e ->getMessage ());
146
+ }
147
+
148
+ return $ output ;
149
+ }
150
+
151
+ /**
152
+ * Generates additional explanation for error message
153
+ *
154
+ * @param array $message
155
+ * @param array $inputPackages
156
+ * @param string|null $workingDir
157
+ * @return string
158
+ */
159
+ protected function generateAdditionalErrorMessage ($ message , $ inputPackages , $ workingDir = null ) {
160
+
161
+ $ matches = [];
162
+ $ errorMessage = '' ;
163
+ $ packages = [];
164
+
165
+ $ rawLines = explode (PHP_EOL , $ message );
166
+
167
+ foreach ($ rawLines as $ line ) {
168
+ if (preg_match (
169
+ '/- (.*) requires (.*) -> no matching package/ ' ,
170
+ $ line ,
171
+ $ matches
172
+
173
+ )
174
+ ) {
175
+ $ packages [] = $ matches [1 ];
176
+ $ packages [] = $ matches [2 ];
177
+ }
178
+ }
179
+
180
+ if (!empty ($ packages )) {
181
+ $ packages = array_unique ($ packages );
182
+ $ packages = $ this ->explodePackagesAndVersions ($ packages );
183
+ $ inputPackages = $ this ->explodePackagesAndVersions ($ inputPackages );
184
+
185
+ $ update = [];
186
+ $ conflicts = [];
187
+
188
+ foreach ($ inputPackages as $ package => $ version ) {
189
+ if (isset ($ packages [$ package ])) {
190
+ $ currentVersion = $ packages [$ package ];
191
+ $ update [] = $ package . ' from version ' . $ currentVersion . ' to ' . $ version ;
192
+ }
193
+ }
194
+
195
+ foreach (array_diff_key ($ packages , $ inputPackages ) as $ package => $ version ) {
196
+
197
+ $ output = $ this ->runComposerCommand (
198
+ ['command ' => 'show ' , 'package ' => $ package ],
199
+ $ workingDir
200
+ );
201
+
202
+ $ versions = $ this ->getPackageVersions ($ output );
203
+
204
+ $ conflicts [] = ' - ' . $ package . ' version ' . $ version
205
+ . ' please try to upgrade it too, available package versions: ' . implode (', ' , $ versions );
206
+ }
207
+
208
+ $ errorMessage = 'You are trying to update package '
209
+ . implode (' and ' , $ update ) . PHP_EOL
210
+ . 'But looks like it conflicts with the following packages: ' . PHP_EOL
211
+ . implode (PHP_EOL , $ conflicts )
212
+ . PHP_EOL ;
213
+ }
214
+
215
+ return $ errorMessage ;
216
+ }
217
+
218
+ /**
219
+ * Returns array that contains package as key and version as value
220
+ *
221
+ * @param array $packages
222
+ * @return array
223
+ */
224
+ protected function explodePackagesAndVersions ($ packages )
225
+ {
226
+ $ packagesAndVersions = [];
227
+ foreach ($ packages as $ package ) {
228
+ $ package = explode (' ' , $ package );
229
+ $ packagesAndVersions [$ package [0 ]] = $ package [1 ];
230
+ }
231
+
232
+ return $ packagesAndVersions ;
233
+ }
234
+
235
+ /**
236
+ * Returns package versions except currently installed based on composer show command output
237
+ *
238
+ * @param string $outputMessage
239
+ * @return array
240
+ */
241
+ protected function getPackageVersions ($ outputMessage )
242
+ {
243
+ $ versions = [];
244
+
245
+ if (preg_match (
246
+ '/versions : (.*)/ ' ,
247
+ $ outputMessage ,
248
+ $ matches
249
+
250
+ )
251
+ ) {
252
+ $ versions = $ matches [1 ];
253
+ $ versions = explode (', ' , $ versions );
254
+ $ versions = array_filter (
255
+ $ versions ,
256
+ function ($ version ) {
257
+ return strpos ($ version , '* ' ) === false ;
258
+ }
259
+ );
260
+ }
261
+
262
+ return $ versions ;
263
+ }
128
264
}
0 commit comments