Tamslo has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/220321

Change subject: [WIP] Introduced ExceptionLookup
......................................................................

[WIP] Introduced ExceptionLookup

Bug: T103108
Change-Id: I4accc458077284d86b5636665a74498806f989f7
---
A includes/Violations/ExceptionLookup.php
M includes/Violations/SqlViolationRepo.php
M includes/WikibaseQualityFactory.php
M tests/phpunit/Violations/SqlViolationRepoTest.php
4 files changed, 329 insertions(+), 215 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikibaseQuality 
refs/changes/21/220321/1

diff --git a/includes/Violations/ExceptionLookup.php 
b/includes/Violations/ExceptionLookup.php
new file mode 100644
index 0000000..cf53868
--- /dev/null
+++ b/includes/Violations/ExceptionLookup.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace WikibaseQuality\Violations;
+
+
+/**
+ * Interface ExceptionLookup
+ * @package WikibaseQuality\Violations
+ * @author BP2014N1
+ * @license GNU GPL v2+
+ */
+interface ExceptionLookup {
+
+       /**
+        * Returns whether a violation is an exception.
+        *
+        * @param string $claimGuid
+        * @param string $constraintId
+        *
+        * @return bool
+        */
+       public function isException( $claimGuid, $constraintId );
+}
\ No newline at end of file
diff --git a/includes/Violations/SqlViolationRepo.php 
b/includes/Violations/SqlViolationRepo.php
index 40d5181..5628f0d 100755
--- a/includes/Violations/SqlViolationRepo.php
+++ b/includes/Violations/SqlViolationRepo.php
@@ -8,6 +8,7 @@
 use MWTimestamp;
 use Wikibase\DataModel\Entity\EntityIdParser;
 use Wikibase\DataModel\Entity\PropertyId;
+use Wikimedia\Assert\Assert;
 
 
 /**
@@ -16,93 +17,117 @@
  * @author BP2014N1
  * @license GNU GPL v2+
  */
