94 lines
2.6 KiB
PHP
94 lines
2.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support\Release;
|
|
|
|
final class FeatureFlagRegistry
|
|
{
|
|
/**
|
|
* Return the raw modular release feature flag config.
|
|
*
|
|
* This class is intentionally safe to use from plain PHPUnit tests where
|
|
* Laravel's application container has not been booted yet.
|
|
*
|
|
* @return array<string, array<string, mixed>>
|
|
*/
|
|
public static function all(): array
|
|
{
|
|
$config = self::loadConfig();
|
|
|
|
return $config['feature_flags'] ?? $config['flags'] ?? [];
|
|
}
|
|
|
|
/**
|
|
* Export a normalized list of flags for release checks and generated docs.
|
|
*
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
public function export(): array
|
|
{
|
|
$flags = [];
|
|
|
|
foreach (self::all() as $key => $definition) {
|
|
$flags[] = [
|
|
'key' => (string) $key,
|
|
'owner' => (string) ($definition['owner'] ?? ''),
|
|
'default' => (bool) ($definition['default'] ?? false),
|
|
'removal_target' => $definition['removal_target'] ?? null,
|
|
'dimensions' => $definition['dimensions'] ?? [],
|
|
];
|
|
}
|
|
|
|
return $flags;
|
|
}
|
|
|
|
/**
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
public static function highRisk(): array
|
|
{
|
|
return array_values(array_filter(
|
|
(new self())->export(),
|
|
fn (array $flag): bool => ($flag['risk'] ?? null) === 'high'
|
|
));
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
private static function loadConfig(): array
|
|
{
|
|
if (class_exists(\Illuminate\Foundation\Application::class)
|
|
&& class_exists(\Illuminate\Container\Container::class)
|
|
) {
|
|
$container = \Illuminate\Container\Container::getInstance();
|
|
|
|
if ($container instanceof \Illuminate\Foundation\Application && $container->bound('config')) {
|
|
return ['flags' => $container['config']->get('modular_release.flags', [])];
|
|
}
|
|
}
|
|
|
|
$path = dirname(__DIR__, 3).'/config/modular_release.php';
|
|
|
|
if (! is_file($path)) {
|
|
return [];
|
|
}
|
|
|
|
$contents = file_get_contents($path);
|
|
|
|
if ($contents === false) {
|
|
return [];
|
|
}
|
|
|
|
if (! preg_match("/'flags'\s*=>\s*\[(.*?)\n\s*\],\s*\n\s*'rollout_tracks'/s", $contents, $matches)) {
|
|
return [];
|
|
}
|
|
|
|
/** @var array<string, array<string, mixed>> $flags */
|
|
$flags = eval('return ['.$matches[1].'];');
|
|
|
|
return ['flags' => is_array($flags) ? $flags : []];
|
|
}
|
|
}
|