First pass on creating config-schema.yaml

The config-schema.yaml follows the settings file format.
It's not used in reality yet, but tests were added
to compare the yaml with the result of DefaultSettings.php
importing.

The list of properties not yet included:
 - 'wgVersion' - deprecated alias to MW_VERSION
 - 'wgConf' - instance of SiteConfiguration
 - 'wgStyleSheetPath' - alias to another global
 - 'wgExtensionDirectory', - depends on $IP
 - 'wgStyleDirectory' - depends on $IP
 - 'wgServiceWiringFiles' - depends on __DIR__
 - 'wgHTTPMaxTimeout' - infinity default
 - 'wgHTTPMaxConnectTimeout', - Infinity default

The PHPDoc was copied over as is into description fields,
it will be converted to something more pleasant in a separate
iteration.

The types were parsed out of PHPDoc and fixed up manually.

Default values come from executing DefaultSettings and serializing
the values into YAML.

Change-Id: I9aa9ad9713bdbdac2bd7b528c609772154b5a135
This commit is contained in:
Petr Pchelko 2021-11-12 15:26:44 -08:00
parent da3b2b4e0b
commit e36a8af70e
3 changed files with 7943 additions and 12 deletions

View file

@ -2,40 +2,40 @@
return [
'config-schema' => [
'wgAuthManagerAutoConfig' => [
'AuthManagerAutoConfig' => [
'mergeStrategy' => 'array_plus_2d'
],
'wgCapitalLinkOverrides' => [
'CapitalLinkOverrides' => [
'mergeStrategy' => 'array_plus'
],
'wgExtraGenderNamespaces' => [
'ExtraGenderNamespaces' => [
'mergeStrategy' => 'array_plus'
],
'wgGrantPermissions' => [
'GrantPermissions' => [
'mergeStrategy' => 'array_plus_2d'
],
'wgGroupPermissions' => [
'GroupPermissions' => [
'mergeStrategy' => 'array_plus_2d'
],
'wgHooks' => [
'Hooks' => [
'mergeStrategy' => 'array_merge_recursive'
],
'wgNamespaceContentModels' => [
'NamespaceContentModels' => [
'mergeStrategy' => 'array_plus'
],
'wgNamespaceProtection' => [
'NamespaceProtection' => [
'mergeStrategy' => 'array_plus'
],
'wgNamespacesWithSubpages' => [
'NamespacesWithSubpages' => [
'mergeStrategy' => 'array_plus'
],
'wgPasswordPolicy' => [
'PasswordPolicy' => [
'mergeStrategy' => 'array_merge_recursive'
],
'wgRateLimits' => [
'RateLimits' => [
'mergeStrategy' => 'array_plus_2d'
],
'wgRevokePermissions' => [
'RevokePermissions' => [
'mergeStrategy' => 'array_plus_2d'
],
]

7829
includes/config-schema.yaml Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,102 @@
<?php
namespace MediaWiki\Tests\Structure;
use ExtensionRegistry;
use MediaWiki\Settings\Config\ArrayConfigBuilder;
use MediaWiki\Settings\Config\PhpIniSink;
use MediaWiki\Settings\SettingsBuilder;
use MediaWikiIntegrationTestCase;
/**
* @coversNothing
*/
class SettingsTest extends MediaWikiIntegrationTestCase {
public function testConfigSchemaIsLoadable() {
$configBuilder = new ArrayConfigBuilder();
$settingsBuilder = new SettingsBuilder(
__DIR__ . '/../../..',
$this->createNoOpMock( ExtensionRegistry::class ),
$configBuilder,
$this->createNoOpMock( PhpIniSink::class )
);
$settingsBuilder->loadFile( 'includes/config-schema.yaml' );
$settingsBuilder->apply();
// Assert we've read some random config value
$this->assertTrue( $configBuilder->build()->has( 'Server' ) );
}
/**
* Check that core default settings validate against the schema
*/
public function testConfigSchemaDefaultsValidate() {
$settingsBuilder = new SettingsBuilder(
__DIR__ . '/../../..',
$this->createNoOpMock( ExtensionRegistry::class ),
new ArrayConfigBuilder(),
$this->createNoOpMock( PhpIniSink::class )
);
$result = $settingsBuilder->loadFile( 'includes/config-schema.yaml' )
->apply()
->validate();
$this->assertArrayEquals( [], $result->getErrors() );
}
/**
* Check that currently loaded settings validate against the schema.
*/
public function testCurrentSettingsValidate() {
global $wgSettings;
$result = $wgSettings->validate();
$this->assertTrue( $result->isGood(), $result->__toString() );
}
/**
* Check that the result of loading config-schema.yaml is the same as DefaultSettings.php
* This test can be removed when DefaultSettings.php is removed.
*/
public function testDefaultSettingsConsistency() {
$defaultSettingsProps = ( static function () {
$IP = 'PLACEHOLDER_IP!';
require __DIR__ . '/../../../includes/DefaultSettings.php';
$vars = get_defined_vars();
unset( $vars['input'] );
unset( $vars['IP'] );
$result = [];
foreach ( $vars as $key => $value ) {
$result[substr( $key, 2 )] = $value;
}
return $result;
} )();
$configBuilder = new ArrayConfigBuilder();
$settingsBuilder = new SettingsBuilder(
__DIR__ . '/../../..',
$this->createNoOpMock( ExtensionRegistry::class ),
$configBuilder,
$this->createNoOpMock( PhpIniSink::class )
);
$settingsBuilder->loadFile( 'includes/config-schema.yaml' );
$settingsBuilder->apply();
foreach ( $defaultSettingsProps as $key => $value ) {
if ( in_array( $key, [
'Version', // deprecated alias to MW_VERSION
'Conf', // instance of SiteConfiguration
'AutoloadClasses', // conditionally initialized
'StyleSheetPath', // Alias to another global
'ExtensionDirectory', // Depends on $IP
'StyleDirectory', // Depends on $IP
'ServiceWiringFiles', // Depends on __DIR__
'HTTPMaxTimeout', // Infinity default
'HTTPMaxConnectTimeout', // Infinity default
] ) ) {
continue;
}
$this->assertTrue( $configBuilder->build()->has( $key ), "Missing $key" );
$this->assertEquals( $value, $configBuilder->build()->get( $key ), "Wrong value for $key\n" );
}
}
}