Sending a mail with aggregated Subversion commit messages

I have stressed the importance of writing sensible commit messages to the other guys at work so it’s easier to see what changes people are doing to the different repositories. Now we have decided to send out a list of commit messages every night to the development team using a cron script. The mail includes all messages from yesterday grouped by the different repositories we have. The list also includes links to the changesets in the different trac instances that can be clicked to see the full diff.

The cronscript is a small PHP script that I thought I might include with you. To be able to use the code out of the box you will need the mod_dav Apache2 module to be able to interact with Subversion via http(s). You can have a look at my Apache+SSL+Subversion+Trac HOWTO for more information on how to install this. You will also need Zend Framework since the code uses Zend_Mail. It’s a pretty small task to rewrite this to use PHP’s mail() instead but that I’ll leave to you. Enough chit chat, here is the code:

<?php
// Date format to use in the arguments to "svn log"
$dateFormat = 'Y-m-d';

// Timestamps for today and yesterday
$today = time();
$yesterday = strtotime('-1 day');

// URL to repos and trac instance
$svnUrl = 'http://yourdomain.com/svn';
$tracUrl = 'http://yourdomain.com/trac';

// Array of repositories to include in the mail
$repositories = array(
    // Include the names of the repositories here. The names will be places after the $svnUrl you
    // specified above
);

// Recipient of the mail
$recipient = 'mail@example.com';

// Initialize mail body
$body = '';

// Loop through each repository
foreach ($repositories as $r) {
    // Initialize output from command
    $output = array();

    // Run svn log
    $url = rtrim($svnUrl, '/') . '/' . $r;
    exec('svn log --xml -r {' . date($dateFormat, $yesterday) . '}:{' . date($dateFormat, $today) . '} ' . $url, $output);

    // Create a string of the output
    $output = implode('', $output);

    // Parse as XML
    $xml = simplexml_load_string($output);

    if ($xml->logentry) {
        $messages = array();

        // Loop through the log entries
        foreach ($xml->logentry as $entry) {
            // Create timestamp so we can compare
            $date = strtotime($entry->date);

            // Only include commits that occured yesterday. Read more about how Subversion deals
            // with dates on http://svnbook.red-bean.com/en/1.5/svn.tour.revs.specifiers.html#svn.tour.revs.dates
            if ($date < $yesterday) {
                continue;
            }

            // Default message
            $commitMessage = '<empty message>';

            if (!empty($entry->msg)) {
                $commitMessage = $entry->msg;
            }

            // Componse URL to changeset in the trac instance
            $url = rtrim($tracUrl, '/') . '/' . $r . '/changeset/' . $entry['revision'];

            $msg  = date('Y-m-d H:i:s', $date) . PHP_EOL;
            $msg .= $entry->author . ': ' . $commitMessage . PHP_EOL;
            $msg .= str_repeat(' ', strlen($entry->author) + 2) . $url . PHP_EOL;

            $messages[] = $msg;
        }

        // Any messages for this repository?
        if (count($messages)) {
            $body .= str_repeat('-', 60) . PHP_EOL;
            $body .= 'Repository: ' . $r . PHP_EOL . PHP_EOL;

            $body .= implode(PHP_EOL, $messages) . PHP_EOL;
        }
    }
}

// Do we have any messages at all?
if (!empty($body)) {
    // Prefix body with a paragraph
    $body = 'Commit messages from yesterday, grouped by repository:' . PHP_EOL . $body;

    require_once 'Zend/Mail.php';

    // Send mail
    $mail = new Zend_Mail();
    $mail->addTo($recipient);
    $mail->setSubject('Commit messages from ' . date($dateFormat, $yesterday));
    $mail->setBodyText($body);
    $mail->send();
}

If your repositories requires authentication you will need to authenticate the user who will run the crontab before running this script. You can for instance log in as the user running the cronscript and manually do a svn log <url>. When you enter the username and password it will be stored inside the ~/.subversion directory so that the user does not have to authenticate the next time he/she interacts with Subversion via http(s).

Advertisements
This entry was posted in PHP, Technology, Work related and tagged , , , , , . Bookmark the permalink.

2 Responses to Sending a mail with aggregated Subversion commit messages

  1. Erlend says:

    Ikke dumt, vil nok få positiv effekt.

  2. christer says:

    @Erlend Folk ble flinkere til å skrive beskjeder med en gang i alle fall.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s