-class SqlViolationRepo implements ViolationLookup, ViolationStore {
+class SqlViolationRepo implements ViolationLookup, ViolationStore, 
ExceptionLookup {
 
-    const ORDER_ASCENDING = 'ASC';
-    const ORDER_DESCENDING = 'DESC';
+       const ORDER_ASCENDING = 'ASC';
+       const ORDER_DESCENDING = 'DESC';
 
        const TABLE_NAME = 'wbq_violations';
 
-    /**
-     * @var EntityIdParser
-     */
-    private $entityIdParser;
+       /**
+        * @var EntityIdParser
+        */
+       private $entityIdParser;
 
        /**
         * @param EntityIdParser $entityIdParser
         */
-    public function __construct( EntityIdParser $entityIdParser ) {
-        $this->entityIdParser = $entityIdParser;
-    }
+       public function __construct( EntityIdParser $entityIdParser ) {
+               $this->entityIdParser = $entityIdParser;
+       }
 
     /**
-     * @see ViolationLookup::get
+     * @see ExceptionLookup::isException
      *
-     * @param ViolationQuery $query
-     * @return Violation[]
-     */
-    public function get( ViolationQuery $query ) {
-        $db = wfGetDB( DB_SLAVE );
-        $result = $db->select(
-            self::TABLE_NAME,
-            '*',
-            $this->buildConditions( $db, $query )
-        );
-
-        $violations = array();
-        foreach ( $result as $row ) {
-            $violations[] = $this->getViolationFromRow( $row );
-        }
-
-        return $violations;
-    }
-
-    /**
-     * @see ViolationRepo::getForPage
-     *
-     * @param ViolationQuery $query
-     * @param int $maxNumber
-     * @param string $direction
      * @param string $claimGuid
      * @param string $constraintId
-        * @return array list( $violations, $prevPageAvailable, 
$nextPageAvailable )
+     *
+     * @return bool
      */
-    public function getForPage( ViolationQuery $query, $maxNumber, $direction, 
$claimGuid, $constraintId ) {
-        if ( !is_int( $maxNumber ) ) {
-            throw new InvalidArgumentException( '$maxNumber must be int.' );
-        }
-        if ( $direction !== self::ORDER_ASCENDING && $direction !== 
self::ORDER_DESCENDING ) {
-            throw new InvalidArgumentException( '$direction must a valid 
direction.' );
-        }
-        if ( $claimGuid && !is_string( $claimGuid ) ) {
-            throw new InvalidArgumentException( '$claimGuid must be string.' );
-        }
-        if ( $constraintId && !is_string( $constraintId ) ) {
-            throw new InvalidArgumentException( '$constraintId must be 
string.' );
-        }
-        if ( $query->getClaimGuid() || $query->getConstraintId() ) {
-            throw new InvalidArgumentException( 'Filtering by claim guid or 
constraint id is not supported.' );
-        }
+       public function isException( $claimGuid, $constraintId ) {
+               Assert::parameterType( 'string', $claimGuid, '$claimGuid' );
+               Assert::parameterType( 'string', $constraintId, '$constraintId' 
);
+               $violationQuery = new ViolationQuery();
+               $violationQuery->setClaimGuid( $claimGuid );
+               $violationQuery->setConstraintId( $constraintId );
 
-        $db = wfGetDB( DB_SLAVE );
-        $queryConditions = $this->buildConditions( $db, $query );
-        $pageConditions = $this->buildPaginationConditions( $db, $direction, 
$claimGuid, $constraintId );
-        $conditions = array_merge( $queryConditions, $pageConditions );
+               $db = wfGetDB( DB_SLAVE );
+               $status = $db->selectField(
+                       self::TABLE_NAME,
+                       'status',
+                       $this->buildConditions( $db, $violationQuery )
+               );
+               return $status === Violation::STATUS_EXCEPTION;
+       }
 
-        $firstKey = $this->getFirstKey( $db, $queryConditions, $direction );
-        $result = $db->select(
-            self::TABLE_NAME,
-            '*',
-            $conditions,
-            __METHOD__,
-            array(
-                'ORDER BY' => "claim_guid $direction, constraint_id 
$direction",
-                'LIMIT' => $maxNumber + 1
-            )
-        );
+       /**
+        * @see ViolationLookup::get
+        *
+        * @param ViolationQuery $query
+        * @return Violation[]
+        */
+       public function get( ViolationQuery $query ) {
+               $db = wfGetDB( DB_SLAVE );
+               $result = $db->select(
+                       self::TABLE_NAME,
+                       '*',
+                       $this->buildConditions( $db, $query )
+               );
 
-        return $this->getViolationsForPageFromResult( $result, $firstKey, 
$direction, $maxNumber );
-    }
+               $violations = array();
+               foreach ( $result as $row ) {
+                       $violations[] = $this->getViolationFromRow( $row );
+               }
+
+               return $violations;
+       }
+
+       /**
+        * @see ViolationRepo::getForPage
+        *
+        * @param ViolationQuery $query
+        * @param int $maxNumber
+        * @param string $direction
+        * @param string $claimGuid
+        * @param string $constraintId
+        * @return array list( $violations, $prevPageAvailable, 
$nextPageAvailable )
+        */
+       public function getForPage( ViolationQuery $query, $maxNumber, 
$direction, $claimGuid, $constraintId ) {
+               if ( !is_int( $maxNumber ) ) {
+                       throw new InvalidArgumentException( '$maxNumber must be 
int.' );
+               }
+               if ( $direction !== self::ORDER_ASCENDING && $direction !== 
self::ORDER_DESCENDING ) {
+                       throw new InvalidArgumentException( '$direction must a 
valid direction.' );
+               }
+               if ( $claimGuid && !is_string( $claimGuid ) ) {
+                       throw new InvalidArgumentException( '$claimGuid must be 
string.' );
+               }
+               if ( $constraintId && !is_string( $constraintId ) ) {
+                       throw new InvalidArgumentException( '$constraintId must 
be string.' );
+               }
+               if ( $query->getClaimGuid() || $query->getConstraintId() ) {
+                       throw new InvalidArgumentException( 'Filtering by claim 
guid or constraint id is not supported.' );
+               }
+
+               $db = wfGetDB( DB_SLAVE );
+               $queryConditions = $this->buildConditions( $db, $query );
+               $pageConditions = $this->buildPaginationConditions( $db, 
$direction, $claimGuid, $constraintId );
+               $conditions = array_merge( $queryConditions, $pageConditions );
+
+               $firstKey = $this->getFirstKey( $db, $queryConditions, 
$direction );
+               $result = $db->select(
+                       self::TABLE_NAME,
+                       '*',
+                       $conditions,
+                       __METHOD__,
+                       array(
+                               'ORDER BY' => "claim_guid $direction, 
constraint_id $direction",
+                               'LIMIT' => $maxNumber + 1
+                       )
+               );
+
+               return $this->getViolationsForPageFromResult( $result, 
$firstKey, $direction, $maxNumber );
+       }
 
        /**
         * @param Violation $violation
@@ -152,23 +177,23 @@
                throw new InvalidArgumentException( 'Given violation does not 
exist in database.' );
        }
 
-    /**
-     * @see ViolationStore::delete
-     *
-     * @param Violation $violation
-     * @return bool|\ResultWrapper
-     * @throws \DBUnexpectedError
-     */
-    public function delete( Violation $violation ) {
-        $db = wfGetDB( DB_MASTER );
-        return $db->delete(
-            self::TABLE_NAME,
-            array(
-                sprintf( 'claim_guid="%s"', $violation->getClaimGuid() ),
-                sprintf( 'constraint_id="%s"', $violation->getConstraintId() )
-            )
-        );
-    }
+       /**
+        * @see ViolationStore::delete
+        *
+        * @param Violation $violation
+        * @return bool|\ResultWrapper
+        * @throws \DBUnexpectedError
+        */
+       public function delete( Violation $violation ) {
+               $db = wfGetDB( DB_MASTER );
+               return $db->delete(
+                       self::TABLE_NAME,
+                       array(
+                               sprintf( 'claim_guid="%s"', 
$violation->getClaimGuid() ),
+                               sprintf( 'constraint_id="%s"', 
$violation->getConstraintId() )
+                       )
+               );
+       }
 
        /**
         * Checks, if violation exists in database. In this case, database row 
of it is returned; otherwise false.
@@ -198,117 +223,117 @@
                );
        }
 
-    /**
-     * Builds array of query conditions for pagination.
-     *
-     * @param DatabaseBase $db
-     * @param string $direction
-     * @param string $claimGuid
-     * @param string $constraintId
-     * @return array
-     */
-    private function buildPaginationConditions( DatabaseBase $db, $direction, 
$claimGuid, $constraintId ) {
-        $conditions = array();
+       /**
+        * Builds array of query conditions for pagination.
+        *
+        * @param DatabaseBase $db
+        * @param string $direction
+        * @param string $claimGuid
+        * @param string $constraintId
+        * @return array
+        */
+       private function buildPaginationConditions( DatabaseBase $db, 
$direction, $claimGuid, $constraintId ) {
+               $conditions = array();
 
-        if ( $claimGuid && $constraintId ) {
-            $operator = '>';
-            $oppositeOperator = '<';
-            if ( $direction === self::ORDER_DESCENDING ) {
-                $operator = '<';
-                $oppositeOperator = '>';
-            }
+               if ( $claimGuid && $constraintId ) {
+                       $operator = '>';
+                       $oppositeOperator = '<';
+                       if ( $direction === self::ORDER_DESCENDING ) {
+                               $operator = '<';
+                               $oppositeOperator = '>';
+                       }
 
-            $quotedClaimGuid = $db->addQuotes( $claimGuid );
-            $quotedConstraintId = $db->addQuotes( $constraintId );
+                       $quotedClaimGuid = $db->addQuotes( $claimGuid );
+                       $quotedConstraintId = $db->addQuotes( $constraintId );
 
-            $conditions[] = sprintf( 'claim_guid%s=%s', $operator, 
$quotedClaimGuid );
-            $conditions[] = sprintf( 'NOT (claim_guid=%s AND 
constraint_id%s=%s)', $quotedClaimGuid, $oppositeOperator, $quotedConstraintId 
);
-        }
+                       $conditions[] = sprintf( 'claim_guid%s=%s', $operator, 
$quotedClaimGuid );
+                       $conditions[] = sprintf( 'NOT (claim_guid=%s AND 
constraint_id%s=%s)', $quotedClaimGuid, $oppositeOperator, $quotedConstraintId 
);
+               }
 
-        return $conditions;
-    }
+               return $conditions;
+       }
 
-    /**
-     * Gets array with primary keys of the first (regarding specified 
direction) violation
-     * for the query in database.
-     *
-     * @param DatabaseBase $db
-     * @param array $conditions
-     * @param string $direction
-     * @return array
-     */
-    private function getFirstKey( DatabaseBase $db, array $conditions, 
$direction ) {
-        $row = $db->selectRow(
-            self::TABLE_NAME,
-            array(
-                'claim_guid',
-                'constraint_id'
-            ),
-            $conditions,
-            __METHOD__,
-            array(
-                'LIMIT' => 1,
-                'ORDER BY' => "claim_guid $direction, constraint_id $direction"
-            )
-        );
+       /**
+        * Gets array with primary keys of the first (regarding specified 
direction) violation
+        * for the query in database.
+        *
+        * @param DatabaseBase $db
+        * @param array $conditions
+        * @param string $direction
+        * @return array
+        */
+       private function getFirstKey( DatabaseBase $db, array $conditions, 
$direction ) {
+               $row = $db->selectRow(
+                       self::TABLE_NAME,
+                       array(
+                               'claim_guid',
+                               'constraint_id'
+                       ),
+                       $conditions,
+                       __METHOD__,
+                       array(
+                               'LIMIT' => 1,
+                               'ORDER BY' => "claim_guid $direction, 
constraint_id $direction"
+                       )
+               );
 
-        if ( $row ) {
-            return $this->getKeyArray( $row );
-        }
+               if ( $row ) {
+                       return $this->getKeyArray( $row );
+               }
 
                return array();
-    }
+       }
 
-    /**
-     * Gets array with primary keys of a given row.
-     *
-     * @param \stdClass $row
-     * @return array
-     */
-    private function getKeyArray( $row ) {
+       /**
+        * Gets array with primary keys of a given row.
+        *
+        * @param \stdClass $row
+        * @return array
+        */
+       private function getKeyArray( $row ) {
                return array( $row->claim_guid, $row->constraint_id );
-    }
+       }
 
-    /**
-     * Build array with query conditions from ViolationQuery object.
-     *
-     * @param DatabaseBase $db
-     * @param ViolationQuery $query
-     * @return array
-     */
-    private function buildConditions( DatabaseBase $db, ViolationQuery $query 
) {
-        $conditions = array();
-        if ( $query->getEntityId() !== null ) {
+       /**
+        * Build array with query conditions from ViolationQuery object.
+        *
+        * @param DatabaseBase $db
+        * @param ViolationQuery $query
+        * @return array
+        */
+       private function buildConditions( DatabaseBase $db, ViolationQuery 
$query ) {
+               $conditions = array();
+               if ( $query->getEntityId() !== null ) {
                        $conditions['entity_id'] = 
$query->getEntityId()->getSerialization();
-        }
-        if ( $query->getPropertyId() !== null ) {
+               }
+               if ( $query->getPropertyId() !== null ) {
                        $conditions['pid'] = 
$query->getPropertyId()->getSerialization();
-        }
-        if ( $query->getClaimGuid() !== null ) {
-            $conditions['claim_guid'] = $query->getClaimGuid();
-        }
-        if ( $query->getConstraintId() !== null ) {
-            $conditions['constraint_id'] = $query->getConstraintId();
-        }
-        if ( $query->getConstraintGroup() !== null ) {
+               }
+               if ( $query->getClaimGuid() !== null ) {
+                       $conditions['claim_guid'] = $query->getClaimGuid();
+               }
+               if ( $query->getConstraintId() !== null ) {
+                       $conditions['constraint_id'] = 
$query->getConstraintId();
+               }
+               if ( $query->getConstraintGroup() !== null ) {
                        $prefix = $query->getConstraintGroup() . 
Violation::CONSTRAINT_ID_DELIMITER;
                        $conditions[] = 'constraint_id' . $db->buildLike( 
$prefix, $db->anyString() );
-        }
-        if ( $query->getConstraintTypeEntityId() !== null ) {
-            $conditions['constraint_type_entity_id'] = 
$query->getConstraintTypeEntityId();
-        }
-        if ( $query->getUpdatedAt() !== null ) {
-            $conditions['updated_at'] = $db->timestamp( $query->getUpdatedAt() 
);
-        }
-        if ( $query->getRevisionId() !== null ) {
-            $conditions['revision_id'] = $query->getRevisionId();
-        }
-        if ( $query->getStatuses() !== null && count( $query->getStatuses() ) 
> 0 ) {
+               }
+               if ( $query->getConstraintTypeEntityId() !== null ) {
+                       $conditions['constraint_type_entity_id'] = 
$query->getConstraintTypeEntityId();
+               }
+               if ( $query->getUpdatedAt() !== null ) {
+                       $conditions['updated_at'] = $db->timestamp( 
$query->getUpdatedAt() );
+               }
+               if ( $query->getRevisionId() !== null ) {
+                       $conditions['revision_id'] = $query->getRevisionId();
+               }
+               if ( $query->getStatuses() !== null && count( 
$query->getStatuses() ) > 0 ) {
                        $conditions['status'] = $query->getStatuses();
-        }
+               }
 
-        return $conditions;
-    }
+               return $conditions;
+       }
 
        /**
         * Creates violation objects from database result and checks, whether 
previous or next page is available
@@ -351,27 +376,27 @@
                return array( $violations, $prevPageAvailable, 
$nextPageAvailable );
        }
 
-    /**
-     * Creates Violation object from single row of a database result.
-     *
-     * @param $row
-     * @return Violation
-     */
-    private function getViolationFromRow( $row ) {
-        $additionalInformation = json_decode( $row->additional_info, true ) ?: 
array();
+       /**
+        * Creates Violation object from single row of a database result.
+        *
+        * @param $row
+        * @return Violation
+        */
+       private function getViolationFromRow( $row ) {
+               $additionalInformation = json_decode( $row->additional_info, 
true ) ?: array();
 
-        return new Violation(
-            $this->entityIdParser->parse( $row->entity_id ),
-            new PropertyId( $row->pid ),
-            $row->claim_guid,
-            $row->constraint_id,
-            $row->constraint_type_entity_id,
-            (int)$row->revision_id,
-            $row->status,
-            $additionalInformation,
+               return new Violation(
+                       $this->entityIdParser->parse( $row->entity_id ),
+                       new PropertyId( $row->pid ),
+                       $row->claim_guid,
+                       $row->constraint_id,
+                       $row->constraint_type_entity_id,
+                       (int)$row->revision_id,
+                       $row->status,
+                       $additionalInformation,
                        $row->updated_at
-        );
-    }
+               );
+       }
 
        /**
         * Gets array from Violation object for database insertions.
@@ -382,17 +407,17 @@
         * @param string|null $status
         * @return array
         */
-    private function getRowFromViolation( DatabaseBase $db, Violation 
$violation, $status = null ) {
-        return array(
-            'entity_id' => $violation->getEntityId()->getSerialization(),
-            'pid' => $violation->getPropertyId()->getSerialization(),
-            'claim_guid' => $violation->getClaimGuid(),
-            'constraint_id' => $violation->getConstraintId(),
-            'constraint_type_entity_id' => 
$violation->getConstraintTypeEntityId(),
-            'status' => $status ?: $violation->getStatus(),
-            'revision_id' => $violation->getRevisionId(),
-            'additional_info' => json_encode( $violation->getAdditionalInfo() 
),
-            'updated_at' => $db->timestamp()
-        );
-    }
+       private function getRowFromViolation( DatabaseBase $db, Violation 
$violation, $status = null ) {
+               return array(
+                       'entity_id' => 
$violation->getEntityId()->getSerialization(),
+                       'pid' => 
$violation->getPropertyId()->getSerialization(),
+                       'claim_guid' => $violation->getClaimGuid(),
+                       'constraint_id' => $violation->getConstraintId(),
+                       'constraint_type_entity_id' => 
$violation->getConstraintTypeEntityId(),
+                       'status' => $status ?: $violation->getStatus(),
+                       'revision_id' => $violation->getRevisionId(),
+                       'additional_info' => json_encode( 
$violation->getAdditionalInfo() ),
+                       'updated_at' => $db->timestamp()
+               );
+       }
 }
\ No newline at end of file
diff --git a/includes/WikibaseQualityFactory.php 
b/includes/WikibaseQualityFactory.php
index 0894665..c48b2a4 100644
--- a/includes/WikibaseQualityFactory.php
+++ b/includes/WikibaseQualityFactory.php
@@ -6,13 +6,12 @@
 use UnexpectedValueException;
 use Wikibase\Repo\WikibaseRepo;
 use WikibaseQuality\Serializer\ViolationSerializer;
-use WikibaseQuality\Violations\DispatchingViolationContext;
 use WikibaseQuality\Violations\DispatchingViolationFormatter;
-use WikibaseQuality\Violations\ViolationContext;
 use WikibaseQuality\Violations\SqlViolationRepo;
 use WikibaseQuality\Violations\ViolationFormatter;
 use WikibaseQuality\Violations\ViolationLookup;
 use WikibaseQuality\Violations\ViolationStore;
+use WikibaseQuality\Violations\ExceptionLookup;
 
 /**
  * Class WikibaseQualityFactory
@@ -56,6 +55,13 @@
        }
 
        /**
+        * @return ExceptionLookup
+        */
+       public function getExceptionLookup() {
+               return $this->getSqlViolationRepo();
+       }
+
+       /**
         * @return ViolationStore
         */
        public function getViolationStore() {
diff --git a/tests/phpunit/Violations/SqlViolationRepoTest.php 
b/tests/phpunit/Violations/SqlViolationRepoTest.php
index 8f60629..caf830e 100755
--- a/tests/phpunit/Violations/SqlViolationRepoTest.php
+++ b/tests/phpunit/Violations/SqlViolationRepoTest.php
@@ -606,4 +606,64 @@
                        )
                );
        }
+
+       public function testIsException() {
+               $violation = new Violation(
+                       new ItemId( 'Q12345' ),
+                       new PropertyId( 'P12345' ),
+                       'P12345$isExceptionTest',
+                       'isExceptionTestTrue',
+                       'Q42',
+                       123456,
+                       'exception',
+                       array(),
+                       '201501010000'
+               );
+
+               $anotherViolation = new Violation(
+                       new ItemId( 'Q12345' ),
+                       new PropertyId( 'P12345' ),
+                       'P12345$isExceptionTest',
+                       'isExceptionTestFalse',
+                       'Q42',
+                       123456,
+                       'exception',
+                       array(),
+                       '201501010000'
+               );
+
+               $this->db->insert(
+                       SqlViolationRepo::TABLE_NAME,
+                       array(
+                               array (
+                                       'entity_id' => 
$violation->getEntityId()->getSerialization(),
+                                       'pid' => 
$violation->getPropertyId()->getSerialization(),
+                                       'claim_guid' => 
$violation->getClaimGuid(),
+                                       'constraint_id' => 
$violation->getConstraintId(),
+                                       'constraint_type_entity_id' => 
$violation->getConstraintTypeEntityId(),
+                                       'revision_id' => 
$violation->getRevisionId(),
+                                       'status' => $violation->getStatus(),
+                                       'additional_info' => json_encode( 
$violation->getAdditionalInfo() ),
+                                       'updated_at' => $this->db->timestamp( 
$violation->getUpdatedAt() )
+                               ),
+                               array (
+                                       'entity_id' => 
$anotherViolation->getEntityId()->getSerialization(),
+                                       'pid' => 
$anotherViolation->getPropertyId()->getSerialization(),
+                                       'claim_guid' => 
$anotherViolation->getClaimGuid(),
+                                       'constraint_id' => 
$anotherViolation->getConstraintId(),
+                                       'constraint_type_entity_id' => 
$anotherViolation->getConstraintTypeEntityId(),
+                                       'revision_id' => 
$anotherViolation->getRevisionId(),
+                                       'status' => 
$anotherViolation->getStatus(),
+                                       'additional_info' => json_encode( 
$anotherViolation->getAdditionalInfo() ),
+                                       'updated_at' => $this->db->timestamp( 
$anotherViolation->getUpdatedAt() )
+                               )
+                       )
+               );
+
+               $shouldBeTrue = $this->violationRepo->isException( 
'P12345$isExceptionTest', 'isExceptionTestTrue' );
+               $shouldBeFalse = $this->violationRepo->isException( 
'P12345$isExceptionTest', 'isExceptionTestFalse' );
+
+               $this->assertTrue( $shouldBeTrue );
+               $this->assertFalse( $shouldBeFalse );
+       }
 }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I4accc458077284d86b5636665a74498806f989f7
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WikibaseQuality
Gerrit-Branch: master
Gerrit-Owner: Tamslo <tamaraslosa...@gmail.com>

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

Reply via email to