Skip to content

Instantly share code, notes, and snippets.

Created May 14, 2014 02:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/335cb8ffbe8e23226482 to your computer and use it in GitHub Desktop.
Save anonymous/335cb8ffbe8e23226482 to your computer and use it in GitHub Desktop.
Client side svn commit hook
#!/usr/bin/env groovy
import groovy.text.SimpleTemplateEngine
import java.text.SimpleDateFormat
def chill = 5 //min
def projects = [
// 'projectName1':/C:\Project\project1/
// 'projectName2':/C:\Project\project2/
]
def subject="[<%=rev%>] [SVN:<%=name%>] [Author:<%=author%>]"
def body = """<%=name%> revision <%=rev%> report
Author: <%=author%>
Date: <%=date%>
Log Message:
--------------------------------------------------
<%=log%>
--------------------------------------------------
<%=fulldiff%>
"""
//new! Rss feed template
def rssItem = """
<item>
<title><![CDATA[<%=subject%>]]></title>
<description><![CDATA[<pre><%=body%></pre>]]></description>
<dc:creator><![CDATA[<%=author%>]]></dc:creator>
<pubDate><%=date%></pubDate>
<guid isPermaLink="false"><%=guid%></guid>
</item>
"""
def engine = new SimpleTemplateEngine()
def BODY = engine.createTemplate(body)
def SUBJECT = engine.createTemplate(subject)
//rss
def RSS_ITEM = engine.createTemplate(rssItem)
def ps = new PrintStream(
new BufferedOutputStream(new FileOutputStream('svndiff.log')))
def printLog(def msg, def ps){
def df = new SimpleDateFormat()
println "[${df.format(new Date())}] $msg"
ps.println "[${df.format(new Date())}] $msg"
}
def parseLog(def log){
try{
def lines = []
new StringReader(log).eachLine{ line -> lines << line }
if(lines.size < 2) return;
def ret = [:]
def items = lines[1].split(/[|]/)
ret['rev'] = items[0].trim().substring(1)
ret['author'] = items[1]
ret['date'] = items[2]
ret['log'] = log
return ret
}catch (Exception e) {
e.printStackTrace()
return null
}
}
def getBASErev(def path){
def base = 'BASE'
"svn info -r BASE $path".execute().in.eachLine{
def m = it=~/Revision:\s+(\d+)/
if(m.matches()){ base = m.group(1) }
}
return base
}
while(true){
try{
projects.each{name, path ->
printLog("processing $name", ps)
def revisions =
"svn log -r BASE:HEAD --limit 30 --incremental $path"
.execute().text.split('-'*72)
def BASErev = getBASErev(path)
def lastrev = null
def logs = [['rev':'BASE']]
revisions.each{rev ->
def parsed = parseLog(rev)
if (parsed != null)logs << parsed
}
if(logs.size == 1){
printLog('already up to date, nothing to process', ps); return
}
def items = [];
for(int i =0; i< logs.size -1; i++){
def rev1 = logs[i], rev2 = logs[i+1]
if(rev2['rev'] == BASErev){ continue;} //no need to diff BASE
def diff =
"svn diff -r ${rev1['rev']}:${rev2['rev']} $path".execute().text
def s = SUBJECT.make([
rev: rev2['rev'], name: name,
author: rev2['author'] ]).toString()
def b = BODY.make([
name: name, rev: rev2['rev'],
author:rev2['author'], date: rev2['date'],
log: logs[i+1]['log'], fulldiff: diff
]).toString()
printLog( "changeset $s ...", ps)
items << RSS_ITEM.make(['subject':s, 'body':b,
'author': rev2['author'],
//here we assume the date is formatted as something like 2014-05-07 19:52:17 -0400 (Wed, 07 May 2014), which may not be true
//striping out the datestamp in parenthesis at the end
'date': rev2['date'].trim().replaceFirst(/[(].+?[)$]/, "").trim(),
'guid': UUID.randomUUID().toString() ]).toString()
lastrev = rev2['rev']
}
def outFileName = name.replaceAll(/\s+/, "_")+"_rss.xml"
new File(outFileName).withWriter{ out ->
out.writeLine("""
<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
<channel>
<title><![CDATA[$name]]></title>
<link>http://devnull.com</link>
<description><![CDATA[$name]]></description>
<language>en-us</language>
""".stripIndent())
items.each(){ item ->
out.writeLine(item)
}
out.writeLine("</channel></rss>")
}
//if everything finishes without problems
//bring the local to the last rev we had diffed
if(lastrev != null){
printLog("svn up -r $lastrev $path", ps) ;
"svn up -r $lastrev $path".execute() }
}
}catch(Exception e){
e.printStackTrace()
}
printLog('\nChilling out for 5 min ...\n', ps)
//chill out for 5 min
sleep chill*1000*60
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment