Add $wgDiffEngine
authorBrad Jorsch <bjorsch@wikimedia.org>
Tue, 5 Nov 2019 15:07:06 +0000 (10:07 -0500)
committerJames D. Forrester <jforrester@wikimedia.org>
Wed, 6 Nov 2019 14:15:24 +0000 (09:15 -0500)
The immediate use case is for testing, where some tests need to use the
PHP implementation even when wikidiff2 is installed.

Bug: T237049
Change-Id: I41dc4c0933429065d7638f518ec31f0a056afc41
(cherry picked from commit f3058c81b9bbdede6eeb70503ecc44a6ba423e0d)

RELEASE-NOTES-1.34
includes/DefaultSettings.php
includes/content/ContentHandler.php
includes/diff/DifferenceEngine.php
tests/phpunit/includes/api/ApiComparePagesTest.php
tests/phpunit/includes/diff/DifferenceEngineTest.php
tests/phpunit/integration/includes/diff/DifferenceEngineSlotDiffRendererIntegrationTest.php

index 27d3028..1259628 100644 (file)
@@ -6,6 +6,10 @@ MediaWiki 1.34 is an pre-release testing branch, and is not recommended
 for use in production.
 
 === Changes since MediaWiki 1.34.0-rc.1 ===
+* $wgDiffEngine (T237049) – This configuration can be used to specify which
+  difference engine to use. MediaWiki continues to default to automatically
+  choosing the first of $wgExternalDiffEngine, wikidiff2, or php that is
+  usable.
 
 == MediaWiki 1.34.0-rc.1 ==
 
index a10c30b..b514504 100644 (file)
@@ -8487,10 +8487,23 @@ $wgUpdateRowsPerQuery = 100;
  */
 
 /**
- * Name of the external diff engine to use. Supported values:
- * * string: path to an external diff executable
- * * false: wikidiff2 PHP/HHVM module if installed, otherwise the default PHP implementation
- * * 'wikidiff', 'wikidiff2', and 'wikidiff3' are treated as false for backwards compatibility
+ * Specify the difference engine to use.
+ *
+ * Supported values:
+ * - 'external': Use an external diff engine, which must be specified via $wgExternalDiffEngine
+ * - 'wikidiff2': Use the wikidiff2 PHP extension
+ * - 'php': PHP implementations included in MediaWiki
+ *
+ * The default (null) is to use the first engine that's available.
+ *
+ * @since 1.34
+ * @var string|null
+ */
+$wgDiffEngine = null;
+
+/**
+ * Name of the external diff engine to use.
+ * @var string|false Path to an external diff executable
  */
 $wgExternalDiffEngine = false;
 
