Skip to content

Commit e074ce3

Browse files
author
Ivan Gavryshko
committed
MAGETWO-40176: Show redundant version when checking component dependency in Magento component manager
- refactored and added commands - fixed custom message - removed composer message if custom appeared
1 parent 87889cf commit e074ce3

File tree

3 files changed

+244
-128
lines changed

3 files changed

+244
-128
lines changed

src/InfoCommand.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Composer;
8+
9+
/**
10+
* Class InfoCommand calls composer info command
11+
*/
12+
class InfoCommand
13+
{
14+
15+
/**
16+
* @var MagentoComposerApplication
17+
*/
18+
protected $magentoComposerApplication;
19+
20+
/**
21+
* Constructor
22+
*
23+
* @param MagentoComposerApplication $magentoComposerApplication
24+
*/
25+
public function __construct(MagentoComposerApplication $magentoComposerApplication)
26+
{
27+
$this->magentoComposerApplication = $magentoComposerApplication;
28+
}
29+
30+
/**
31+
* Runs InfoCommand command
32+
*
33+
* @param string $package
34+
* @param bool $installed
35+
* @param null $version
36+
* @return array|bool
37+
*/
38+
public function run($package, $installed = false, $version = null)
39+
{
40+
$commandParameters = [
41+
'command' => 'info',
42+
'package' => $package,
43+
'-i' => $installed
44+
];
45+
46+
$result = [];
47+
48+
try {
49+
$output = $this->magentoComposerApplication->runComposerCommand(
50+
$commandParameters
51+
);
52+
} catch (\RuntimeException $e) {
53+
return false;
54+
}
55+
56+
$rawLines = explode(PHP_EOL, $output);
57+
58+
foreach ($rawLines as $line) {
59+
$chunk = explode(':', $line);
60+
if (count($chunk) === 2) {
61+
$result[trim($chunk[0])] = trim($chunk[1]);
62+
}
63+
64+
}
65+
66+
$result = $this->extractVersions($result);
67+
68+
return $result;
69+
}
70+
71+
/**
72+
* Extracts package versions info
73+
*
74+
* @param array $packageInfo
75+
* @return array
76+
*/
77+
private function extractVersions($packageInfo)
78+
{
79+
$versions = explode(', ', $packageInfo['versions']);
80+
81+
if (count($versions) === 1) {
82+
$packageInfo['current_version'] = str_replace('* ', '', $packageInfo['versions']);
83+
$packageInfo['available_versions'] = [];
84+
} else {
85+
$currentVersion = array_values(preg_grep("/^\*.*/", $versions));
86+
$packageInfo['current_version'] = str_replace('* ', '', $currentVersion[0]);
87+
$packageInfo['available_versions'] = array_values(preg_grep("/^\*.*/", $versions, PREG_GREP_INVERT));
88+
}
89+
90+
return $packageInfo;
91+
}
92+
}

src/MagentoComposerApplication.php

Lines changed: 0 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -123,132 +123,4 @@ public function runComposerCommand(array $commandParams, $workingDir = null)
123123

