Commit graph

47 commits

Author SHA1 Message Date
jenkins-bot
9e8355c87d Merge "Allow namespaces defined in extension.json to be overwritten locally." 2017-05-21 08:02:22 +00:00
Kunal Mehta
fdb7e94104 registration: Move attributes out of the top level
This moves attributes out of the top level, and namespaces them under
each extension. If the extension that it belongs to is not installed,
the attribute is not exported and dropped.

The full name of the attribute is the name of the extension plus the
name of the attribute key. This enforces the recommendation that the
attribute name start with the extension's name.

Add test coverage for attributes under manifest_version 1 and 2.

Bug: T133627
Depends-On: I5a148763f68989c8da313a4fb1d0213658ee4495
Depends-On: I5a148763f68989c8da313a4fb1d0213658ee4459
Change-Id: I8613a027c56e2c9d2c6a83ca14749eb1c8fc23be
2017-05-15 20:09:50 -07:00
daniel
e4fc1ffec3 Allow namespaces defined in extension.json to be overwritten locally.
This allows extension namespaces to be assigned a custom ID, e.g. in case
the namespace pre-defined by the extension is already taken on the local
wiki.

This is done by defining the respective namespace constant in
LocalSettings.php.

Bug: T160462
Change-Id: If648d6e218847e6632d643ea724cd3da3945db70
2017-05-11 12:16:24 +02:00
Gergő Tisza
525bfbc8df Switch to librarized version of TestingAccessWrapper
Replaces \TestingAccessWrapper (defined in core) with
\Wikimedia\TestingAccessWrapper (defined in the composer package
wikimedia/testing-access-wrapper).

See https://gerrit.wikimedia.org/r/#/q/topic:librarize-testing-access-wrapper
for downstream patches.

The core version of the class is kept around for a while to avoid
circular dependency problems.

Bug: T163434
Change-Id: I52cc257e593da3d6c3b01a909e554a950225aec8
2017-04-20 14:15:57 +00:00
Kunal Mehta
b6d43206a6 registration: Always specify version number in extension.schema.json file
Instead of having the current version of the schema live at
extension.schema.json, always include a version number in it. This
simplifies both the code, and makes merging, cherry-picks, rebasing,
etc. easier when the current schema version changes.

Change-Id: I1b5ef4ced1eb34b8bdda7ba9b3f086b1997b704c
2016-12-16 11:47:15 -08:00
Kunal Mehta
90cfe33631 registration: Improve dependency checking
* Pass $coreVersion to VersionChecker's constructor, don't require a
setter.
* Bump ExtensionRegistry::CACHE_VERSION
* Return single strings from handle* functions, avoid array_merge calls
* Improve invalid version error message
* Fix naming of VersionCheckerTest class

Change-Id: Id4f66b815aa41dbbc4b966095d6b99e542e548b4
2016-12-15 15:09:26 -08:00
Florian Schmidt
90698a878b registration: Allow specifying extension dependencies
There are some extensoins that depend upon another extension or skin,
usually in different ways:
* A constant that is added in the dependency extension, and the
existence of is checked for. This is problematic because it requires a
specific load order.
* Checking whether a specific class exists. This is problematic because
it is extremely fragile, and breaks whenever the class is renamed.
* Checking ExtensionRegistry::isLoaded(). This is mostly there, but it
only checks at runtime, and doesn't provide any machine readable data.

Furthermore, developers implement each one differently, with very little
standardization.

With this, extensions may now specify what other extensions they depend
on. This is for explicit *hard* dependencies that must be installed.

For example:
	"requires": {
		"MediaWiki": ">= 1.25.0",
		"extensions": {
			"FakeExtension": "*"
		},
		"skins": {
			"FakeSkin": "*"
		}
	}

This would add a minimum requirement on MediaWiki 1.25.0+ (already
implemented), as well as the requirement that the FakeExtension extension
needs to be installed, as well as the FakeSkin skin. A wildcard (*) is
used instead of an explicit version requirement as many extensions do
not actually version themselves, and there is no consistent versioning
scheme yet.

Bug: T117277
Change-Id: If1cccee1a16a867a71bb0285691c400443d8a30a
2016-12-14 19:18:09 +01:00
Florian Schmidt
5f11f7818c registration: Generalize CoreVersionChecker to VersionChecker
This allows us to put other requirements more easily into extension
registration, such as skins and/or extensions.

