Merge "Update required PHP version to 7.0.13"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 14 Feb 2019 20:40:35 +0000 (20:40 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 14 Feb 2019 20:40:35 +0000 (20:40 +0000)
14 files changed:
RELEASE-NOTES-1.33
docs/extension.schema.v2.json
includes/changes/EnhancedChangesList.php
includes/installer/DatabaseInstaller.php
includes/libs/objectcache/WANObjectCache.php
includes/shell/Command.php
includes/templates/EnhancedChangesListGroup.mustache
resources/Resources.php
resources/src/jquery/jquery.makeCollapsible.styles.less
resources/src/mediawiki.special.changeslist.enhanced.css [deleted file]
resources/src/mediawiki.special.changeslist.enhanced.less [new file with mode: 0644]
resources/src/startup/mediawiki.js
tests/phpunit/data/registration/good.json
tests/phpunit/includes/changes/EnhancedChangesListTest.php

index 7f519f9..0cee392 100644 (file)
@@ -79,6 +79,8 @@ production.
 === Bug fixes in 1.33 ===
 * (T164211) Special:UserRights could sometimes fail with a
   "conflict detected" error when there weren't any conflicts.
+* (T215566) Unable to determine if the database exists
+  during a fresh installation.
 
 === Action API changes in 1.33 ===
 * (T198913) Added 'ApiOptions' hook.
index 15a1590..22edac0 100644 (file)
@@ -3,6 +3,12 @@
        "description": "MediaWiki extension.json schema",
        "type": "object",
        "additionalProperties": false,
+       "patternProperties": {
+               "^@": {
+                       "type": "string",
+                       "description": "Arbitrary notes, ignored by the parser."
+               }
+       },
        "properties": {
                "manifest_version": {
                        "type": "integer",
index 28b30d8..51a26ba 100644 (file)
@@ -77,12 +77,12 @@ class EnhancedChangesList extends ChangesList {
                $this->lastdate = '';
                $this->rclistOpen = false;
                $this->getOutput()->addModuleStyles( [
+                       'mediawiki.icon',
                        'mediawiki.special.changeslist',
                        'mediawiki.special.changeslist.enhanced',
                ] );
                $this->getOutput()->addModules( [
                        'jquery.makeCollapsible',
-                       'mediawiki.icon',
                ] );
 
                return '<div class="mw-changeslist">';
index a146ae4..bb30d3d 100644 (file)
@@ -23,6 +23,8 @@
 use Wikimedia\Rdbms\LBFactorySingle;
 use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\DBExpectedError;
+use Wikimedia\Rdbms\DBConnectionError;
 
 /**
  * Base class for DBMS-specific installation helper classes.
@@ -620,7 +622,12 @@ abstract class DatabaseInstaller {
                        return false;
                }
 
-               if ( !$this->db->selectDB( $this->getVar( 'wgDBname' ) ) ) {
+               try {
+                       $this->db->selectDB( $this->getVar( 'wgDBname' ) );
+               } catch ( DBConnectionError $e ) {
+                       // Don't catch DBConnectionError
+                       throw $e;
+               } catch ( DBExpectedError $e ) {
                        return false;
                }
 
index 88f87f8..b0f311f 100644 (file)
@@ -1264,21 +1264,26 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                        }
                }
 
-               // A deleted key with a negative TTL left must be tombstoned
+               // Only a tombstoned key yields no value yet has a (negative) "current time left"
                $isTombstone = ( $curTTL !== null && $value === false );
-               if ( $isTombstone && $lockTSE <= 0 ) {
-                       // Use the INTERIM value for tombstoned keys to reduce regeneration load
-                       $lockTSE = self::INTERIM_KEY_TTL;
+               // Decide if only one thread should handle regeneration at a time
+               if ( $isTombstone ) {
+                       // Note that since tombstones no-op set(), $lockTSE and $curTTL cannot be used to
+                       // deduce the key hotness because $curTTL will always keep increasing until the
+                       // tombstone expires or is overwritten by a new tombstone. Also, even if $lockTSE
+                       // is not set, constant regeneration of a key for the tombstone lifetime might be
+                       // very expensive. In either case, reduce regeneration load during this time by
+                       // using the INTERIM value key with a small TTL.
+                       $useMutex = true;
+               } else {
+                       $useMutex =
+                               // Assume a key is hot if requested soon ($lockTSE seconds) after invalidation.
+                               // This avoids stampedes when timestamps from $checkKeys/$touchedCallback bump.
+                               ( $curTTL !== null && $curTTL <= 0 && abs( $curTTL ) <= $lockTSE ) ||
+                               // Assume a key is hot if there is no value and a busy fallback is given.
+                               // This avoids stampedes on eviction or preemptive renegeration taking too long.
+                               ( $busyValue !== null && $value === false );
                }
-               // Assume a key is hot if requested soon after invalidation
-               $isHot = ( $curTTL !== null && $curTTL <= 0 && abs( $curTTL ) <= $lockTSE );
-               // Use the mutex if there is no value and a busy fallback is given
-               $checkBusy = ( $busyValue !== null && $value === false );
-               // Decide whether a single thread should handle regenerations.
-               // This avoids stampedes when $checkKeys are bumped and when preemptive
-               // renegerations take too long. It also reduces regenerations while $key
-               // is tombstoned. This balances cache freshness with avoiding DB load.
-               $useMutex = ( $isHot || ( $isTombstone && $lockTSE > 0 ) || $checkBusy );
 
                $lockAcquired = false;
                if ( $useMutex ) {
@@ -1325,17 +1330,17 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                $valueIsCacheable = ( $value !== false && $ttl >= 0 );
 
                // When delete() is called, writes are write-holed by the tombstone,
-               // so use a special INTERIM key to pass the new value around threads.
-               if ( ( $isTombstone && $lockTSE > 0 ) && $valueIsCacheable ) {
-                       $tempTTL = max( 1, (int)$lockTSE ); // set() expects seconds
+               // so use a special INTERIM key to pass the new value among threads.
+               if ( $isTombstone && $valueIsCacheable ) {
+                       $tempTTL = max( self::INTERIM_KEY_TTL, (int)$lockTSE ); // set() expects seconds
                        $newAsOf = $this->getCurrentTime();
                        $wrapped = $this->wrap( $value, $tempTTL, $newAsOf );
                        // Avoid using set() to avoid pointless mcrouter broadcasting
                        $this->setInterimValue( $key, $wrapped, $tempTTL );
                }
 
-               // Save the value unless a mutex-winning thread is already expected to do that
-               if ( $valueIsCacheable && ( !$useMutex || $lockAcquired ) ) {
+               // Save the value unless a lock-winning thread is already expected to do that
+               if ( $valueIsCacheable && !$isTombstone && ( !$useMutex || $lockAcquired ) ) {
                        $setOpts['lockTSE'] = $lockTSE;
                        $setOpts['staleTTL'] = $staleTTL;
                        // Use best known "since" timestamp if not provided
index d504611..1936d00 100644 (file)
@@ -433,9 +433,9 @@ class Command {
                        // TODO replace with clear_last_error when requirements are bumped to PHP7
                        set_error_handler( function () {
                        }, 0 );
-                       \MediaWiki\suppressWarnings();
+                       \Wikimedia\suppressWarnings();
                        trigger_error( '' );
-                       \MediaWiki\restoreWarnings();
+                       \Wikimedia\restoreWarnings();
                        restore_error_handler();
 
                        $readPipes = array_filter( $pipes, function ( $fd ) use ( $desc ) {
index 6037d37..6d9d6b0 100644 (file)
@@ -10,7 +10,7 @@
                                <div class="mw-rcfilters-ui-highlights-color-c5" data-color="c5"></div>
                        </div>
                </td>
-               <td><span class="mw-collapsible-toggle mw-collapsible-arrow mw-enhancedchanges-arrow mw-enhancedchanges-arrow-space"></span></td>
+               <td><span class="mw-collapsible-toggle mw-collapsible-arrow mw-enhancedchanges-arrow mw-enhancedchanges-arrow-space mw-collapsible-toggle-collapsed"></span></td>
                <td class="mw-changeslist-line-prefix">{{{ prefix }}}</td>
                <td class="mw-enhanced-rc" colspan="2">{{{ collectedRcFlags }}}&#160;{{ timestamp }}&#160;</td>
                <td class="mw-changeslist-line-inner">
index d461867..8f3e8c4 100644 (file)
@@ -2130,7 +2130,7 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.special.changeslist.enhanced' => [
-               'styles' => 'resources/src/mediawiki.special.changeslist.enhanced.css',
+               'styles' => 'resources/src/mediawiki.special.changeslist.enhanced.less',
        ],
        'mediawiki.special.changeslist.legend' => [
                'styles' => 'resources/src/mediawiki.special.changeslist.legend.less',
@@ -2357,6 +2357,7 @@ return [
                'dependencies' => [
                        'mediawiki.api',
                        'mediawiki.jqueryMsg',
+                       'mediawiki.notify',
                        'mediawiki.Title',
                        'mediawiki.util',
                        'oojs-ui-core',
index 1ab91a9..ec96cb6 100644 (file)
@@ -47,7 +47,8 @@
        ul.mw-collapsible:not( @{exclude} ):before,
        // Where the tbody or thead is the first child of the collapsible table
        table.mw-collapsible:not( @{exclude} ) :first-child tr:first-child th:last-child:before,
-       table.mw-collapsible:not( @{exclude} ) > caption:first-child:after {
+       table.mw-collapsible:not( @{exclude} ) > caption:first-child:after,
+       div.mw-collapsible:not( @{exclude} ):before {
                content: '[@{msg-collapsible-collapse}]';
        }
 
diff --git a/resources/src/mediawiki.special.changeslist.enhanced.css b/resources/src/mediawiki.special.changeslist.enhanced.css
deleted file mode 100644 (file)
index 275004f..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*!
- * Styling for Special:Watchlist and Special:RecentChanges when preference 'usenewrc'
- * a.k.a. Enhanced Recent Changes is enabled.
- */
-
-table.mw-enhanced-rc {
-       border: 0;
-       border-spacing: 0;
-}
-
-table.mw-enhanced-rc th,
-table.mw-enhanced-rc td {
-       padding: 0;
-       vertical-align: top;
-}
-
-td.mw-enhanced-rc {
-       white-space: nowrap;
-       font-family: monospace, monospace;
-}
-
-.mw-enhanced-rc-time {
-       font-family: monospace, monospace;
-}
-
-table.mw-enhanced-rc td.mw-enhanced-rc-nested {
-       padding-left: 1em;
-}
-
-/* Show/hide arrows in enhanced changeslist */
-.mw-enhanced-rc .collapsible-expander {
-       float: none;
-}
-
-/* If JS is disabled, the arrows or the placeholder space shouldn't be shown */
-.client-nojs .mw-enhancedchanges-arrow-space {
-       display: none;
-}
-
-.mw-enhancedchanges-arrow {
-       padding-top: 2px;
-}
-
-.mw-enhancedchanges-arrow-space {
-       display: inline-block;
-       *display: inline; /* IE7 and below */
-       zoom: 1;
-       width: 15px;
-       height: 15px;
-}
-
-.mw-enhanced-watched .mw-enhanced-rc-time {
-       font-weight: bold;
-}
-
-span.changedby {
-       font-size: 95%;
-}
diff --git a/resources/src/mediawiki.special.changeslist.enhanced.less b/resources/src/mediawiki.special.changeslist.enhanced.less
new file mode 100644 (file)
index 0000000..d7923f4
--- /dev/null
@@ -0,0 +1,58 @@
+/*!
+ * Styling for Special:Watchlist and Special:RecentChanges when preference 'usenewrc'
+ * a.k.a. Enhanced Recent Changes is enabled.
+ */
+
+table.mw-enhanced-rc {
+       border: 0;
+       border-spacing: 0;
+
+       th,
+       td {
+               padding: 0;
+               vertical-align: top;
+       }
+
+       td.mw-enhanced-rc-nested {
+               padding-left: 1em;
+       }
+}
+
+td.mw-enhanced-rc {
+       white-space: nowrap;
+       font-family: monospace, monospace;
+}
+
+.mw-enhanced-rc-time {
+       font-family: monospace, monospace;
+}
+
+/* Show/hide arrows in enhanced changeslist */
+.mw-enhanced-rc .collapsible-expander {
+       float: none;
+}
+
+/* If JS is disabled, the arrows or the placeholder space shouldn't be shown */
+.client-nojs .mw-enhancedchanges-arrow-space {
+       display: none;
+}
+
+.mw-enhancedchanges-arrow {
+       padding-top: 2px;
+}
+
+.mw-enhancedchanges-arrow-space {
+       display: inline-block;
+       *display: inline; /* IE7 and below */
+       zoom: 1;
+       width: 15px;
+       height: 15px;
+}
+
+.mw-enhanced-watched .mw-enhanced-rc-time {
+       font-weight: bold;
+}
+
+span.changedby {
+       font-size: 95%;
+}
index b5ba6a6..65cf316 100644 (file)
                         * @param {Function} [callback] Callback to run after request resolution
                         */
                        function addScript( src, callback ) {
+                               // Use a <script> element rather than XHR. Using XHR changes the request
+                               // headers (potentially missing a cache hit), and reduces caching in general
+                               // since browsers cache XHR much less (if at all). And XHR means we retrieve
+                               // text, so we'd need to eval, which then messes up line numbers.
+                               // The drawback is that <script> does not offer progress events, feedback is
+                               // only given after downloading, parsing, and execution have completed.
                                var script = document.createElement( 'script' );
                                script.src = src;
                                script.onload = script.onerror = function () {
index cfad069..8c02466 100644 (file)
@@ -1,5 +1,7 @@
 {
        "name": "FooBar",
+       "@note": "This is a note",
+       "@duck": "Docs say any @-item is ignored",
        "attributes": {
                "FooBar": {
                        "Attr": [ "test" ]
@@ -8,5 +10,12 @@
                        "Attr": [ "test2" ]
                }
        },
+       "config": {
+               "MyConfigValue": {
+                       "value": 42,
+                       "description": "Very important config value",
+                       "public": true
+               }
+       },
        "manifest_version": 2
 }
index 420fe74..eff2c85 100644 (file)
@@ -26,6 +26,12 @@ class EnhancedChangesListTest extends MediaWikiLangTestCase {
 
                $styleModules = $enhancedChangesList->getOutput()->getModuleStyles();
 
+               $this->assertContains(
+                       'mediawiki.icon',
+                       $styleModules,
+                       'has mediawiki.icon'
+               );
+
                $this->assertContains(
                        'mediawiki.special.changeslist',
                        $styleModules,
@@ -46,7 +52,6 @@ class EnhancedChangesListTest extends MediaWikiLangTestCase {
                $modules = $enhancedChangesList->getOutput()->getModules();
 
                $this->assertContains( 'jquery.makeCollapsible', $modules, 'has jquery.makeCollapsible' );
-               $this->assertContains( 'mediawiki.icon', $modules, 'has mediawiki.icon' );
        }
 
        public function testBeginRecentChangesList_html() {