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

Change subject: \SMW\JobBase improve testability and eliminate GLOBALS from 
SMW\UpdateJob
......................................................................


\SMW\JobBase improve testability and eliminate GLOBALS from SMW\UpdateJob

Code coverage: 100%
CRAP: 11

* Use JobBase to access general purpose Setter/Getter
* Move SMWUpdateJob to SMW\UpdateJob (SMWUpdateJob object is still accessible)
* Eliminate global wgParser from UpdateJob
* SMW\UpdateJob logic should go in its own class but for now ...

Change-Id: I3b41d4e506a2c425903ec3690f3500dcec939ac4
---
M includes/Setup.php
A includes/jobs/JobBase.php
M includes/jobs/PropertySubjectsUpdateDispatcherJob.php
M includes/jobs/UpdateJob.php
M tests/phpunit/MockObjectBuilder.php
A tests/phpunit/includes/jobs/JobBaseTest.php
M tests/phpunit/includes/jobs/UpdateJobTest.php
7 files changed, 491 insertions(+), 67 deletions(-)

Approvals:
  Mwjames: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/includes/Setup.php b/includes/Setup.php
index 9a9ff03..17b4054 100644
--- a/includes/Setup.php
+++ b/includes/Setup.php
@@ -417,9 +417,10 @@
        $wgAutoloadClasses['SMW\Test\CompatibilityTestCase']         = 
$testsDir . 'CompatibilityTestCase.php';
 
        // Jobs
-       $wgJobClasses['SMWUpdateJob']       = 'SMWUpdateJob';
+       $wgAutoloadClasses['SMW\JobBase']   = $smwgIP . 
'includes/jobs/JobBase.php';
+       $wgJobClasses['SMW\UpdateJob']      = 'SMW\UpdateJob';
        $wgAutoloadClasses['SMWUpdateJob']  = $smwgIP . 
'includes/jobs/UpdateJob.php';
-       $wgAutoloadClasses['SMW\UpdateJob']  = $smwgIP . 
'includes/jobs/UpdateJob.php'; // 1.9
+       $wgAutoloadClasses['SMW\UpdateJob'] = $smwgIP . 
'includes/jobs/UpdateJob.php'; // 1.9
        $wgJobClasses['SMWRefreshJob']      = 'SMWRefreshJob';
        $wgAutoloadClasses['SMWRefreshJob'] = $smwgIP . 
'includes/jobs/SMW_RefreshJob.php';
 
diff --git a/includes/jobs/JobBase.php b/includes/jobs/JobBase.php
new file mode 100644
index 0000000..d129a5c
--- /dev/null
+++ b/includes/jobs/JobBase.php
@@ -0,0 +1,118 @@
+<?php
+
+namespace SMW;
+
+use Job;
+
+/**
+ * Job base class
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since   1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Job base class
+ *
+ * @ingroup Job
+ */
+abstract class JobBase extends Job {
+
+       /** $var Store */
+       protected $store = null;
+
+       /** $var Settings */
+       protected $settings = null;
+
+       /** $var CacheHandler */
+       protected $cache = null;
+
+       /**
+        * Sets Store object
+        *
+        * @since 1.9
+        *
+        * @param Store $store
+        */
+       public function setStore( Store $store ) {
+               $this->store = $store;
+       }
+
+       /**
+        * Returns Store object
+        *
+        * @since 1.9
+        *
+        * @return Store
+        */
+       public function getStore() {
+
+               if ( $this->store === null ) {
+                       $this->store = StoreFactory::getStore();
+               }
+
+               return $this->store;
+       }
+
+       /**
+        * Sets Settings object
+        *
+        * @since 1.9
+        *
+        * @param Store $store
+        */
+       public function setSettings( Settings $settings ) {
+               $this->settings = $settings;
+       }
+
+       /**
+        * Returns Settings object
+        *
+        * @since 1.9
+        *
+        * @return Settings
+        */
+       public function getSettings() {
+
+               if ( $this->settings === null ) {
+                       $this->settings = Settings::newFromGlobals();
+               }
+
+               return $this->settings;
+       }
+
+       /**
+        * Returns CacheHandler object
+        *
+        * @since 1.9
+        *
+        * @return CacheHandler
+        */
+       public function getCache() {
+
+               if ( $this->cache === null ) {
+                       $this->cache = CacheHandler::newFromId( 
$this->getSettings()->get( 'smwgCacheType' ) );
+               }
+
+               return $this->cache;
+       }
+}
diff --git a/includes/jobs/PropertySubjectsUpdateDispatcherJob.php 
b/includes/jobs/PropertySubjectsUpdateDispatcherJob.php
index e0d4142..284495e 100644
--- a/includes/jobs/PropertySubjectsUpdateDispatcherJob.php
+++ b/includes/jobs/PropertySubjectsUpdateDispatcherJob.php
@@ -39,10 +39,7 @@
  * @ingroup Job
  * @ingroup Dispatcher
  */
