Lines
100.00%
17 / 17
Methods
100.00%
7 / 7
Classes
100.00%
1 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| mergeConfigTree | 100.00% | 8 / 8 | 100.00% | 1 / 1 | 3 | ||
| loadConfig | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| buildValidatedConfigTree | 100.00% | 3 / 3 | 100.00% | 1 / 1 | 1 | ||
| locateConfigFile | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| findMissingDefaultFile | 100.00% | 2 / 2 | 100.00% | 1 / 1 | 3 | ||
| readConfigFile | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 2 | ||
| 13 | final readonly class ConfigLoader | |
| 14 | { | |
| 15 | private const string DEFAULT_CONFIG_FILE = 'stewart.yaml'; | |
| 16 | ||
| 17 | public function __construct( | |
| 18 | private EnvironmentPlaceholders $placeholders, | |
| 19 | private EnvironmentOverlay $overlay, | |
| 20 | private ConfigFileReader $files, | |
| 21 | private ProjectRoot $projectRoot, | |
| 22 | private StewartConfigSchema $configuration, | |
| 23 | ) {} | |
| 24 | ||
| 25 | /** | |
| 26 | * @param array<string, mixed> $cliOverrides | |
| 27 | * @return array<array-key, mixed> | |
| 28 | * @throws ConfigurationException | |
| 29 | */ | |
| 30 | public function mergeConfigTree(?string $path, array $cliOverrides = []): array | |
| 31 | { | |
| 32 | $tree = $this->configuration->buildConfigTree(); | |
| 33 | $fileConfig = $this->placeholders->resolve($tree, $this->readConfigFile($path)); | |
| 34 | $configs = [$fileConfig, $this->overlay->collectEnvironmentOverrides($tree, $fileConfig)]; | |
| 35 | ||
| 36 | if ($cliOverrides !== []) { | |
| 37 | $configs[] = $cliOverrides; | |
| 38 | } | |
| 39 | ||
| 40 | try { | |
| 41 | return new Processor()->process($tree, $configs); | |
| 42 | } catch (InvalidConfigurationException $e) { | |
| 43 | throw ConfigurationException::createForReason(ConfigurationError::SchemaViolation, $e); | |
| 44 | } | |
| 45 | } | |
| 46 | ||
| 47 | /** | |
| 48 | * @param array<string, mixed> $cliOverrides | |
| 49 | * @throws ConfigurationException | |
| 50 | * @throws IdentifierException | |
| 51 | */ | |
| 52 | public function loadConfig(?string $path, array $cliOverrides = []): StewartConfig | |
| 53 | { | |
| 54 | return StewartConfig::fromSection(ConfigSection::forRoot($this->mergeConfigTree($path, $cliOverrides))); | |
| 55 | } | |
| 56 | ||
| 57 | /** | |
| 58 | * @return array<array-key, mixed> | |
| 59 | * @throws ConfigurationException | |
| 60 | * @throws IdentifierException | |
| 61 | */ | |
| 62 | public function buildValidatedConfigTree(?string $path): array | |
| 63 | { | |
| 64 | $tree = $this->mergeConfigTree($path); | |
| 65 | StewartConfig::fromSection(ConfigSection::forRoot($tree)); | |
| 66 | ||
| 67 | return $tree; | |
| 68 | } | |
| 69 | ||
| 70 | public function locateConfigFile(?string $path): string | |
| 71 | { | |
| 72 | return $path ?? $this->projectRoot->resolvePath(self::DEFAULT_CONFIG_FILE); | |
| 73 | } | |
| 74 | ||
| 75 | public function findMissingDefaultFile(?string $path): ?string | |
| 76 | { | |
| 77 | $defaultFile = $this->locateConfigFile(null); | |
| 78 | ||
| 79 | return $path === null && !is_file($defaultFile) ? $defaultFile : null; | |
| 80 | } | |
| 81 | ||
| 82 | /** | |
| 83 | * @return array<array-key, mixed> | |
| 84 | * @throws ConfigurationException | |
| 85 | */ | |
| 86 | private function readConfigFile(?string $path): array | |
| 87 | { | |
| 88 | // Container setups may configure everything through the environment. | |
| 89 | return $this->findMissingDefaultFile($path) !== null ? [] : $this->files->readYamlMap($this->locateConfigFile($path)); | |
| 90 | } | |
| 91 | } |