p59
This commit is contained in:
@@ -96,6 +96,7 @@ final readonly class GenreSourceOfTruthGuard
|
||||
$coverageErrors = $this->validateConfigurationValueCoverage($configurationValues);
|
||||
array_push($errors, ...$coverageErrors);
|
||||
|
||||
$nativeValueNodes = $this->countGenreNativeValueNodes($configurationValues);
|
||||
$declaredSourcePaths = $this->collectSourcePaths($configurationValues);
|
||||
$uniqueSourcePaths = [];
|
||||
foreach ($declaredSourcePaths as $valuePath => $sourcePaths) {
|
||||
@@ -157,6 +158,7 @@ final readonly class GenreSourceOfTruthGuard
|
||||
|
||||
$summary = $this->summarizeRows($rows);
|
||||
$summary['configuration_value_groups'] = count($configurationValues);
|
||||
$summary['genre_native_value_nodes'] = $nativeValueNodes;
|
||||
$summary['source_path_value_nodes'] = count($declaredSourcePaths);
|
||||
$summary['declared_source_paths'] = count($uniqueSourcePaths);
|
||||
$summary['violations'] = count($errors);
|
||||
@@ -190,10 +192,15 @@ final readonly class GenreSourceOfTruthGuard
|
||||
{
|
||||
$sourcePaths = $value['source_paths'] ?? null;
|
||||
$hasSourcePaths = is_array($sourcePaths) && $sourcePaths !== [];
|
||||
$hasGenreNativeOrigin = $this->hasGenreNativeOrigin($value);
|
||||
if (array_key_exists('source_paths', $value) && !$hasSourcePaths && $path !== '') {
|
||||
$errors[] = sprintf('genre.configuration_values.%s.source_paths must be a non-empty list when declared.', $path);
|
||||
}
|
||||
|
||||
if (array_key_exists('origin', $value) && !$hasGenreNativeOrigin && $path !== '') {
|
||||
$errors[] = sprintf('genre.configuration_values.%s.origin must be genre_native when declared.', $path);
|
||||
}
|
||||
|
||||
if ($hasSourcePaths) {
|
||||
$seen = [];
|
||||
foreach ($sourcePaths as $sourcePath) {
|
||||
@@ -209,13 +216,13 @@ final readonly class GenreSourceOfTruthGuard
|
||||
}
|
||||
}
|
||||
|
||||
$covered = $coveredBySourcePath || $hasSourcePaths;
|
||||
$covered = $coveredBySourcePath || $hasSourcePaths || $hasGenreNativeOrigin;
|
||||
if ($path !== '' && !$covered && $this->hasDirectPayload($value)) {
|
||||
$errors[] = sprintf('genre.configuration_values.%s must declare source_paths or inherit them from a parent value node.', $path);
|
||||
}
|
||||
|
||||
foreach ($value as $key => $child) {
|
||||
if ($key === 'source_paths' || $key === 'description' || !is_string($key) || !is_array($child)) {
|
||||
if ($this->isMetadataKey($key) || !is_string($key) || !is_array($child)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -230,7 +237,7 @@ final readonly class GenreSourceOfTruthGuard
|
||||
private function hasDirectPayload(array $value): bool
|
||||
{
|
||||
foreach ($value as $key => $child) {
|
||||
if ($key === 'source_paths' || $key === 'description') {
|
||||
if ($this->isMetadataKey($key)) {
|
||||
continue;
|
||||
}
|
||||
if (!is_array($child)) {
|
||||
@@ -241,6 +248,45 @@ final readonly class GenreSourceOfTruthGuard
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** @param array<int|string, mixed> $value */
|
||||
private function hasGenreNativeOrigin(array $value): bool
|
||||
{
|
||||
$origin = $value['origin'] ?? null;
|
||||
|
||||
return is_string($origin) && trim($origin) === 'genre_native';
|
||||
}
|
||||
|
||||
private function isMetadataKey(mixed $key): bool
|
||||
{
|
||||
return $key === 'source_paths' || $key === 'description' || $key === 'origin';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $configurationValues
|
||||
*/
|
||||
private function countGenreNativeValueNodes(array $configurationValues): int
|
||||
{
|
||||
return $this->countGenreNativeValueNodesRecursive($configurationValues, '');
|
||||
}
|
||||
|
||||
/** @param array<int|string, mixed> $value */
|
||||
private function countGenreNativeValueNodesRecursive(array $value, string $path): int
|
||||
{
|
||||
$count = $path !== '' && $this->hasGenreNativeOrigin($value) ? 1 : 0;
|
||||
|
||||
foreach ($value as $key => $child) {
|
||||
if ($this->isMetadataKey($key) || !is_string($key) || !is_array($child)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$childPath = $path === '' ? $key : $path . '.' . $key;
|
||||
$count += $this->countGenreNativeValueNodesRecursive($child, $childPath);
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $configurationValues
|
||||
* @return array<string, string[]>
|
||||
@@ -277,7 +323,7 @@ final readonly class GenreSourceOfTruthGuard
|
||||
}
|
||||
|
||||
foreach ($value as $key => $child) {
|
||||
if ($key === 'source_paths' || $key === 'description' || !is_string($key) || !is_array($child)) {
|
||||
if ($this->isMetadataKey($key) || !is_string($key) || !is_array($child)) {
|
||||
continue;
|
||||
}
|
||||
$childPath = $path === '' ? $key : $path . '.' . $key;
|
||||
@@ -485,6 +531,7 @@ final readonly class GenreSourceOfTruthGuard
|
||||
'configuration_value_groups' => 0,
|
||||
'source_path_value_nodes' => 0,
|
||||
'declared_source_paths' => 0,
|
||||
'genre_native_value_nodes' => 0,
|
||||
'legacy_fallback_empty' => 0,
|
||||
'legacy_frozen_non_empty' => 0,
|
||||
'legacy_non_empty_unregistered' => 0,
|
||||
|
||||
Reference in New Issue
Block a user