Previously, SettingsBuilder would allow configuration to be loaded
and modified until it was "finalized", at which point configuration
became read only. This patch introduces an intermediate stage where
registration dynamic manipulation of config values can be performed,
after all extensions have been loaded and all config schemas are known.
Motivation:
Extension registration callbacks are typically used to dynamically set
config variables, often based on other configuration. This should be
done using SettingsBuilder rather than global variables. But previously,
we could only be sure that all extensions are known after SettingsBuilder
was "finalized", at which point it would be impossible to change config
values.
Change-Id: I6f8f9f3f7252f0024282d7b005671f28a5b3acc3
MediaWikiTitleCodec: I removed the comment about dbkey being
"conveniently nullified" since that is no longer correct. The first
preg_replace() can return null, and that is guarded. The second
preg_replace() hopefully can't return null, because if it does, trim()
will generate a deprecation notice on PHP 8.1.
Some other self-explanatory changes.
Change-Id: Iad0ace821eba782c3033ec8abfeac461ac4e8ace
While accessing a SettingsBuilder instance via global state should not
be encouraged, we still need it sometimes. So use a static getter
instead of a global variable. That way, we can emit deprecation warnings
when we have proper alternatives available.
Change-Id: I0013bdab474710fd521532dd2653b3789e2ede34
Follows-up I58ff3c193190d78a. Small step toward not run-time reading
the global (and using Config here is non-trivial/unsafe).
Change-Id: Ic527e493baabe700c50f75fadaa5b51615a5e597
This adds functionality to SettingsBuilder for collecting warnings to be
logged later, when the logging mechanism has been set up.
This also adds a validation step to update.php that aborts the update
if any warnings have been registered in SettingsBuilder, or the settings
fail to validate against the settings schema.
Change-Id: I387905289fb93591f79b96bf4c6cb5ec692b2aff
Apparently, $wgLocaltimezone is set to the empty string in many
existing LocalSettings.php file, presumably because the installer
failed to detect the correct time zone.
The new code for handling automatic defaults will only trigger if
$wgLocaltimezone is null, not when it is otherwise empty.
This adds fallback code in strategic places to ensure that the empty
string is handled correctly.
Bug: T305093
Change-Id: I39226466f2bb6a36823ae9032fc62f981eabc64a
The goal is to keep the actual default values for settings in the same
place as the setting is declared, and applied using the regular means
for loading the settings -- not in a separate piece of code that needs
to be loaded through some entirely different mechanism.
SetupDynamicConfig.php now contains a few categories of things:
* Post-processing of configuration settings, where already-set settings
are altered. This could be moved to MainConfigSchema too as a separate
set of methods.
* Processing of old aliases of settings (blacklist, slave) that are not
registered as settings anymore and therefore are not available to
MainConfigSchema. This could perhaps be moved to LocalSettings
processing somehow?
* Setting $wgUseEnotif, which is also not registered as a setting.
Easiest would be just to declare it as a setting and have it set
unconditionally.
* Setting the actual timezone to $wgLocaltimezone. This is not related
to configuration and should just be in Setup.php.
Bug: T305093
Change-Id: Ia5c23b52dbbfcb3d07ffcf5d3b7f2d7befba2a26
Follows-up I8520d8cb16 and Ib941c22d6b7ec5f1b9, and adds an internal
setter for use by Setup.php, and for wmf-config:rpc/RunSingleJob.php
which is a use case for setting it after Setup.php but before most
code execution. Interact with a component owner instead of directly
maintaining state and providing a shared API through the Config object.
Change-Id: I5c3d4b11f4e0eb3906ccb5b5fe3979e026459859
DefaultSettings.php has been replaced by MainConfigSchema.
Loading DefaultSettings.php is deprecated.
Code that needs to have access to configuration defaults should use the
ConfigSchema service object.
Bug: T300129
Change-Id: I7b2c0ca95a78990be1cdb9dd9ace92f6dcf1af15
Allow callers of MWExceptionHandler::getStructuredExceptionData() and
jsonSerializeException() to explicitly control whether a backtrace is
included in the return value. This avoids the need to rely on the
LogExceptionBacktrace setting in static methods.
Bug: T294739
Change-Id: Ib941c22d6b7ec5f1b984bf5ded90652e42ad7b67
The global variable $IP has been replaced by the MW_INSTALL_PATH
constant. Clarify the continued use of $IP on Setup.php.
Change-Id: I157abfd9049fb8382da53005a084ab86f47e8d8a
Loading the config schema from MainConfigSchema using reflection is
slow, so we don't want to do it when serving traffic. But when
re-generating DefaultSettings.php or config-schema.php, we want to load
the schema from the canonical source. That way, these scripts can still
be used if DefaultSettings.php and config-schema.php are broken.
Change-Id: Idc0d8ca0f4a700b771e6182d53ef4a0efab7110c
Nothing in vendor can depend on anything in our classes, whereas the
reverse dependency could exist, so it makes sense to load vendor first.
This ensures that vendor facilities are available in anything loaded
from our autoloader, for instance polyfills like
str_starts_with()/str_ends_with.
Change-Id: I7407bf7a5b201836fde24db97be2dab2856738b5
Caused by I535aa31699d99cd08579b235c48784029c5d04b6, which removed the
global declaration for $wgCommandLineMode. This made $wgCommandLineMode
uninitialized if not on the command line, which of course meant unit
tests didn't catch it.
Change-Id: I260bfaa91e7ec58043ee33d0467e0f76885f5d16
Now largely automated:
VARS=$(grep -o "'[A-Za-z0-9_]*'" includes/MainConfigNames.php | \
tr "\n" '|' | sed "s/|$/\n/;s/'//g")
sed -i -E "s/'($VARS)'/MainConfigNames::\1/g" \
$(grep -ERIl "'($VARS)'" includes/)
Then git add -p with lots of error-prone manual checking. Then
semi-manually add all the necessary "use" lines:
vim $(grep -L 'use MediaWiki\\MainConfigNames;' \
$(git diff --cached --name-only --diff-filter=M HEAD^))
I didn't bother fixing lines that were over 100 characters unless they
were over 120 and triggered phpcs.
Bug: T305805
Change-Id: I74e0ab511abecb276717ad4276a124760a268147
This was causing a fatal error when running some integration tests on
PHP 8.1: "FatalError: $wgBaseDirectory must not be modified in settings
files! Use the MW_INSTALL_PATH environment variable to override the
installation root directory." It seems it caused other (less obviously
related) errors as well.
The root cause was that TestSetup::requireOnceInGlobalScope() was
copying the values of globals to local scope, but didn't make the local
name an alias for the global. This meant that when code outside of the
current scope changed global variables, it wasn't reflected locally. Now
we instead declare all existing global variables as globals. This still
doesn't help if the included file declares a new variable and then it's
changed by code outside the current scope -- the new value will not be
reflected in the current scope. Hopefully this doesn't happen.
I don't understand why this bug didn't happen in versions before 8.1.
Presumably it's related somehow to changes in global handling in 8.1.
It seems like the best solution is to edit these files so they don't
expect to be in global scope to begin with -- just access globals only
via $GLOBALS.
Change-Id: I535aa31699d99cd08579b235c48784029c5d04b6
TestSetup seems a nice place for this function. This way, it can also be
reused in the other boostrap file whilst we migrate the entrypoint.
Also, replace the check in MediaWikiIntegrationTestCase with another
constant; this also makes it easier to understand when exactly that code
should run.
Bug: T90875
Change-Id: I7858d982378ab4b6f11c4e9bf955d83d1acbc85d
To do so, we move the relevant parts to a separate include file that's
included both by Setup and the test.
The --color-moved option is highly recommended when reviewing this patch
to verify correctness.
More tests to come.
Bug: T305093
Change-Id: I931b92357ec48db4665891c8546f86264885e881
Use name constants instead of string literals in calls to Config::get
and ServiceOptions::get, when referring to core configuration variables.
This protects against typos and makes the decumentation and schema
declaration of the config settings discoverable.
This is the first batch, only touching files directly under /includes/
Change-Id: I7252e636c7c86d950d9257b33491af492c6dd5eb
Instead of loading global variabls from DefaultSettings.php, load the schema from config-schema.php.
For 1.38, keep a DefaultSettings.php and use it if MW_USE_LEGACY_DEFAULT_SETTINGS is set.
Additional changes:
* Removes timing stats collection. This was temporary, to make sure
performance is OK in production.
* Removes loop to pull in config globals, when Setup is included in
bootstrap.php. This is only the case when invoking phpunit tests
with IDE integration. The code in Setup.php is buggy and redundant
while bootstrap.php still pulls in DefaultSettings.php.
This code will be put back in I7b2c0ca95a78990be.
Bug: T305176
Change-Id: I399df9e1ee678e525e37c172d0fd8e1e634436e5
The default value for GitInfoCacheDirectory doesn't seem to be necessary
outside of GitInfo.php, so move it from Setup to there. Theoretically
this could break third-party code that uses this setting and was relying
on Setup.php to set a default value, but it doesn't seem very likely.
I didn't find any other dynamic configuration that could be moved out of
Setup so easily:
* MainWANCache isn't accessed outside of ServiceWiring, but Setup
still needs to check it to initialize WANObjectCaches.
* ForeignFileRepos is only read in FileBackendGroup, but various tests
(including in extensions) reset it and their behavior will be affected
if they no longer override the various related settings like
UseInstantCommons.
* ShortPagesNamespaceBlacklist handling could be moved to
SpecialShortPages.php, but that would require re-adding it as a
recognized configuration setting, which doesn't seem worth the tiny
code simplification.
Bug: T305093
Change-Id: Iec8c391fec8396846216a9708d75df57f7d799a2
Added support for an easy to configure multi-tenant ("wiki farm") mode:
Settings for each site can be placed in a directory specified by
$wgWikiFarmSettingsDirectory. Site detection is controlled by
$wgWikiFarmSiteDetector and defaults to the requested host name.
Instructions for manual testing: https://etherpad.wikimedia.org/p/T221535
Bug: T221535
Change-Id: I7581921b7d99ba1fe7e25523fde691d76b67a99c
This adds an experimental mode that loads LocalSettings.php in a
function, rather than in top level global scope. This is controlled
using the MW_USE_LOCAL_SETTINGS_LOADER environment variable.
This is not intended for use in production as this time.
The experimental mode should be available in the 1.38 release,
so people can try it out with different setups.
Bug: T304183
Depends-On: Ie6245ff8cd2bc7bab2af3b1450070185dbc2d824
Change-Id: I0f20024803336064ecb07b51fa56581af7b67a85
This allows MW_USE_CONFIG_SCHEMA to be defined as a constant instead of
an environment variable. This is useful if we want to set it in
multiversion. We could use putenv, but its interaction with getenv is a
mess, see the warning on
<https://www.php.net/manual/en/function.getenv.php>.
Bug: T304460
Change-Id: I0bd87e2ddde70ba9fede65b8d607eec01b39aed5
Make phan stricter about null types by setting null_casts_as_any_type to
false (the default in mediawiki-phan-config)
Remaining false positive issues are suppressed.
The suppression and the setting change can only be done together
Bug: T242536
Bug: T301991
Change-Id: I0f295382b96fb3be8037a01c10487d9d591e7e01
Application logic should use the BaseDirectory config variable.
Framework code should use MW_INSTALL_PATH to locate files should.
NOTE: Update https://www.mediawiki.org/wiki/Manual:$IP
Bug: T300301
Depends-On: I7142af16d692f26e90673b058029f572c1ea3991
Change-Id: Ib4caa80bb7007c4c7960a2fd370cf5da7d9ba344
$wgStyleSheetPath has been a deprecated alias for $wgStylePath since 1.3 (2004).
Time to get rid of it.
Change-Id: I78a6394003b9aefab7aa8559b8e2b22bc50154fc
In order to safely transition Setup.php to load config-schema.yaml
rather than DefaultSettings.php, we need to be able to test the new
setup mechanism selectively, on only a few hosts.
This patch makes Setup.php use config-schema.yaml if the
MW_USE_CONFIG_SCHEMA variable is set.
The condition could be patched in production to be based on the host
name or a request parameter for further experimentation in the live
environment.
Bug: T300129
Change-Id: Idc12b8e6ee2a3cc41cf5ab8d1eb755e6fab0213d
Sometimes, we need to force an exact value and bypass the default
behavior of merging config variables.
This also renames setConfigValue to putConfigValue, to avoid confusion
about the behavior of that method.
Change-Id: I82c606632b94f974e655a44a0b63394de7a0804b
We are already passing SettingsBuilder into callbacks registered with
MW_SETUP_CALLBACK. Do the same for MW_CONFIG_CALLBACK.
This will allow us to avoid messing with global variabls in more places.
Bug: T294739
Change-Id: Ic6296907139912351b53dc80672ef950c0aefeb3