Skip to content

Commit

Permalink
Merge pull request #28 from swiftotter/21-config-loader-changes
Browse files Browse the repository at this point in the history
#21 - Config loader changes, refactoring and cleanup
  • Loading branch information
michalbiarda authored Jun 23, 2022
2 parents 952f956 + a29d4ca commit a2a1f04
Show file tree
Hide file tree
Showing 13 changed files with 294 additions and 513 deletions.
File renamed without changes.
126 changes: 53 additions & 73 deletions src/System/Configuration.php
Original file line number Diff line number Diff line change
@@ -1,63 +1,58 @@
<?php
/**
* SwiftOtter_Base is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SwiftOtter_Base is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with SwiftOtter_Base. If not, see <http://www.gnu.org/licenses/>.
*
* @author Joseph Maxwell
* @copyright SwiftOtter Studios, 10/8/16
* @package default
**/

declare(strict_types=1);

namespace Driver\System;
use Driver\System\Configuration\YamlLoader;

use Driver\System\Configuration\FileCollector;
use Driver\System\Configuration\FileLoader;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Yaml;

use function array_keys;
use function array_merge;
use function array_reduce;
use function array_walk;
use function count;
use function explode;
use function is_array;
use function is_int;
use function is_string;

class Configuration
{
/** @var YamlLoader $loader */
protected $loader;

protected $nodes = [
'pipelines' => []
];
private FileCollector $fileCollector;
private FileLoader $loader;
private array $nodes = ['pipelines' => []];
private array $files = [];

protected $files = [];

public function __construct(YamlLoader $loader)
public function __construct(FileCollector $fileCollector, FileLoader $fileLoader)
{
$this->loader = $loader;
$this->fileCollector = $fileCollector;
$this->loader = $fileLoader;
}

public function getNodes()
public function getNodes(): array
{
if (!count($this->files)) {
$this->loadAllConfiguration();
foreach ($this->fileCollector->get() as $file) {
$this->loadConfigurationFor($file);
};
}

return $this->nodes;
}

/**
* @return mixed
*/
public function getNode($node)
{
$path = explode('/', $node);
$nodes = $this->getNodes();

return array_reduce($path, function($nodes, $item) {
if (isset($nodes[$item])) {
return $nodes[$item];
} else {
return null;
}
return $nodes[$item] ?? null;
}, $nodes);
}

Expand All @@ -68,7 +63,7 @@ public function getNodeString($node): string
return is_string($value) ? $value : '';
}

protected function loadConfigurationFor($file)
private function loadConfigurationFor($file): void
{
if (!isset($this->files[$file])) {
try {
Expand All @@ -89,11 +84,9 @@ protected function loadConfigurationFor($file)
throw $e;
}
}

return $this->files[$file];
}

private function recursiveMerge(array $array1, array $array2)
private function recursiveMerge(array $array1, array $array2): array
{
$merged = $array1;

Expand All @@ -111,10 +104,8 @@ private function recursiveMerge(array $array1, array $array2)

/**
* Special handling for pipelines as they don't exactly follow the key/value pattern.
*
* @param $input
*/
protected function mergePipelines($new)
private function mergePipelines(array $new): array
{
if (!isset($this->nodes['pipelines']) || !count($this->nodes['pipelines'])) {
return $new;
Expand Down Expand Up @@ -146,7 +137,7 @@ protected function mergePipelines($new)
}, []);
}

