Created
May 14, 2014 02:28
-
-
Save anonymous/335cb8ffbe8e23226482 to your computer and use it in GitHub Desktop.
Client side svn commit hook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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