-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathRootProjectUpdater.php
167 lines (143 loc) · 5.18 KB
/
RootProjectUpdater.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\ComposerRootUpdatePlugin\Updater;
use Composer\Composer;
use Composer\Downloader\FilesystemException;
use Magento\ComposerRootUpdatePlugin\Utils\PackageUtils;
use Magento\ComposerRootUpdatePlugin\Utils\Console;
use Magento\ComposerRootUpdatePlugin\Plugin\PluginDefinition;
use RuntimeException;
/**
* Handles updates of the root project composer.json file based on necessary changes for the target version
*/
class RootProjectUpdater
{
/**
* @var Console $console
*/
protected $console;
/**
* @var Composer $composer
*/
protected $composer;
/**
* @var PackageUtils $pkgUtils;
*/
protected $pkgUtils;
/**
* @var array $jsonChanges Json-writable sections of composer.json that have been updated
*/
protected $jsonChanges;
/**
* @param Console $console
* @param Composer $composer
* @return void
*/
public function __construct(Console $console, Composer $composer)
{
$this->console = $console;
$this->composer = $composer;
$this->pkgUtils = new PackageUtils($console, $composer);
$this->jsonChanges = [];
}
/**
* Look ahead to the target magento/project version and execute any changes to the root composer.json file in-memory
*
* @param RootPackageRetriever $retriever
* @param bool $overrideOption
* @param bool $ignorePlatformReqs
* @param string $phpVersion
* @param string $stability
* @return bool Returns true if updates were necessary and prepared successfully
*/
public function runUpdate(
RootPackageRetriever $retriever,
bool $overrideOption,
bool $ignorePlatformReqs,
string $phpVersion,
string $stability,
bool $isOverrideCommand
): bool {
$composer = $this->composer;
if (!$this->pkgUtils->findRequire($composer, PluginDefinition::PACKAGE_NAME)) {
// If the plugin requirement has been removed but we're still trying to run (code still existing in the
// vendor directory), return without executing.
return false;
}
$origEdition = $retriever->getOriginalEdition();
$origVersion = $retriever->getOriginalVersion();
$prettyOrigVersion = $retriever->getPrettyOriginalVersion();
if (!$retriever->getTargetRootPackage($ignorePlatformReqs, $phpVersion, $stability)) {
throw new RuntimeException('Root composer.json updates cannot run without a valid target metapackage');
}
if ($origEdition == $retriever->getTargetEdition() && $origVersion == $retriever->getTargetVersion()) {
$this->console->labeledVerbose(
'The metapackage requirement matches the current installation; no root updates are required'
);
return false;
}
if (!$retriever->getOriginalRootPackage($overrideOption)) {
$this->console->log('Skipping root composer.json update.');
return false;
}
$this->console->setVerboseLabel($retriever->getTargetLabel());
$project = $this->pkgUtils->getProjectPackageName($origEdition);
$this->console->labeledVerbose(
"Base root project package version: $project $prettyOrigVersion"
);
$resolver = new DeltaResolver($this->console, $overrideOption, $retriever, $isOverrideCommand);
$jsonChanges = $resolver->resolveRootDeltas();
if ($jsonChanges) {
$this->jsonChanges = $jsonChanges;
return true;
}
return false;
}
/**
* Write the changed composer.json file
*
* @return void
* @throws FilesystemException if the composer.json read or write failed
*/
public function writeUpdatedComposerJson()
{
if (!$this->jsonChanges) {
return;
}
$filePath = $this->composer->getConfig()->getConfigSource()->getName();
$json = json_decode(file_get_contents($filePath), true);
if ($json === null) {
throw new FilesystemException('Failed to read ' . $filePath);
}
foreach ($this->jsonChanges as $section => $newContents) {
if ($newContents === null || $newContents === []) {
if (key_exists($section, $json)) {
unset($json[$section]);
}
} else {
$json[$section] = $newContents;
}
}
$this->console->labeledVerbose('Writing changes to the root composer.json...');
$retVal = file_put_contents(
$filePath,
json_encode($json, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
);
if ($retVal === false) {
throw new FilesystemException('Failed to write updated magento/project values to ' . $filePath);
}
$this->console->labeledVerbose("$filePath has been updated");
}
/**
* Return the changes to be made in composer.json
*
* @return array
*/
public function getJsonChanges(): array
{
return $this->jsonChanges;
}
}