From 23c79b228c0fcab6e6b16e5c6a530aaca1b845ac Mon Sep 17 00:00:00 2001 From: Florian Date: Wed, 20 Jan 2016 19:27:47 +0100 Subject: [PATCH] Structure test: Add autoload.php order check If a class is added manually to the autoload.php another run of the maintenance script will probably add unnecessary noise to another change. The added structure test checks, if the output of the maintenance script equals to the contents of the commited autoload.php. Bug: T121921 Change-Id: I3a426b92892f4c00cab33a13f6a717751120367c --- includes/utils/AutoloadGenerator.php | 86 ++++++++++++++++------ maintenance/generateLocalAutoload.php | 13 ++-- tests/phpunit/structure/AutoLoaderTest.php | 11 +++ 3 files changed, 81 insertions(+), 29 deletions(-) diff --git a/includes/utils/AutoloadGenerator.php b/includes/utils/AutoloadGenerator.php index 916e2f881c..de52cd949c 100644 --- a/includes/utils/AutoloadGenerator.php +++ b/includes/utils/AutoloadGenerator.php @@ -14,6 +14,9 @@ * $gen->generateAutoload(); */ class AutoloadGenerator { + const FILETYPE_JSON = 'json'; + const FILETYPE_PHP = 'php'; + /** * @var string Root path of the project being scanned for classes */ @@ -122,11 +125,11 @@ class AutoloadGenerator { * Updates the AutoloadClasses field at the given * filename. * - * @param {string} $filename Filename of JSON + * @param string $filename Filename of JSON * extension/skin registration file + * @return string Updated Json of the file given as the $filename parameter */ protected function generateJsonAutoload( $filename ) { - require_once __DIR__ . '/../../includes/json/FormatJson.php'; $key = 'AutoloadClasses'; $json = FormatJson::decode( file_get_contents( $filename ), true ); unset( $json[$key] ); @@ -148,10 +151,8 @@ class AutoloadGenerator { // Sorting the list of autoload classes. ksort( $json[$key] ); - // Update file, using constants for the required - // formatting. - file_put_contents( $filename, - FormatJson::encode( $json, true ) . "\n" ); + // Return the whole JSON file + return FormatJson::encode( $json, true ) . "\n"; } /** @@ -198,8 +199,7 @@ class AutoloadGenerator { } $output = implode( "\n\t", $content ); - file_put_contents( - $filename, + return <<variableName}; {$output} ]; -EOD - ); +EOD; } /** - * Write out all known classes to autoload.php, extension.json, or skin.json in - * the provided basedir + * Returns all known classes as a string, which can be used to put into a target + * file (e.g. extension.json, skin.json or autoload.php) * * @param string $commandName Value used in file comment to direct * developers towards the appropriate way to update the autoload. + * @return string */ - public function generateAutoload( $commandName = 'AutoloadGenerator' ) { + public function getAutoload( $commandName = 'AutoloadGenerator' ) { // We need to check whether an extenson.json or skin.json exists or not, and // incase it doesn't, update the autoload.php file. - $jsonFilename = null; - if ( file_exists( $this->basepath . "/extension.json" ) ) { - $jsonFilename = $this->basepath . "/extension.json"; - } elseif ( file_exists( $this->basepath . "/skin.json" ) ) { - $jsonFilename = $this->basepath . "/skin.json"; - } + $fileinfo = $this->getTargetFileinfo(); - if ( $jsonFilename !== null ) { - $this->generateJsonAutoload( $jsonFilename ); + if ( $fileinfo['type'] === AutoloadGenerator::FILETYPE_JSON ) { + return $this->generateJsonAutoload( $fileinfo['filename'] ); } else { - $this->generatePHPAutoload( $commandName, $this->basepath . '/autoload.php' ); + return $this->generatePHPAutoload( $commandName, $fileinfo['filename'] ); + } + } + + /** + * Returns the filename of the extension.json of skin.json, if there's any, or + * otherwise the path to the autoload.php file in an array as the "filename" + * key and with the type (AutoloadGenerator::FILETYPE_JSON or AutoloadGenerator::FILETYPE_PHP) + * of the file as the "type" key. + * + * @return array + */ + public function getTargetFileinfo() { + $fileinfo = [ + 'filename' => $this->basepath . '/autoload.php', + 'type' => AutoloadGenerator::FILETYPE_PHP + ]; + if ( file_exists( $this->basepath . '/extension.json' ) ) { + $fileinfo = [ + 'filename' => $this->basepath . '/extension.json', + 'type' => AutoloadGenerator::FILETYPE_JSON + ]; + } elseif ( file_exists( $this->basepath . '/skin.json' ) ) { + $fileinfo = [ + 'filename' => $this->basepath . '/skin.json', + 'type' => AutoloadGenerator::FILETYPE_JSON + ]; } + + return $fileinfo; } + /** * Ensure that Unix-style path separators ("/") are used in the path. * @@ -249,6 +273,24 @@ EOD protected static function normalizePathSeparator( $path ) { return str_replace( '\\', '/', $path ); } + + /** + * Initialize the source files and directories which are used for the MediaWiki default + * autoloader in {mw-base-dir}/autoload.php including: + * * includes/ + * * languages/ + * * maintenance/ + * * mw-config/ + * * /*.php + */ + public function initMediaWikiDefault() { + foreach ( [ 'includes', 'languages', 'maintenance', 'mw-config' ] as $dir ) { + $this->readDir( $this->basepath . '/' . $dir ); + } + foreach ( glob( $this->basepath . '/*.php' ) as $file ) { + $this->readFile( $file ); + } + } } /** diff --git a/maintenance/generateLocalAutoload.php b/maintenance/generateLocalAutoload.php index 8b1d86df73..0c278bc18e 100644 --- a/maintenance/generateLocalAutoload.php +++ b/maintenance/generateLocalAutoload.php @@ -10,12 +10,11 @@ require_once __DIR__ . '/../includes/utils/AutoloadGenerator.php'; $base = dirname( __DIR__ ); $generator = new AutoloadGenerator( $base, 'local' ); -foreach ( [ 'includes', 'languages', 'maintenance', 'mw-config' ] as $dir ) { - $generator->readDir( $base . '/' . $dir ); -} -foreach ( glob( $base . '/*.php' ) as $file ) { - $generator->readFile( $file ); -} +$generator->initMediaWikiDefault(); // Write out the autoload -$generator->generateAutoload( 'maintenance/generateLocalAutoload.php' ); +$fileinfo = $generator->getTargetFileinfo(); +file_put_contents( + $fileinfo['filename'], + $generator->getAutoload( 'maintenance/generateLocalAutoload.php' ) +); diff --git a/tests/phpunit/structure/AutoLoaderTest.php b/tests/phpunit/structure/AutoLoaderTest.php index 58de8e8491..f36b51a7e9 100644 --- a/tests/phpunit/structure/AutoLoaderTest.php +++ b/tests/phpunit/structure/AutoLoaderTest.php @@ -143,4 +143,15 @@ class AutoLoaderTest extends MediaWikiTestCase { $this->assertFalse( $uncerealized instanceof __PHP_Incomplete_Class, "unserialize() can load classes case-insensitively." ); } + + function testAutoloadOrder() { + $path = realpath( __DIR__ . '/../../..' ); + $oldAutoload = file_get_contents( $path . '/autoload.php' ); + $generator = new AutoloadGenerator( $path, 'local' ); + $generator->initMediaWikiDefault(); + $newAutoload = $generator->getAutoload( 'maintenance/generateLocalAutoload.php' ); + + $this->assertEquals( $oldAutoload, $newAutoload, 'autoload.php does not match' . + ' output of generateLocalAutoload.php script.' ); + } } -- 2.20.1