Skip to content

Commit 67140cf

Browse files
author
Ivan Gavryshko
committed
MAGETWO-38917: Process composer generated messages
- added additional message over composer error message
1 parent 6db12b6 commit 67140cf

File tree

1 file changed

+139
-3
lines changed

1 file changed

+139
-3
lines changed

src/MagentoComposerApplication.php

Lines changed: 139 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class MagentoComposerApplication
2121
{
2222

2323
const COMPOSER_WORKING_DIR = '--working-dir';
24-
24+
2525
/**
2626
* Path to Composer home directory
2727
*
@@ -121,8 +121,144 @@ public function runComposerCommand(array $commandParams, $workingDir = null)
121121
);
122122
}
123123

124-
//TODO: parse output based on command
125-
126124
return $this->consoleOutput->fetch();
127125
}
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+
}
128264
}

0 commit comments

Comments
 (0)