Bug: T117277
Change-Id: I3ec1b28b6af380621585cd61b38e5ebb8be9f9c7
2016-12-14 19:18:09 +01:00
Roan Kattouw
a8e20be5f3 ExtensionRegistryTest: Illustrate priority in array_replace_recursive test case
When two keys have conflicting values, the value from extension.json wins
when using this merge strategy.

Change-Id: I0222682f3b3fb08f80afc7dda677da7bbfe8e5d1
2016-12-01 00:27:33 +00:00
Yuri Astrakhan
ab224f8211 Added array_replace_recursive merge strategy
For extension registry, add array_replace_recursive merge strategy,
as some extensions/configuration may prefer that to array_merge_recursive.

In some cases, configuration is merged from multiple extensions,
such as JsonConfig's $wgJsonConfigs configuration: ZeroBanner defines

	"JsonZeroConfig": {
		"namespace": 480,
		"nsName": "Zero",
		"isLocal": false,
		"cacheKey": "1"
	}

and mobile.php overrides it with
	$wgJsonConfigs['JsonZeroConfig']['isLocal'] = false;
	$wgJsonConfigs['JsonZeroConfig']['remote'] = [
		'url' => 'https://zero.wikimedia.org/w/api.php',
		'username' => $wmgZeroPortalApiUserName,
		'password' => $wmgZeroPortalApiPassword,
	];

Having identical value 'isLocal' would be converted into an array
if array_merge_recursive is used, but the replace strategy fixes it.

Change-Id: Ica6ddd0ae76f23e60de9b6235c6e2a3f2754a95d
2016-10-24 19:20:04 +00:00
Kunal Mehta
9ffc40235b registration: Support config setings that are relative paths
Add support for configuration settings that are relative paths to the
extension directory. The most common use-case for this is where the
extension ships a generic default file, but sysadmins or packagers may
want to override it. Setting `"path": true` on the config definition
will make the value be interpreted as a relative path.

And add tests!

Bug: T100956
Change-Id: Ia87ced25b35be7a314ee2937e0ccc63f9acc5bb5
2016-07-24 14:49:57 +00:00
Max Semenik
836494c891 Fix coverage annotations
Broken by Id1071fc0647892438e5cd0e3ee621fbdaaa64014
Causes https://integration.wikimedia.org/ci/job/mediawiki-core-code-coverage/2146/console

Change-Id: I9dd0ff7a5fa17c6395dee52ad87faf1f8e612904
2016-07-19 23:05:35 -07:00
Kunal Mehta
ee71c2658e registration: Add test to check extension.json globals are documented
Verify that all the global settings listed in
ExtensionProcessor::$globalSettings are documented in the extension.json
schema.

Change-Id: If0ed09ed19b92934e869bbd40d8716a83e4b0a30
2016-07-15 16:42:55 +00:00
umherirrender
eac06f65ce Use more short array syntax in comments (/tests/)
Change-Id: I86c73cb9447ac562a73348b4030e24ebf49a90dc
2016-07-10 17:23:29 +02:00
Florian
7c4d73183c registration: Allow string value for Hooks
Instead of forcing an object even for single-hook-listeners, allow
string values, too (one hook listener for one hook, only). Also:
use it as default for the conversion script, if only one listener
is added to a hook (which is usually the case). This leads into a
much cleaner output of the Hooks section of extension.json.

Bug: T133628
Change-Id: Ie9e54f0931c41706eb8d82d00256698992ec41cc
2016-05-03 13:23:07 -07:00
Timo Tijhof
4193700b19 Add missing namespace to @covers comments
PHP_CodeCoverage_Exception:
> Trying to @cover not existing method "SwiftFileBackend::sanitzeHdrs".
> Trying to @cover not existing method "LineFormatter::normalizeException".
> Trying to @cover not existing method "MonologSpi::mergeConfig".
> Trying to @cover not existing method "ProcessCacheLRU::het".
> Trying to @cover not existing method "BitmapHandler::swapICCProfile".
> Trying to @cover not existing class or interface "checkParseSafety".
> Trying to @cover not existing method "Article::__call". (was removed).
> Trying to @cover not existing method "ExtensionProcessor::extracttExtensionMessagesFiles".
> Trying to @cover not existing method "FileContentsHasher::getFileContentHash".

Makes code coverage run fail at the moment. These used to be warnings
in PHPUnit 3.x, but are now hard exceptions in PHPUnit 4.x when requesting
a coverage report.

Change-Id: If7f45ca57fd7d480d35b1414a889398837c0c472
2016-02-23 03:56:49 +00:00
Timo Tijhof
04362aa613 registration: Avoid double slashes in localBasePath
Noticed it in APC usage for ResourceLoader that various keys from
FileContentsHasher contain double slashes. All from extensions that
use the `"localBasePath": ""` trick in extension.json (e.g. Citoid).

