Skip to content

Commit abc3e7c

Browse files
ajardineduard13
authored andcommitted
Make the module list more deterministic
1 parent f69bf0c commit abc3e7c

File tree

2 files changed

+82
-5
lines changed

2 files changed

+82
-5
lines changed

lib/internal/Magento/Framework/Module/ModuleList/Loader.php

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,24 +126,29 @@ private function getModuleConfigs()
126126
*
127127
* @param array $origList
128128
* @return array
129-
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
129+
* @throws \Exception
130130
*/
131-
private function sortBySequence($origList)
131+
private function sortBySequence(array $origList): array
132132
{
133133
ksort($origList);
134+
$modules = $this->prearrangeModules($origList);
135+
134136
$expanded = [];
135-
foreach ($origList as $moduleName => $value) {
137+
foreach ($modules as $moduleName => $value) {
138+
$sequence = $this->expandSequence($origList, $moduleName);
139+
asort($sequence);
140+
136141
$expanded[] = [
137142
'name' => $moduleName,
138-
'sequence' => $this->expandSequence($origList, $moduleName),
143+
'sequence' => $sequence,
139144
];
140145
}
141146

142147
// Use "bubble sorting" because usort does not check each pair of elements and in this case it is important
143148
$total = count($expanded);
144149
for ($i = 0; $i < $total - 1; $i++) {
145150
for ($j = $i; $j < $total; $j++) {
146-
if (in_array($expanded[$j]['name'], $expanded[$i]['sequence'])) {
151+
if (in_array($expanded[$j]['name'], $expanded[$i]['sequence'], true)) {
147152
$temp = $expanded[$i];
148153
$expanded[$i] = $expanded[$j];
149154
$expanded[$j] = $temp;
@@ -159,6 +164,27 @@ private function sortBySequence($origList)
159164
return $result;
160165
}
161166

167+
/**
168+
* Prearrange all modules by putting those from Magento before the others
169+
*
170+
* @param array $modules
171+
* @return array
172+
*/
173+
private function prearrangeModules(array $modules): array
174+
{
175+
$breakdown = ['magento' => [], 'others' => []];
176+
177+
foreach ($modules as $moduleName => $moduleDetails) {
178+
if (strpos($moduleName, 'Magento_') !== false) {
179+
$breakdown['magento'][$moduleName] = $moduleDetails;
180+
} else {
181+
$breakdown['others'][$moduleName] = $moduleDetails;
182+
}
183+
}
184+
185+
return array_merge($breakdown['magento'], $breakdown['others']);
186+
}
187+
162188
/**
163189
* Accumulate information about all transitive "sequence" references
164190
*

lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,55 @@ public function testLoadCircular()
160160
]));
161161
$this->loader->load();
162162
}
163+
164+
/**
165+
* @throws \Magento\Framework\Exception\LocalizedException
166+
*/
167+
public function testLoadPrearranged(): void
168+
{
169+
$fixtures = [
170+
'Foo_Bar' => ['name' => 'Foo_Bar', 'sequence' => ['Magento_Store']],
171+
'Magento_Directory' => ['name' => 'Magento_Directory', 'sequence' => ['Magento_Store']],
172+
'Magento_Store' => ['name' => 'Magento_Store', 'sequence' => []],
173+
'Magento_Theme' => ['name' => 'Magento_Theme', 'sequence' => ['Magento_Store', 'Magento_Directory']],
174+
'Test_HelloWorld' => ['name' => 'Test_HelloWorld', 'sequence' => ['Magento_Theme']]
175+
];
176+
177+
$index = 0;
178+
foreach ($fixtures as $name => $fixture) {
179+
$this->converter->expects($this->at($index++))->method('convert')->willReturn([$name => $fixture]);
180+
}
181+
182+
$this->registry->expects($this->once())
183+
->method('getPaths')
184+
->willReturn([
185+
'/path/to/Foo_Bar',
186+
'/path/to/Magento_Directory',
187+
'/path/to/Magento_Store',
188+
'/path/to/Magento_Theme',
189+
'/path/to/Test_HelloWorld'
190+
]);
191+
192+
$this->driver->expects($this->exactly(5))
193+
->method('fileGetContents')
194+
->will($this->returnValueMap([
195+
['/path/to/Foo_Bar/etc/module.xml', null, null, self::$sampleXml],
196+
['/path/to/Magento_Directory/etc/module.xml', null, null, self::$sampleXml],
197+
['/path/to/Magento_Store/etc/module.xml', null, null, self::$sampleXml],
198+
['/path/to/Magento_Theme/etc/module.xml', null, null, self::$sampleXml],
199+
['/path/to/Test_HelloWorld/etc/module.xml', null, null, self::$sampleXml],
200+
]));
201+
202+
// Load the full module list information
203+
$result = $this->loader->load();
204+
205+
$this->assertSame(
206+
['Magento_Store', 'Magento_Directory', 'Magento_Theme', 'Foo_Bar', 'Test_HelloWorld'],
207+
array_keys($result)
208+
);
209+
210+
foreach ($fixtures as $name => $fixture) {
211+
$this->assertSame($fixture, $result[$name]);
212+
}
213+
}
163214
}

0 commit comments

Comments
 (0)