From 4de667f3c2dd2fea0f246a313a9ed848a793ed2f Mon Sep 17 00:00:00 2001 From: Kunal Mehta Date: Thu, 28 Jul 2016 14:44:06 -0700 Subject: [PATCH] maintenance: Allow having a nicer error message if an extension isn't enabled Maintenance scripts can be invoked regardless of whether an extension is enabled on a wiki or not. On wiki farms where some wikis may have an extension or not, this can potentially be rather confusing. Especially when the script bails out with a fatal class missing error or a database table missing. This allows maintenance scripts to specify that they require an extension by calling: $this->requireExtension( 'ExtensionName' ); in the script's constructor. Bug: T141531 Change-Id: Icfbf063bb9c9ac9e55c3a5a8ed815528a2c1ce1e --- RELEASE-NOTES-1.28 | 2 ++ maintenance/Maintenance.php | 42 +++++++++++++++++++++++++++++++++++ maintenance/doMaintenance.php | 3 +++ 3 files changed, 47 insertions(+) diff --git a/RELEASE-NOTES-1.28 b/RELEASE-NOTES-1.28 index cff734b796..41e94be634 100644 --- a/RELEASE-NOTES-1.28 +++ b/RELEASE-NOTES-1.28 @@ -36,6 +36,8 @@ production. * Added a new hook, 'UploadVerifyUpload', which can be used to reject a file upload. Unlike 'UploadVerifyFile' it provides information about upload comment and the file description page, but does not run for uploads to stash. +* (T141604) Extensions can now provide a better error message when their + maintenance scripts are run without the extension being installed. === External library changes in 1.28 === diff --git a/maintenance/Maintenance.php b/maintenance/Maintenance.php index 27d816115e..8368aabebb 100644 --- a/maintenance/Maintenance.php +++ b/maintenance/Maintenance.php @@ -123,6 +123,12 @@ abstract class Maintenance { */ private $config; + /** + * @see Maintenance::requireExtension + * @var array + */ + private $requiredExtensions = []; + /** * Used to read the options in the order they were passed. * Useful for option chaining (Ex. dumpBackup.php). It will @@ -506,6 +512,42 @@ abstract class Maintenance { $this->config = $config; } + /** + * Indicate that the specified extension must be + * loaded before the script can run. + * + * This *must* be called in the constructor. + * + * @since 1.28 + * @param string $name + */ + protected function requireExtension( $name ) { + $this->requiredExtensions[] = $name; + } + + /** + * Verify that the required extensions are installed + * + * @since 1.28 + */ + public function checkRequiredExtensions() { + $registry = ExtensionRegistry::getInstance(); + $missing = []; + foreach ( $this->requiredExtensions as $name ) { + if ( !$registry->isLoaded( $name ) ) { + $missing[] = $name; + } + } + + if ( $missing ) { + $joined = implode( ', ', $missing ); + $msg = "The following extensions are required to be installed " + . "for this script to run: $joined. Please enable them and then try again."; + $this->error( $msg, 1 ); + } + + } + /** * Run a child maintenance script. Pass all of the current arguments * to it. diff --git a/maintenance/doMaintenance.php b/maintenance/doMaintenance.php index 000e5f9f08..1272ca221a 100644 --- a/maintenance/doMaintenance.php +++ b/maintenance/doMaintenance.php @@ -99,6 +99,9 @@ require_once "$IP/includes/Setup.php"; // Initialize main config instance $maintenance->setConfig( ConfigFactory::getDefaultInstance()->makeConfig( 'main' ) ); +// Sanity-check required extensions are installed +$maintenance->checkRequiredExtensions(); + // Do the work $maintenance->execute(); -- 2.20.1