Change-Id: I5bac1e2e05e063aa7ff251ce7ffaa965a3451db9
2016-02-18 10:25:02 -08:00
Kunal Mehta
6e9b4f0e9c Convert all array() syntax to []
Per wikitech-l consensus:
 https://lists.wikimedia.org/pipermail/wikitech-l/2016-February/084821.html

Notes:
* Disabled CallTimePassByReference due to false positives (T127163)

Change-Id: I2c8ce713ce6600a0bb7bf67537c87044c7a45c4b
2016-02-17 01:33:00 -08:00
Kunal Mehta
8e61ed3507 registration: Prevent loading the same thing twice
Normally the registry load queue should filter out duplicates, but if
people do weird things with symlinks, throw a useful error message if
the double-loading makes it all the way to the processor.

Bug: T121493
Change-Id: I47f5cd754e5f3c91e6b83a6d0ab542404347a421
2015-12-29 17:52:11 -08:00
jenkins-bot
c6e300e9f8 Merge "registration: Allow loading composer's autoloader if it exists" 2015-12-30 00:16:43 +00:00
victorbarbu
7489cdfc05 registration: Allow loading composer's autoloader if it exists
Extensions that have composer dependencies can set
 "load_composer_autoloader": true
to load "$dir/vendor/autoload.php" if it exists.

While it is recommended to use composer-merge-plugin to manage
composer dependencies for extensions, using a local autoloader
can be easier for development and is used by ExtensionDistributor.

Bug: T119766
Change-Id: Ib031bef17c8a7d708a5c7878e74967d19217bbc8
2015-12-29 23:20:17 +00:00
umherirrender
54c1e18eec Remove various double empty newlines
The double empty newline is not needed between functions, variable or at
end of file

Change-Id: Ib866a95084c4601ac150a2b402cfa184ebc18afa
2015-12-27 18:55:12 +00:00
Amir E. Aharoni
bfdd3369c2 Fix Generic.Files.LineLength phpcs check in files under phpunit/includes
Bug: T102614
Change-Id: Iee3df5f064f595ecebe8210cc936bc3d20a122c9
2015-10-03 17:13:29 +00:00
jenkins-bot
35f61c7c4b Merge "registration: Allow extensions to specify which MW core versions they require" 2015-09-22 04:57:47 +00:00
Kunal Mehta
cef1f31167 registration: Allow extensions to specify which MW core versions they require
This adds a "requires" property to extension.json, which extensions and
skins can use to indicate which versions of MediaWiki core they support.
The hacky wfUseMW() is now deprecated in favor of this.

Rather than writing our own version constraint and parser library, we
can re-use composer's, which was recently split out into a separate
library named "composer/semver" for this patch.

Any syntax accepted by composer[1] is available for usage here. Test
cases have been provided to demonstrate how versions are parsed. For now
it is recommended that people stick to expressing compatability with
stable versions (e.g. ">= 1.26").

This patch does not support requiring specific MediaWiki core WMF
branches, since those do not follow the standard semver format that
composer parses. If we are unable to parse $wgVersion, all checking will
be skipped and reported as compatible.

[1] https://getcomposer.org/doc/01-basic-usage.md#package-versions

Bug: T99084
Change-Id: I7785827216e16c596356d0ae42d6b30f3f179f10
2015-09-21 09:56:53 -07:00
Kunal Mehta
0a83ef3cf7 registration: Fix merging of array_plus
We want the local configuration ($GLOBALS[$key]) to override the default
values ($val). This matches what `array_merge` does.

Bug: T112868
Change-Id: I9c333a1fa67d3f24e09ffed3072b2897389f6139
2015-09-17 10:29:02 -07:00
Kunal Mehta
17a41f9277 registration: Allow custom prefixes for configuration settings
Allow extensions which are using "$eg" or any other prefix to migrate.

Extensions can override the default of "wg" by setting a magic "_prefix"
key in the "config" object.

Note that the migration helper script will not be able to automatically
migrate custom-prefixed configuration settings.

Bug: T97186
Change-Id: I79203cd5e3a2405b92ad01da869de3bd3d359d19
2015-09-03 12:44:46 +00:00
Kunal Mehta
1ebb0f5659 registration: Overhaul merging of globals
Instead of hardcoding specific global settings in ExtensionRegistry,
create specific "merge strategies" that are used to merge globals.