124124
return $this->consoleOutput->fetch();
125125
}
126-
127-
/**
128-
* Runs composer update --dry-run command
129-
*
130-
* @param array $packages
131-
* @param string|null $workingDir
132-
* @return string
133-
* @throws \RuntimeException
134-
*/
135-
public function runRequireUpdateDryRun($packages, $workingDir = null)
136-
{
137-
try {
138-
// run require
139-
$this->runComposerCommand(
140-
['command' => 'require', 'packages' => $packages, '--no-update' => true],
141-
$workingDir
142-
);
143-
144-
$output = $this->runComposerCommand(
145-
['command' => 'update', '--dry-run' => true],
146-
$workingDir
147-
);
148-
} catch (\RuntimeException $e) {
149-
$errorMessage = $this->generateAdditionalErrorMessage($e->getMessage(), $packages, $workingDir);
150-
throw new \RuntimeException($errorMessage . PHP_EOL . $e->getMessage(), $e->getCode(), $e);
151-
}
152-
153-
return $output;
154-
}
155-
156-
/**
157-
* Generates additional explanation for error message
158-
*
159-
* @param array $message
160-
* @param array $inputPackages
161-
* @param string|null $workingDir
162-
* @return string
163-
*/
164-
protected function generateAdditionalErrorMessage($message, $inputPackages, $workingDir = null) {
165-
166-
$matches = [];
167-
$errorMessage = '';
168-
$packages = [];
169-
$rawLines = explode(PHP_EOL, $message);
170-
171-
foreach ($rawLines as $line) {
172-
if (preg_match('/- (.*) requires (.*) -> no matching package/', $line, $matches)) {
173-
$packages[] = $matches[1];
174-
$packages[] = $matches[2];
175-
}
176-
}
177-
178-
if (!empty($packages)) {
179-
$packages = array_unique($packages);
180-
$packages = $this->explodePackagesAndVersions($packages);
181-
$inputPackages = $this->explodePackagesAndVersions($inputPackages);
182-
183-
$update = [];
184-
$conflicts = [];
185-
186-
foreach ($inputPackages as $package => $version) {
187-
if (isset($packages[$package])) {
188-
$update[] = $package . ' to ' . $version;
189-
}
190-
}
191-
192-
foreach (array_diff_key($packages, $inputPackages) as $package => $version) {
193-
$output = $this->runComposerCommand(
194-
['command' => 'show', 'package' => $package],
195-
$workingDir
196-
);
197-
198-
$versions = $this->getPackageVersions($output);
199-
200-
$conflicts[] = ' - ' . $package . ' version ' . $version
201-
. ' please try to upgrade it to one of the following package versions: ' . implode(', ', $versions);
202-
}
203-
204-
$errorMessage = 'You are trying to update package(s) '
205-
. implode(', ', $update) . PHP_EOL
206-
. "We've detected conflicts with the following packages:" . PHP_EOL
207-
. implode(PHP_EOL, $conflicts)
208-
. PHP_EOL;
209-
}
210-
211-
return $errorMessage;
212-
}
213-
214-
/**
215-
* Returns array that contains package as key and version as value
216-
*
217-
* @param array $packages
218-
* @return array
219-
*/
220-
protected function explodePackagesAndVersions($packages)
221-
{
222-
$packagesAndVersions = [];
223-
foreach ($packages as $package) {
224-
$package = explode(' ', $package);
225-
$packagesAndVersions[$package[0]] = $package[1];
226-
}
227-
228-
return $packagesAndVersions;
229-
}
230-
231-
/**
232-
* Returns package versions except currently installed based on composer show command output
233-
*
234-
* @param string $outputMessage
235-
* @return array
236-
*/
237-
protected function getPackageVersions($outputMessage)
238-
{
239-
$versions = [];
240-
241-
if (preg_match('/versions : (.*)/', $outputMessage, $matches)) {
242-
$versions = $matches[1];
243-
$versions = explode(', ', $versions);
244-
$versions = array_filter(
245-
$versions,
246-
function ($version) {
247-
return strpos($version, '*') === false;
248-
}
249-
);
250-
}
251-
252-
return $versions;
253-
}
254126
}

