Skip to content

Commit

Permalink
documentation & config validator as services, used by databox.
Browse files Browse the repository at this point in the history
  • Loading branch information
jygaulier committed Dec 5, 2024
1 parent 82ea1d5 commit e9a9626
Show file tree
Hide file tree
Showing 20 changed files with 528 additions and 272 deletions.
5 changes: 3 additions & 2 deletions databox/api/config/validator/validation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ App\Entity\Core\RenditionDefinition:
- workspace
- class.workspace
- parent.workspace
- App\Validator\ValidRenditionDefinitionConstraint: ~
properties:
class:
- NotNull: ~
Expand Down Expand Up @@ -176,8 +177,8 @@ App\Entity\Core\Tag:
errorPath: name

App\Entity\Integration\WorkspaceIntegration:
constraints:
- App\Validator\ValidIntegrationOptionsConstraint: ~
constraints:
- App\Validator\ValidIntegrationOptionsConstraint: ~

App\Entity\Integration\IntegrationData:
properties:
Expand Down
41 changes: 41 additions & 0 deletions databox/api/src/Command/DocumentationDumperCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

use Alchemy\RenditionFactory\DocumentationDumper as RenditionFactoryDocumentationDumper;


#[AsCommand('app:documentation:dump')]
class DocumentationDumperCommand extends Command
{
public function __construct(
private readonly RenditionFactoryDocumentationDumper $renditionFactoryDocumentationDumper,
)
{
parent::__construct();
}

protected function configure(): void
{
parent::configure();

$this
->setName('app:documentation:dump')
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln('# rendition factory');
$output->writeln($this->renditionFactoryDocumentationDumper->dump());

return 0;
}
}
15 changes: 15 additions & 0 deletions databox/api/src/Validator/ValidRenditionDefinitionConstraint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace App\Validator;

use Symfony\Component\Validator\Constraint;

class ValidRenditionDefinitionConstraint extends Constraint
{
public function getTargets(): string|array
{
return self::CLASS_CONSTRAINT;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace App\Validator;


use Alchemy\RenditionFactory\Config\Validator;
use Alchemy\RenditionFactory\Config\YamlLoader;
use App\Entity\Core\RenditionDefinition;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class ValidRenditionDefinitionConstraintValidator extends ConstraintValidator
{
public function __construct(private readonly YamlLoader $yamlLoader, private readonly Validator $validator)
{
}

/**
* @param RenditionDefinition $value
* @param ValidRenditionDefinitionConstraint $constraint
*/
public function validate($value, Constraint $constraint): void
{
try {
$config = $this->yamlLoader->parse($value->getDefinition());
$this->validator->validate($config);
} catch (\Throwable $e) {
$this->context
->buildViolation($e->getMessage())
->addViolation();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
autoconfigure: true

Alchemy\RenditionFactory\Command\CreateCommand: ~
Alchemy\RenditionFactory\Command\ConfigCommand: ~
Alchemy\RenditionFactory\Command\ConfigurationValidateCommand: ~

Alchemy\RenditionFactory\Context\TransformationContextFactory: ~
Alchemy\RenditionFactory\FileFamilyGuesser: ~
Expand Down Expand Up @@ -102,3 +102,9 @@ services:
Alchemy\RenditionFactory\Format\FormatGuesser: ~
Alchemy\RenditionFactory\Format\FormatFactory: ~
Alchemy\RenditionFactory\Config\ModuleOptionsResolver: ~

Alchemy\RenditionFactory\DocumentationDumper:
tags:
- { name: 'documentation.dumper' }

Alchemy\RenditionFactory\Config\Validator: ~
123 changes: 0 additions & 123 deletions lib/php/rendition-factory/src/Command/ConfigCommand.php

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Alchemy\RenditionFactory\Command;

use Alchemy\RenditionFactory\Config\Validator;
use Alchemy\RenditionFactory\Config\YamlLoader;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand('alchemy:rendition-factory:conf:validate')]
class ConfigurationValidateCommand extends Command
{
public function __construct(
private readonly YamlLoader $yamlLoader,
private readonly Validator $validator,
) {
parent::__construct();
}

protected function configure(): void
{
parent::configure();

$this->addArgument('config', InputArgument::REQUIRED, 'A build config YAML file to validate')
->setHelp('Validate a config file.')
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$config = $this->yamlLoader->load($input->getArgument('config'));
$this->validator->validate($config);

$output->writeln('Configuration is valid.');

return 0;
}
}
58 changes: 58 additions & 0 deletions lib/php/rendition-factory/src/Config/Validator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Alchemy\RenditionFactory\Config;

use Alchemy\RenditionFactory\DTO\BuildConfig\BuildConfig;
use Alchemy\RenditionFactory\DTO\FamilyEnum;
use Alchemy\RenditionFactory\Transformer\TransformerModuleInterface;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
use Symfony\Component\DependencyInjection\ServiceLocator;

class Validator
{
public function __construct(
#[TaggedLocator(TransformerModuleInterface::TAG, defaultIndexMethod: 'getName')]
private readonly ServiceLocator $transformers,
) {

}

public function getTransformers(): ServiceLocator
{
return $this->transformers;
}

public function validate(BuildConfig $config): void
{
foreach (FamilyEnum::cases() as $family) {
$familyConfig = $config->getFamily($family);
if (null === $familyConfig) {
continue;
}
foreach ($familyConfig->getTransformations() as $transformation) {
$transformerName = $transformation->getModule();

/** @var TransformerModuleInterface $transformer */
$transformer = $this->transformers->get($transformerName);

try {
$this->checkTransformerConfiguration($transformer, $transformation->toArray());
} catch (\Throwable $e) {
$msg = sprintf("Error in module \"%s\"\n%s", $transformerName, $e->getMessage());
throw new InvalidConfigurationException($msg);
}
}
}
}

private function checkTransformerConfiguration(TransformerModuleInterface $transformer, array $options): void
{
$documentation = $transformer->getDocumentation();
$treeBuilder = $documentation->getTreeBuilder();

$processor = new Processor();
$processor->process($treeBuilder->buildTree(), ['root' => $options]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function isEnabled(): bool
return $this->enabled;
}

public function asArray(): array
public function toArray(): array
{
return [
'module' => $this->module,
Expand Down
Loading

0 comments on commit e9a9626

Please sign in to comment.