Merge strategies are set for core properties in the ExtensionProcessor,
and extensions can set them for their own configuration settings using
the magic "_merge_strategy" key.

The following merge strategies are included:
* array_merge_recursive - call `array_merge_recursive` on the two arrays
* array_plus - use the "+" operator to combine arrays, preserving
               integer keys
* array_plus_2d - A version of array_plus that works on 2d arrays, used
                  for merging arrays like $wgGroupPermissions
* array_merge - call `array_merge` (default)

This changes the merging of various namespaces related settings to use
array_plus so they actually work.

Bug: T107646
Change-Id: I64cb0553864e3b78b0f203333f58bb73b86a6434
2015-08-02 12:04:25 -07:00
Vivek Ghaisas
d6def861bf Explicitly declare property visibility, remove use of var
Codesniffer says that the `var` keyword must not be used to declare a
property and that visibility must be declared on class properties.

Change-Id: I28240aa0f394588b1df315621dbcd260c51430c1
2015-06-21 00:07:13 +03:00
Kunal Mehta
ce5a0c5cd2 registration: Don't override boolean false settings
Our optimization of !$GLOBALS[$key] was affecting settings where a true
setting was being disabled in LocalSettings.php. Now explicitly check it
is an array before overriding it.

Bug: T100767
Change-Id: Id5397e526d66559bfabe6065223b1181a8a9d31e
2015-06-03 08:03:20 -07:00
Kunal Mehta
a1368a3d9b registration: Version the extension.json schema
Versioning the extension.json schema will allow us to make breaking changes
to the schema in a non-breaking manner.

Extensiosn and skins will set a 'manifest_version' value, stating which
version of the schema the file is written for. Processor::extractInfo() will
be  passed the version number, and can switch behavior depending upon it.

For backwards-compatability, a version number of 1 is assumed if none is set.
The validateRegistrationFile.php script will emit a warning if this is the
case.

Bug: T99344
Change-Id: I2086a1465ceaeedd1ccc6804fda2c304ad16ffa0
2015-05-28 22:20:59 +00:00
jenkins-bot
f61844cbe3 Merge "registration: Add test case to demonstrate T98347 is invalid" 2015-05-21 17:27:35 +00:00
Kunal Mehta
a3f47a5915 registration: Use a static whitelist of keys that are not attributes
Rather than continuously creating an array of keys that were used, just
hardcode a list of keys that aren't attributes. This also handles keys
like "AutoloadClasses" that is handled by the registry.

Bug: T98977
Change-Id: I35088a76ff4c58db71e8c9bc139fa0ccca738e3b
2015-05-17 23:32:33 -07:00
Kunal Mehta
048b148edb registration: Add test case to demonstrate T98347 is invalid
Change-Id: I0f5c1bfa0d83465beffb1cc5ebaa457169569228
2015-05-15 17:57:12 -07:00
Kunal Mehta
2fcd5d7909 registration: Fix having multiple callbacks for a single hook
Bug: T98975
Change-Id: I40ff36090d18344fabdb018519209671b7883fa1
2015-05-13 12:30:21 -07:00
Kunal Mehta
77a813f21f registration: Support ResourceModuleSkinStyles
Structurally, it's set up exactly the same as ResourceModules, so we can
re-use the same code.

Bug: T91566
Change-Id: I7cd1330edc3e97b4658c81aac67071a90ac61fb6
2015-04-07 08:43:16 -07:00
umherirrender
14cc0fdf8e Avoid @backupGlobals in ExtensionRegistryTest
Change-Id: Ia2c764b1c1ee8cff64e1ccdb863e5ef7534a286a
2015-02-22 11:02:15 +01:00
Kunal Mehta
ad64077cbc Fix @backupGlobals annotation in ExtensionRegistryTest
Change-Id: I9a38354030eb2638d7988c0f903fb2181ec17cc6
2015-02-21 22:02:58 +00:00
Kunal Mehta
1b22e7783b registration: Improve merging of arrays
Currently we use array_merge_recursive when merging any array, which is really
only needed for merging $wgHooks entries, and causes issues when trying to
merge default settings if the config is already set.

$wgHooks and $wgGroupPermissions are now special cased when merging, and all
other arrays are just +='d.

Bug: T88665
Bug: T89364
Change-Id: I773a9463d4428aa618c17f848c01b24e04610e95
2015-02-16 23:12:32 +00:00
Kunal Mehta
18aab5e395 registration: Apply ResourceFileModulePaths to all modules
Previously any module definition that specified a "class" was skipped. This
is problematic for custom modules that extend ResourceLoaderFileModule and
should be using the default paths.

