r68645 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r68644‎ | r68645 | r68646 >
Date:21:48, 27 June 2010
Author:mah
Status:resolved (Comments)
Tags:
Comment:
* consolidate some installer functionals into the Installer class
* add beginning of CliInstallerOutput class
* make it possible to override LocalSettings from a maint script
* make basic cli installation possible (only tested mysql so far)
Modified paths:
  • /trunk/phase3/config/new-index.php (modified) (history)
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/installer/CliInstaller.php (modified) (history)
  • /trunk/phase3/includes/installer/CliInstallerOutput.php (added) (history)
  • /trunk/phase3/includes/installer/Installer.php (modified) (history)
  • /trunk/phase3/maintenance/Maintenance.php (modified) (history)
  • /trunk/phase3/maintenance/doMaintenance.php (modified) (history)
  • /trunk/phase3/maintenance/install.php (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/install.php
@@ -20,35 +20,41 @@
2121 * @see wfWaitForSlaves()
2222 */
2323
24 -define( 'MW_NO_DB', 1 );
25 -define( 'MW_NO_SESSION', 1 );
26 -define( 'MW_CONFIG_CALLBACK', 'wfInstallerConfig' );
 24+define( 'MW_CONFIG_CALLBACK', 'Installer::overrideConfig' );
2725
28 -$IP = dirname( dirname( __FILE__ ) );
 26+require_once( dirname( dirname( __FILE__ ) )."/maintenance/Maintenance.php" );
2927
30 -require_once( "$IP/maintenance/Maintenance.php" );
31 -
3228 class CommandLineInstaller extends Maintenance {
3329 public function __construct() {
 30+ parent::__construct();
 31+
3432 $this->addArg( 'name', 'The name of the wiki', true);
 33+
3534 $this->addArg( 'admin', 'The username of the wiki administrator (WikiSysop)', false);
3635 $this->addOption( 'pass', 'The password for the wiki administrator. You will be prompted for this if it isn\'t provided', false, true);
37 - /* $this->addOption( 'email', 'The email for the wiki administrator', false, true); */
 36+ $this->addOption( 'email', 'The email for the wiki administrator', false, true);
 37+
3838 $this->addOption( 'lang', 'The language to use (en)', false, true );
3939 /* $this->addOption( 'cont-lang', 'The content language (en)', false, true ); */
40 - $this->addOption( 'db-type', 'The type of database (mysql)', false, true );
41 - /* $this->addOption( 'db-host', 'The database host (localhost)', false, true ); */
42 - /* $this->addOption( 'db-port', 'The database port (3306 for mysql, 5432 for pg)', false, true ); */
43 - $this->addOption( 'db-name', 'The database name (my_wiki)', false, true );
44 - $this->addOption( 'db-path', 'The path for the SQLite DB (/var/data)', false, true );
45 - /* $this->addOption( 'db-schema', 'The schema for the MediaWiki DB in pg (mediawiki)', false, true ); */
46 - /* $this->addOption( 'db-tsearch2-schema', 'The schema for the tsearch2 DB in pg (public)', false, true ); */
 40+
 41+ $this->addOption( 'dbtype', 'The type of database (mysql)', false, true );
 42+ /* $this->addOption( 'dbhost', 'The database host (localhost)', false, true ); */
 43+ /* $this->addOption( 'dbport', 'The database port (3306 for mysql, 5432 for pg)', false, true ); */
 44+ $this->addOption( 'dbname', 'The database name (my_wiki)', false, true );
 45+ $this->addOption( 'dbpath', 'The path for the SQLite DB (/var/data)', false, true );
 46+ $this->addOption( 'installdbuser', 'The user to use for installing (root)', false, true );
 47+ $this->addOption( 'installdbpass', 'The pasword for the DB user to install as.', false, true );
 48+ /* $this->addOption( 'dbschema', 'The schema for the MediaWiki DB in pg (mediawiki)', false, true ); */
 49+ /* $this->addOption( 'dbtsearch2schema', 'The schema for the tsearch2 DB in pg (public)', false, true ); */
4750 /* $this->addOption( 'namespace', 'The project namespace (same as the name)', false, true ); */
4851 }
4952
5053 public function execute() {
51 - $installer = new CliInstaller( $this->mArgs[0], $this->mArgs[1], $this->mOptions );
 54+ $adminName = isset( $this->mArgs[1] ) ? $this->mArgs[1] : null;
5255
 56+ $installer =
 57+ new CliInstaller( $this->mArgs[0], $adminName, $this->mOptions );
 58+
5359 $installer->execute();
5460 }
5561 }
Index: trunk/phase3/maintenance/doMaintenance.php
@@ -61,9 +61,13 @@
6262 require_once( "$IP/includes/AutoLoader.php" );
6363 require_once( "$IP/includes/Defines.php" );
6464
65 -// Load settings, using wikimedia-mode if needed
66 -// Fixme: replace this hack with general farm-friendly code
67 -if ( file_exists( "$IP/wmf-config/wikimedia-mode" ) ) {
 65+if ( defined( 'MW_CONFIG_CALLBACK' ) ) {
 66+ # Use a callback function to configure MediaWiki
 67+ require_once( "$IP/includes/DefaultSettings.php" );
 68+ call_user_func( MW_CONFIG_CALLBACK );
 69+} elseif ( file_exists( "$IP/wmf-config/wikimedia-mode" ) ) {
 70+ // Load settings, using wikimedia-mode if needed
 71+ // Fixme: replace this hack with general farm-friendly code
6872 # TODO FIXME! Wikimedia-specific stuff needs to go away to an ext
6973 # Maybe a hook?
7074 global $cluster;
@@ -76,6 +80,7 @@
7781 } else {
7882 require_once( $maintenance->loadSettings() );
7983 }
 84+
8085 if ( $maintenance->getDbType() === Maintenance::DB_ADMIN &&
8186 is_readable( "$IP/AdminSettings.php" ) )
8287 {
Index: trunk/phase3/maintenance/Maintenance.php
@@ -217,7 +217,8 @@
218218 * Throw some output to the user. Scripts can call this with no fears,
219219 * as we handle all --quiet stuff here
220220 * @param $out String: the text to show to the user
221 - * @param $channel Mixed: unique identifier for the channel. See function outputChanneled.
 221+ * @param $channel Mixed: unique identifier for the channel. See
 222+ * function outputChanneled.
222223 */
223224 protected function output( $out, $channel = null ) {
224225 if ( $this->mQuiet ) {
@@ -256,13 +257,14 @@
257258
258259 private $atLineStart = true;
259260 private $lastChannel = null;
260 -
 261+
261262 /**
262263 * Message outputter with channeled message support. Messages on the
263264 * same channel are concatenated, but any intervening messages in another
264265 * channel start a new line.
265266 * @param $msg String: the message without trailing newline
266 - * @param $channel Channel identifier or null for no channel. Channel comparison uses ===.
 267+ * @param $channel Channel identifier or null for no
 268+ * channel. Channel comparison uses ===.
267269 */
268270 public function outputChanneled( $msg, $channel = null ) {
269271 $handle = fopen( 'php://stdout', 'w' );
@@ -556,7 +558,7 @@
557559 $die = true;
558560 }
559561 }
560 -
 562+
561563 if ( $die ) {
562564 $this->maybeHelp( true );
563565 }
@@ -588,7 +590,7 @@
589591 $screenWidth = 80; // TODO: Caculate this!
590592 $tab = " ";
591593 $descWidth = $screenWidth - ( 2 * strlen( $tab ) );
592 -
 594+
593595 ksort( $this->mParams );
594596 if ( $this->hasOption( 'help' ) || $force ) {
595597 $this->mQuiet = false;
Index: trunk/phase3/includes/installer/Installer.php
@@ -215,6 +215,16 @@
216216 * Constructor, always call this from child classes
217217 */
218218 function __construct() {
 219+ // Disable the i18n cache and LoadBalancer
 220+ Language::getLocalisationCache()->disableBackend();
 221+ LBFactory::disableBackend();
 222+
 223+ // Load the installer's i18n file
 224+ global $wgExtensionMessagesFiles;
 225+ $wgExtensionMessagesFiles['MediawikiInstaller'] =
 226+ './includes/installer/Installer.i18n.php';
 227+
 228+
219229 $this->settings = $this->internalDefaults;
220230 foreach ( $this->defaultVarNames as $var ) {
221231 $this->settings[$var] = $GLOBALS[$var];
@@ -909,7 +919,7 @@
910920 }
911921 }
912922
913 - /*
 923+ /**
914924 * On POSIX systems return the primary group of the webserver we're running under.
915925 * On other systems just returns null.
916926 *
@@ -934,4 +944,22 @@
935945
936946 return $group;
937947 }
 948+
 949+ /**
 950+ * Override the necessary bits of the config to run an installation
 951+ */
 952+ public static function overrideConfig() {
 953+ define( 'MW_NO_SESSION', 1 );
 954+
 955+ // Don't access the database
 956+ $GLOBALS['wgUseDatabaseMessages'] = false;
 957+ // Debug-friendly
 958+ $GLOBALS['wgShowExceptionDetails'] = true;
 959+ // Don't break forms
 960+ $GLOBALS['wgExternalLinkTarget'] = '_blank';
 961+
 962+ // Extended debugging. Maybe disable before release?
 963+ $GLOBALS['wgShowSQLErrors'] = true;
 964+ $GLOBALS['wgShowDBErrorBacktrace'] = true;
 965+ }
938966 }
Index: trunk/phase3/includes/installer/CliInstaller.php
@@ -1,24 +1,41 @@
22 <?php
33
4 -function wfInstallerConfig() {
5 - // Don't access the database
6 - $GLOBALS['wgUseDatabaseMessages'] = false;
7 - // Debug-friendly
8 - $GLOBALS['wgShowExceptionDetails'] = true;
9 - // Don't break forms
10 - $GLOBALS['wgExternalLinkTarget'] = '_blank';
 4+class CliInstaller extends Installer {
115
12 - // Extended debugging. Maybe disable before release?
13 - $GLOBALS['wgShowSQLErrors'] = true;
14 - $GLOBALS['wgShowDBErrorBacktrace'] = true;
15 -}
 6+ /* The maintenance class in effect */
 7+ private $maint;
168
17 -class CliInstaller extends Installer {
 9+ private $optionMap = array(
 10+ 'dbtype' => 'wgDBtype',
 11+ 'dbserver' => 'wgDBserver',
 12+ 'dbname' => 'wgDBname',
 13+ 'dbuser' => 'wgDBuser',
 14+ 'dbpass' => 'wgDBpassword',
 15+ 'dbprefix' => 'wgDBprefix',
 16+ 'dbtableoptions' => 'wgDBTableOptions',
 17+ 'dbmysql5' => 'wgDBmysql5',
 18+ 'dbserver' => 'wgDBserver',
 19+ 'dbport' => 'wgDBport',
 20+ 'dbname' => 'wgDBname',
 21+ 'dbuser' => 'wgDBuser',
 22+ 'dbpass' => 'wgDBpassword',
 23+ 'dbschema' => 'wgDBmwschema',
 24+ 'dbts2schema' => 'wgDBts2schema',
 25+ 'dbpath' => 'wgSQLiteDataDir',
 26+ );
1827
 28+
1929 /** Constructor */
2030 function __construct( $siteName, $admin = null, $option = array()) {
2131 parent::__construct();
2232
 33+ foreach ( $this->optionMap as $opt => $global ) {
 34+ if ( isset( $option[$opt] ) ) {
 35+ $GLOBALS[$global] = $option[$opt];
 36+ $this->setVar( $global, $option[$opt] );
 37+ }
 38+ }
 39+
2340 if ( isset( $option['lang'] ) ) {
2441 global $wgLang, $wgContLang, $wgLanguageCode;
2542 $this->setVar( '_UserLang', $option['lang'] );
@@ -31,22 +48,48 @@
3249 if ( $admin ) {
3350 $this->setVar( '_AdminName', $admin );
3451 } else {
35 - $this->setVar( '_AdminName', wfMsgForContent( 'config-admin-default-username' ) );
 52+ $this->setVar( '_AdminName',
 53+ wfMsgForContent( 'config-admin-default-username' ) );
3654 }
 55+
 56+ if ( !isset( $option['installdbuser'] ) ) {
 57+ $this->setVar( '_InstallUser',
 58+ $this->getVar( 'wgDBuser' ) );
 59+ $this->setVar( '_InstallPassword',
 60+ $this->getVar( 'wgDBpassword' ) );
 61+ }
 62+
 63+ if ( isset( $option['pass'] ) ) {
 64+ $this->setVar( '_AdminPassword', $option['pass'] );
 65+ }
 66+
 67+ $this->output = new CliInstallerOutput( $this );
3768 }
3869
3970 /**
4071 * Main entry point.
4172 */
4273 function execute( ) {
43 - var_dump($this->getVar('_AdminName'));
 74+ foreach( $this->getInstallSteps() as $step ) {
 75+ $this->showMessage("Installing $step... ");
 76+ $func = 'install' . ucfirst( $step );
 77+ $status = $this->{$func}();
 78+ $ok = $status->isGood();
 79+ if ( !$ok ) {
 80+ $this->showStatusError( $status );
 81+ exit;
 82+ }
 83+ $this->showMessage("done\n");
 84+ }
4485 }
4586
4687 function showMessage( $msg /*, ... */ ) {
47 - echo "Message: $msg\n";
 88+ $this->output->addHTML($msg);
 89+ $this->output->output();
4890 }
4991
5092 function showStatusError( $status ) {
51 - echo "Error: $status\n";
 93+ $this->output->addHTML($status->getWikiText()."\n");
 94+ $this->output->flush();
5295 }
5396 }
Index: trunk/phase3/includes/installer/CliInstallerOutput.php
@@ -0,0 +1,83 @@
 2+<?php
 3+
 4+/**
 5+ * Output class modelled on OutputPage.
 6+ *
 7+ * I've opted to use a distinct class rather than derive from OutputPage here in
 8+ * the interests of separation of concerns: if we used a subclass, there would be
 9+ * quite a lot of things you could do in OutputPage that would break the installer,
 10+ * that wouldn't be immediately obvious.
 11+ */
 12+class CliInstallerOutput {
 13+
 14+ function __construct( $parent ) {
 15+ $this->parent = $parent;
 16+ }
 17+
 18+ function addHTML( $html ) {
 19+ $this->contents .= $html;
 20+ }
 21+
 22+ function addWikiText( $text ) {
 23+ $this->addHTML( $this->parent->parse( $text ) );
 24+ }
 25+
 26+ function addHTMLNoFlush( $html ) {
 27+ $this->contents .= $html;
 28+ }
 29+
 30+ function addWarning( $msg ) {
 31+ $this->warnings .= "<p>$msg</p>\n";
 32+ }
 33+
 34+ function addWarningMsg( $msg /*, ... */ ) {
 35+ $params = func_get_args();
 36+ array_shift( $params );
 37+ $this->addWarning( wfMsg( $msg, $params ) );
 38+ }
 39+
 40+ function redirect( $url ) {
 41+ if ( $this->headerDone ) {
 42+ throw new MWException( __METHOD__ . ' called after sending headers' );
 43+ }
 44+ $this->redirectTarget = $url;
 45+ }
 46+
 47+ function output() {
 48+ $this->flush();
 49+ $this->outputFooter();
 50+ }
 51+
 52+ function useShortHeader( $use = true ) {
 53+ }
 54+
 55+ function flush() {
 56+ echo $this->contents;
 57+ flush();
 58+ $this->contents = '';
 59+ }
 60+
 61+ function getDir() {
 62+ global $wgLang;
 63+ if( !is_object( $wgLang ) || !$wgLang->isRtl() )
 64+ return 'ltr';
 65+ else
 66+ return 'rtl';
 67+ }
 68+
 69+ function getLanguageCode() {
 70+ global $wgLang;
 71+ if( !is_object( $wgLang ) )
 72+ return 'en';
 73+ else
 74+ return $wgLang->getCode();
 75+ }
 76+
 77+ function outputWarnings() {
 78+ $this->addHTML( $this->warnings );
 79+ $this->warnings = '';
 80+ }
 81+
 82+ function outputFooter() {}
 83+
 84+}
Property changes on: trunk/phase3/includes/installer/CliInstallerOutput.php
___________________________________________________________________
Added: svn:eol-syle
185 + native
Index: trunk/phase3/includes/AutoLoader.php
@@ -414,6 +414,7 @@
415415
416416 # includes/installer
417417 'CliInstaller' => 'includes/installer/CliInstaller.php',
 418+ 'CliInstallerOutput' => 'includes/installer/CliInstallerOutput.php',
418419 'Installer' => 'includes/installer/Installer.php',
419420 'InstallerDBType' => 'includes/installer/InstallerDBType.php',
420421 'LBFactory_InstallerFake' => 'includes/installer/Installer.php',
Index: trunk/phase3/config/new-index.php
@@ -1,35 +1,12 @@
22 <?php
33
4 -define( 'MW_NO_DB', 1 );
5 -define( 'MW_NO_SESSION', 1 );
6 -define( 'MW_CONFIG_CALLBACK', 'wfInstallerConfig' );
 4+define( 'MW_CONFIG_CALLBACK', 'Installer::overrideConfig' );
75
8 -function wfInstallerConfig() {
9 - // Don't access the database
10 - $GLOBALS['wgUseDatabaseMessages'] = false;
11 - // Debug-friendly
12 - $GLOBALS['wgShowExceptionDetails'] = true;
13 - // Don't break forms
14 - $GLOBALS['wgExternalLinkTarget'] = '_blank';
15 -
16 - // Extended debugging. Maybe disable before release?
17 - $GLOBALS['wgShowSQLErrors'] = true;
18 - $GLOBALS['wgShowDBErrorBacktrace'] = true;
19 -}
20 -
216 chdir( ".." );
227 require( './includes/WebStart.php' );
238 require_once( './maintenance/updaters.inc' ); // sigh...
249
25 -// Disable the i18n cache and LoadBalancer
26 -Language::getLocalisationCache()->disableBackend();
27 -LBFactory::disableBackend();
28 -
29 -// Load the installer's i18n file
30 -$wgExtensionMessagesFiles['MediawikiInstaller'] = './includes/installer/Installer.i18n.php';
31 -
3210 $installer = new WebInstaller( $wgRequest );
33 -$wgParser->setHook( 'doclink', array( $installer, 'docLink' ) );
3411
3512 if ( !$installer->startSession() ) {
3613 $installer->finish();

Follow-up revisions

RevisionCommit summaryAuthorDate
r68756Fix for r68645: <doclink> was removed in refactordemon00:52, 30 June 2010
r68908* Eliminate CLIInstallerOutput per r68645 since, yes, it wasn't needed....mah21:15, 2 July 2010
r99118Follow-up r68645: back out --email, still not usedmaxsem17:00, 6 October 2011

Comments

#Comment by Tim Starling (talk | contribs)   03:31, 30 June 2010

I'm not sure there is any need for a CliInstallerOutput class. There is only one reference to $installer->output in common code, and that's a bug (see r65860). But if there was a need for it, it would be derived from a common base class with common functionality factored out, it wouldn't be copied from WebInstallerOutput, complete with an irrelevant comment discussing the differences from the OutputPage class.

-define( 'MW_CONFIG_CALLBACK', 'wfInstallerConfig' );
+define( 'MW_CONFIG_CALLBACK', 'Installer::overrideConfig' );

Please either revert this or modify doMaintenance.php and WebStart.php so that it works in PHP 5.1. The latter would be along the lines of:

$callback = MW_CONFIG_CALLBACK;
if ( strpos( $callback, '::' ) !== false ) {
    $callback = explode( '::', $callback, 2 );
}
call_user_func( $callback );
#Comment by MarkAHershberger (talk | contribs)   04:27, 30 June 2010

see r68760 for callback fix.

#Comment by MarkAHershberger (talk | contribs)   04:31, 30 June 2010

re: the output class. When I added SQLite support, I added ->output usage. Obviously ugly and should be fixed also.

Status & tagging log