gwynne Mon, 20 Jul 2009 04:40:31 +0000
Revision: http://svn.php.net/viewvc?view=revision&revision=284413
Changed paths:
A SVNROOT/commit-bugs.php
U SVNROOT/commit-email.php
A SVNROOT/commit-svnroot.php
U SVNROOT/post-commit
Log:
- reorganized the post-commit hook quite a bit to load common information and
call sub-hooks for various tasks
- added a catch-all email for php/php-src/ to ensure some emails get where
they're going
- moved Rasmus' bug stuff to its own file
- moved the SVNROOT check to its own file as well
- make a passing attempt to marshal back to the client the results of SVNROOT
updates
- actually show the client an error when SMTP connection fails
- use ===/!== instead of ==/!= in a couple places as a matter of style
Added: SVNROOT/commit-bugs.php
===================================================================
--- SVNROOT/commit-bugs.php (rev 0)
+++ SVNROOT/commit-bugs.php 2009-07-20 04:40:31 UTC (rev 284413)
@@ -0,0 +1,107 @@
+<?php
+
+// This script is intended to be called from post-commit. It assumes that all
+// the appropriate variables and functions are defined.
+
+// -----------------------------------------------------------------------------------------------------------------------------
+// Constants
+$version = substr('$Revision$', strlen('$Revision: '), -2);
+$bug_pattern = '/(?:(pecl|pear)\s*)?(?:bug|#)[\s#:]*([0-9]+)/iuX';
+$bug_url_prefixes = array(
+ 'pear' => 'http://pear.php.net/bugs',
+ 'pecl' => 'http://pecl.php.net/bugs',
+ '' => 'http://bugs.php.net',
+);
+$bug_rpc_url = 'http://bugs.php.net/rpc.php';
+$viewvc_url_prefix = 'http://svn.php.net/viewvc/?view=revision&revision=';
+
+// -----------------------------------------------------------------------------------------------------------------------------
+// Get the list of mentioned bugs from the commit log
+if (preg_match_all($bug_pattern, $commit_info['log_message'], $matched_bugs, PREG_SET_ORDER) < 1) {
+ // If no bugs matched, we don't have to do anything.
+ return;
+}
+
+// -----------------------------------------------------------------------------------------------------------------------------
+// Process the matches
+$bug_list = array();
+foreach ($matched_bugs as $matched_bug) {
+ $bug = array();
+ $bug['project'] = isset($matched_bug[1]) ? $matched_bug[1] : '';
+ $bug['number'] = intval($matched_bug[2]);
+ $bugid = $bug['project'] . $bug['number'];
+ $bug['url_prefix'] = isset($bug_url_prefixes[$bug['project']]) ? $bug_url_prefixes[$bug['project']] : $bug_url_prefixes[''];
+ $bug['url'] = $bug['url_prefix'] . '/' . $bug['number'];
+ $bug['status'] = 'unknown';
+ $bug['short_desc'] = '';
+ $bug_list[$bugid] = $bug;
+}
+
+// -----------------------------------------------------------------------------------------------------------------------------
+// Make an RPC call for each bug
+if (!$is_DEBUG) {
+ include __DIR__ . '/secret.inc';
+}
+foreach ($bug_list as &$bug) {
+ // Only do this for core PHP bugs
+ if ($bug['project'] !== '') {
+ continue;
+ }
+
+ $comment = "Automatic comment from SVN on behalf of {$commit_info['author']}\n" .
+ "Revision: {$viewvc_url_prefix}{$REV}\n" .
+ "Log: {$commit_info['log_message']}\n";
+
+ $postdata = array(
+ 'user' => $commit_info['author'],
+ 'id' => $bug['number'],
+ 'ncomment' => $comment,
+ 'MAGIC_COOKIE' => $is_DEBUG ? 'nonsense' : $SVN_MAGIC_COOKIE,
+ );
+ array_walk($postdata, create_function('&$v, $k', '$v = rawurlencode($k) . "=" . rawurlencode($v);'));
+ $postdata = implode('&', $postdata);
+
+ if ($is_DEBUG) {
+ print "DEBUG: Bug #{$bug['number']}: Would have posted this rawurlencoded string to {$bug_rpc_url}:\n{$postdata}\n";
+ if (mt_rand(0, 1) === 1) {
+ $bug['error'] = 'DEBUG-some kind of error';
+ } else {
+ $bug['status'] = 'DEBUG-unknown';
+ $bug['short_desc'] = "DEBUG-Bug #{$bug['number']}";
+ }
+ continue;
+ }
+ // Hook an env var so emails can be resent without messing with bugs
+ if (getenv('NOBUG')) {
+ continue;
+ }
+
+ $ch = curl_init();
+ curl_setopt_array(array(
+ CURLOPT_URL => $bug_rpc_url,
+ CURLOPT_RETURNTRANSFER => TRUE,
+ CURLOPT_POST => TRUE,
+ CURLOPT_CONNECTTIMEOUT => 5,
+ CURLOPT_TIMEOUT => 5,
+ CURLOPT_POSTFIELDS => $postdata,
+ ));
+
+ $result = curl_exec($ch);
+
+ if ($result === FALSE) {
+ $bug['error'] = curl_error($ch);
+ } else {
+ $bug_server_data = json_decode($result, TRUE);
+ if (isset($bug_server_data['result']['status'])) {
+ $bug['status'] = $bug_server_data['result']['status']['status'];
+ $bug['short_desc'] = $bug_server_data['result']['status']['sdesc'];
+ } else {
+ $bug['error'] = $bug_server_data['result']['error'];
+ }
+ }
+ curl_close($ch);
+}
+unset($SVN_MAGIC_COOKIE);
+
+// $bug_list is now available to later-running hooks
+?>
Property changes on: SVNROOT/commit-bugs.php
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Modified: SVNROOT/commit-email.php
===================================================================
--- SVNROOT/commit-email.php 2009-07-20 04:31:07 UTC (rev 284412)
+++ SVNROOT/commit-email.php 2009-07-20 04:40:31 UTC (rev 284413)
@@ -1,9 +1,7 @@
<?php
-// Note that this script is intended to be called from inside the post-commit
-// hook. It makes some assumptions: $REPOS and $REV are defined, the
-// run_svnlook() function is declared, $changed_paths and $dirs_changed are
-// determined.
+// This script is intended to be called from post-commit. It assumes that all
+// the appropriate variables and functions are defined.
// -----------------------------------------------------------------------------------------------------------------------------
// Constants
@@ -30,6 +28,7 @@
'|^php/ZendAPI|' => array('[email protected]', '[email protected]'),
'|^php/php-src/Zend|' => array('[email protected]'),
'|^php/php-src/TSRM|' => array('[email protected]'),
+ '|^php/php-src|' => array('[email protected]'),
// phpdoc
'|^phpdoc/doc-base|' => array('[email protected]'),
@@ -117,43 +116,11 @@
}
// -----------------------------------------------------------------------------------------------------------------------------
-// Get info from commit
-$commit_info = run_svnlook('info');
-$commit_user = trim($commit_info[0]);
-$commit_date = strtotime(substr($commit_info[1], 0, strlen("0000-00-00 00:00:00 +0000")));
-$commit_log = implode("\n", array_slice($commit_info, 3));
-// Support bug#1234 bug url extraction
-$bugs = preg_match_all("/(?:pecl|pear|)\\s*(?:bug|#)[\\s#:]*([0-9]+)/i", $commit_log, $bugs_array);
-
-// -----------------------------------------------------------------------------------------------------------------------------
-// Determine "from" address
-// Various repositories can play with this to read from their equivelant of the old cvsusers folder, or whatever else they like
-$usersDB = file(dirname(__FILE__) . '/users.db');
-$from = NULL;
-$saw_last_ISO = FALSE;
-foreach ($usersDB as $userline) {
- list ($username, $fullname, $email) = explode(":", trim($userline));
- if ($username === 'ladderalice') {
- $saw_last_ISO = TRUE;
- }
- if ($username === $commit_user) {
- if ($saw_last_ISO !== TRUE) {
- $fullname = iconv("ISO-8859-1", "UTF-8//TRANSLIT", $fullname);
- }
- $from = array($username, $fullname);
- break;
- }
-}
-if (is_null($from)) {
- die("Couldn't find user\n");
-}
-
-// -----------------------------------------------------------------------------------------------------------------------------
// Build list of e-mail addresses and parent changed path
$emails_to = array();
-$parent_path = $dirs_changed[0];
+$parent_path = $commit_info['dirs_changed'][0];
-foreach ($dirs_changed as $changed_path) {
+foreach ($commit_info['dirs_changed'] as $changed_path) {
foreach ($commit_email_list as $regex => $email_list) {
if (preg_match($regex, $changed_path, $matches) === 1) {
$emails_to = array_merge($emails_to, $email_list);
@@ -173,32 +140,18 @@
$emails_to = array_unique($emails_to);
// -----------------------------------------------------------------------------------------------------------------------------
-// Get diffs
-$diffs = run_svnlook('diff');
-$diffs = implode("\n", $diffs);
-$diffs_length = strlen($diffs);
+// Process diffs
+$diffs_length = strlen($commit_info['diffs']);
$diffs_string = ($diffs_length > 262144 ? "<diffs exceeded maximum size>" :
- ($diffs_length > 8192 ? NULL : $diffs));
+ ($diffs_length > 8192 ? NULL : $commit_info['diffs']));
// -----------------------------------------------------------------------------------------------------------------------------
// Build e-mail
-$boundary = sha1("{$commit_user}{$commit_date}");
-$messageid = "{$commit_user}-{$commit_date}-{$REV}-" . mt_rand();
+$boundary = sha1("{$commit_info['author']}{$commit_info['date']}");
+$messageid = "{$commit_info['author']}-{$commit_info['date']}-{$REV}-" . mt_rand();
$subject = "svn: " . ($parent_path === '' ? '/' : $parent_path);
-switch (substr(trim($changed_paths[0]),4)) {
- case 'pear': $bug_url = 'http://pear.php.net/bugs'; break;
- case 'pecl': $bug_url = 'http://pecl.php.net/bugs'; break;
- default: $bug_url = 'http://bugs.php.net'; break;
-}
-foreach($bugs_array[0] as $k=>$bug_match) {
- if(stristr($bug_match,'pecl')) $bug_urls[$k] = 'http://pecl.php.net/bugs';
- else if(stristr($bug_match,'pear')) $bug_urls[$k] = 'http://pear.php.net/bugs';
- else $bug_urls[$k] = $bug_url;
-
-}
-
-foreach ($changed_paths as $changed_path) {
+foreach ($commit_info['changed_paths'] as $changed_path) {
$changed_path = trim(strstr($changed_path, ' '));
if (substr($changed_path, -1) !== '/') {
$subject .= ' ' . substr($changed_path, strlen($parent_path));
@@ -206,46 +159,26 @@
}
$subject = substr($subject, 0, 950); // Max SMTP line length = 998. Some slop in this value.
-$fullname = "=?utf-8?q?" . imap_8bit(str_replace(array('?', ' '), array('=3F', '_'), $from[1])) . "?=";
+$fullname = "=?utf-8?q?" . imap_8bit(str_replace(array('?', ' '), array('=3F', '_'), $commit_info['author_name'])) . "?=";
-$msg_headers = "From: {$fullname} <{$from[[email protected]>\r\n" .
+$msg_headers = "From: {$fullname} <{$commit_info['author'][email protected]>\r\n" .
"To: " . implode(', ', $emails_to) . "\r\n" .
"Message-ID: <svn{[email protected]>\r\n" .
- "Date: " . date(DATE_RFC822, $commit_date) . "\r\n" .
+ "Date: " . date(DATE_RFC822, $commit_info['date']) . "\r\n" .
"Subject: {$subject}\r\n" .
"MIME-Version: 1.0\r\n" .
"Content-Type: multipart/mixed; boundary=\"{$boundary}\"\r\n";
$bugs_body = '';
-if ($bugs) {
- include '/home/svn/SVNROOT/secret.inc';
- $bugs_body = (count($bugs_array[1])>1) ? "Bugs: " : "Bug: ";
- foreach ($bugs_array[1] as $k=>$bug_id) {
- $bug_sdesc = '';
- $bug_status = '';
- if($bug_urls[$k]=='http://bugs.php.net') {
- $ch = curl_init('http://bugs.php.net/rpc.php');
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch, CURLOPT_POST, 1);
- $ncomment = "Automatic comment from SVN on behalf of {$from[0]}\n" .
- "Log: $commit_log\n" .
- "Revision: http://svn.php.net/viewvc?view=revision&revision={$REV}\n";
- curl_setopt($ch, CURLOPT_POSTFIELDS, "user=" . rawurlencode($from[0]) .
- "&id={$bug_id}" .
- "&ncomment=" . rawurlencode($ncomment) .
- "&MAGIC_COOKIE=$SVN_MAGIC_COOKIE");
- $ret = curl_exec($ch);
- if($ret !== false ) {
- $json = json_decode($ret,true);
- if(isset($json['result']['status'])) {
- $bug_status = ' ('.$json['result']['status']['status'].')';
- $bug_sdesc = ' '.$json['result']['status']['sdesc'];
- }
- }
- curl_close($ch);
+if (isset($bug_list) && count($bug_list) > 0) {
+ $bugs_body = count($bug_list) > 1 ? "Bugs: " : "Bug: ";
+ foreach ($bug_list as $n => $bug) {
+ if (isset($bug['error'])) {
+ $status = '(error getting bug information)';
+ } else {
+ $status = "({$bug['status']}) {$bug['short_desc']}";
}
- if($k) $bugs_body .= ' ';
- $bugs_body .= $bug_urls[$k]."/$bug_id{$bug_status}{$bug_sdesc}\r\n";
+ $bugs_body .= "{$bug['url']} {$status}\r\n ";
}
}
@@ -253,17 +186,17 @@
"Content-Type: text/plain; charset=\"utf-8\"\r\n" .
"Content-Transfer-Encoding: 8bit\r\n" .
"\r\n" .
- "{$commit_user}\t\t" . date(DATE_RFC2822, $commit_date) . "\r\n" .
+ "{$commit_info['author']}\t\t" . date(DATE_RFC2822, $commit_info['date']) . "\r\n" .
"\r\n" .
"Revision: http://svn.php.net/viewvc?view=revision&revision={$REV}\r\n" .
"\r\n" .
"Changed paths:\r\n" .
- "\t" . implode("\r\n\t", $changed_paths) . "\r\n" .
+ "\t" . implode("\r\n\t", $commit_info['changed_paths']) . "\r\n" .
"\r\n" .
"Log:\r\n" .
- $commit_log . "\r\n" .
- "$bugs_body\r\n" .
- $diffs_string;
+ "{$commit_info['log_message']}\r\n" .
+ "{$bugs_body}\r\n" .
+ str_replace("\n", "\r\n", $diffs_string);
if ($diffs_string === NULL) {
$msg_body .=
@@ -287,7 +220,7 @@
$socket = fsockopen($smtp_server, getservbyname('smtp', 'tcp'), $errno);
}
if ($socket === FALSE) {
- die("Couldn't connect to SMTP server {$smtp_server}. Errno: {$errno}.\n");
+ fail("Couldn't connect to SMTP server {$smtp_server}. Errno: {$errno}.\n");
}
fwrite($socket,
Added: SVNROOT/commit-svnroot.php
===================================================================
--- SVNROOT/commit-svnroot.php (rev 0)
+++ SVNROOT/commit-svnroot.php 2009-07-20 04:40:31 UTC (rev 284413)
@@ -0,0 +1,34 @@
+<?php
+
+// This script is intended to be called from post-commit. It assumes that all
+// the appropriate variables and functions are defined.
+
+// -----------------------------------------------------------------------------------------------------------------------------
+// Constants
+$version = substr('$Revision$', strlen('$Revision: '), -2);
+
+// -----------------------------------------------------------------------------------------------------------------------------
+// Check for a SVNROOT commit
+$SVNROOT_changed = FALSE;
+foreach ($commit_info['dirs_changed'] as $changed_path) {
+ if (substr($changed_path, 0, 7) == 'SVNROOT') {
+ $SVNROOT_changed = TRUE;
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------------------------------------------------------------
+// If SVNROOT had a commit, we need to update the admin copy
+if ($SVNROOT_changed) {
+ if ($is_DEBUG) {
+ print "Updating SVNROOT...\n";
+ }
+ chdir(__DIR__);
+ exec('exec svn update', $output, $status);
+ fwrite(stderr, implode("\n", $output) . "\n");
+ if ($status != 0) {
+ fail("svn update on SVNROOT failed with exit code {$status}!\n");
+ }
+}
+
+?>
Property changes on: SVNROOT/commit-svnroot.php
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Modified: SVNROOT/post-commit
===================================================================
--- SVNROOT/post-commit 2009-07-20 04:31:07 UTC (rev 284412)
+++ SVNROOT/post-commit 2009-07-20 04:40:31 UTC (rev 284413)
@@ -23,10 +23,13 @@
if (version_compare('5.2.0', PHP_VERSION, '>')) {
fail("Requires at least PHP 5.2.\n");
}
+if (!defined('__DIR__')) {
+ define('__DIR__', dirname(__FILE__));
+}
// -----------------------------------------------------------------------------------------------------------------------------
// Arguments
-if ($argc != 3) {
+if ($argc !== 3) {
fail("Pass exactly two arguments: REPOS and REV.\n");
}
$REPOS = $argv[1];
@@ -37,7 +40,7 @@
function run_svnlook($command)
{
exec('exec svnlook ' . escapeshellarg($command) . ' -r ' . escapeshellarg($GLOBALS['REV']) . ' ' . escapeshellarg($GLOBALS['REPOS']), $output, $status);
- if ($status != 0) {
+ if ($status !== 0) {
fail("svnlook failed with exit code {$status}\nOutput:\n" . implode("\n", $output) . "\n");
}
return $output;
@@ -45,35 +48,42 @@
// -----------------------------------------------------------------------------------------------------------------------------
// Build list of changes
-$changed_paths = run_svnlook('changed');
-$dirs_changed = run_svnlook('dirs-changed');
+$commit_info = array(
+ 'changed_paths' => run_svnlook('changed'),
+ 'dirs_changed' => run_svnlook('dirs-changed'),
+ 'author' => ($is_DEBUG && getenv("DEBUGUSER")) ? getenv("DEBUGUSER") : trim(implode('', run_svnlook('author'))),
+ 'log_message' => trim(implode('', run_svnlook('log'))),
+ 'date' => strtotime(substr(trim(implode('', run_svnlook('date'))), 0, strlen("0000-00-00 00:00:00 +0000"))),
+ 'diffs' => implode("\n", run_svnlook('diff')),
+);
// -----------------------------------------------------------------------------------------------------------------------------
-// Call e-mailer script
-require dirname(__FILE__) . '/commit-email.php';
-
-// -----------------------------------------------------------------------------------------------------------------------------
-// Check for a SVNROOT commit
-$SVNROOT_changed = FALSE;
-foreach ($dirs_changed as $changed_path) {
- if (substr($changed_path, 0, 7) == 'SVNROOT') {
- $SVNROOT_changed = TRUE;
+// Read the user database
+$usersDB = file(dirname(__FILE__) . '/users.db');
+$saw_last_ISO = FALSE;
+foreach ($usersDB as $userline) {
+ list ($username, $fullname, $email) = explode(":", trim($userline));
+ if ($username === 'ladderalice') {
+ $saw_last_ISO = TRUE;
}
+ if ($username === $commit_info['author']) {
+ if ($saw_last_ISO !== TRUE) {
+ $fullname = iconv("ISO-8859-1", "UTF-8//TRANSLIT", $fullname);
+ }
+ $commit_info['author_name'] = $fullname;
+ $commit_info['author_email'] = $email;
+ break;
+ }
}
+if (!isset($commit_info['author_name'])) {
+ fail("Couldn't find user\n");
+}
// -----------------------------------------------------------------------------------------------------------------------------
-// If SVNROOT had a commit, we need to update the admin copy
-if ($SVNROOT_changed) {
- if ($is_DEBUG) {
- print "Updating SVNROOT...\n";
- }
- chdir(dirname(__FILE__));
- exec('exec svn update', $output, $status);
- print implode("\n", $output) . "\n";
- if ($status != 0) {
- fail("svn update on SVNROOT failed with exit code {$status}!\n");
- }
-}
+// Call various sub-scripts
+require __DIR__ . '/commit-bugs.php';
+require __DIR__ . '/commit-email.php';
+require __DIR__ . '/commit-svnroot.php';
// -----------------------------------------------------------------------------------------------------------------------------
// Done!
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php