Since we can't determine at initialization time whether a module class is a
ResourceLoaderFileModule or not, just add the default paths to all modules,
and leave it up to the individual classes to use the extra arguments or not.

Change-Id: Iee5d178343326030968755983f62629b81ef3c88
2015-02-11 01:46:11 +00:00
jenkins-bot
884ac54872 Merge "registration: Add resource template-like functionality to extension.json" 2015-02-09 23:21:09 +00:00
Kunal Mehta
912a5e5ec3 registration: Add resource template-like functionality to extension.json
This allows for extensions to specify common arguments to ResourceLoader
module definitions by only specifying them once.

The only supported values are "localBasePath" (which is relative to the
current directory), "remoteSkinPath", and "remoteExtPath". If a module
is using a custom class or is already specifying paths, the default paths
will not be added.

Tests are included to cover existing functionality and newly added
functionality. The convertExtensionToRegistration.php script was also
extended to try and guess what the default paths should be.

Bug: T88786
Change-Id: I802461796e8d8584dacf3b0c811b5ba97a4a8f7f
2015-02-09 15:14:06 -08:00
Kunal Mehta
7067b6130d registration: Fix regression in ExtensionMessagesFiles handling
In f2daeaa749, the handling of MessageDirs was fixed to properly
handle arrays, except that broke ExtensionMessagesFiles which doesn't
support arrays. Since both settings are pretty much different, I split
them into separate functions.

Bug: T88858
Change-Id: I48765af2489d2ef1e30adb1d7c5a5a8f23bf522d
2015-02-06 15:02:26 -08:00
Kunal Mehta
f2daeaa749 registration: Fix handling of MessagesDirs array and add tests
Previously the code was designed to handle:
  "MessagesDirs": {
    "FooBar": "i18n"
  }

However, it can also be an array, and some extensions (VisualEditor)
use it like:

  "MessagesDirs": {
    "FooBar": [
      "i18n",
      "also-i18n"
    ]
  }

This properly handles both strings and arrays and adds tests to verify
the behavior.

Change-Id: Iff1523b86f754cac1f5b8d822d4324c5fbfc1a50
2015-01-30 13:00:22 -08:00
Kunal Mehta
920ef42ae0 registration: Ignore keys prefixed with @ in "config"
This will allow for documentation of individual configuration
options.

Change-Id: I180bc742c96985c2a8358aef814d993fca9aba84
2015-01-26 23:00:07 -08:00
Kunal Mehta
896b9b5c65 registration: Ignore attributes that start with @
Allow these to be used for fake comments or other information
that should not be loaded.

Change-Id: Id79cd8b18988b94db565b2ddbc31ee6f17a89fca
2015-01-13 11:49:09 -08:00
Kunal Mehta
bfe4ddd810 Implement extension registration from an extension.json file
Introduces wfLoadExtension()/wfLoadSkin() which should be used in
LocalSettings.php rather than require-ing a PHP entry point.

Extensions and skins would add "extension.json" or "skin.json" files
in their root, which contains all the information typically
present in PHP entry point files (classes to autoload, special pages,
API modules, etc.) A full schema can be found at
docs/extension.schema.json, and a script to validate these to the
schema is provided. An additional script is provided to convert
typical PHP entry point files into their JSON equivalents.

The basic flow of loading an extension goes like:
 * Get the ExtensionRegistry singleton instance
 * ExtensionRegistry takes a filename, reads the file or tries
   to get the parsed JSON from APC if possible.
 * The JSON is run through a Processor instance,
   which registers things with the appropriate
   global settings.
 * The output of the processor is cached in APC if possible.
 * The extension/skin is marked as loaded in the
   ExtensionRegistry and a callback function is executed
   if one was specified.

For ideal performance, a batch loading method is also provided:
 * The absolute path name to the JSON file is queued
   in the ExtensionRegistry instance.
 * When loadFromQueue() is called, it constructs a hash
   unique to the members of the current queue, and sees
   if the queue has been cached in APC. If not, it processes
   each file individually, and combines the result of each
   Processor into one giant array, which is cached in APC.
 * The giant array then sets various global settings,
   defines constants, and calls callbacks.

To invalidate the cached processed info, by default the mtime
of each JSON file is checked. However that can be slow if you
have a large number of extensions, so you can set $wgExtensionInfoMTime
to the mtime of one file, and `touch` it whenever you update
your extensions.

Change-Id: I7074b65d07c5c7d4e3f1fb0755d74a0b07ed4596
2015-01-08 01:40:01 +00:00