Skip to content

Commit 544c407

Browse files
Merge pull request #187 from magento-commerce/develop
MCLOUD-14686: Cloud-tools May release
2 parents 1df1f13 + a800bbc commit 544c407

7 files changed

Lines changed: 607 additions & 87 deletions

File tree

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "magento/magento-cloud-patches",
33
"description": "Provides critical fixes for Magento 2 Enterprise Edition",
44
"type": "magento2-component",
5-
"version": "1.1.13",
5+
"version": "1.1.14",
66
"license": "OSL-3.0",
77
"repositories": {
88
"repo.magento.com": {

src/Application.php

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,60 @@
88
namespace Magento\CloudPatches;
99

1010
use Composer\Composer;
11-
use Magento\CloudPatches\Command;
1211
use Psr\Container\ContainerInterface;
12+
use Symfony\Component\Console\Application as SymfonyApplication;
13+
use Symfony\Component\Console\Command\Command as SymfonyCommand;
1314

1415
/**
1516
* @inheritdoc
1617
*/
17-
class Application extends \Symfony\Component\Console\Application
18+
class Application extends SymfonyApplication
1819
{
1920
/**
2021
* @var ContainerInterface
2122
*/
22-
private $container;
23+
private ContainerInterface $container;
2324

2425
/**
26+
* Command classes registered by default in the application.
27+
*
28+
* @var class-string<SymfonyCommand>[]
29+
*/
30+
private const DEFAULT_COMMAND_CLASSES = [
31+
Command\Apply::class,
32+
Command\Revert::class,
33+
Command\Status::class,
34+
];
35+
36+
/**
37+
* Application constructor.
38+
*
2539
* @param ContainerInterface $container
2640
*/
2741
public function __construct(ContainerInterface $container)
2842
{
2943
$this->container = $container;
44+
$package = $container->get(Composer::class)->getPackage();
3045

3146
parent::__construct(
32-
$container->get(Composer::class)->getPackage()->getPrettyName(),
33-
$container->get(Composer::class)->getPackage()->getPrettyVersion()
47+
$package->getPrettyName(),
48+
$package->getPrettyVersion()
3449
);
3550
}
3651

3752
/**
38-
* @inheritdoc
53+
* Get the default commands that should always be available.
54+
*
55+
* @return SymfonyCommand[]
3956
*/
4057
protected function getDefaultCommands(): array
4158
{
42-
return array_merge(parent::getDefaultCommands(), [
43-
$this->container->get(Command\Apply::class),
44-
$this->container->get(Command\Revert::class),
45-
$this->container->get(Command\Status::class)
46-
]);
59+
$instances = array_map(
60+
fn (string $commandClass): SymfonyCommand =>
61+
$this->container->get($commandClass),
62+
self::DEFAULT_COMMAND_CLASSES
63+
);
64+
65+
return array_merge(parent::getDefaultCommands(), $instances);
4766
}
4867
}

src/ApplicationEce.php

Lines changed: 122 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,149 @@
88
namespace Magento\CloudPatches;
99

1010
use Composer\Composer;
11+
use Composer\InstalledVersions;
1112
use Magento\CloudPatches\Command;
1213
use Psr\Container\ContainerInterface;
14+
use Symfony\Component\Console\Command\Command as SymfonyCommand;
15+
use Symfony\Component\Console\Application as SymfonyApplication;
16+
use Throwable;
1317

1418
/**
1519
* @inheritDoc
1620
*/
17-
class ApplicationEce extends \Symfony\Component\Console\Application
21+
class ApplicationEce extends SymfonyApplication
1822
{
23+
/**
24+
* Default package name to look for in InstalledVersions and composer.json.
25+
*/
26+
private const DEFAULT_PACKAGE_NAME = 'magento/magento-cloud-patches';
27+
1928
/**
2029
* @var ContainerInterface
2130
*/
22-
private $container;
31+
private ContainerInterface $container;
2332

2433
/**
25-
* @param ContainerInterface $container
34+
* Command classes registered by default in the application.
35+
*
36+
* @var class-string<SymfonyCommand>[]
37+
*/
38+
private const DEFAULT_COMMAND_CLASSES = [
39+
Command\Ece\Apply::class,
40+
Command\Ece\Revert::class,
41+
Command\Status::class,
42+
Command\Verify::class
43+
];
44+
45+
/**
46+
* Initialize the application and resolve its name and version.
47+
*
48+
* Version information is resolved from InstalledVersions,
49+
* composer.json, or Composer package metadata.
50+
*
51+
* @param ContainerInterface $container Application container.
2652
*/
2753
public function __construct(ContainerInterface $container)
2854
{
29-
$this->container = $container;
55+
$this->container = $container;
56+
[$name, $version] = $this->resolveApplicationMetadata($container);
3057

31-
parent::__construct(
32-
$container->get(Composer::class)->getPackage()->getPrettyName(),
33-
$container->get(Composer::class)->getPackage()->getPrettyVersion()
34-
);
58+
parent::__construct($name, $version);
59+
}
60+
61+
/**
62+
* Read composer.json safely.
63+
* This method attempts to read the composer.json file and decode its contents.
64+
* It handles potential errors gracefully, returning null if the file cannot be read or parsed.
65+
*
66+
* @return array|null Decoded composer.json data or null if unavailable.
67+
*/
68+
private function readComposerJson(): ?array
69+
{
70+
if (class_exists(InstalledVersions::class)
71+
&& InstalledVersions::isInstalled(self::DEFAULT_PACKAGE_NAME)
72+
) {
73+
$installPath = InstalledVersions::getInstallPath(self::DEFAULT_PACKAGE_NAME);
74+
75+
if ($installPath) {
76+
$path = $installPath . '/composer.json';
77+
78+
if (is_file($path)) {
79+
try {
80+
return json_decode(
81+
(string) file_get_contents($path),
82+
true,
83+
512,
84+
JSON_THROW_ON_ERROR
85+
);
86+
} catch (Throwable $e) {
87+
return null;
88+
}
89+
}
90+
}
91+
}
92+
93+
return null;
3594
}
3695

3796
/**
38-
* @inheritDoc
97+
* Resolve application name and version.
98+
* This method ensures that the application can accurately report its own name and
99+
* version regardless of how it is installed or executed.
100+
*
101+
* @param ContainerInterface $container The application container used to create Composer instance if needed.
102+
* @return array An array containing the resolved application name and version.
103+
*/
104+
private function resolveApplicationMetadata(ContainerInterface $container): array
105+
{
106+
// Read composer.json to get the default package name dynamically
107+
$composerJson = $this->readComposerJson();
108+
$defaultPackage = $composerJson['name'] ?? self::DEFAULT_PACKAGE_NAME;
109+
110+
// 1️. Composer InstalledVersions: If the package is installed via Composer,
111+
// it retrieves the name and version from InstalledVersions.
112+
if (class_exists(InstalledVersions::class) && InstalledVersions::isInstalled($defaultPackage)) {
113+
return [
114+
$defaultPackage,
115+
InstalledVersions::getPrettyVersion($defaultPackage)
116+
?? InstalledVersions::getVersion($defaultPackage)
117+
?? 'unknown'
118+
];
119+
}
120+
121+
// 2. composer.json: If InstalledVersions is not available,
122+
// it uses the already-read composer.json data.
123+
if ($composerJson) {
124+
return [
125+
$composerJson['name'] ?? self::DEFAULT_PACKAGE_NAME,
126+
$composerJson['version'] ?? 'unknown'
127+
];
128+
}
129+
130+
// 3️. Composer runtime metadata: If both previous methods fail, it falls back to using the Composer
131+
// runtime metadata to determine the name and version.
132+
$composer = $container->get(Composer::class);
133+
$package = $composer->getPackage();
134+
135+
return [
136+
$package->getPrettyName(),
137+
$package->getPrettyVersion()
138+
];
139+
}
140+
141+
/**
142+
* Get the default commands that should always be available.
143+
*
144+
* @return SymfonyCommand[]
39145
*/
40146
protected function getDefaultCommands(): array
41147
{
42-
return array_merge(parent::getDefaultCommands(), [
43-
$this->container->get(Command\Ece\Apply::class),
44-
$this->container->get(Command\Ece\Revert::class),
45-
$this->container->get(Command\Status::class),
46-
$this->container->get(Command\Verify::class)
47-
]);
148+
$instances = array_map(
149+
fn (string $commandClass): SymfonyCommand =>
150+
$this->container->get($commandClass),
151+
self::DEFAULT_COMMAND_CLASSES
152+
);
153+
154+
return array_merge(parent::getDefaultCommands(), $instances);
48155
}
49156
}

0 commit comments

Comments
 (0)