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&amp;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('zend-engine-...@lists.php.net', 'doc-...@lists.php.net'),
     '|^php/php-src/Zend|' => array('zend-engine-...@lists.php.net'),
     '|^php/php-src/TSRM|' => array('zend-engine-...@lists.php.net'),
+    '|^php/php-src|' => array('php-cvs@lists.php.net'),

     // phpdoc
     '|^phpdoc/doc-base|' => array('doc-...@lists.php.net'),
@@ -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[...@php.net>\r\n" .
+$msg_headers = "From: {$fullname} <{$commit_info['author']...@php.net>\r\n" .
                "To: " . implode(', ', $emails_to) . "\r\n" .
                "Message-ID: <svn{$message...@svn.php.net>\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

Reply via email to