svn: /web/doc-editor/trunk/ .htaccess install/doc-editor.sql js/locale/fr.js js/ui/component/BuildStatus.js js/ui/component/CheckBuildPrompt.js js/ui/component/MainMenu.js js/ui/task/CheckBuildTask.js php/ExtJsController.php php/LogManager.php php/RepositoryFetcher.php php/RepositoryManager.php scripts/cron/check_build.php
[email protected] (Yannick Torres)
| Newsgroups | php.doc.web |
|---|---|
| Message-ID | <[email protected]> |
yannick Wed, 16 Dec 2009 22:48:36 +0000
Revision: http://svn.php.net/viewvc?view=revision&revision=292225
Log:
Fix bug #50193 & Review all check build system. You need to upgrade the database structure with this commit
Bug: http://bugs.php.net/50193 (Open) Backslashes from newline tokens in example scripts are stripped
Changed paths:
U web/doc-editor/trunk/.htaccess
U web/doc-editor/trunk/install/doc-editor.sql
U web/doc-editor/trunk/js/locale/fr.js
U web/doc-editor/trunk/js/ui/component/BuildStatus.js
U web/doc-editor/trunk/js/ui/component/CheckBuildPrompt.js
U web/doc-editor/trunk/js/ui/component/MainMenu.js
U web/doc-editor/trunk/js/ui/task/CheckBuildTask.js
U web/doc-editor/trunk/php/ExtJsController.php
U web/doc-editor/trunk/php/LogManager.php
U web/doc-editor/trunk/php/RepositoryFetcher.php
U web/doc-editor/trunk/php/RepositoryManager.php
U web/doc-editor/trunk/scripts/cron/check_build.php
svn-diffs-292225.txt
(text/x-diff, 22.4 KB)
Modified: web/doc-editor/trunk/.htaccess
===================================================================
--- web/doc-editor/trunk/.htaccess 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/.htaccess 2009-12-16 22:48:36 UTC (rev 292225)
@@ -1,3 +1,4 @@
+php_flag magic_quotes_gpc Off
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^do/([^\?]+)$ php/controller.php?task=$1&%{QUERY_STRING}
Modified: web/doc-editor/trunk/install/doc-editor.sql
===================================================================
--- web/doc-editor/trunk/install/doc-editor.sql 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/install/doc-editor.sql 2009-12-16 22:48:36 UTC (rev 292225)
@@ -8,7 +8,7 @@
-- --------------------------------------------------------
--
--- Structure of table `commitMessage`
+-- Structure of table `staticValue`
--
CREATE TABLE IF NOT EXISTS `staticValue` (
@@ -187,13 +187,13 @@
-- --------------------------------------------------------
--
--- Structure of table `buildLog`
+-- Structure of table `failedBuildLog`
--
-CREATE TABLE IF NOT EXISTS `buildLog` (
+CREATE TABLE IF NOT EXISTS `failedBuildLog` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`project` varchar(50) NOT NULL,
`lang` varchar(10) NOT NULL,
- `status` enum('0','1') NOT NULL,
+ `log` mediumtext NOT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Modified: web/doc-editor/trunk/js/locale/fr.js
===================================================================
--- web/doc-editor/trunk/js/locale/fr.js 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/js/locale/fr.js 2009-12-16 22:48:36 UTC (rev 292225)
@@ -148,7 +148,7 @@
i18n["Remove this file"] = "Supprimer ce fichier";
i18n["This action will mark this file as need deleted.<br/><br/>You need commit this change to take it effect.<br/><br/>Please, confirm this action."] = "Voulez-vous marquer ce fichier comme devant être effacé ?<br/><br/>L'effacement sera effectif qu'une fois le commit émis.<br/><br/>Vous devez confirmer cette action.";
i18n["View in a new Tab"] = "Voir dans un nouvel onglet";
-i18n["Translation build status"] = "Statut de la compilation";
+i18n["Last failed build"] = "Dernier échec de la compilation";
i18n["Language"] = "Langage";
// Main Menu
@@ -165,7 +165,8 @@
i18n["Check Build"] = "Vérifier la compilation";
i18n["Go !"] = "Commencer !";
i18n["Please, wait until the build is checked..."] = "Merci de patienter pendant la vérification.";
- i18n["Check Build Result"] = "Résultat de la vérification";
+ i18n["Last failed build for {0}"] = "Dernier échec pour {0}";
+ i18n["Last failed build for the documentation {0}"] = "Dernier échec pour la documentation {0}";
i18n["You're about to check the build via this command:"] = "Vous allez vérifier la compilation avec la commande suivante :";
i18n["Enable detailed XML error messages"] = "Activer les messages d'erreur XML détaillés";
Modified: web/doc-editor/trunk/js/ui/component/BuildStatus.js
===================================================================
--- web/doc-editor/trunk/js/ui/component/BuildStatus.js 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/js/ui/component/BuildStatus.js 2009-12-16 22:48:36 UTC (rev 292225)
@@ -2,11 +2,46 @@
//------------------------------------------------------------------------------
// BuildStatus Internals
+ui.component._BuildStatus.display = function(config)
+{
+ Ext.apply(this, config);
+
+ XHR({
+ scope: this,
+ params : {
+ task : 'getFailedBuildData',
+ idFailedBuild : this.idFailedBuild
+ },
+ success : function(response)
+ {
+ var o = Ext.decode(response.responseText),
+ mess = o.mess.join("<br/>");
+
+ // Display
+ if ( Ext.getCmp('main-panel').findById('last_failed_build_' + this.lang) ) {
+ Ext.getCmp('main-panel').remove('last_failed_build_' + this.lang);
+ }
+
+ Ext.getCmp('main-panel').add({
+ xtype : 'panel',
+ id : 'last_failed_build_' + this.lang,
+ title : String.format(_('Last failed build for {0}'),Ext.util.Format.uppercase(this.lang)),
+ tabTip : String.format(_('Last failed build for the documentation {0}'), Ext.util.Format.uppercase(this.lang)),
+ closable : true,
+ autoScroll : true,
+ iconCls : 'checkBuild',
+ html : '<div class="check-build-content">' + mess + '</div>'
+ });
+ Ext.getCmp('main-panel').setActiveTab('last_failed_build_' + this.lang);
+ }
+ });
+};
+
// BuildStatus Grid datastore
ui.component._BuildStatus.ds = new Ext.data.Store({
proxy : new Ext.data.HttpProxy({
- url : './do/getBuildStatusData'
+ url : './do/getFailedBuild'
}),
reader : new Ext.data.JsonReader(
{
@@ -25,10 +60,6 @@
mapping : 'date',
type : 'date',
dateFormat : 'Y-m-d H:i:s'
- }, {
- name : 'status',
- mapping : 'status',
- type : 'int'
}
])
)
@@ -41,16 +72,6 @@
return '<div class="flag flag-' + value + '">' + value + '</div>';
};
-// BuildStatus Grid status cell renderer
-ui.component._BuildStatus.rendererStatus = function(value)
-{
- if (value === 0) {
- return 'Nok';
- } else {
- return 'Ok';
- }
-};
-
// BuildStatus Grid columns definition
ui.component._BuildStatus.columns = [
{
@@ -65,15 +86,36 @@
sortable : true,
dataIndex : 'lang',
renderer : ui.component._BuildStatus.rendererLanguage
- }, {
- header : _("Status"),
- width : 45,
- sortable : true,
- dataIndex : 'status',
- renderer : ui.component._BuildStatus.rendererStatus
}
];
+// BuildStatus context menu
+ui.component._BuildStatus.menu = function(config)
+{
+ Ext.apply(this, config);
+ this.init();
+ ui.component._BuildStatus.menu.superclass.constructor.call(this);
+};
+Ext.extend(ui.component._BuildStatus.menu, Ext.menu.Menu,
+{
+ init : function()
+ {
+ Ext.apply(this,
+ {
+ items : [{
+ scope : this,
+ text : '<b>' + _('View in a new Tab') + '</b>',
+ iconCls : 'PendingPatch',
+ handler : function()
+ {
+ this.grid.fireEvent('rowdblclick',
+ this.grid, this.rowIdx, this.event
+ );
+ }
+ }]
+ });
+ }
+});
//------------------------------------------------------------------------------
// BuildStatus Grid
@@ -86,16 +128,33 @@
columns : ui.component._BuildStatus.columns,
view : new Ext.grid.GridView({
- forceFit : true,
- getRowClass : function(record, numIndex, rowParams, store)
- {
- if (record.data.status === 0) {
- return 'summary_3';
- }
- }
+ forceFit : true
}),
listeners : {
scope : this,
+ rowcontextmenu : function(grid, rowIndex, e)
+ {
+
+ e.stopEvent();
+
+ grid.getSelectionModel().selectRow(rowIndex);
+
+ tmp = new ui.component._BuildStatus.menu({
+ grid : grid,
+ rowIdx : rowIndex,
+ event : e
+ }).showAt(e.getXY());
+ },
+ rowdblclick : function(grid, rowIndex, e)
+ {
+ var storeRecord = grid.store.getAt(rowIndex), tmp;
+
+ tmp = new ui.component._BuildStatus.display({
+ idFailedBuild : storeRecord.id,
+ lang : storeRecord.data["lang"]
+ });
+
+ },
render : function(grid)
{
grid.store.load.defer(20, grid.store);
Modified: web/doc-editor/trunk/js/ui/component/CheckBuildPrompt.js
===================================================================
--- web/doc-editor/trunk/js/ui/component/CheckBuildPrompt.js 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/js/ui/component/CheckBuildPrompt.js 2009-12-16 22:48:36 UTC (rev 292225)
@@ -30,7 +30,7 @@
baseCls : 'x-plain',
bodyStyle : 'padding:5px 5px 0',
html : _('You\'re about to check the build via this command:') +
- '<br/><br/>/usr/bin/php configure.php --with-lang=' + phpDoc.userLang + '<br><br>'
+ '<br/><br/>/usr/bin/php configure.php --with-lang=' + phpDoc.userLang + '<br/><br/>'
}, {
xtype : 'checkbox',
id : 'option-xml-details',
Modified: web/doc-editor/trunk/js/ui/component/MainMenu.js
===================================================================
--- web/doc-editor/trunk/js/ui/component/MainMenu.js 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/js/ui/component/MainMenu.js 2009-12-16 22:48:36 UTC (rev 292225)
@@ -64,7 +64,7 @@
handler : function() { return false; },
menu : new Ext.menu.Menu({
items : [{
- text : _('Translation build status'),
+ text : _('Last failed build'),
iconCls : 'BuildStatus',
handler : function()
{
@@ -74,7 +74,7 @@
// if tab not exist, create new tab
Ext.getCmp('main-panel').add({
id : 'tab-build-status',
- title : _('Translation build status'),
+ title : _('Last failed build'),
iconCls : 'BuildStatus',
layout : 'fit',
closable : true,
Modified: web/doc-editor/trunk/js/ui/task/CheckBuildTask.js
===================================================================
--- web/doc-editor/trunk/js/ui/task/CheckBuildTask.js 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/js/ui/task/CheckBuildTask.js 2009-12-16 22:48:36 UTC (rev 292225)
@@ -5,7 +5,7 @@
XHR({
params : {
task : 'getLogFile',
- file : 'log_check_build'
+ file : 'log_check_build_' + phpDoc.userLang
},
success : function(response)
{
@@ -40,7 +40,7 @@
XHR({
params : {
task : 'checkLockFile',
- lockFile : 'lock_check_build'
+ lockFile : 'lock_check_build_' + phpDoc.userLang
},
success : function(response)
{
Modified: web/doc-editor/trunk/php/ExtJsController.php
===================================================================
--- web/doc-editor/trunk/php/ExtJsController.php 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/php/ExtJsController.php 2009-12-16 22:48:36 UTC (rev 292225)
@@ -492,7 +492,7 @@
}
// Remove \
- $fileContent = stripslashes($this->getRequestVariable('fileContent'));
+ $fileContent = $this->getRequestVariable('fileContent');
// Replace by space
$fileContent = str_replace(" ", "", $fileContent);
@@ -771,19 +771,30 @@
}
$xmlDetails = $this->getRequestVariable('xmlDetails');
+ $return = "";
- $lock = new LockFile('lock_check_build');
+ $lang = AccountManager::getInstance()->vcsLang;
+
+ $lock = new LockFile('lock_check_build_'.$lang);
if ($lock->lock()) {
+ // Remove old log from DB
+ RepositoryManager::getInstance()->cleanUpBeforeCheckBuild();
+
// Start the checkBuild system
- $output = RepositoryManager::getInstance()->checkBuild($xmlDetails);
+ $return = RepositoryManager::getInstance()->checkBuild($lang, $xmlDetails);
}
// Remove the lock File
$lock->release();
// Send output into a log file
- LogManager::getInstance()->saveOutputLog('log_check_build', $output);
+ LogManager::getInstance()->saveOutputLog('log_check_build_'.$lang, $return["logContent"]);
+ // If the state of this build is ko, we save it into DB
+ if( $return["state"] == 'ko' ) {
+ LogManager::getInstance()->saveFailedBuild($lang, $return["logContent"]);
+ }
+
return JsonResponseBuilder::success();
}
@@ -1100,16 +1111,34 @@
}
/**
- * Get data about the status of the build
+ * Get the content of a failed build
*/
- public function getBuildStatusData()
+ public function getFailedBuildData()
{
AccountManager::getInstance()->isLogged();
- $r = LogManager::getInstance()->getBuildLogStatus();
+ $idFailedBuild = $this->getRequestVariable('idFailedBuild');
+ $r = LogManager::getInstance()->getFailedBuildData($idFailedBuild);
+
return JsonResponseBuilder::success(
array(
+ 'mess' => $r
+ )
+ );
+ }
+
+ /**
+ * Get all failed build
+ */
+ public function getFailedBuild()
+ {
+ AccountManager::getInstance()->isLogged();
+
+ $r = LogManager::getInstance()->getFailedBuild();
+
+ return JsonResponseBuilder::success(
+ array(
'nbItems' => $r['nb'],
'Items' => $r['node']
)
Modified: web/doc-editor/trunk/php/LogManager.php
===================================================================
--- web/doc-editor/trunk/php/LogManager.php 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/php/LogManager.php 2009-12-16 22:48:36 UTC (rev 292225)
@@ -118,31 +118,72 @@
*/
public function readOutputLog($file)
{
- return file_get_contents(DOC_EDITOR_VCS_PATH . '../.' . $file);
+
+ return $this->highlightBuildLog(file_get_contents(DOC_EDITOR_VCS_PATH . '../.' . $file));
}
/**
- * Save buildLog status.
+ * Save failed build log.
*
* @param $lang The lang checked
- * @param $status The status of the build. 0 if the build is broken, 1 otherwise.
+ * @param $log The content of the log
*/
- public function saveBuildLogStatus($lang, $status)
+ public function saveFailedBuild($lang, $log)
{
$s = sprintf(
- 'INSERT INTO `buildLog` (`project`, `lang`, `status`, `date`)
+ 'INSERT INTO `failedBuildLog` (`project`, `lang`, `log`, `date`)
VALUES ("php","%s", "%s", now())',
- $lang, $status
+ $lang, DBConnection::getInstance()->real_escape_string(json_encode($log))
);
DBConnection::getInstance()->query($s);
}
/**
- * Get buildLog data.
+ * Highlight buildLog with some colors.
+ *
+ * @param $content The content of the log we want to highlight
+ * @return The log highlighted
*/
- public function getBuildLogStatus()
+ public function highlightBuildLog($content)
{
- $s = 'SELECT `id`, `lang`, `status`, `date` FROM `buildLog`';
+
+ $reg_red = array(
+ '/(Warning: )/',
+ '/(Notice: )/',
+ '/(Eyh man. No worries. Happ shittens. Try again after fixing the errors above.)/'
+ );
+
+ $reg_blue = array(
+ '/(Loading and parsing manual.xml...)/',
+ '/(Checking )/',
+ '/(Saving it...)/',
+ '/(Generating )/',
+ '/( on line )/',
+ '/(line: )/',
+ '/(Creating file )/'
+ );
+
+ $content = preg_replace(
+ $reg_red,
+ '<span style="color: #c22900; font-weight: bold;">$1</span>',
+ $content
+ );
+
+ $content = preg_replace(
+ $reg_blue,
+ '<span style="color: #418bd4; font-weight: bold;">$1</span>',
+ $content
+ );
+
+ return $content;
+ }
+
+ /**
+ * Get the list of failed build.
+ */
+ public function getFailedBuild()
+ {
+ $s = 'SELECT `id`, `lang`, `date` FROM `failedBuildLog`';
$r = DBConnection::getInstance()->query($s);
$node = array();
@@ -152,6 +193,22 @@
return array('nb' => $r->num_rows, 'node' => $node);
}
+
+ /**
+ * Get the data about a failed build.
+ *
+ * @param $id The id of the failed build into DB we want to retrieve
+ * @return The content of this failed build
+ */
+ public function getFailedBuildData($id)
+ {
+ $s = 'SELECT `log` FROM `failedBuildLog` WHERE `id`=\''.$id.'\'';
+ $r = DBConnection::getInstance()->query($s);
+
+ $a = $r->fetch_object();
+
+ return $this->highlightBuildLog(json_decode($a->log));
+ }
}
?>
Modified: web/doc-editor/trunk/php/RepositoryFetcher.php
===================================================================
--- web/doc-editor/trunk/php/RepositoryFetcher.php 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/php/RepositoryFetcher.php 2009-12-16 22:48:36 UTC (rev 292225)
@@ -164,7 +164,7 @@
$m = $this->getModifies();
$s = sprintf(
- 'SELECT * FROM `files` WHERE `lang` = "%s" AND reviewed != \'yes\'',
+ 'SELECT * FROM `files` WHERE `lang` = "%s" AND reviewed != \'yes\' LIMIT 100',
$vcsLang
);
$r = DBConnection::getInstance()->query($s);
Modified: web/doc-editor/trunk/php/RepositoryManager.php
===================================================================
--- web/doc-editor/trunk/php/RepositoryManager.php 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/php/RepositoryManager.php 2009-12-16 22:48:36 UTC (rev 292225)
@@ -65,13 +65,13 @@
/**
* CleanUp the dataBase before check the build.
- * We only stock in DB the last status for one language.
+ * We only stock in DB the last failed build on a month.
*
* @see checkBuild
*/
public function cleanUpBeforeCheckBuild()
{
- DBConnection::getInstance()->query("TRUNCATE TABLE `buildLog`");
+ DBConnection::getInstance()->query("DELETE FROM `failedBuildLog` WHERE `date` < date_sub(now(),interval 1 month)");
}
/**
@@ -92,32 +92,46 @@
}
/**
- * Check the build of your file (using configure.php script).
+ * Check the build of the documentation (using configure.php script).
* PHP binary should be in /usr/bin
*
+ * @param $lang The lang of the documentation we want to check the build. We must take out $lang to be able to use this method from cron script on multiple language
* @param $enable_xml_details Indicate whether the checking includes xml-details
* @return The output log.
*/
- public function checkBuild($enable_xml_details=false)
+ public function checkBuild($lang, $enable_xml_details="false")
{
+
+ $return = Array(
+ "state" => "ok",
+ "logContent" => ""
+ );
+
$cmd = 'cd '.DOC_EDITOR_VCS_PATH.'/doc-base/;'
.'/usr/bin/php configure.php '
- .'--with-lang='.AccountManager::getInstance()->vcsLang.' --disable-segfault-error';
+ .'--with-lang='.$lang.' --disable-segfault-error';
- if ($enable_xml_details) {
+ if ( $enable_xml_details == "true" ) {
$cmd .= ' --enable-xml-details';
}
$cmd .= ';';
- $output = array();
- exec($cmd, $output);
+ $trial_threshold = 3;
+ while ($trial_threshold-- > 0) {
+ $output = array();
+ exec($cmd, $output);
+ if (strlen(trim(implode('', $output))) != 0) break;
+ }
- // Format the output
- // TODO: extract the string replace outside this function
- $output = str_replace("Warning", '<span style="color: #FF0000; font-weight: bold;">Warning</span>', $output);
+ $return["logContent"] = $output;
- return $output;
+ // We save the result of this check only if it failed.
+ if (!strstr(implode(" ", $output), 'All good. Saving .manual.xml... done.')) {
+ $return["state"] = "ko";
+ }
+
+ return $return;
}
/**
@@ -846,7 +860,7 @@
$files[$i]->lang, $files[$i]->path, $files[$i]->name
);
DBConnection::getInstance()->query($query);
- }
+ }
}
/**
Modified: web/doc-editor/trunk/scripts/cron/check_build.php
===================================================================
--- web/doc-editor/trunk/scripts/cron/check_build.php 2009-12-16 22:40:17 UTC (rev 292224)
+++ web/doc-editor/trunk/scripts/cron/check_build.php 2009-12-16 22:48:36 UTC (rev 292225)
@@ -18,39 +18,36 @@
// For all language, we check the build
foreach (RepositoryManager::getInstance()->availableLang as $lang) {
- $cmd = 'cd '.DOC_EDITOR_VCS_PATH.'/doc-base/;/usr/bin/php configure.php --with-lang='.$lang.' --disable-segfault-error';
- $output = array();
- exec($cmd, $output);
+ $return = RepositoryManager::getInstance()->checkBuild($lang);
- $m = implode("\n", $output);
- $msg = "Your documentation is broken. The build is done on Friday.
+ // What we must do when the build failed
+ if( $return["state"] == "ko" ) {
+ $msg = "Your documentation is broken. The build is done on Friday.
+
Please, try to fix it *quickly*.
Here is the output of the configure.php script :
=============================
-$m
+".implode("\n", $return["logContent"])."
--
This email is send automatically by the PhpDocumentation Online Editor.
";
- $status = 1;
- // Send an email only if the build is broken
- if (!strstr($msg, 'All good. Saving .manual.xml... done.')) {
-
- $status = 0;
-
$to = "[email protected]";
$subject = "[DOC-".strtoupper($lang)."] - Your documentation is broken";
+ // We send an email for this failed build
AccountManager::getInstance()->email($to, $subject, $msg);
+
+ // We store it into DB
+ LogManager::getInstance()->saveFailedBuild($lang, $return["logContent"]);
}
- LogManager::getInstance()->saveBuildLogStatus($lang, $status);
}
?>