Skip to content

Commit

Permalink
Rework namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Korbeil committed Nov 22, 2020
0 parents commit 9663567
Show file tree
Hide file tree
Showing 284 changed files with 16,458 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/Tests/ export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/phpunit.xml export-ignore
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
vendor
composer.lock

Tests/generated/*
!Tests/generated/.gitkeep
Tests/fixtures/*/generated
32 changes: 32 additions & 0 deletions Application.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Jane\Component\JsonSchema;

use Jane\Component\JsonSchema\Console\Command\DumpConfigCommand;
use Jane\Component\JsonSchema\Console\Command\GenerateCommand;
use Jane\Component\JsonSchema\Console\Loader\ConfigLoader;
use Jane\Component\JsonSchema\Console\Loader\SchemaLoader;
use Symfony\Component\Console\Application as BaseApplication;

class Application extends BaseApplication
{
public const VERSION = '6.x-dev';

/**
* Constructor.
*/
public function __construct()
{
parent::__construct('Jane', self::VERSION);

$this->boot();
}

protected function boot(): void
{
$configLoader = new ConfigLoader();

$this->add(new GenerateCommand($configLoader, new SchemaLoader()));
$this->add(new DumpConfigCommand($configLoader));
}
}
36 changes: 36 additions & 0 deletions Console/Command/DumpConfigCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Jane\Component\JsonSchema\Console\Command;

use Jane\Component\JsonSchema\Console\Loader\ConfigLoaderInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\VarDumper\VarDumper;

class DumpConfigCommand extends Command
{
/** @var ConfigLoaderInterface */
protected $configLoader;

public function __construct(ConfigLoaderInterface $configLoader)
{
parent::__construct(null);
$this->configLoader = $configLoader;
}

public function configure()
{
$this->setName('dump-config');
$this->setDescription('Dump Jane configuration for debugging purpose');
$this->addOption('config-file', 'c', InputOption::VALUE_REQUIRED, 'File to use for Jane configuration', '.jane');
}

public function execute(InputInterface $input, OutputInterface $output)
{
VarDumper::dump($this->configLoader->load($input->getOption('config-file')));

return 0;
}
}
104 changes: 104 additions & 0 deletions Console/Command/GenerateCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

namespace Jane\Component\JsonSchema\Console\Command;

use Jane\Component\JsonSchema\Console\Loader\ConfigLoaderInterface;
use Jane\Component\JsonSchema\Console\Loader\SchemaLoaderInterface;
use Jane\Component\JsonSchema\Jane;
use Jane\Component\JsonSchema\Printer;
use Jane\Component\JsonSchema\Registry\Registry;
use Jane\Component\JsonSchema\Registry\RegistryInterface;
use PhpParser\PrettyPrinter\Standard;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class GenerateCommand extends Command
{
/** @var ConfigLoaderInterface */
protected $configLoader;

/** @var SchemaLoaderInterface */
protected $schemaLoader;

public function __construct(ConfigLoaderInterface $configLoader, SchemaLoaderInterface $schemaLoader)
{
parent::__construct(null);
$this->configLoader = $configLoader;
$this->schemaLoader = $schemaLoader;
}

/**
* {@inheritdoc}
*/
public function configure()
{
$this->setName('generate');
$this->setDescription('Generate a set of class and normalizers given a specific Json Schema file');
$this->addOption('config-file', 'c', InputOption::VALUE_REQUIRED, 'File to use for Jane configuration', '.jane');
}

/**
* {@inheritdoc}
*/
public function execute(InputInterface $input, OutputInterface $output)
{
$options = $this->configLoader->load($input->getOption('config-file'));
$registries = $this->registries($options);

foreach ($registries as $registry) {
$jane = Jane::build($options);
$fixerConfigFile = '';

if (\array_key_exists('fixer-config-file', $options) && null !== $options['fixer-config-file']) {
$fixerConfigFile = $options['fixer-config-file'];
}

$printer = new Printer(new Standard(), $fixerConfigFile);

if (\array_key_exists('use-fixer', $options) && \is_bool($options['use-fixer'])) {
$printer->setUseFixer($options['use-fixer']);
}
if (\array_key_exists('clean-generated', $options) && \is_bool($options['clean-generated'])) {
$printer->setCleanGenerated($options['clean-generated']);
}

$jane->generate($registry);
$printer->output($registry);
}

return 0;
}

protected function registries(array $options): array
{
$registries = [];
if (\array_key_exists($fileKey = $this->configLoader->fileKey(), $options)) {
$localRegistry = $this->newRegistry($options[$fileKey], $options);
$localRegistry->addSchema($this->schemaLoader->resolve($options[$fileKey], $options));
$localRegistry->addOutputDirectory($options['directory']);

$registries[] = $localRegistry;
} else {
foreach ($options['mapping'] as $schema => $schemaOptions) {
$mappedSchema = $this->schemaLoader->resolve($schema, $schemaOptions);
$mappedRegistry = $this->newRegistry($schema, $schemaOptions);

if (!\array_key_exists($hash = $mappedRegistry->getOptionsHash(), $registries)) {
$registries[$hash] = $mappedRegistry;
}

$registries[$hash]->addSchema($mappedSchema);
$registries[$hash]->addOutputDirectory($schemaOptions['directory']);
}
}

return $registries;
}

protected function newRegistry(string $schemaFile, array $options): RegistryInterface
{
return new Registry();
}
}
72 changes: 72 additions & 0 deletions Console/Loader/ConfigLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

namespace Jane\Component\JsonSchema\Console\Loader;

use Symfony\Component\OptionsResolver\OptionsResolver;

class ConfigLoader implements ConfigLoaderInterface
{
public function fileKey(): string
{
return 'json-schema-file';
}

public function load(string $path): array
{
if (!file_exists($path)) {
throw new \RuntimeException(sprintf('Config file %s does not exist', $path));
}

$options = require $path;

if (!\is_array($options)) {
throw new \RuntimeException(sprintf('Invalid config file specified or invalid return type in file %s', $path));
}

return $this->resolveConfiguration($options);
}

protected function resolveConfiguration(array $options = [])
{
$optionsResolver = new OptionsResolver();
$optionsResolver->setDefaults($this->resolveConfigurationDefaults());

if (\array_key_exists($this->fileKey(), $options)) {
$optionsResolver->setRequired($this->resolveConfigurationRequired());
} else {
$optionsResolver->setRequired([
'mapping',
]);
}

return $optionsResolver->resolve($options);
}

protected function resolveConfigurationRequired(): array
{
return [
$this->fileKey(),
'root-class',
'namespace',
'directory',
];
}

protected function resolveConfigurationDefaults(): array
{
return [
'reference' => true,
'strict' => true,
'date-format' => \DateTime::RFC3339,
'full-date-format' => 'Y-m-d',
'date-prefer-interface' => null,
'date-input-format' => null,
'use-fixer' => false,
'fixer-config-file' => null,
'clean-generated' => true,
'use-cacheable-supports-method' => null,
'skip-null-values' => true,
'skip-required-fields' => false,
];
}
}
10 changes: 10 additions & 0 deletions Console/Loader/ConfigLoaderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Jane\Component\JsonSchema\Console\Loader;

interface ConfigLoaderInterface
{
public function fileKey(): string;

public function load(string $path): array;
}
54 changes: 54 additions & 0 deletions Console/Loader/SchemaLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Jane\Component\JsonSchema\Console\Loader;

use Jane\Component\JsonSchema\Registry\Schema;
use Jane\Component\JsonSchema\Registry\SchemaInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class SchemaLoader implements SchemaLoaderInterface
{
public function resolve(string $schema, array $options = []): SchemaInterface
{
$optionsResolver = new OptionsResolver();

$optionsResolver->setDefined($this->getDefinedOptions());
$optionsResolver->setRequired($this->getRequiredOptions());
$options = $optionsResolver->resolve($options);

return $this->newSchema($schema, $options);
}

protected function newSchema(string $schema, array $options): SchemaInterface
{
return new Schema($schema, $options['namespace'], $options['directory'], $options['root-class'] ?? '');
}

protected function getDefinedOptions(): array
{
return [
'json-schema-file',
'reference',
'date-format',
'full-date-format',
'date-prefer-interface',
'date-input-format',
'strict',
'use-fixer',
'fixer-config-file',
'clean-generated',
'use-cacheable-supports-method',
'skip-null-values',
'skip-required-fields',
];
}

protected function getRequiredOptions(): array
{
return [
'root-class',
'namespace',
'directory',
];
}
}
10 changes: 10 additions & 0 deletions Console/Loader/SchemaLoaderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Jane\Component\JsonSchema\Console\Loader;

use Jane\Component\JsonSchema\Registry\SchemaInterface;

interface SchemaLoaderInterface
{
public function resolve(string $schema, array $options = []): SchemaInterface;
}
32 changes: 32 additions & 0 deletions Generator/ChainGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Jane\Component\JsonSchema\Generator;

use Jane\Component\JsonSchema\Generator\Context\Context;
use Jane\Component\JsonSchema\Registry\Registry;

abstract class ChainGenerator
{
/** @var GeneratorInterface[] */
private $generators = [];

public function addGenerator(GeneratorInterface $generator): void
{
$this->generators[] = $generator;
}

abstract protected function createContext(Registry $registry): Context;

public function generate(Registry $registry): void
{
$context = $this->createContext($registry);

foreach ($registry->getSchemas() as $schema) {
$context->setCurrentSchema($schema);

foreach ($this->generators as $generator) {
$generator->generate($schema, $schema->getRootName(), $context);
}
}
}
}
Loading

0 comments on commit 9663567

Please sign in to comment.