protected function mergePipeline($existing, $new)
private function mergePipeline($existing, $new)
{
array_walk($new, function($value) use (&$existing) {
$existing = $this->mergeStageIntoPipeline($existing, $value);
Expand All @@ -155,46 +146,35 @@ protected function mergePipeline($existing, $new)
return $existing;
}

protected function mergeStageIntoPipeline($existing, $newStage)
private function mergeStageIntoPipeline(array $existing, array $newStage): array
{
$matched = false;

$output = array_reduce(array_keys($existing), function($carry, $existingKey) use ($existing, $newStage, &$matched) {
$existingStage = $existing[$existingKey];
$currentMatch = isset($newStage['name']) && isset($existingStage['name']) && $newStage['name'] == $existingStage['name'];
$matched = $matched || $currentMatch;

if (!$currentMatch) {
return $carry;
}
$output = array_reduce(
array_keys($existing),
function($carry, $existingKey) use ($existing, $newStage, &$matched) {
$existingStage = $existing[$existingKey];
$currentMatch = isset($newStage['name'])
&& isset($existingStage['name'])
&& $newStage['name'] == $existingStage['name'];
$matched = $matched || $currentMatch;

if (!$currentMatch) {
return $carry;
}

$carry[$existingKey] = array_merge($existingStage, $newStage);
$carry[$existingKey]['actions'] = array_merge($existingStage['actions'], $newStage['actions']);
$carry[$existingKey] = array_merge($existingStage, $newStage);
$carry[$existingKey]['actions'] = array_merge($existingStage['actions'], $newStage['actions']);

return $carry;
}, $existing);
return $carry;
},
$existing
);

if (!$matched) {
$output[] = $newStage;
}

return $output;
}

protected function consolidateStage($existing, $new)
{

}

protected function stripFileExtension($file)
{
return pathinfo($file, PATHINFO_FILENAME);
}

protected function loadAllConfiguration()
{
foreach ($this->loader->get() as $file) {
$this->loadConfigurationFor((string)$file);
};
}
}
71 changes: 71 additions & 0 deletions src/System/Configuration/FileCollector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace Driver\System\Configuration;

use function array_filter;
use function array_map;
use function array_merge;
use function array_reverse;
use function array_unique;
use function file_exists;

class FileCollector
{
private const FILE_EXTENSION = '.yaml';
private const ALLOWED_FOLDERS = [
'config',
'config.d'
];
private const ALLOWED_FILES = [
'anonymize',
'pipelines',
'commands',
'engines',
'connections',
'config',
'reduce',
'environments'
];

/**
* @return string[]
*/
public function get(): array
{
$folderCollection = (new FolderCollectionFactory())->create(self::ALLOWED_FOLDERS);
$output = [];

foreach ($folderCollection as $folder) {
$files = array_filter(self::ALLOWED_FILES, function ($file) use ($folder) {
return file_exists($folder . '/' . $file . self::FILE_EXTENSION);
});

$output = array_merge($output, array_map(function ($file) use ($folder) {
return $folder . '/' . $file . self::FILE_EXTENSION;
}, $files));
}

return array_unique(array_reverse($output));
}

/**
* @return string[]
*/
public function getIndividual(string $file): array
{
$folderCollection = (new FolderCollectionFactory())->create(self::ALLOWED_FOLDERS);
$output = [];

foreach ($folderCollection as $folder) {
$path = $folder . '/' . $file . self::FILE_EXTENSION;

if (file_exists($path)) {
$output[] = $path;
}
}

return $output;
}
}
28 changes: 28 additions & 0 deletions src/System/Configuration/FileLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Driver\System\Configuration;

use Exception;

use function file_exists;

class FileLoader
{
/**
* Returns the contents of a file.
* @throws Exception
*/
public function load(string $file): string
{
if (!$file || !file_exists($file)) {
throw new Exception("{$file} doesn't exist.");
}
$content = file_get_contents($file);
if ($content === false) {
throw new Exception("Unable to load {$file}");
}
return $content;
}
}
46 changes: 46 additions & 0 deletions src/System/Configuration/FolderCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Driver\System\Configuration;

class FolderCollection implements \Iterator
{
/** @var string[] */
private array $folders;

private int $position = 0;

/**
* @param string[] $folders
*/
public function __construct(array $folders)
{
$this->folders = $folders;
}

public function current(): string
{
return $this->folders[$this->position];
}

public function next(): void
{
++$this->position;
}

public function key(): int
{
return $this->position;
}

public function valid(): bool
{
return isset($this->folders[$this->position]);
}

public function rewind(): void
{
$this->position = 0;
}
}
Loading

0 comments on commit a2a1f04

Please sign in to comment.