Skip to content

Instantly share code, notes, and snippets.

@joho
Created February 17, 2009 00:01
Show Gist options
  • Save joho/65477 to your computer and use it in GitHub Desktop.
Save joho/65477 to your computer and use it in GitHub Desktop.
SVN post commit diff email script in ruby
#!/usr/bin/ruby -w
# Send svn checkin email, based on a script by Adam Doppelt,
# in turn based on a script by Elliott Hughes.
# Paste this into a file called "post-commit" in your repo's hooks
# folder
# jb - http://whoisjohnbarton.com
require 'cgi'
require 'net/smtp'
# constants
SMTP_HOST = 'localhost'
FROM_ADDRESS = "CHANGE THIS"
TO_ADDRESSES = ["CHANGE THIS", "AND THIS TOO"]
SVNLOOK = "/usr/bin/svnlook"
# convert a list of files to HTML
def filesToHtml(title, list, revision = nil)
return "" if list.length == 0
# truncate if too big
list[200..-1] = "..." if list.length > 200
result = ""
result << "\n<h3>#{title}</h3>\n"
result << "<div class=\"files\">\n"
list.each do |file|
result << " "
result << CGI.escapeHTML(file)
result << "<br/>\n"
end
result << "</div>\n"
result
end
# Subversion's commit-email.pl suggests that svnlook might create files.
Dir.chdir("/tmp")
# process ARGV
repo = ARGV.shift
revision = ARGV.shift
raise "bad args" if !repo || !revision
#
# Get the overview information.
#
info = `#{SVNLOOK} info #{repo} -r #{revision}`.split("\n")
author = info.shift
date = info.shift
size = info.shift
subject = info[0]
comment = info.join("\n")
#
# iterate changed files
#
added = []
modified = []
removed = []
props_modified = []
`#{SVNLOOK} changed #{repo} -r #{revision}`.split("\n").each do |line|
op = line[0,1]
props = line[1,1]
file = line[4..-1]
# escape the filename
file = CGI.escapeHTML(file)
case op
when 'A' then added.push(file)
when 'U' then modified.push(file)
when 'D' then removed.push(file)
end
props_modified.push(file) if props == 'U'
end
#
# build the message body
#
body = <<EOF
<html>
<head>
<style type="text/css">
.main {
font : 10pt verdana;
background: white;
width: 95%
}
.main h3 {
margin: 15px 0px 5px 0px;
}
.comment {
border: 1px solid #dddddd;
padding: 5px;
}
.files {
border: 1px solid #dddddd;
padding: 5px;
background: #eeeeff;
}
</style>
</head>
<body>
<div class="main">
<h3>Revision #{revision} by #{CGI.escapeHTML(author)}</h3>
<div class="comment">
#{CGI.escapeHTML(comment).split("\n").join("<br/>")}
</div>
#{filesToHtml("Added Paths", added)}
#{filesToHtml("Modified Paths", modified, revision)}
#{filesToHtml("Removed Paths", removed)}
#{filesToHtml("Property Changed", props_modified)}
</div>
</body>
</html>
EOF
#
# Write the mail headers
#
header = ""
header << "Subject: [svn] [#{revision}] #{subject}\n"
header << "MIME-Version: 1.0\n"
header << "Content-Type: text/html; charset=UTF-8\n"
header << "Content-Transfer-Encoding: 8bit\n"
header << "\n"
#
# Send the mail.
#
begin
Net::SMTP.start(SMTP_HOST) do |smtp|
smtp.sendmail header + body, FROM_ADDRESS, TO_ADDRESSES
end
rescue
exit 1
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment