Skip to content

Conversation

@GromNaN
Copy link
Member

@GromNaN GromNaN commented Oct 21, 2025

Q A
Branch? 7.4
Bug fix? no
New feature? yes
Deprecations? no
Issues Fix #59603
License MIT

Supersede #59620, but generate nested objects instead of flatten definitions with hash as id. This is easier to read.

This PR only take care of the generating a JSON schema from a config node.
I also wrote this script that can be put in a composer plugin or a standalone script to generate a unique schema file for all the environments.

<?php

use Symfony\Component\Config\Builder\JsonSchemaGenerator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
use Symfony\Component\HttpKernel\Bundle\BundleInterface;

require_once __DIR__.'/vendor/autoload.php';
$bundles = require __DIR__.'/config/bundles.php';

$jsonschemaGenerator = new JsonSchemaGenerator();
$container = new ContainerBuilder();
// The debug parameter can vary based on the environment
$container->setParameter('kernel.debug', true);

$schema = (object) [
    '$schema' => 'http://json-schema.org/draft-07/schema#',
    'type' => 'object',
    'additionalProperties' => false,
    'properties' => new \stdClass(),
    '$defs' => new \stdClass(),
];

$allEnvs = ['dev', 'prod', 'test'];
foreach ($allEnvs as $env) {
    $schema->properties->{'when@' . $env} = (object)[
        'type' => 'object',
        'properties' => new \stdClass(),
        'additionalProperties' => false,
    ];
}

foreach ($bundles as $class => $envs) {
    $bundle = new $class();
    assert($bundle instanceof BundleInterface);
    $extension = $bundle->getContainerExtension();
    if ($extension instanceof ConfigurationExtensionInterface) {
        $configuration = $extension->getConfiguration([], $container);
        if ($configuration) {
            $node = $configuration->getConfigTreeBuilder()->buildTree();

            $name = $node->getName();
            $ref = (object) ['$ref' => '#/$defs/'.$name];
            $schema->{'$defs'}->{$name} = $jsonschemaGenerator->generate($node);

            if ($envs === ['all' => true]) {
                $schema->properties->{$name} = $ref;
                $envs = $allEnvs;
            } else {
                $envs = array_keys(array_filter($envs));
            }

            foreach ($envs as $env) {
                $schema->properties->{'when@'.$env}->properties->{$name} = $ref;
            }
        }
    }
}

file_put_contents(__DIR__.'/config/schema.json', json_encode($schema, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_THROW_ON_ERROR));

Comment on lines +221 to +224
if ($_ENV['TEST_GENERATE_FIXTURES'] ?? false) {
file_put_contents(__DIR__ . '/../Fixtures/Configuration/ExampleConfiguration.schema.json', $jsonSchema);
$this->markTestIncomplete('TEST_GENERATE_FIXTURES is set');
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same pattern proposed in #62121

@stof
Copy link
Member

stof commented Oct 21, 2025

I also wrote this script that can be put in a composer plugin or a standalone script to generate a unique schema file for all the environments.

if you expect such script to be a supported use case, the JsonSchemaGenerator should not be an internal class, as this script relies on using this class.

@GromNaN GromNaN force-pushed the dx-config-schema-v2 branch 2 times, most recently from 4239dc4 to 93c3cbb Compare October 22, 2025 16:30

if ($node->isDeprecated()) {
$schema['deprecated'] = true;
$schema['deprecationMessage'] = $node->getDeprecationMessage($node);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deprecationMessage is not a JSON Schema key. This info should move to description.

@nicolas-grekas nicolas-grekas modified the milestones: 7.4, 8.1 Nov 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DX][Config] Generate JSON schema for Yaml configuration

5 participants