Skip to content
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

#21 - Config loader changes, refactoring and cleanup #28

Merged
merged 1 commit into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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