jenkins-bot has submitted this change and it was merged.

Change subject: registration: Version the extension.json schema
......................................................................


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
---
M docs/extension.schema.json
M includes/registration/ExtensionProcessor.php
M includes/registration/ExtensionRegistry.php
M includes/registration/Processor.php
M maintenance/convertExtensionToRegistration.php
M maintenance/validateRegistrationFile.php
M tests/phpunit/includes/registration/ExtensionProcessorTest.php
7 files changed, 61 insertions(+), 13 deletions(-)

Approvals:
  Ori.livneh: Looks good to me, approved
  Legoktm: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/docs/extension.schema.json b/docs/extension.schema.json
index d5c17a1..34cfe2c 100644
--- a/docs/extension.schema.json
+++ b/docs/extension.schema.json
@@ -3,6 +3,11 @@
        "description": "MediaWiki extension.json schema",
        "type": "object",
        "properties": {
+               "manifest_version": {
+                       "type": "integer",
+                       "description": "Version of the extension.json schema 
the extension.json file is in.",
+                       "required": true
+               },
                "name": {
                        "type": "string",
                        "description": "The extension's canonical name.",
diff --git a/includes/registration/ExtensionProcessor.php 
b/includes/registration/ExtensionProcessor.php
index b0398eb..0a09ff5 100644
--- a/includes/registration/ExtensionProcessor.php
+++ b/includes/registration/ExtensionProcessor.php
@@ -81,6 +81,7 @@
                'config',
                'ParserTestFiles',
                'AutoloadClasses',
+               'manifest_version',
        );
 
        /**
@@ -125,9 +126,10 @@
        /**
         * @param string $path
         * @param array $info
+        * @param int $version manifest_version for info
         * @return array
         */
-       public function extractInfo( $path, array $info ) {
+       public function extractInfo( $path, array $info, $version ) {
                $this->extractConfig( $info );
                $this->extractHooks( $info );
                $dir = dirname( $path );
diff --git a/includes/registration/ExtensionRegistry.php 
b/includes/registration/ExtensionRegistry.php
index ac39699..1c36407 100644
--- a/includes/registration/ExtensionRegistry.php
+++ b/includes/registration/ExtensionRegistry.php
@@ -12,6 +12,16 @@
 class ExtensionRegistry {
 
        /**
+        * Version of the highest supported manifest version
+        */
+       const MANIFEST_VERSION = 1;
+
+       /**
+        * Version of the oldest supported manifest version
+        */
+       const OLDEST_MANIFEST_VERSION = 1;
+
+       /**
         * @var BagOStuff
         */
        protected $cache;
@@ -128,11 +138,19 @@
                        if ( !is_array( $info ) ) {
                                throw new Exception( "$path is not a valid JSON 
file." );
                        }
+                       if ( !isset( $info['manifest_version' ] ) ) {
+                               // For backwards-compatability, assume a 
version of 1
+                               $info['manifest_version'] = 1;
+                       }
+                       $version = $info['manifest_version'];
+                       if ( $version < self::OLDEST_MANIFEST_VERSION || 
$version > self::MANIFEST_VERSION ) {
+                               throw new Exception( "$path: unsupported 
manifest_version: {$version}" );
+                       }
                        $autoload = $this->processAutoLoader( dirname( $path ), 
$info );
                        // Set up the autoloader now so custom processors will 
work
                        $GLOBALS['wgAutoloadClasses'] += $autoload;
                        $autoloadClasses += $autoload;
-                       $processor->extractInfo( $path, $info );
+                       $processor->extractInfo( $path, $info, $version );
                }
                $data = $processor->getExtractedInfo();
                // Need to set this so we can += to it later
diff --git a/includes/registration/Processor.php 
b/includes/registration/Processor.php
index 391f108..e1aaca7 100644
--- a/includes/registration/Processor.php
+++ b/includes/registration/Processor.php
@@ -16,9 +16,10 @@
         *
         * @param string $path Absolute path of JSON file
         * @param array $info
+        * @param int $version manifest_version for info
         * @return array "credits" information to store
         */
-       public function extractInfo( $path, array $info );
+       public function extractInfo( $path, array $info, $version );
 
        /**
         * @return array With following keys:
diff --git a/maintenance/convertExtensionToRegistration.php 
b/maintenance/convertExtensionToRegistration.php
index e0631a7..8adae2d 100644
--- a/maintenance/convertExtensionToRegistration.php
+++ b/maintenance/convertExtensionToRegistration.php
@@ -118,7 +118,8 @@
                        }
                }
                $out += $this->json;
-
+               // Put this at the bottom
+               $out['manifest_version'] = ExtensionRegistry::MANIFEST_VERSION;
                $type = $this->hasOption( 'skin' ) ? 'skin' : 'extension';
                $fname = "{$this->dir}/$type.json";
                $prettyJSON = FormatJson::encode( $out, "\t", 
FormatJson::ALL_OK );
diff --git a/maintenance/validateRegistrationFile.php 
b/maintenance/validateRegistrationFile.php
index e764661..08af11a 100644
--- a/maintenance/validateRegistrationFile.php
+++ b/maintenance/validateRegistrationFile.php
@@ -12,18 +12,39 @@
                        $this->error( 'The JsonSchema library cannot be found, 
please install it through composer.', 1 );
                }
 
-               $retriever = new JsonSchema\Uri\UriRetriever();
-               $schema = $retriever->retrieve('file://' . dirname( __DIR__ ) . 
'/docs/extension.schema.json' );
                $path = $this->getArg( 0 );
                $data = json_decode( file_get_contents( $path ) );
                if ( !is_object( $data ) ) {
                        $this->error( "$path is not a valid JSON file.", 1 );
                }
+               if ( !isset( $data->manifest_version ) ) {
+                       $this->output("Warning: No manifest_version set, 
assuming 1.\n" );
+                       // For backwards-compatability assume 1
+                       $data->manifest_version = 1;
+               }
+               $version = $data->manifest_version;
+               if ( $version !== ExtensionRegistry::MANIFEST_VERSION ) {
+                       $schemaPath = dirname( __DIR__ ) . 
"/docs/extension.schema.v$version.json";
+               } else {
+                       $schemaPath = dirname( __DIR__ ) . 
'/docs/extension.schema.json';
+               }
+
+               if ( $version < ExtensionRegistry::OLDEST_MANIFEST_VERSION
+                       || $version > ExtensionRegistry::MANIFEST_VERSION
+               ) {
+                       $this->error( "Error: $path is using a non-supported 
schema version, it should use "
+                               . ExtensionRegistry::MANIFEST_VERSION, 1 );
+               } elseif ( $version < ExtensionRegistry::MANIFEST_VERSION ) {
+                       $this->output( "Warning: $path is using a deprecated 
schema, and should be updated to "
+                               . ExtensionRegistry::MANIFEST_VERSION . "\n" );
+               }
+               $retriever = new JsonSchema\Uri\UriRetriever();
+               $schema = $retriever->retrieve('file://' . $schemaPath );
 
                $validator = new JsonSchema\Validator();
                $validator->check( $data, $schema );
                if ( $validator->isValid() ) {
-                       $this->output( "$path validates against the schema!\n" 
);
+                       $this->output( "$path validates against the version 
$version schema!\n" );
                } else {
                        foreach ( $validator->getErrors() as $error ) {
                                $this->output( "[{$error['property']}] 
{$error['message']}\n" );
diff --git a/tests/phpunit/includes/registration/ExtensionProcessorTest.php 
b/tests/phpunit/includes/registration/ExtensionProcessorTest.php
index 9474496..2df5568 100644
--- a/tests/phpunit/includes/registration/ExtensionProcessorTest.php
+++ b/tests/phpunit/includes/registration/ExtensionProcessorTest.php
@@ -28,7 +28,7 @@
                        '@metadata' => array( 'foobarbaz' ),
                        'AnAttribute' => array( 'omg' ),
                        'AutoloadClasses' => array( 'FooBar' => 
'includes/FooBar.php' ),
-               ) );
+               ), 1 );
 
                $extracted = $processor->getExtractedInfo();
                $attributes = $extracted['attributes'];
@@ -95,7 +95,7 @@
         */
        public function testRegisterHooks( $pre, $info, $expected ) {
                $processor = new MockExtensionProcessor( array( 'wgHooks' => 
$pre ) );
-               $processor->extractInfo( $this->dir, $info );
+               $processor->extractInfo( $this->dir, $info, 1 );
                $extracted = $processor->getExtractedInfo();
                $this->assertEquals( $expected, 
$extracted['globals']['wgHooks'] );
        }
@@ -112,7 +112,7 @@
                                '@IGNORED' => 'yes',
                        ),
                ) + self::$default;
-               $processor->extractInfo( $this->dir, $info );
+               $processor->extractInfo( $this->dir, $info, 1 );
                $extracted = $processor->getExtractedInfo();
                $this->assertEquals( 'somevalue', 
$extracted['globals']['wgBar'] );
                $this->assertEquals( 10, $extracted['globals']['wgFoo'] );
@@ -149,7 +149,7 @@
         */
        public function testExtracttExtensionMessagesFiles( $input, $expected ) 
{
                $processor = new ExtensionProcessor();
-               $processor->extractInfo( $this->dir, $input + self::$default );
+               $processor->extractInfo( $this->dir, $input + self::$default, 1 
);
                $out = $processor->getExtractedInfo();
                foreach ( $expected as $key => $value ) {
                        $this->assertEquals( $value, $out['globals'][$key] );
@@ -177,7 +177,7 @@
         */
        public function testExtractMessagesDirs( $input, $expected ) {
                $processor = new ExtensionProcessor();
-               $processor->extractInfo( $this->dir, $input + self::$default );
+               $processor->extractInfo( $this->dir, $input + self::$default, 1 
);
                $out = $processor->getExtractedInfo();
                foreach ( $expected as $key => $value ) {
                        $this->assertEquals( $value, $out['globals'][$key] );
@@ -190,7 +190,7 @@
         */
        public function testExtractResourceLoaderModules( $input, $expected ) {
                $processor = new ExtensionProcessor();
-               $processor->extractInfo( $this->dir, $input + self::$default );
+               $processor->extractInfo( $this->dir, $input + self::$default, 1 
);
                $out = $processor->getExtractedInfo();
                foreach ( $expected as $key => $value ) {
                        $this->assertEquals( $value, $out['globals'][$key] );

-- 
To view, visit https://gerrit.wikimedia.org/r/212239
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I2086a1465ceaeedd1ccc6804fda2c304ad16ffa0
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Legoktm <legoktm.wikipe...@gmail.com>
Gerrit-Reviewer: Legoktm <legoktm.wikipe...@gmail.com>
Gerrit-Reviewer: Ori.livneh <o...@wikimedia.org>
Gerrit-Reviewer: Parent5446 <tylerro...@gmail.com>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to