diff --git a/composer.json b/composer.json index 9d95850..b7c08b6 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,7 @@ "illuminate/support": "^9.50", "symfony/console": "^6.2", "symfony/filesystem": "^6.2", + "symfony/validator": "^6.2", "symfony/yaml": "^6.2", "twig/twig": "^3.5" }, diff --git a/composer.lock b/composer.lock index 7bf7131..4bb2079 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2920bd7876ea4f69e4b8a8fc1033ff31", + "content-hash": "61a819cfeb5a3812904360f37d501b98", "packages": [ { "name": "amphp/amp", @@ -3458,6 +3458,114 @@ ], "time": "2022-11-25T10:21:52+00:00" }, + { + "name": "symfony/validator", + "version": "v6.2.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/validator.git", + "reference": "0ebfbe384790e61147e3d7f4aa0afbd6190198c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/validator/zipball/0ebfbe384790e61147e3d7f4aa0afbd6190198c4", + "reference": "0ebfbe384790e61147e3d7f4aa0afbd6190198c4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^1.1|^2|^3" + }, + "conflict": { + "doctrine/annotations": "<1.13", + "doctrine/lexer": "<1.1", + "phpunit/phpunit": "<5.4.3", + "symfony/dependency-injection": "<5.4", + "symfony/expression-language": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/intl": "<5.4", + "symfony/property-info": "<5.4", + "symfony/translation": "<5.4", + "symfony/yaml": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.13|^2", + "egulias/email-validator": "^2.1.10|^3|^4", + "symfony/cache": "^5.4|^6.0", + "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/intl": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/translation": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "egulias/email-validator": "Strict (RFC compliant) email validation", + "psr/cache-implementation": "For using the mapping cache.", + "symfony/config": "", + "symfony/expression-language": "For using the Expression validator and the ExpressionLanguageSyntax constraints", + "symfony/http-foundation": "", + "symfony/intl": "", + "symfony/property-access": "For accessing properties within comparison constraints", + "symfony/property-info": "To automatically add NotNull and Type constraints", + "symfony/translation": "For translating validation errors.", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Validator\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to validate values", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/validator/tree/v6.2.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-20T17:45:48+00:00" + }, { "name": "symfony/var-dumper", "version": "v6.2.3", diff --git a/src/Console/Command/BuildConfigurationCommand.php b/src/Console/Command/BuildConfigurationCommand.php index 49a572f..c80d291 100644 --- a/src/Console/Command/BuildConfigurationCommand.php +++ b/src/Console/Command/BuildConfigurationCommand.php @@ -15,6 +15,9 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; 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 Twig\Environment; @@ -53,8 +56,51 @@ final class BuildConfigurationCommand extends Command $io = new SymfonyStyle($input, $output); $configurationData = Yaml::parseFile($configFile); - $configurationData['dockerCompose'] = $configurationData['docker-compose']; - $configurationData['docker-compose'] = null; + + $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(), + + 'docker-compose' => new Assert\Optional(), + + 'dockerfile' => new Assert\Optional(), + + 'php' => new Assert\Optional(), + ], + ); + + $violations = $validator->validate($configurationData, $constraint, $groups); + if (0 < $violations->count()) { + $io->error('Configuration is invalid.'); + + $io->listing( + collect($violations) + ->map(fn(ConstraintViolation $v) => "{$v->getInvalidValue()} - {$v->getMessage()}") + ->toArray() + ); + + return Command::FAILURE; + } if (isset($configurationData['docker-compose'])) { $configurationData['dockerCompose'] = $configurationData['docker-compose'];