refactor: extract a configuration validator

This commit is contained in:
Oliver Davies 2023-02-22 15:03:01 +00:00
parent 46747d2bf8
commit a70557d2d5
4 changed files with 77 additions and 43 deletions

View file

@ -2,6 +2,7 @@
<?php <?php
use OliverDaviesLtd\BuildConfigs\Console\Command\BuildConfigurationCommand; use OliverDaviesLtd\BuildConfigs\Console\Command\BuildConfigurationCommand;
use OliverDaviesLtd\BuildConfigs\Validator\ConfigurationValidator;
use Symfony\Component\Console\Application; use Symfony\Component\Console\Application;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
use Twig\Environment; use Twig\Environment;
@ -11,11 +12,13 @@ require __DIR__ . '/../vendor/autoload.php';
$filesystem = new Filesystem(); $filesystem = new Filesystem();
$twig = new Environment(new FilesystemLoader([__DIR__.'/../templates'])); $twig = new Environment(new FilesystemLoader([__DIR__.'/../templates']));
$configurationValidator = new ConfigurationValidator();
$application = new Application(); $application = new Application();
$command = new BuildConfigurationCommand($twig, $filesystem, $configurationValidator);
$application->addCommands([ $application->addCommands([
new BuildConfigurationCommand($twig, $filesystem), new BuildConfigurationCommand($twig, $filesystem, $configurationValidator),
]); ]);
$application->setDefaultCommand('build-configs', true); $application->setDefaultCommand('build-configs', true);

View file

@ -8,6 +8,7 @@ use Illuminate\Support\Arr;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use OliverDaviesLtd\BuildConfigs\Enum\Language; use OliverDaviesLtd\BuildConfigs\Enum\Language;
use OliverDaviesLtd\BuildConfigs\Enum\WebServer; use OliverDaviesLtd\BuildConfigs\Enum\WebServer;
use OliverDaviesLtd\BuildConfigs\Validator\ConfigurationValidator;
use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@ -15,9 +16,6 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\Validation;
use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Yaml;
use Twig\Environment; use Twig\Environment;
@ -35,6 +33,7 @@ final class BuildConfigurationCommand extends Command
public function __construct( public function __construct(
private Environment $twig, private Environment $twig,
private Filesystem $filesystem, private Filesystem $filesystem,
private ConfigurationValidator $configurationValidator,
) { ) {
parent::__construct(); parent::__construct();
@ -57,46 +56,8 @@ final class BuildConfigurationCommand extends Command
$configurationData = Yaml::parseFile($configFile); $configurationData = Yaml::parseFile($configFile);
$validator = Validation::createValidator(); $violations = $this->configurationValidator->validate($configurationData);
$groups = new Assert\GroupSequence(['Default', 'custom']);
$constraint = new Assert\Collection(
[
'name' => [
new Assert\NotNull(),
new Assert\Type('string'),
new Assert\Length(['min' => 1]),
],
'language' => [
new Assert\NotNull(),
new Assert\Type('string'),
new Assert\Choice(['php']),
],
'type' => [
new Assert\NotNull(),
new Assert\Type('string'),
new Assert\Choice(['drupal-project', 'php-library']),
],
'database' => new Assert\Optional(),
'drupal' => new Assert\Optional(),
'docker-compose' => new Assert\Optional(),
'dockerfile' => new Assert\Optional(),
// TODO: this should be a boolean if present.
'justfile' => new Assert\Optional(),
'php' => new Assert\Optional(),
'web' => new Assert\Optional(),
],
);
$violations = $validator->validate($configurationData, $constraint, $groups);
if (0 < $violations->count()) { if (0 < $violations->count()) {
$io->error('Configuration is invalid.'); $io->error('Configuration is invalid.');

View file

@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace OliverDaviesLtd\BuildConfigs\Validator;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Validation;
final class ConfigurationValidator implements ValidatorInterface
{
public function validate(array $configurationData): ConstraintViolationListInterface
{
$validator = Validation::createValidator();
$groups = new Assert\GroupSequence(['Default', 'custom']);
$constraint = new Assert\Collection(
[
'name' => [
new Assert\NotNull(),
new Assert\Type('string'),
new Assert\Length(['min' => 1]),
],
'language' => [
new Assert\NotNull(),
new Assert\Type('string'),
new Assert\Choice(['php']),
],
'type' => [
new Assert\NotNull(),
new Assert\Type('string'),
new Assert\Choice(['drupal-project', 'php-library']),
],
'database' => new Assert\Optional(),
'drupal' => new Assert\Optional(),
'docker-compose' => new Assert\Optional(),
'dockerfile' => new Assert\Optional(),
// TODO: this should be a boolean if present.
'justfile' => new Assert\Optional(),
'php' => new Assert\Optional(),
'web' => new Assert\Optional(),
],
);
return $validator->validate($configurationData, $constraint, $groups);
}
}

View file

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace OliverDaviesLtd\BuildConfigs\Validator;
use Symfony\Component\Validator\ConstraintViolationListInterface;
interface ValidatorInterface
{
public function validate(array $configurationData): ConstraintViolationListInterface;
}