src/RequireUpdateDryRunCommand.php

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Composer;
8+
9+
10+
class RequireUpdateDryRunCommand
11+
{
12+
/**
13+
* @var MagentoComposerApplication
14+
*/
15+
protected $magentoComposerApplication;
16+
17+
/**
18+
* @var InfoCommand
19+
*/
20+
protected $infoCommand;
21+
22+
/**
23+
* Constructor
24+
*
25+
* @param MagentoComposerApplication $magentoComposerApplication
26+
* @param InfoCommand $infoCommand
27+
*/
28+
public function __construct(
29+
MagentoComposerApplication $magentoComposerApplication,
30+
InfoCommand $infoCommand
31+
) {
32+
$this->magentoComposerApplication = $magentoComposerApplication;
33+
$this->infoCommand = $infoCommand;
34+
}
35+
36+
/**
37+
* Runs composer update --dry-run command
38+
*
39+
* @param array $packages
40+
* @param string|null $workingDir
41+
* @return string
42+
* @throws \RuntimeException
43+
*/
44+
public function run($packages, $workingDir = null)
45+
{
46+
try {
47+
// run require
48+
$this->magentoComposerApplication->runComposerCommand(
49+
['command' => 'require', 'packages' => $packages, '--no-update' => true],
50+
$workingDir
51+
);
52+
53+
$output = $this->magentoComposerApplication->runComposerCommand(
54+
['command' => 'update', '--dry-run' => true],
55+
$workingDir
56+
);
57+
} catch (\RuntimeException $e) {
58+
$errorMessage = $this->generateAdditionalErrorMessage($e->getMessage(), $packages);
59+
if ($errorMessage) {
60+
throw new \RuntimeException($errorMessage, $e->getCode(), $e);
61+
} else {
62+
throw new \RuntimeException($e->getMessage(), $e->getCode(), $e);
63+
}
64+
65+
}
66+
67+
return $output;
68+
}
69+
70+
/**
71+
* Generates additional explanation for error message
72+
*
73+
* @param array $message
74+
* @param array $inputPackages
75+
* @return string
76+
*/
77+
protected function generateAdditionalErrorMessage($message, $inputPackages)
78+
{
79+
80+
$matches = [];
81+
$errorMessage = '';
82+
$packages = [];
83+
$rawLines = explode(PHP_EOL, $message);
84+
85+
foreach ($rawLines as $line) {
86+
if (preg_match('/- (.*) requires (.*) -> no matching package/', $line, $matches)) {
87+
$packages[] = $matches[1];
88+
$packages[] = $matches[2];
89+
}
90+
}
91+
92+
if (!empty($packages)) {
93+
$packages = array_unique($packages);
94+
$packages = $this->explodePackagesAndVersions($packages);
95+
$inputPackages = $this->explodePackagesAndVersions($inputPackages);
96+
97+
$update = [];
98+
$conflicts = [];
99+
100+
foreach ($inputPackages as $package => $version) {
101+
if (isset($packages[$package])) {
102+
$update[] = $package . ' to ' . $version;
103+
}
104+
}
105+
106+
foreach (array_diff_key($packages, $inputPackages) as $package => $version) {
107+
108+
if (!$packageInfo = $this->infoCommand->run($package, true)) {
109+
return false;
110+
}
111+
112+
$currentVersion = $packageInfo['current_version'];
113+
114+
if (empty($packageInfo['available_versions'])) {
115+
$packageInfo = $this->infoCommand->run($package);
116+
if (empty($packageInfo['available_versions'])) {
117+
return false;
118+
}
119+
}
120+
121+
$conflicts[] = ' - ' . $package . ' version ' . $currentVersion . '. '
122+
. 'Please try to update it to one of the following package versions: '
123+
. implode(', ', $packageInfo['available_versions']);
124+
}
125+
126+
$errorMessage = 'You are trying to update package(s) '
127+
. implode(', ', $update) . PHP_EOL
128+
. "We've detected conflicts with the following packages:" . PHP_EOL
129+
. implode(PHP_EOL, $conflicts)
130+
. PHP_EOL;
131+
}
132+
133+
return $errorMessage;
134+
}
135+
136+
/**
137+
* Returns array that contains package as key and version as value
138+
*
139+
* @param array $packages
140+
* @return array
141+
*/
142+
protected function explodePackagesAndVersions($packages)
143+
{
144+
$packagesAndVersions = [];
145+
foreach ($packages as $package) {
146+
$package = explode(' ', $package);
147+
$packagesAndVersions[$package[0]] = $package[1];
148+
}
149+
150+
return $packagesAndVersions;
151+
}
152+
}

0 commit comments

Comments
 (0)