From 5f11f7818c3e3f82245ce92aa699e08fa086b70a Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Sat, 3 Dec 2016 19:06:46 +0100 Subject: [PATCH] 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 --- autoload.php | 2 +- includes/registration/CoreVersionChecker.php | 68 ---------- includes/registration/ExtensionProcessor.php | 8 +- includes/registration/ExtensionRegistry.php | 19 +-- includes/registration/VersionChecker.php | 128 ++++++++++++++++++ ...CheckerTest.php => VersionCheckerTest.php} | 10 +- 6 files changed, 148 insertions(+), 87 deletions(-) delete mode 100644 includes/registration/CoreVersionChecker.php create mode 100644 includes/registration/VersionChecker.php rename tests/phpunit/includes/registration/{CoreVersionCheckerTest.php => VersionCheckerTest.php} (83%) 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/VersionCheckerTest.php similarity index 83% rename from tests/phpunit/includes/registration/CoreVersionCheckerTest.php rename to tests/phpunit/includes/registration/VersionCheckerTest.php index 1dfcd82226..daa407f3b2 100644 --- a/tests/phpunit/includes/registration/CoreVersionCheckerTest.php +++ b/tests/phpunit/includes/registration/VersionCheckerTest.php @@ -8,8 +8,14 @@ class CoreVersionCheckerTest extends PHPUnit_Framework_TestCase { * @dataProvider provideCheck */ public function testCheck( $coreVersion, $constraint, $expected ) { - $checker = new CoreVersionChecker( $coreVersion ); - $this->assertEquals( $expected, $checker->check( $constraint ) ); + $checker = new VersionChecker(); + $checker->setCoreVersion( $coreVersion ); + $this->assertEquals( $expected, !(bool)$checker->checkArray( [ + 'FakeExtension' => [ + 'MediaWiki' => $constraint, + ], + ] ) + ); } public static function provideCheck() { -- 2.20.1