index 533f639..0e8b5bc 100644 (file)
@@ -651,7 +651,7 @@ abstract class ContentHandler {
                $slotDiffRenderer->setLanguage( $contentLanguage );
 
                $engine = DifferenceEngine::getEngine();
-               if ( $engine === false ) {
+               if ( $engine === 'php' ) {
                        $slotDiffRenderer->setEngine( TextSlotDiffRenderer::ENGINE_PHP );
                } elseif ( $engine === 'wikidiff2' ) {
                        $slotDiffRenderer->setEngine( TextSlotDiffRenderer::ENGINE_WIKIDIFF2 );
index 4235488..af01ca1 100644 (file)
@@ -1178,7 +1178,7 @@ class DifferenceEngine extends ContextSource {
                $engine = $this->getEngine();
                $params = [
                        'diff',
-                       $engine,
+                       $engine === 'php' ? false : $engine, // Back compat
                        self::DIFF_VERSION,
                        "old-{$this->mOldid}",
                        "rev-{$this->mNewid}"
@@ -1288,32 +1288,59 @@ class DifferenceEngine extends ContextSource {
        }
 
        /**
-        * Process ExternalDiffEngine config and get a sane, usable engine
+        * Process DiffEngine config and get a sane, usable engine
         *
-        * @return bool|string 'wikidiff2', path to an executable, or false
+        * @return string 'wikidiff2', 'php', or path to an executable
         * @internal For use by this class and TextSlotDiffRenderer only.
         */
        public static function getEngine() {
+               $diffEngine = MediaWikiServices::getInstance()->getMainConfig()
+                       ->get( 'DiffEngine' );
                $externalDiffEngine = MediaWikiServices::getInstance()->getMainConfig()
                        ->get( 'ExternalDiffEngine' );
 
-               if ( $externalDiffEngine ) {
-                       if ( is_string( $externalDiffEngine ) ) {
-                               if ( is_executable( $externalDiffEngine ) ) {
-                                       return $externalDiffEngine;
-                               }
-                               wfDebug( 'ExternalDiffEngine config points to a non-executable, ignoring' );
-                       } else {
-                               wfWarn( 'ExternalDiffEngine config is set to a non-string value, ignoring' );
-                       }
-               }
+               if ( $diffEngine === null ) {
+                       $engines = [ 'external', 'wikidiff2', 'php' ];
+               } else {
+                       $engines = [ $diffEngine ];
+               }
+
+               $failureReason = null;
+               foreach ( $engines as $engine ) {
+                       switch ( $engine ) {
+                               case 'external':
+                                       if ( is_string( $externalDiffEngine ) ) {
+                                               if ( is_executable( $externalDiffEngine ) ) {
+                                                       return $externalDiffEngine;
+                                               }
+                                               $failureReason = 'ExternalDiffEngine config points to a non-executable';
+                                               if ( $diffEngine === null ) {
+                                                       wfDebug( "$failureReason, ignoring" );
+                                               }
+                                       } else {
+                                               $failureReason = 'ExternalDiffEngine config is set to a non-string value';
+                                               if ( $diffEngine === null && $externalDiffEngine ) {
+                                                       wfWarn( "$failureReason, ignoring" );
+                                               }
+                                       }
+                                       break;
 
-               if ( function_exists( 'wikidiff2_do_diff' ) ) {
-                       return 'wikidiff2';
-               }
+                               case 'wikidiff2':
+                                       if ( function_exists( 'wikidiff2_do_diff' ) ) {
+                                               return 'wikidiff2';
+                                       }
+                                       $failureReason = 'wikidiff2 is not available';
+                                       break;
 
-               // Native PHP
-               return false;
+                               case 'php':
+                                       // Always available.
+                                       return 'php';
+
+                               default:
+                                       throw new DomainException( 'Invalid value for $wgDiffEngine: ' . $engine );
+                       }
+               }
+               throw new UnexpectedValueException( "Cannot use diff engine '$engine': $failureReason" );
        }
 
        /**
@@ -1367,7 +1394,7 @@ class DifferenceEngine extends ContextSource {
                $engine = self::getEngine();
                if ( $engine === 'wikidiff2' ) {
                        return $this->debug( 'wikidiff2' );
-               } elseif ( $engine === false ) {
+               } elseif ( $engine === 'php' ) {
                        return $this->debug( 'native PHP' );
                } else {
                        return $this->debug( "external $engine" );
index 9b32e9e..26c3f8f 100644 (file)
@@ -121,6 +121,8 @@ class ApiComparePagesTest extends ApiTestCase {
         * @dataProvider provideDiff
         */
        public function testDiff( $params, $expect, $exceptionCode = false, $sysop = false ) {
+               $this->setMwGlobals( [ 'wgDiffEngine' => 'php' ] );
+
                $this->doReplacements( $params );
 
                $params += [
index 46eaaea..43fe53f 100644 (file)
@@ -32,6 +32,8 @@ class DifferenceEngineTest extends MediaWikiTestCase {
                if ( !self::$revisions ) {
                        self::$revisions = $this->doEdits();
                }
+
+               $this->setMwGlobals( [ 'wgDiffEngine' => 'php' ] );
        }
 
        /**
index a211001..e0e321e 100644 (file)
@@ -9,7 +9,10 @@ class DifferenceEngineSlotDiffRendererIntegrationTest extends \MediaWikiIntegrat
         * @covers DifferenceEngineSlotDiffRenderer::getExtraCacheKeys
         */
        public function testGetExtraCacheKeys_noExternalDiffEngineConfigured() {
-               $this->setMwGlobals( [ 'wgExternalDiffEngine' => null ] );
+               $this->setMwGlobals( [
+                       'wgDiffEngine' => null,
+                       'wgExternalDiffEngine' => null,
+               ] );
 
                $differenceEngine = new CustomDifferenceEngine();
                $slotDiffRenderer = new DifferenceEngineSlotDiffRenderer( $differenceEngine );