From 9ffc40235b926e9280bae432908214c9cae045f3 Mon Sep 17 00:00:00 2001 From: Kunal Mehta Date: Fri, 22 Jul 2016 15:08:21 -0700 Subject: [PATCH] registration: Support config setings that are relative paths Add support for configuration settings that are relative paths to the extension directory. The most common use-case for this is where the extension ships a generic default file, but sysadmins or packagers may want to override it. Setting `"path": true` on the config definition will make the value be interpreted as a relative path. And add tests! Bug: T100956 Change-Id: Ia87ced25b35be7a314ee2937e0ccc63f9acc5bb5 --- docs/extension.schema.json | 5 +++ includes/registration/ExtensionProcessor.php | 10 ++++-- .../registration/ExtensionProcessorTest.php | 34 +++++++++++++++++-- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/docs/extension.schema.json b/docs/extension.schema.json index 14a9731198..9c8160da24 100644 --- a/docs/extension.schema.json +++ b/docs/extension.schema.json @@ -881,6 +881,11 @@ ], "default": "array_merge" }, + "path": { + "description": "Whether this should be interpreted as a filesystem path, relative to extension directory root", + "type": "boolean", + "default": false + }, "description": { "type": ["string", "array"], "description": "A description of the config setting, mostly for documentation/developers" diff --git a/includes/registration/ExtensionProcessor.php b/includes/registration/ExtensionProcessor.php index 0bf2842f3f..9563fc09f2 100644 --- a/includes/registration/ExtensionProcessor.php +++ b/includes/registration/ExtensionProcessor.php @@ -162,14 +162,14 @@ class ExtensionProcessor implements Processor { * @return array */ public function extractInfo( $path, array $info, $version ) { + $dir = dirname( $path ); if ( $version === 2 ) { - $this->extractConfig2( $info ); + $this->extractConfig2( $info, $dir ); } else { // $version === 1 $this->extractConfig1( $info ); } $this->extractHooks( $info ); - $dir = dirname( $path ); $this->extractExtensionMessagesFiles( $dir, $info ); $this->extractMessagesDirs( $dir, $info ); $this->extractNamespaces( $info ); @@ -381,8 +381,9 @@ class ExtensionProcessor implements Processor { * @todo In the future, this should be done via Config interfaces * * @param array $info + * @param string $dir */ - protected function extractConfig2( array $info ) { + protected function extractConfig2( array $info, $dir ) { if ( isset( $info['config_prefix'] ) ) { $prefix = $info['config_prefix']; } else { @@ -394,6 +395,9 @@ class ExtensionProcessor implements Processor { if ( isset( $value['merge_strategy'] ) ) { $value[ExtensionRegistry::MERGE_STRATEGY] = $data['merge_strategy']; } + if ( isset( $data['path'] ) && $data['path'] ) { + $value = "$dir/$value"; + } $this->globals["$prefix$key"] = $value; } } diff --git a/tests/phpunit/includes/registration/ExtensionProcessorTest.php b/tests/phpunit/includes/registration/ExtensionProcessorTest.php index be7fe91b1a..11995de944 100644 --- a/tests/phpunit/includes/registration/ExtensionProcessorTest.php +++ b/tests/phpunit/includes/registration/ExtensionProcessorTest.php @@ -2,11 +2,12 @@ class ExtensionProcessorTest extends MediaWikiTestCase { - private $dir; + private $dir, $dirname; public function setUp() { parent::setUp(); $this->dir = __DIR__ . '/FooBar/extension.json'; + $this->dirname = dirname( $this->dir ); } /** @@ -110,7 +111,7 @@ class ExtensionProcessorTest extends MediaWikiTestCase { /** * @covers ExtensionProcessor::extractConfig1 */ - public function testExtractConfig() { + public function testExtractConfig1() { $processor = new ExtensionProcessor; $info = [ 'config' => [ @@ -136,6 +137,35 @@ class ExtensionProcessorTest extends MediaWikiTestCase { $this->assertEquals( 'somevalue', $extracted['globals']['egBar'] ); } + /** + * @covers ExtensionProcessor::extractConfig2 + */ + public function testExtractConfig2() { + $processor = new ExtensionProcessor; + $info = [ + 'config' => [ + 'Bar' => [ 'value' => 'somevalue' ], + 'Foo' => [ 'value' => 10 ], + 'Path' => [ 'value' => 'foo.txt', 'path' => true ], + ], + ] + self::$default; + $info2 = [ + 'config' => [ + 'Bar' => [ 'value' => 'somevalue' ], + ], + 'config_prefix' => 'eg', + 'name' => 'FooBar2', + ]; + $processor->extractInfo( $this->dir, $info, 2 ); + $processor->extractInfo( $this->dir, $info2, 2 ); + $extracted = $processor->getExtractedInfo(); + $this->assertEquals( 'somevalue', $extracted['globals']['wgBar'] ); + $this->assertEquals( 10, $extracted['globals']['wgFoo'] ); + $this->assertEquals( "{$this->dirname}/foo.txt", $extracted['globals']['wgPath'] ); + // Custom prefix: + $this->assertEquals( 'somevalue', $extracted['globals']['egBar'] ); + } + public static function provideExtractExtensionMessagesFiles() { $dir = __DIR__ . '/FooBar/'; return [ -- 2.20.1