}
}
},
+ "dev-requires": {
+ "type": "object",
+ "description": "Indicates what dependencies are required for development purposes such as running tests. This syntax may be extended in the future.",
+ "additionalProperties": false,
+ "properties": {
+ "MediaWiki": {
+ "type": "string",
+ "description": "Version constraint string against MediaWiki core."
+ },
+ "platform": {
+ "type": "object",
+ "description": "Indicates version constraints against platform services.",
+ "additionalProperties": false,
+ "properties": {
+ "php": {
+ "type": "string",
+ "description": "Version constraint string against PHP."
+ },
+ "ability-shell": {
+ "type": "boolean",
+ "default": false,
+ "description": "Whether this extension requires shell access."
+ }
+ },
+ "patternProperties": {
+ "^ext-": {
+ "type": "string",
+ "description": "Required PHP extension.",
+ "enum": ["*"]
+ }
+ }
+ },
+ "extensions": {
+ "type": "object",
+ "description": "Set of version constraint strings against specific extensions."
+ },
+ "skins": {
+ "type": "object",
+ "description": "Set of version constraint strings against specific skins."
+ }
+ }
+ },
"ResourceFileModulePaths": {
"type": "object",
"description": "Default paths to use for all ResourceLoader file modules",
}
}
},
+ "dev-requires": {
+ "type": "object",
+ "description": "Indicates what dependencies are required for development purposes such as running tests. This syntax may be extended in the future.",
+ "additionalProperties": false,
+ "properties": {
+ "MediaWiki": {
+ "type": "string",
+ "description": "Version constraint string against MediaWiki core."
+ },
+ "platform": {
+ "type": "object",
+ "description": "Indicates version constraints against platform services.",
+ "additionalProperties": false,
+ "properties": {
+ "php": {
+ "type": "string",
+ "description": "Version constraint string against PHP."
+ },
+ "ability-shell": {
+ "type": "boolean",
+ "default": false,
+ "description": "Whether this extension requires shell access."
+ }
+ },
+ "patternProperties": {
+ "^ext-": {
+ "type": "string",
+ "description": "Required PHP extension.",
+ "enum": ["*"]
+ }
+ }
+ },
+ "extensions": {
+ "type": "object",
+ "description": "Set of version constraint strings against specific extensions."
+ },
+ "skins": {
+ "type": "object",
+ "description": "Set of version constraint strings against specific skins."
+ }
+ }
+ },
"ResourceFileModulePaths": {
"type": "object",
"description": "Default paths to use for all ResourceLoader file modules",
];
}
- public function getRequirements( array $info ) {
- return $info['requires'] ?? [];
+ public function getRequirements( array $info, $includeDev ) {
+ // Quick shortcuts
+ if ( !$includeDev || !isset( $info['dev-requires'] ) ) {
+ return $info['requires'] ?? [];
+ }
+
+ if ( !isset( $info['requires'] ) ) {
+ return $info['dev-requires'] ?? [];
+ }
+
+ // OK, we actually have to merge everything
+ $merged = [];
+
+ // Helper that combines version requirements by
+ // picking the non-null if one is, or combines
+ // the two. Note that it is not possible for
+ // both inputs to be null.
+ $pick = function ( $a, $b ) {
+ if ( $a === null ) {
+ return $b;
+ } elseif ( $b === null ) {
+ return $a;
+ } else {
+ return "$a $b";
+ }
+ };
+
+ $req = $info['requires'];
+ $dev = $info['dev-requires'];
+ if ( isset( $req['MediaWiki'] ) || isset( $dev['MediaWiki'] ) ) {
+ $merged['MediaWiki'] = $pick(
+ $req['MediaWiki'] ?? null,
+ $dev['MediaWiki'] ?? null
+ );
+ }
+
+ $platform = array_merge(
+ array_keys( $req['platform'] ?? [] ),
+ array_keys( $dev['platform'] ?? [] )
+ );
+ if ( $platform ) {
+ foreach ( $platform as $pkey ) {
+ if ( $pkey === 'php' ) {
+ $value = $pick(
+ $req['platform']['php'] ?? null,
+ $dev['platform']['php'] ?? null
+ );
+ } else {
+ // Prefer dev value, but these should be constant
+ // anyways (ext-* and ability-*)
+ $value = $dev['platform'][$pkey] ?? $req['platform'][$pkey];
+ }
+ $merged['platform'][$pkey] = $value;
+ }
+ }
+
+ foreach ( [ 'extensions', 'skins' ] as $thing ) {
+ $things = array_merge(
+ array_keys( $req[$thing] ?? [] ),
+ array_keys( $dev[$thing] ?? [] )
+ );
+ foreach ( $things as $name ) {
+ $merged[$thing][$name] = $pick(
+ $req[$thing][$name] ?? null,
+ $dev[$thing][$name] ?? null
+ );
+ }
+ }
+
+ return $merged;
}
protected function extractHooks( array $info ) {
*/
protected $testAttributes = [];
+ /**
+ * Whether to check dev-requires
+ *
+ * @var bool
+ */
+ protected $checkDev = false;
+
/**
* @var ExtensionRegistry
*/
return self::$instance;
}
+ /**
+ * @since 1.34
+ * @param bool $check
+ */
+ public function setCheckDevRequires( $check ) {
+ $this->checkDev = $check;
+ }
+
/**
* @param string $path Absolute path to the JSON file
*/
'registration' => self::CACHE_VERSION,
'mediawiki' => $wgVersion,
'abilities' => $this->getAbilities(),
+ 'checkDev' => $this->checkDev,
];
// We use a try/catch because we don't want to fail here
}
// get all requirements/dependencies for this extension
- $requires = $processor->getRequirements( $info );
+ $requires = $processor->getRequirements( $info, $this->checkDev );
// validate the information needed and add the requirements
if ( is_array( $requires ) && $requires && isset( $info['name'] ) ) {
*
* @since 1.26
* @param array $info
+ * @param bool $includeDev
* @return array Where keys are the name to have a constraint on,
* like 'MediaWiki'. Values are a constraint string like "1.26.1".
*/
- public function getRequirements( array $info );
+ public function getRequirements( array $info, $includeDev );
/**
* Get the path for additional autoloaders, e.g. the one of Composer.
$processor = new ExtensionProcessor();
$this->assertSame(
$info['requires'],
- $processor->getRequirements( $info )
+ $processor->getRequirements( $info, false )
);
$this->assertSame(
[],
- $processor->getRequirements( [] )
+ $processor->getRequirements( [], false )
+ );
+ }
+
+ public function testGetDevRequirements() {
+ $info = self::$default + [
+ 'dev-requires' => [
+ 'MediaWiki' => '>= 1.31.0',
+ 'platform' => [
+ 'ext-foo' => '*',
+ ],
+ 'skins' => [
+ 'Baz' => '*',
+ ],
+ 'extensions' => [
+ 'Biz' => '*',
+ ],
+ ],
+ ];
+ $processor = new ExtensionProcessor();
+ $this->assertSame(
+ $info['dev-requires'],
+ $processor->getRequirements( $info, true )
+ );
+ // Set some standard requirements, so we can test merging
+ $info['requires'] = [
+ 'MediaWiki' => '>= 1.25.0',
+ 'platform' => [
+ 'php' => '>= 5.5.9'
+ ],
+ 'extensions' => [
+ 'Bar' => '*'
+ ]
+ ];
+ $this->assertSame(
+ [
+ 'MediaWiki' => '>= 1.25.0 >= 1.31.0',
+ 'platform' => [
+ 'php' => '>= 5.5.9',
+ 'ext-foo' => '*',
+ ],
+ 'extensions' => [
+ 'Bar' => '*',
+ 'Biz' => '*',
+ ],
+ 'skins' => [
+ 'Baz' => '*',
+ ],
+ ],
+ $processor->getRequirements( $info, true )
+ );
+
+ // If there's no dev-requires, it just returns requires
+ unset( $info['dev-requires'] );
+ $this->assertSame(
+ $info['requires'],
+ $processor->getRequirements( $info, true )
);
}