-
-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expand references #156
Expand references #156
Changes from all commits
db62a7b
2b55f90
6dc1132
9b09bf0
ca77914
62e38a4
14c184e
a8cbfcb
b51f2c5
1c7e2af
5601267
41566f6
213f7c4
54690d7
feb7489
f111e78
894778d
3e5429e
ddbcc1b
3a3a022
ea76db0
d5cce0a
0291adf
e1f2a3f
f07acd7
3130a4d
7e934f8
f3876ce
a12abfe
9bfc9b1
de89472
67f2389
dbec55e
3dcd4c8
877b9ee
25f676b
68d3ad5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,180 @@ | ||||||
<?php | ||||||
|
||||||
declare(strict_types=1); | ||||||
|
||||||
namespace Yiisoft\Config\Composer; | ||||||
|
||||||
use ErrorException; | ||||||
use Yiisoft\Config\MergePlan; | ||||||
use Yiisoft\Config\Options; | ||||||
|
||||||
use function in_array; | ||||||
|
||||||
/** | ||||||
* @internal | ||||||
* | ||||||
* @psalm-import-type FileType from MergePlan | ||||||
* @psalm-import-type MergePlanType from MergePlan | ||||||
*/ | ||||||
final class MergePlanCollector | ||||||
{ | ||||||
private const PACKAGES_ORDER = [ | ||||||
Options::VENDOR_OVERRIDE_PACKAGE_NAME => 1, | ||||||
Options::ROOT_PACKAGE_NAME => 2, | ||||||
]; | ||||||
|
||||||
/** | ||||||
* @psalm-var array<string, array<string, list<FileType>>> | ||||||
*/ | ||||||
private array $mergePlan = []; | ||||||
|
||||||
/** | ||||||
* @psalm-var array<string,true|null> | ||||||
*/ | ||||||
private array $processedGroups = []; | ||||||
|
||||||
/** | ||||||
* Adds an item to the merge plan. | ||||||
* | ||||||
* @param array|string $file The config file. | ||||||
* @param string $package The package name. | ||||||
* @param string $group The group name. | ||||||
* | ||||||
* @psalm-param array{0:string,1:string}|string $file | ||||||
*/ | ||||||
public function add(array|string $file, string $package, string $group): void | ||||||
{ | ||||||
$this->mergePlan[$group][$package][] = $file; | ||||||
} | ||||||
|
||||||
/** | ||||||
* Adds a multiple items to the merge plan. | ||||||
* | ||||||
* @param array $files The config files. | ||||||
* @param string $package The package name. | ||||||
* @param string $group The group name. | ||||||
* | ||||||
* @psalm-param list<string|array{0:string,1:string}> $files | ||||||
*/ | ||||||
public function addMultiple( | ||||||
array $files, | ||||||
string $package, | ||||||
string $group, | ||||||
): void { | ||||||
$this->mergePlan[$group][$package] = $files; | ||||||
} | ||||||
|
||||||
/** | ||||||
* Add empty group if it doesn't exist. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* | ||||||
* @param string $group The group name. | ||||||
*/ | ||||||
public function addGroup(string $group): void | ||||||
{ | ||||||
if (!isset($this->mergePlan[$group])) { | ||||||
$this->mergePlan[$group] = []; | ||||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* Returns the merge plan as an array. | ||||||
* | ||||||
* @psalm-return MergePlanType | ||||||
*/ | ||||||
public function asArray(): array | ||||||
{ | ||||||
$groups = []; | ||||||
foreach ($this->mergePlan as $group => $packages) { | ||||||
$groups[$group] = $this->expandVariablesInPackages($packages); | ||||||
} | ||||||
|
||||||
$environments = []; | ||||||
foreach ($groups as $packages) { | ||||||
foreach ($packages as $files) { | ||||||
foreach ($files as $file) { | ||||||
if (is_array($file)) { | ||||||
$environments[$file[0]] = true; | ||||||
Check warning on line 96 in src/Composer/MergePlanCollector.php
|
||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
return [ | ||||||
'groups' => $groups, | ||||||
'environments' => array_keys($environments), | ||||||
]; | ||||||
} | ||||||
|
||||||
/** | ||||||
* @throws ErrorException | ||||||
* | ||||||
* @psalm-param array<string, list<FileType>> $packages | ||||||
* @psalm-return array<string, list<FileType>> | ||||||
*/ | ||||||
private function expandVariablesInPackages(array $packages, ?string $targetGroup = null): array | ||||||
{ | ||||||
if ($targetGroup !== null) { | ||||||
if (!isset($this->mergePlan[$targetGroup])) { | ||||||
throw new ErrorException( | ||||||
sprintf('The "%s" configuration group does not exist.', $targetGroup), | ||||||
severity: E_USER_ERROR | ||||||
); | ||||||
} | ||||||
|
||||||
if (isset($this->processedGroups[$targetGroup])) { | ||||||
throw new ErrorException('Circular references in configuration.', severity: E_USER_ERROR); | ||||||
} | ||||||
$this->processedGroups[$targetGroup] = true; | ||||||
$groupPackages = $this->expandVariablesInPackages($this->mergePlan[$targetGroup]); | ||||||
$this->processedGroups[$targetGroup] = null; | ||||||
|
||||||
$variable = '$' . $targetGroup; | ||||||
foreach ($groupPackages as $groupPackage => $groupItems) { | ||||||
$packageItems = $packages[$groupPackage] ?? []; | ||||||
$packages[$groupPackage] = in_array($variable, $packageItems, true) | ||||||
? $this->replaceVariableToFiles($packageItems, $variable, $groupItems) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
: array_merge($packageItems, $groupItems); | ||||||
} | ||||||
foreach ($packages as $package => $items) { | ||||||
$packages[$package] = array_values( | ||||||
array_filter( | ||||||
$items, | ||||||
static fn($item) => $item !== $variable, | ||||||
) | ||||||
); | ||||||
} | ||||||
uksort( | ||||||
$packages, | ||||||
static fn(string $a, string $b) => (self::PACKAGES_ORDER[$a] ?? 0) <=> (self::PACKAGES_ORDER[$b] ?? 0), | ||||||
Check warning on line 148 in src/Composer/MergePlanCollector.php
|
||||||
); | ||||||
} | ||||||
|
||||||
foreach ($packages as $items) { | ||||||
foreach ($items as $item) { | ||||||
if (!is_array($item) && Options::isVariable($item)) { | ||||||
return $this->expandVariablesInPackages($packages, substr($item, 1)); | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
return $packages; | ||||||
} | ||||||
|
||||||
/** | ||||||
* @psalm-param list<FileType> $items | ||||||
* @psalm-param list<FileType> $files | ||||||
* @psalm-return list<FileType> | ||||||
*/ | ||||||
private function replaceVariableToFiles(array $items, string $variable, array $files): array | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
{ | ||||||
$result = []; | ||||||
foreach ($items as $item) { | ||||||
if ($item === $variable) { | ||||||
$result = array_merge($result, $files); | ||||||
} else { | ||||||
$result[] = $item; | ||||||
} | ||||||
} | ||||||
return $result; | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.