-class PropertySubjectsUpdateDispatcherJob extends Job {
-
-       /** $var Store */
-       protected $store = null;
+class PropertySubjectsUpdateDispatcherJob extends JobBase {
 
        /** $var Job */
        protected $jobs = array();
@@ -60,17 +57,6 @@
        public function __construct( Title $title, $params = array(), $id = 0 ) 
{
                parent::__construct( 'SMW\PropertySubjectsUpdateDispatcherJob', 
$title, $params, $id );
                $this->store = StoreFactory::getStore( isset( $params['store'] 
) ? $params['store'] : null );
-       }
-
-       /**
-        * Sets Store object
-        *
-        * @since 1.9
-        *
-        * @param Store $store
-        */
-       public function setStore( Store $store ) {
-               $this->store = $store;
        }
 
        /**
diff --git a/includes/jobs/UpdateJob.php b/includes/jobs/UpdateJob.php
index 7d0e471..843aea9 100644
--- a/includes/jobs/UpdateJob.php
+++ b/includes/jobs/UpdateJob.php
@@ -1,16 +1,48 @@
 <?php
+
+namespace SMW;
+
+use ParserOutput;
+use LinkCache;
+use WikiPage;
+use Revision;
+use Title;
+use User;
+use Job;
+
 /**
- * File containing SMWUpdateJob.
+ * UpdateJob is responsible for the asynchronous update of semantic data
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since   1.9
  *
  * @author Daniel M. Herzig
  * @author Markus Krötzsch
- * @file
- * @ingroup SMW
+ * @author mwjames
  */
 
 /**
- * SMWUpdateJob updates the semantic data in the database for a given title
- * using the MediaWiki JobQueue. Update jobs are created if, when saving an 
article,
+ * UpdateJob is responsible for the asynchronous update of semantic data
+ * using MediaWiki's JobQueue infrastructure.
+ *
+ * Update jobs are created if, when saving an article,
  * it is detected that the content of other pages must be re-parsed as well 
(e.g.
  * due to some type change).
  *
@@ -19,69 +51,98 @@
  * formatting in-page values based on a datatype thathas since been changed), 
whereas
  * the Factbox and query/browsing interfaces might already show the updated 
records.
  *
- * @ingroup SMW
+ * @ingroup Job
  */
-class SMWUpdateJob extends Job {
+class UpdateJob extends JobBase {
 
-       function __construct( Title $title ) {
-               parent::__construct( 'SMWUpdateJob', $title );
-       }
+       /** @var WikiPage */
+       protected $wikiPage = null;
+
+       /** @var Revision */
+       protected $revision = null;
+
+       /** @var ParserOutput */
+       protected $parserOutput = null;
 
        /**
-        * Returns Title object
+        * @since  1.9
         *
-        * @since 1.9
-        *
-        * @return \Title
+        * @param Title $title
         */
-       public function getTitle() {
-               return $this->title;
+       function __construct( Title $title ) {
+               parent::__construct( 'SMW\UpdateJob', $title );
        }
 
        /**
         * Run job
         * @return boolean success
         */
-       function run() {
-               wfProfileIn( 'SMWUpdateJob::run (SMW)' );
-               global $wgParser;
+       public function run() {
+               Profiler::In( __METHOD__ . '-run' );
 
                LinkCache::singleton()->clear();
 
-               if ( is_null( $this->title ) ) {
-                       $this->error = "SMWUpdateJob: Invalid title";
-                       wfProfileOut( 'SMWUpdateJob::run (SMW)' );
+               if ( $this->getTitle() === null ) {
+                       $this->setLastError( __METHOD__ . ': Invalid title' );
+                       Profiler::Out( __METHOD__ . '-run' );
                        return false;
-               } elseif ( !$this->title->exists() ) {
-                       smwfGetStore()->deleteSubject( $this->title ); // be 
sure to clear the data
-                       wfProfileOut( 'SMWUpdateJob::run (SMW)' );
+               } elseif ( !$this->getTitle()->exists() ) {
+                       $this->getStore()->deleteSubject( $this->getTitle() ); 
// be sure to clear the data
+                       Profiler::Out( __METHOD__ . '-run' );
                        return true;
                }
 
-               $revision = Revision::newFromTitle( $this->title );
-               if ( !$revision ) {
-                       $this->error = 'SMWUpdateJob: Page exists but no 
revision was found for "' . $this->title->getPrefixedDBkey() . '"';
-                       wfProfileOut( 'SMWUpdateJob::run (SMW)' );
+               if ( !$this->getParserOutput() instanceof ParserOutput ) {
                        return false;
                }
 
-               wfProfileIn( __METHOD__ . '-parse' );
-               $options = new ParserOptions();
-               $output = $wgParser->parse( $revision->getText(), $this->title, 
$options, true, true, $revision->getID() );
+               Profiler::In( __METHOD__ . '-update' );
 
-               wfProfileOut( __METHOD__ . '-parse' );
-               wfProfileIn( __METHOD__ . '-update' );
-
-               // @since 1.9
-               // SMWParseData::storeData( $output, $this->title, false );
-               $parserData = new SMW\ParserData( $this->title, $output );
+               $parserData = new ParserData( $this->getTitle(), 
$this->getParserOutput() );
                $parserData->disableUpdateJobs();
                $parserData->updateStore();
 
-               wfProfileOut( __METHOD__ . '-update' );
-               wfProfileOut( 'SMWUpdateJob::run (SMW)' );
+               Profiler::Out( __METHOD__ . '-update' );
+               Profiler::Out( __METHOD__ . '-run' );
 
                return true;
+       }
+
+       /**
+        * Builds and returns a ParserOutput object
+        *
+        * @since 1.9
+        *
+        * @return ParserOutput|null
+        */
+       public function getParserOutput() {
+
+               if ( $this->parserOutput === null ) {
+                       Profiler::In( __METHOD__ );
+
+                       if ( $this->wikiPage === null ) {
+                               $this->wikiPage = WikiPage::factory( 
$this->getTitle() );
+                       }
+
+                       if ( $this->revision === null && $this->wikiPage !== 
null ) {
+                               $this->revision = 
$this->wikiPage->getRevision();
+                       }
+
+                       if ( !$this->revision || $this->revision === null ) {
+                               $this->setLastError( __METHOD__ . " No revision 
available for {$this->getTitle()->getPrefixedDBkey()}" );
+                               Profiler::Out( __METHOD__ );
+                               return false;
+                       }
+
+                       $this->parserOutput = $this->wikiPage->getParserOutput(
+                               $this->wikiPage->makeParserOptions( 
User::newFromId( $this->revision->getUser() ) ),
+                               $this->revision->getId()
+                       );
+
+                       Profiler::Out( __METHOD__ );
+               }
+
+               return $this->parserOutput;
        }
 
        /**
@@ -89,19 +150,20 @@
         * disables jobs.
         * @note Any method that inserts jobs with Job::batchInsert or 
otherwise must
         * implement this check individually. The below is not called in these 
cases.
+        *
+        * @codeCoverageIgnore
         */
        function insert() {
-               global $smwgEnableUpdateJobs;
-               if ( $smwgEnableUpdateJobs ) {
+               if ( $this->getSettings()->get( 'smwgEnableUpdateJobs' ) ) {
                        parent::insert();
                }
        }
-
 }
 
 /**
- * SMWUpdateJob class alias
+ * SMWUpdateJob
  *
- * @since 1.9
+ * @deprecated since 1.9
+ * @codeCoverageIgnore
  */
-class_alias( 'SMWUpdateJob', 'SMW\UpdateJob' );
+class_alias( 'SMW\UpdateJob', 'SMWUpdateJob' );
diff --git a/tests/phpunit/MockObjectBuilder.php 
b/tests/phpunit/MockObjectBuilder.php
index a767270..67d4e9d 100644
--- a/tests/phpunit/MockObjectBuilder.php
+++ b/tests/phpunit/MockObjectBuilder.php
@@ -135,6 +135,22 @@
        }
 
        /**
+        * Returns a ParserOptions object
+        *
+        * @since 1.9
+        *
+        * @return ParserOptions
+        */
+       public function getMockParserOptions() {
+
+               $parserOptions = $this->getMockBuilder( 'ParserOptions' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               return $parserOptions;
+       }
+
+       /**
         * Returns a WikiPage object
         *
         * @since 1.9
@@ -150,6 +166,18 @@
                $wikiPage->expects( $this->any() )
                        ->method( 'getTimestamp' )
                        ->will( $this->returnValue( $this->set( 'getTimestamp' 
) ) );
+
+               $wikiPage->expects( $this->any() )
+                       ->method( 'getRevision' )
+                       ->will( $this->returnValue( $this->set( 'getRevision' ) 
) );
+
+               $wikiPage->expects( $this->any() )
+                       ->method( 'getParserOutput' )
+                       ->will( $this->returnValue( $this->set( 
'getParserOutput' ) ) );
+
+               $wikiPage->expects( $this->any() )
+                       ->method( 'makeParserOptions' )
+                       ->will( $this->returnValue( $this->set( 
'makeParserOptions' ) ) );
 
                return $wikiPage;
        }
@@ -174,6 +202,14 @@
                $revision->expects( $this->any() )
                        ->method( 'getParentId' )
                        ->will( $this->returnValue( $this->set( 'getParentId' ) 
) );
+
+               $revision->expects( $this->any() )
+                       ->method( 'getId' )
+                       ->will( $this->returnValue( $this->set( 'getId' ) ) );
+
+               $revision->expects( $this->any() )
+                       ->method( 'getUser' )
+                       ->will( $this->returnValue( $this->set( 'getUser' ) ) );
 
                return $revision;
        }
@@ -347,6 +383,10 @@
                        ->will( $this->returnValue( $this->set( 
'getPropertiesSpecial' ) ) );
 
                $store->expects( $this->any() )
+                       ->method( 'deleteSubject' )
+                       ->will( $this->returnValue( $this->set( 'deleteSubject' 
) ) );
+
+               $store->expects( $this->any() )
                        ->method( 'getUnusedPropertiesSpecial' )
                        ->will( $this->returnValue( $this->set( 
'getUnusedPropertiesSpecial' ) ) );
 
@@ -439,7 +479,7 @@
 
                $title->expects( $this->any() )
                        ->method( 'getNamespace' )
-                       ->will( $this->returnValue( $this->set( 'getNamespace' 
) ) );
+                       ->will( $this->returnValue( $this->set( 'getNamespace', 
NS_MAIN ) ) );
 
                $title->expects( $this->any() )
                        ->method( 'isKnown' )
diff --git a/tests/phpunit/includes/jobs/JobBaseTest.php 
b/tests/phpunit/includes/jobs/JobBaseTest.php
new file mode 100644
index 0000000..1b90079
--- /dev/null
+++ b/tests/phpunit/includes/jobs/JobBaseTest.php
@@ -0,0 +1,115 @@
+<?php
+
+namespace SMW\Test;
+
+use SMW\JobBase;
+
+/**
+ * Tests for the JobBase class
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since   1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * @covers \SMW\JobBase
+ *
+ * @ingroup Test
+ *
+ * @group SMW
+ * @group SMWExtension
+ */
+class JobBaseTest extends SemanticMediaWikiTestCase {
+
+       /**
+        * Returns the name of the class to be tested
+        *
+        * @return string|false
+        */
+       public function getClass() {
+               return '\SMW\JobBase';
+       }
+
+       /**
+        * Helper method that returns a JobBase object
+        *
+        * @since 1.9
+        *
+        * @param $result
+        *
+        * @return JobBase
+        */
+       private function getInstance() {
+               return $this->getMockForAbstractClass( $this->getClass(), 
array( $this->newTitle(), array() ) );
+       }
+
+       /**
+        * @test JobBase::__construct
+        *
+        * @since 1.9
+        */
+       public function testConstructor() {
+               $this->assertInstanceOf( $this->getClass(), 
$this->getInstance() );
+       }
+
+       /**
+        * @test JobBase::getStore
+        * @test JobBase::setStore
+        *
+        * @since 1.9
+        */
+       public function testGetSetStore() {
+
+               $instance = $this->getInstance();
+
+               $this->assertInstanceOf( '\SMW\Store', $instance->getStore() );
+               $instance->setStore( $this->newMockObject()->getMockStore() );
+               $this->assertInstanceOf( '\SMW\Store', $instance->getStore() );
+       }
+
+       /**
+        * @test JobBase::setSettings
+        * @test JobBase::getSettings
+        *
+        * @since 1.9
+        */
+       public function testGetSetSettings() {
+
+               $instance = $this->getInstance();
+
+               $this->assertInstanceOf( '\SMW\Settings', 
$instance->getSettings() );
+               $instance->setSettings( $this->getSettings() );
+               $this->assertInstanceOf( '\SMW\Settings', 
$instance->getSettings() );
+       }
+
+       /**
+        * @test JobBase::getCache
+        *
+        * @since 1.9
+        */
+       public function testGetCache() {
+
+               $instance = $this->getInstance();
+               $this->assertInstanceOf( '\SMW\CacheHandler', 
$instance->getCache() );
+       }
+
+}
diff --git a/tests/phpunit/includes/jobs/UpdateJobTest.php 
b/tests/phpunit/includes/jobs/UpdateJobTest.php
index b3f312b..d4ac56e 100644
--- a/tests/phpunit/includes/jobs/UpdateJobTest.php
+++ b/tests/phpunit/includes/jobs/UpdateJobTest.php
@@ -4,6 +4,7 @@
 
 use SMW\UpdateJob;
 
+use Title;
 /**
  * Tests for the UpdateJob class
  *
@@ -38,7 +39,7 @@
  * @group SMW
  * @group SMWExtension
  */
-class UpdateJobTest extends SemanticMediaWikiTestCase {
+class UpdateJobTest extends ParserTestCase {
 
        /**
         * Returns the name of the class to be tested
@@ -56,12 +57,20 @@
         *
         * @return UpdateJob
         */
-       private function getInstance() {
-               return new UpdateJob( $this->getTitle() );
+       private function getInstance( Title $title = null ) {
+               $instance = new UpdateJob( $title === null ? $this->newTitle() 
: $title );
+
+               // Set smwgEnableUpdateJobs to false in order to avoid having 
jobs being
+               // inserted as real jobs to the queue
+               $instance->setSettings( $this->getSettings( array( 
'smwgEnableUpdateJobs' => false ) ) );
+               return $instance;
        }
 
        /**
         * @test UpdateJob::__construct
+        *
+        * FIXME Delete SMWUpdateJob assertion after all references to
+        * SMWUpdateJob have been removed
         *
         * @since 1.9
         */
@@ -70,4 +79,97 @@
                $this->assertInstanceOf( 'SMWUpdateJob', $this->getInstance() );
        }
 
+       /**
+        * @test UpdateJob::run
+        * @dataProvider titleWikiPageDataProvider
+        *
+        * @since 1.9
+        */
+       public function testRun( $test, $expected ) {
+
+               $instance = $this->getInstance( $test['title'] );
+               $instance->setStore( $this->newMockObject()->getMockStore() );
+
+               // Provides access to the wikiPage property and
+               // replace it with a controllable mock bject
+               $reflector = $this->newReflector();
+               $wikiPage  = $reflector->getProperty( 'wikiPage' );
+               $wikiPage->setAccessible( true );
+               $wikiPage->setValue( $instance, $test['wikiPage'] );
+
+               $this->assertEquals( $expected['result'], $instance->run() );
+       }
+
+       /**
+        * Provides title and wikiPage samples
+        *
+        * @return array
+        */
+       public function titleWikiPageDataProvider() {
+
+               $provider = array();
+               $wikiPage = $this->newMockObject()->getMockWikiPage();
+
+               // #0 Title does not exists, deleteSubject() is being executed
+               $title = $this->newMockObject( array(
+                       'getDBkey' => 'Lila',
+                       'exists'   => false
+               ) )->getMockTitle();
+
+               $provider[] = array(
+                       array(
+                               'title'     => $title,
+                               'wikiPage'  => $wikiPage,
+                       ),
+                       array(
+                               'result'    => true
+                       )
+               );
+
+               // #1 No revision, no further activities
+               $title = $this->newMockObject( array(
+                       'getDBkey' => 'Lala',
+                       'exists'   => true
+               ) )->getMockTitle();
+
+               $provider[] = array(
+                       array(
+                               'title'    => $title,
+                               'wikiPage' => null
+                       ),
+                       array(
+                               'result'   => false
+                       )
+               );
+
+               // #2 Valid revision and parserOuput
+               $title = $this->newMockObject( array(
+                       'getDBkey' => 'Lula',
+                       'exists'   => true
+               ) )->getMockTitle();
+
+               $revision = $this->newMockObject( array(
+                       'getId'   => 9001,
+                       'getUser' => 'Lala'
+               ) )->getMockRevision();
+
+               $wikiPage = $this->newMockObject( array(
+                       'getRevision'       => $revision,
+                       'makeParserOptions' => 
$this->newMockObject()->getMockParserOptions(),
+                       'getParserOutput'   => $this->newParserOutput()
+               ) )->getMockWikiPage();
+
+               $provider[] = array(
+                       array(
+                               'title'    => $title,
+                               'wikiPage' => $wikiPage
+                       ),
+                       array(
+                               'result'      => true
+                       )
+               );
+
+               return $provider;
+       }
+
 }

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I3b41d4e506a2c425903ec3690f3500dcec939ac4
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/SemanticMediaWiki
Gerrit-Branch: master
Gerrit-Owner: Mwjames <[email protected]>
Gerrit-Reviewer: Mwjames <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to