Use class constants to define config schema, rather than config-schema.yaml
Instead of maintaining the config schema as a yaml file, we maintain it as a set of constants in a class. From the information in these constants, we can generate a JSON schema (yaml) file, and an php file containing optimized arrays for fast loading. Advantages: - PHP doc available to IDEs. The generated markdown file is no longer needed. - Can use PHP constants when defining default values. NOTE: needs backport to 1.38 Change-Id: I663c08b8a200644cbe7e5f65c20f1592a4f3974d
This commit is contained in:
parent
5ec380a8f6
commit
2fe23d6860
13 changed files with 13229 additions and 8509 deletions
|
|
@ -286,6 +286,7 @@ $wgAutoloadLocalClasses = [
|
|||
'Config' => __DIR__ . '/includes/config/Config.php',
|
||||
'ConfigException' => __DIR__ . '/includes/config/ConfigException.php',
|
||||
'ConfigFactory' => __DIR__ . '/includes/config/ConfigFactory.php',
|
||||
'ConfigSchemaDerivativeTrait' => __DIR__ . '/maintenance/includes/ConfigSchemaDerivativeTrait.php',
|
||||
'ConfiguredReadOnlyMode' => __DIR__ . '/includes/ConfiguredReadOnlyMode.php',
|
||||
'ConstantDependency' => __DIR__ . '/includes/cache/dependency/ConstantDependency.php',
|
||||
'Content' => __DIR__ . '/includes/content/Content.php',
|
||||
|
|
@ -541,8 +542,8 @@ $wgAutoloadLocalClasses = [
|
|||
'GanConverter' => __DIR__ . '/includes/language/converters/GanConverter.php',
|
||||
'GenderCache' => __DIR__ . '/includes/cache/GenderCache.php',
|
||||
'GenerateCollationData' => __DIR__ . '/maintenance/language/generateCollationData.php',
|
||||
'GenerateConfigDoc' => __DIR__ . '/maintenance/generateConfigDoc.php',
|
||||
'GenerateConfigSchema' => __DIR__ . '/maintenance/generateConfigSchema.php',
|
||||
'GenerateConfigSchemaArray' => __DIR__ . '/maintenance/generateConfigSchemaArray.php',
|
||||
'GenerateConfigSchemaYaml' => __DIR__ . '/maintenance/generateConfigSchemaYaml.php',
|
||||
'GenerateJsonI18n' => __DIR__ . '/maintenance/generateJsonI18n.php',
|
||||
'GenerateNormalizerDataAr' => __DIR__ . '/maintenance/language/generateNormalizerDataAr.php',
|
||||
'GenerateNormalizerDataMl' => __DIR__ . '/maintenance/language/generateNormalizerDataMl.php',
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
11903
includes/MainConfigSchema.php
Normal file
11903
includes/MainConfigSchema.php
Normal file
File diff suppressed because it is too large
Load diff
97
includes/Settings/Source/ReflectionSchemaSource.php
Normal file
97
includes/Settings/Source/ReflectionSchemaSource.php
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
namespace MediaWiki\Settings\Source;
|
||||
|
||||
use MediaWiki\Settings\SettingsBuilderException;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
|
||||
/**
|
||||
* Constructs a settings array based on a PHP class by inspecting class
|
||||
* members to construct a schema.
|
||||
*
|
||||
* @since 1.38
|
||||
*/
|
||||
class ReflectionSchemaSource implements SettingsSource {
|
||||
|
||||
/**
|
||||
* Name of a PHP class
|
||||
* @var string
|
||||
*/
|
||||
private $class;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $includeDoc;
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param bool $includeDoc
|
||||
*/
|
||||
public function __construct( string $class, bool $includeDoc = false ) {
|
||||
$this->class = $class;
|
||||
$this->includeDoc = $includeDoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SettingsBuilderException
|
||||
* @return array
|
||||
*/
|
||||
public function load(): array {
|
||||
$schemas = [];
|
||||
|
||||
try {
|
||||
$class = new ReflectionClass( $this->class );
|
||||
foreach ( $class->getReflectionConstants() as $const ) {
|
||||
if ( !$const->isPublic() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = $const->getName();
|
||||
$value = $const->getValue();
|
||||
|
||||
if ( !is_array( $value ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $this->includeDoc ) {
|
||||
$doc = $const->getDocComment();
|
||||
if ( $doc ) {
|
||||
$value['description'] = $this->normalizeComment( $doc );
|
||||
}
|
||||
}
|
||||
|
||||
$schemas[ $name ] = $value;
|
||||
}
|
||||
} catch ( ReflectionException $e ) {
|
||||
throw new SettingsBuilderException(
|
||||
'Failed to load schema from class {class}',
|
||||
[ 'class' => $this->class ],
|
||||
0,
|
||||
$e
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
'config-schema' => $schemas
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this file source as a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string {
|
||||
return 'class ' . $this->class;
|
||||
}
|
||||
|
||||
private function normalizeComment( string $doc ) {
|
||||
$doc = preg_replace( '/^\s*\/\*+\s*|\s*\*+\/\s*$/s', '', $doc );
|
||||
$doc = preg_replace( '/^\s*\**$/m', " ", $doc );
|
||||
$doc = preg_replace( '/^\s*\**[ \t]?/m', '', $doc );
|
||||
return $doc;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -289,8 +289,8 @@ return [
|
|||
'CopyUploadTimeout' => [
|
||||
'default' => false,
|
||||
'type' => [
|
||||
0 => 'integer',
|
||||
1 => 'boolean',
|
||||
0 => 'boolean',
|
||||
1 => 'integer',
|
||||
],
|
||||
],
|
||||
'MaxUploadSize' => [
|
||||
|
|
@ -3394,9 +3394,6 @@ return [
|
|||
'UseAutomaticEditSummaries' => [
|
||||
'default' => true,
|
||||
],
|
||||
'CommandLineMode' => [
|
||||
'default' => false,
|
||||
],
|
||||
'CommandLineDarkBg' => [
|
||||
'default' => false,
|
||||
],
|
||||
|
|
@ -4234,7 +4231,7 @@ return [
|
|||
'type' => [
|
||||
0 => 'string',
|
||||
1 => 'boolean',
|
||||
2 => null,
|
||||
2 => 'null',
|
||||
],
|
||||
],
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,102 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Convert a JSON abstract schema to a schema file in the given DBMS type
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @ingroup Maintenance
|
||||
*/
|
||||
|
||||
use MediaWiki\Settings\Source\FileSource;
|
||||
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
/**
|
||||
* Maintenance script to generate doc/configuration.md from
|
||||
* includes/config-schema.yaml
|
||||
*
|
||||
* @ingroup Maintenance
|
||||
*/
|
||||
class GenerateConfigDoc extends Maintenance {
|
||||
/** @var string */
|
||||
private const DEFAULT_INPUT_PATH = 'includes/config-schema.yaml';
|
||||
|
||||
/** @var string */
|
||||
private const DEFAULT_OUTPUT_PATH = 'docs/Configuration.md';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->addDescription( 'Build Configuration.md file from config-schema.yaml' );
|
||||
|
||||
$this->addOption(
|
||||
'schema',
|
||||
'Path to the config schema file relative to $IP. Default: ' . self::DEFAULT_INPUT_PATH,
|
||||
false,
|
||||
true
|
||||
);
|
||||
$this->addOption(
|
||||
'output',
|
||||
'Path to output relative to $IP. Default: ' . self::DEFAULT_OUTPUT_PATH,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
$input = ( new FileSource( $this->getInputPath() ) )->load();
|
||||
|
||||
$result = "<!-- This file is automatically generated using maintenance/generateConfigDoc.php. -->\n";
|
||||
$result .= "<!-- Do not edit this file directly. -->\n";
|
||||
$result .= "<!-- See maintenance/generateConfigDoc.php for instructions. -->\n";
|
||||
|
||||
$result .= "This is a list of configuration variables that can be set in LocalSettings.php.\n\n";
|
||||
|
||||
// Table of contents
|
||||
$result .= "[TOC]\n\n";
|
||||
|
||||
// Details about each config variable
|
||||
foreach ( $input['config-schema'] as $configKey => $configSchema ) {
|
||||
$result .= "# $configKey {#$configKey}\n";
|
||||
if ( array_key_exists( 'description', $configSchema ) ) {
|
||||
$result .= $configSchema['description'];
|
||||
}
|
||||
$result .= "\n\n";
|
||||
}
|
||||
|
||||
file_put_contents( $this->getOutputPath(), $result );
|
||||
}
|
||||
|
||||
private function getInputPath(): string {
|
||||
global $IP;
|
||||
$inputPath = $this->getOption( 'schema', self::DEFAULT_INPUT_PATH );
|
||||
return $IP . DIRECTORY_SEPARATOR . $inputPath;
|
||||
}
|
||||
|
||||
private function getOutputPath(): string {
|
||||
global $IP;
|
||||
$outputPath = $this->getOption( 'output', self::DEFAULT_OUTPUT_PATH );
|
||||
if ( $outputPath === '-' || $outputPath === 'php://stdout' ) {
|
||||
return 'php://stdout';
|
||||
}
|
||||
return $IP . DIRECTORY_SEPARATOR . $outputPath;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$maintClass = GenerateConfigDoc::class;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
<?php
|
||||
|
||||
use MediaWiki\Settings\Source\FileSource;
|
||||
use Wikimedia\StaticArrayWriter;
|
||||
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
/**
|
||||
* Maintenance script that generates the PHP representation of the config-schema.yaml file.
|
||||
*
|
||||
* @ingroup Maintenance
|
||||
*/
|
||||
class GenerateConfigSchema extends Maintenance {
|
||||
|
||||
/** @var string */
|
||||
private const DEFAULT_INPUT_PATH = 'includes/config-schema.yaml';
|
||||
|
||||
/** @var string */
|
||||
private const DEFAULT_OUTPUT_PATH = 'includes/config-schema.php';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
$this->addDescription( 'Build config-schema.php file from config-schema.yaml' );
|
||||
$this->addOption(
|
||||
'schema',
|
||||
'Path to the config schema file relative to $IP. Default: ' . self::DEFAULT_INPUT_PATH,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
$this->addOption(
|
||||
'output',
|
||||
'Path to output relative to $IP. Default: ' . self::DEFAULT_OUTPUT_PATH,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
$schema = ( new FileSource( $this->getInputPath() ) )->load();
|
||||
|
||||
foreach ( $schema['config-schema'] as $key => &$value ) {
|
||||
unset( $value['description'] );
|
||||
}
|
||||
|
||||
$content = ( new StaticArrayWriter() )->write(
|
||||
$schema,
|
||||
"This file is automatically generated using maintenance/generateConfigSchema.php.\n" .
|
||||
"phpcs:disable Generic.Files.LineLength"
|
||||
);
|
||||
|
||||
file_put_contents( $this->getOutputPath(), $content );
|
||||
}
|
||||
|
||||
private function getInputPath(): string {
|
||||
global $IP;
|
||||
$inputPath = $this->getOption( 'schema', self::DEFAULT_INPUT_PATH );
|
||||
return $IP . DIRECTORY_SEPARATOR . $inputPath;
|
||||
}
|
||||
|
||||
private function getOutputPath(): string {
|
||||
global $IP;
|
||||
$outputPath = $this->getOption( 'output', self::DEFAULT_OUTPUT_PATH );
|
||||
if ( $outputPath === '-' || $outputPath === 'php://stdout' ) {
|
||||
return 'php://stdout';
|
||||
}
|
||||
return $IP . DIRECTORY_SEPARATOR . $outputPath;
|
||||
}
|
||||
}
|
||||
|
||||
$maintClass = GenerateConfigSchema::class;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
50
maintenance/generateConfigSchemaArray.php
Normal file
50
maintenance/generateConfigSchemaArray.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
use Wikimedia\StaticArrayWriter;
|
||||
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
require_once __DIR__ . '/includes/ConfigSchemaDerivativeTrait.php';
|
||||
|
||||
/**
|
||||
* Maintenance script that generates the PHP representation of the config-schema.yaml file.
|
||||
*
|
||||
* @ingroup Maintenance
|
||||
*/
|
||||
class GenerateConfigSchemaArray extends Maintenance {
|
||||
use ConfigSchemaDerivativeTrait;
|
||||
|
||||
/** @var string */
|
||||
private const DEFAULT_OUTPUT_PATH = __DIR__ . '/../includes/config-schema.php';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
$this->addDescription( 'Generate an optimized config-schema.php file.' );
|
||||
|
||||
$this->addOption(
|
||||
'output',
|
||||
'Path to output relative to $IP. Default: ' . self::DEFAULT_OUTPUT_PATH,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
$schema = $this->loadSettingsSource();
|
||||
|
||||
foreach ( $schema['config-schema'] as $key => &$value ) {
|
||||
unset( $value['description'] );
|
||||
}
|
||||
|
||||
$content = ( new StaticArrayWriter() )->write(
|
||||
$schema,
|
||||
"This file is automatically generated using maintenance/generateConfigSchema.php.\n" .
|
||||
"phpcs:disable Generic.Files.LineLength"
|
||||
);
|
||||
|
||||
$this->writeOutput( self::DEFAULT_OUTPUT_PATH, $content );
|
||||
}
|
||||
}
|
||||
|
||||
$maintClass = GenerateConfigSchemaArray::class;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
59
maintenance/generateConfigSchemaYaml.php
Normal file
59
maintenance/generateConfigSchemaYaml.php
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
require_once __DIR__ . '/includes/ConfigSchemaDerivativeTrait.php';
|
||||
|
||||
/**
|
||||
* Maintenance script that generates a YAML file containing a JSON Schema representation
|
||||
* of the config schema.
|
||||
*
|
||||
* @ingroup Maintenance
|
||||
*/
|
||||
class GenerateConfigSchemaYaml extends Maintenance {
|
||||
use ConfigSchemaDerivativeTrait;
|
||||
|
||||
/** @var string */
|
||||
private const DEFAULT_OUTPUT_PATH = __DIR__ . '/../docs/config-schema.yaml';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
$this->addDescription( 'Generate config-schema.yaml' );
|
||||
|
||||
$this->addOption(
|
||||
'output',
|
||||
'Output file. Default: ' . self::DEFAULT_OUTPUT_PATH,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
$schemas = $this->loadSchema();
|
||||
|
||||
// Cast empty arrays to objects if they are declared to be of type object.
|
||||
// This ensures they get represented in yaml as {} rather than [].
|
||||
foreach ( $schemas as &$sch ) {
|
||||
if ( isset( $sch['default'] ) && isset( $sch['type'] ) ) {
|
||||
$types = (array)$sch['type'];
|
||||
if ( $sch['default'] === [] && in_array( 'object', $types ) ) {
|
||||
$sch['default'] = new stdClass();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$yamlFlags = Yaml::DUMP_OBJECT_AS_MAP
|
||||
| Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK
|
||||
| Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE;
|
||||
|
||||
$array = [ 'config-schema' => $schemas ];
|
||||
$yaml = Yaml::dump( $array, 4, 4, $yamlFlags );
|
||||
|
||||
$this->writeOutput( self::DEFAULT_OUTPUT_PATH, $yaml );
|
||||
}
|
||||
}
|
||||
|
||||
$maintClass = GenerateConfigSchemaYaml::class;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
96
maintenance/includes/ConfigSchemaDerivativeTrait.php
Normal file
96
maintenance/includes/ConfigSchemaDerivativeTrait.php
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
/**
|
||||
* @defgroup Benchmark Benchmark
|
||||
* @ingroup Maintenance
|
||||
*/
|
||||
|
||||
/**
|
||||
* Trait for scripts generating files based on the config schema.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @ingroup Config
|
||||
*/
|
||||
|
||||
use MediaWiki\MainConfigSchema;
|
||||
use MediaWiki\Settings\Source\ReflectionSchemaSource;
|
||||
|
||||
/**
|
||||
* Trait for scripts generating files based on the config schema.
|
||||
* @ingroup Config
|
||||
* @since 1.38
|
||||
*/
|
||||
trait ConfigSchemaDerivativeTrait {
|
||||
|
||||
/**
|
||||
* Loads the config schema from the MainConfigSchema class.
|
||||
*
|
||||
* @return array An associative array with a single key, 'config-schema',
|
||||
* containing the config schema definition.
|
||||
*/
|
||||
private function loadSettingsSource(): array {
|
||||
$source = new ReflectionSchemaSource( MainConfigSchema::class, true );
|
||||
$settings = $source->load();
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the config schema from the MainConfigSchema class.
|
||||
*
|
||||
* @return array the config schema definition.
|
||||
*/
|
||||
private function loadSchema(): array {
|
||||
return $this->loadSettingsSource()['config-schema'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $defaultPath
|
||||
* @param string $content
|
||||
*/
|
||||
private function writeOutput( $defaultPath, $content ) {
|
||||
$path = $this->getOutputPath( $defaultPath );
|
||||
|
||||
// ensure a single line break at the end of the file
|
||||
$content = trim( $content ) . "\n";
|
||||
|
||||
file_put_contents( $path, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $default The default output path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getOutputPath( $default ): string {
|
||||
$outputPath = $this->getOption( 'output', $default );
|
||||
if ( $outputPath === '-' ) {
|
||||
$outputPath = 'php://stdout';
|
||||
}
|
||||
return $outputPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stub for method supplied by the Maintenance base class.
|
||||
*
|
||||
* @param string $name The name of the param
|
||||
* @param mixed|null $default Anything you want, default null
|
||||
* @return mixed
|
||||
* @return-taint none
|
||||
*/
|
||||
abstract protected function getOption( $name, $default = null );
|
||||
|
||||
}
|
||||
|
|
@ -3,12 +3,13 @@
|
|||
namespace MediaWiki\Tests\Structure;
|
||||
|
||||
use ExtensionRegistry;
|
||||
use MediaWiki\MainConfigSchema;
|
||||
use MediaWiki\Settings\Config\ArrayConfigBuilder;
|
||||
use MediaWiki\Settings\Config\PhpIniSink;
|
||||
use MediaWiki\Settings\SettingsBuilder;
|
||||
use MediaWiki\Settings\Source\FileSource;
|
||||
use MediaWiki\Settings\Source\Format\YamlFormat;
|
||||
use MediaWiki\Settings\Source\PhpSettingsSource;
|
||||
use MediaWiki\Settings\Source\ReflectionSchemaSource;
|
||||
use MediaWiki\Settings\Source\SettingsSource;
|
||||
use MediaWiki\Shell\Shell;
|
||||
use MediaWikiIntegrationTestCase;
|
||||
|
|
@ -19,21 +20,14 @@ use MediaWikiIntegrationTestCase;
|
|||
class SettingsTest extends MediaWikiIntegrationTestCase {
|
||||
|
||||
/**
|
||||
* Returns the contents of config-schema.yaml as an array.
|
||||
* Returns the main configuration schema as a settings array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function getSchemaData(): array {
|
||||
static $data = null;
|
||||
|
||||
if ( !$data ) {
|
||||
$file = __DIR__ . '/../../../includes/config-schema.yaml';
|
||||
$data = file_get_contents( $file );
|
||||
$yaml = new YamlFormat();
|
||||
$data = $yaml->decode( $data );
|
||||
}
|
||||
|
||||
return $data;
|
||||
private function getSchemaData(): array {
|
||||
$source = new ReflectionSchemaSource( MainConfigSchema::class, true );
|
||||
$settings = $source->load();
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -90,13 +84,13 @@ class SettingsTest extends MediaWikiIntegrationTestCase {
|
|||
}
|
||||
|
||||
public function provideConfigGeneration() {
|
||||
yield 'docs/Configuration.md' => [
|
||||
'script' => __DIR__ . '/../../../maintenance/generateConfigDoc.php',
|
||||
'expectedFile' => __DIR__ . '/../../../docs/Configuration.md',
|
||||
yield 'includes/config-schema.php' => [
|
||||
'script' => MW_INSTALL_PATH . '/maintenance/generateConfigSchemaArray.php',
|
||||
'expectedFile' => MW_INSTALL_PATH . '/includes/config-schema.php',
|
||||
];
|
||||
yield 'incl/Configuration.md' => [
|
||||
'script' => __DIR__ . '/../../../maintenance/generateConfigSchema.php',
|
||||
'expectedFile' => __DIR__ . '/../../../includes/config-schema.php',
|
||||
yield 'docs/config-schema.yaml' => [
|
||||
'script' => MW_INSTALL_PATH . '/maintenance/generateConfigSchemaYaml.php',
|
||||
'expectedFile' => MW_INSTALL_PATH . '/docs/config-schema.yaml',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -108,10 +102,13 @@ class SettingsTest extends MediaWikiIntegrationTestCase {
|
|||
|
||||
$result = $schemaGenerator->execute();
|
||||
$this->assertSame( 0, $result->getExitCode(), 'Config generation must finish successfully' );
|
||||
$this->assertSame( '', $result->getStderr(), 'Config generation must not have errors' );
|
||||
|
||||
$errors = $result->getStderr();
|
||||
$errors = preg_replace( '/^Xdebug:.*\n/m', '', $errors );
|
||||
$this->assertSame( '', $errors, 'Config generation must not have errors' );
|
||||
|
||||
$oldGeneratedSchema = file_get_contents( $expectedFile );
|
||||
$relativePath = wfRelativePath( $script, __DIR__ . '/../../..' );
|
||||
$relativePath = wfRelativePath( $script, MW_INSTALL_PATH );
|
||||
|
||||
$this->assertEquals(
|
||||
$oldGeneratedSchema,
|
||||
|
|
@ -121,8 +118,8 @@ class SettingsTest extends MediaWikiIntegrationTestCase {
|
|||
}
|
||||
|
||||
public function provideDefaultSettingsConsistency() {
|
||||
yield 'YAML' => [ new FileSource( 'includes/config-schema.yaml' ) ];
|
||||
yield 'PHP' => [ new PhpSettingsSource( 'includes/config-schema.php' ) ];
|
||||
yield 'YAML' => [ new FileSource( MW_INSTALL_PATH . '/docs/config-schema.yaml' ) ];
|
||||
yield 'PHP' => [ new PhpSettingsSource( MW_INSTALL_PATH . '/includes/config-schema.php' ) ];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -132,7 +129,7 @@ class SettingsTest extends MediaWikiIntegrationTestCase {
|
|||
*/
|
||||
public function testDefaultSettingsConsistency( SettingsSource $source ) {
|
||||
$defaultSettingsProps = ( static function () {
|
||||
require __DIR__ . '/../../../includes/DefaultSettings.php';
|
||||
require MW_INSTALL_PATH . '/includes/DefaultSettings.php';
|
||||
$vars = get_defined_vars();
|
||||
unset( $vars['input'] );
|
||||
$result = [];
|
||||
|
|
@ -150,7 +147,7 @@ class SettingsTest extends MediaWikiIntegrationTestCase {
|
|||
$this->createNoOpMock( PhpIniSink::class )
|
||||
);
|
||||
$settingsBuilder->load( $source );
|
||||
$settingsBuilder->apply();
|
||||
$defaults = iterator_to_array( $settingsBuilder->getDefaultConfig() );
|
||||
|
||||
foreach ( $defaultSettingsProps as $key => $value ) {
|
||||
if ( in_array( $key, [
|
||||
|
|
@ -160,9 +157,12 @@ class SettingsTest extends MediaWikiIntegrationTestCase {
|
|||
] ) ) {
|
||||
continue;
|
||||
}
|
||||
$this->assertTrue( $configBuilder->build()->has( $key ), "Missing $key" );
|
||||
$this->assertEquals( $value, $configBuilder->build()->get( $key ), "Wrong value for $key\n" );
|
||||
$this->assertArrayHasKey( $key, $defaults, "Missing $key from $source" );
|
||||
$this->assertEquals( $value, $defaults[ $key ], "Wrong value for $key\n" );
|
||||
}
|
||||
|
||||
$missingKeys = array_diff_key( $defaults, $defaultSettingsProps );
|
||||
$this->assertSame( [], $missingKeys, 'Keys missing from DefaultSettings.php' );
|
||||
}
|
||||
|
||||
public function provideArraysHaveMergeStrategy() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace MediaWiki\Tests\Unit\Settings\Source;
|
||||
|
||||
use MediaWiki\Settings\SettingsBuilderException;
|
||||
use MediaWiki\Settings\Source\ReflectionSchemaSource;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \MediaWiki\Settings\Source\ReflectionSchemaSource
|
||||
*/
|
||||
class ReflectionSchemaSourceTest extends TestCase {
|
||||
|
||||
public const TEST_SCHEMA = [
|
||||
'type' => 'object'
|
||||
];
|
||||
|
||||
private const TEST_PRIVATE = [
|
||||
'type' => 'object'
|
||||
];
|
||||
|
||||
public const TEST_STRING = 'test';
|
||||
|
||||
public function testLoad() {
|
||||
$source = new ReflectionSchemaSource( self::class );
|
||||
$settings = $source->load();
|
||||
|
||||
$this->assertArrayHasKey( 'config-schema', $settings );
|
||||
$this->assertArrayHasKey( 'TEST_SCHEMA', $settings['config-schema'] );
|
||||
$this->assertArrayHasKey( 'type', $settings['config-schema']['TEST_SCHEMA'] );
|
||||
$this->assertSame( 'object', $settings['config-schema']['TEST_SCHEMA']['type'] );
|
||||
|
||||
$this->assertArrayNotHasKey( 'TEST_PRIVATE', $settings['config-schema'] );
|
||||
$this->assertArrayNotHasKey( 'TEST_STRING', $settings['config-schema'] );
|
||||
}
|
||||
|
||||
public function testLoadInvalidClass() {
|
||||
$this->expectException( SettingsBuilderException::class );
|
||||
|
||||
$source = new ReflectionSchemaSource( 'ThisClassDoesNotExist' );
|
||||
$source->load();
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue