From: Florian Schmidt Date: Sat, 3 Dec 2016 18:06:46 +0000 (+0100) Subject: registration: Generalize CoreVersionChecker to VersionChecker X-Git-Tag: 1.31.0-rc.0~4567^2 X-Git-Url: http://git.cyclocoop.org/ecrire?a=commitdiff_plain;h=5f11f7818c3e3f82245ce92aa699e08fa086b70a;p=lhc%2Fweb%2Fwiklou.git 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 --- diff --git a/autoload.php b/autoload.php index e079686bc4..91f7700523 100644 --- a/autoload.php +++ b/autoload.php @@ -293,7 +293,6 @@ $wgAutoloadLocalClasses = [ 'CopyJobQueue' => __DIR__ . '/maintenance/copyJobQueue.php', 'CoreParserFunctions' => __DIR__ . '/includes/parser/CoreParserFunctions.php', 'CoreTagHooks' => __DIR__ . '/includes/parser/CoreTagHooks.php', - 'CoreVersionChecker' => __DIR__ . '/includes/registration/CoreVersionChecker.php', 'CreateAndPromote' => __DIR__ . '/maintenance/createAndPromote.php', 'CreateFileOp' => __DIR__ . '/includes/libs/filebackend/fileop/CreateFileOp.php', 'CreditsAction' => __DIR__ . '/includes/actions/CreditsAction.php', @@ -1523,6 +1522,7 @@ $wgAutoloadLocalClasses = [ 'UzConverter' => __DIR__ . '/languages/classes/LanguageUz.php', 'VFormHTMLForm' => __DIR__ . '/includes/htmlform/VFormHTMLForm.php', 'ValidateRegistrationFile' => __DIR__ . '/maintenance/validateRegistrationFile.php', + 'VersionChecker' => __DIR__ . '/includes/registration/VersionChecker.php', 'ViewAction' => __DIR__ . '/includes/actions/ViewAction.php', 'VirtualRESTService' => __DIR__ . '/includes/libs/virtualrest/VirtualRESTService.php', 'VirtualRESTServiceClient' => __DIR__ . '/includes/libs/virtualrest/VirtualRESTServiceClient.php', diff --git a/includes/registration/CoreVersionChecker.php b/includes/registration/CoreVersionChecker.php deleted file mode 100644 index f64d826da0..0000000000 --- a/includes/registration/CoreVersionChecker.php +++ /dev/null @@ -1,68 +0,0 @@ -versionParser = new VersionParser(); - try { - $this->coreVersion = new Constraint( - '==', - $this->versionParser->normalize( $coreVersion ) - ); - } catch ( UnexpectedValueException $e ) { - // Non-parsable version, don't fatal. - } - } - - /** - * Check that the provided constraint is compatible with the current version of core - * - * @param string $constraint Something like ">= 1.26" - * @return bool - */ - public function check( $constraint ) { - if ( $this->coreVersion === false ) { - // Couldn't parse the core version, so we can't check anything - return true; - } - - return $this->versionParser->parseConstraints( $constraint ) - ->matches( $this->coreVersion ); - } -} diff --git a/includes/registration/ExtensionProcessor.php b/includes/registration/ExtensionProcessor.php index d9671324fe..1212f9972c 100644 --- a/includes/registration/ExtensionProcessor.php +++ b/includes/registration/ExtensionProcessor.php @@ -216,13 +216,7 @@ class ExtensionProcessor implements Processor { } public function getRequirements( array $info ) { - $requirements = []; - $key = ExtensionRegistry::MEDIAWIKI_CORE; - if ( isset( $info['requires'][$key] ) ) { - $requirements[$key] = $info['requires'][$key]; - } - - return $requirements; + return isset( $info['requires'] ) ? $info['requires'] : []; } protected function extractHooks( array $info ) { diff --git a/includes/registration/ExtensionRegistry.php b/includes/registration/ExtensionRegistry.php index 70dc6248f0..0521f3b263 100644 --- a/includes/registration/ExtensionRegistry.php +++ b/includes/registration/ExtensionRegistry.php @@ -204,7 +204,8 @@ class ExtensionRegistry { $autoloaderPaths = []; $processor = new ExtensionProcessor(); $incompatible = []; - $coreVersionParser = new CoreVersionChecker( $wgVersion ); + $versionParser = new VersionChecker(); + $versionParser->setCoreVersion( $wgVersion ); foreach ( $queue as $path => $mtime ) { $json = file_get_contents( $path ); if ( $json === false ) { @@ -217,14 +218,14 @@ class ExtensionRegistry { // Check any constraints against MediaWiki core $requires = $processor->getRequirements( $info ); - if ( isset( $requires[self::MEDIAWIKI_CORE] ) - && !$coreVersionParser->check( $requires[self::MEDIAWIKI_CORE] ) - ) { - // Doesn't match, mark it as incompatible. - $incompatible[] = "{$info['name']} is not compatible with the current " - . "MediaWiki core (version {$wgVersion}), it requires: " . $requires[self::MEDIAWIKI_CORE] - . '.'; - continue; + if ( $requires ) { + $versionCheck = $versionParser->checkArray( + [ $info['name'] => $requires ] + ); + $incompatible = array_merge( $incompatible, $versionCheck ); + if ( $versionCheck ) { + continue; + } } if ( !isset( $info['manifest_version'] ) ) { diff --git a/includes/registration/VersionChecker.php b/includes/registration/VersionChecker.php new file mode 100644 index 0000000000..b61a10e4b2 --- /dev/null +++ b/includes/registration/VersionChecker.php @@ -0,0 +1,128 @@ +versionParser = new VersionParser(); + } + + /** + * Set MediaWiki core version. + * + * @param string $coreVersion Current version of core + * @return VersionChecker $this + */ + public function setCoreVersion( $coreVersion ) { + try { + $this->coreVersion = new Constraint( + '==', + $this->versionParser->normalize( $coreVersion ) + ); + $this->coreVersion->setPrettyString( $coreVersion ); + } catch ( UnexpectedValueException $e ) { + // Non-parsable version, don't fatal. + } + + return $this; + } + + /** + * Check all given dependencies if they are compatible with the named + * installed extensions in the $credits array. + * + * Example $extDependencies: + * { + * 'GoogleAPIClient' => { + * 'MediaWiki' => '>= 1.25.0' + * } + * } + * + * @param array $extDependencies All extensions that depend on other ones + * @return array + */ + public function checkArray( array $extDependencies ) { + $errors = []; + foreach ( $extDependencies as $extension => $dependencies ) { + foreach ( $dependencies as $dependencyType => $values ) { + switch ( $dependencyType ) { + case ExtensionRegistry::MEDIAWIKI_CORE: + $errors = array_merge( + $errors, + $this->handleMediaWikiDependency( $values, $extension ) + ); + break; + default: + throw new UnexpectedValueException( 'Dependency type ' . $dependencyType . + ' unknown in ' . $extension ); + } + } + } + + return $errors; + } + + /** + * Handle a dependency to MediaWiki core. It will check, if a MediaWiki version constraint was + * set with self::setCoreVersion before this call (if not, it will return an empty array) and + * checks the version constraint given against it. + * + * @param string $constraint The required version constraint for this dependency + * @param string $checkedExt The Extension, which depends on this dependency + * @return array An empty array, if MediaWiki version is compatible with $constraint, an array + * with an error message, otherwise. + */ + private function handleMediaWikiDependency( $constraint, $checkedExt ) { + if ( $this->coreVersion === false ) { + // Couldn't parse the core version, so we can't check anything + return []; + } + + // if the installed and required version are compatible, return an empty array + if ( $this->versionParser->parseConstraints( $constraint ) + ->matches( $this->coreVersion ) ) { + return []; + } + // otherwise mark this as incompatible. + return [ "{$checkedExt} is not compatible with the current " + . "MediaWiki core (version {$this->coreVersion->getPrettyString()}), it requires: " + . $constraint . '.' ]; + } +} diff --git a/tests/phpunit/includes/registration/CoreVersionCheckerTest.php b/tests/phpunit/includes/registration/CoreVersionCheckerTest.php deleted file mode 100644 index 1dfcd82226..0000000000 --- a/tests/phpunit/includes/registration/CoreVersionCheckerTest.php +++ /dev/null @@ -1,38 +0,0 @@ -assertEquals( $expected, $checker->check( $constraint ) ); - } - - public static function provideCheck() { - return [ - // [ $wgVersion, constraint, expected ] - [ '1.25alpha', '>= 1.26', false ], - [ '1.25.0', '>= 1.26', false ], - [ '1.26alpha', '>= 1.26', true ], - [ '1.26alpha', '>= 1.26.0', true ], - [ '1.26alpha', '>= 1.26.0-stable', false ], - [ '1.26.0', '>= 1.26.0-stable', true ], - [ '1.26.1', '>= 1.26.0-stable', true ], - [ '1.27.1', '>= 1.26.0-stable', true ], - [ '1.26alpha', '>= 1.26.1', false ], - [ '1.26alpha', '>= 1.26alpha', true ], - [ '1.26alpha', '>= 1.25', true ], - [ '1.26.0-alpha.14', '>= 1.26.0-alpha.15', false ], - [ '1.26.0-alpha.14', '>= 1.26.0-alpha.10', true ], - [ '1.26.1', '>= 1.26.2, <=1.26.0', false ], - [ '1.26.1', '^1.26.2', false ], - // Accept anything for un-parsable version strings - [ '1.26mwf14', '== 1.25alpha', true ], - [ 'totallyinvalid', '== 1.0', true ], - ]; - } -} diff --git a/tests/phpunit/includes/registration/VersionCheckerTest.php b/tests/phpunit/includes/registration/VersionCheckerTest.php new file mode 100644 index 0000000000..daa407f3b2 --- /dev/null +++ b/tests/phpunit/includes/registration/VersionCheckerTest.php @@ -0,0 +1,44 @@ +setCoreVersion( $coreVersion ); + $this->assertEquals( $expected, !(bool)$checker->checkArray( [ + 'FakeExtension' => [ + 'MediaWiki' => $constraint, + ], + ] ) + ); + } + + public static function provideCheck() { + return [ + // [ $wgVersion, constraint, expected ] + [ '1.25alpha', '>= 1.26', false ], + [ '1.25.0', '>= 1.26', false ], + [ '1.26alpha', '>= 1.26', true ], + [ '1.26alpha', '>= 1.26.0', true ], + [ '1.26alpha', '>= 1.26.0-stable', false ], + [ '1.26.0', '>= 1.26.0-stable', true ], + [ '1.26.1', '>= 1.26.0-stable', true ], + [ '1.27.1', '>= 1.26.0-stable', true ], + [ '1.26alpha', '>= 1.26.1', false ], + [ '1.26alpha', '>= 1.26alpha', true ], + [ '1.26alpha', '>= 1.25', true ], + [ '1.26.0-alpha.14', '>= 1.26.0-alpha.15', false ], + [ '1.26.0-alpha.14', '>= 1.26.0-alpha.10', true ], + [ '1.26.1', '>= 1.26.2, <=1.26.0', false ], + [ '1.26.1', '^1.26.2', false ], + // Accept anything for un-parsable version strings + [ '1.26mwf14', '== 1.25alpha', true ], + [ 'totallyinvalid', '== 1.0', true ], + ]; + } +}