Pages
-
Recent Posts
- Revolving Door: MPAA Hires Chief USTR Negotiator Behind ACTA And TPP’s IP Chapter
- Copyright Maximalists’ Incredible Sense Of Entitlement: If It Challenges The Biz Model We Chose, It Must Be Illegal
- Turkey’s Prime Minister Sues His Own Country Over Twitter
- Picturefill 2
- Police File On Student ‘Bullied Into Committing Suicide’ Strangely Lacking In Evidence Of Bullying
Archives
- April 2014
- March 2014
- February 2014
- January 2014
- December 2013
- November 2013
- October 2013
- September 2013
- August 2013
- July 2013
- June 2013
- May 2013
- April 2013
- March 2013
- February 2013
- January 2013
- December 2012
- November 2012
- October 2012
- September 2012
- August 2012
- July 2012
- June 2012
- May 2012
- April 2012
- March 2012
- February 2012
- January 2012
- December 2011
- November 2011
- October 2011
- September 2011
- August 2011
- July 2011
- June 2011
- May 2011
- April 2011
- March 2011
- February 2011
- January 2011
- December 2010
- November 2010
- October 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- March 2010
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- December 2008
- November 2008
- October 2008
Meta
Category Archives: XML
PHPHOST BLOG
Web Hosting Related Articles You May Need
Searching Subversion Logs with Groovy
There are times when I want to quickly search a Subversion repository by author, by range of revisions, and/or by commit messages. Krzysztof Kotowicz has posted the blog post Grep Subversion log messages with svn-grep that introduces svn-grep, a bash script making use of the command line XML toolkit called xmlstarlet (xmlstarlet is also available on Windows). This is a pretty useful script in and of itself, but it gave me an idea for a Groovy-based script that could run on multiple (all JVM-supported) platforms.
searchSvnLog.groovy
#!/usr/bin/env groovy
//
// searchSvnLog.groovy
//
def cli = new CliBuilder(
usage: 'searchSvnLog.groovy -r <revision1> -p <revision2> -a <author> -s <stringInMessage>')
import org.apache.commons.cli.Option
cli.with
{
h(longOpt: 'help', 'Usage Information', required: false)
r(longOpt: 'revision1', 'First SVN Revision', args: 1, required: false)
p(longOpt: 'revision2', 'Last SVN Revision', args: 1, required: false)
a(longOpt: 'author', 'Revision Author', args: 1, required: false)
s(longOpt: 'search', 'Search String', args: 1, required: false)
t(longOpt: 'target', 'SVN target directory/URL', args: 1, required: true)
}
def opt = cli.parse(args)
if (!opt) return
if (opt.h) cli.usage()
Integer revision1 = opt.r ? (opt.r as int) : null
Integer revision2 = opt.p ? (opt.p as int) : null
if (revision1 != null && revision2 != null && revision1 > revision2)
{
println "It makes no sense to search for revisions ${revision1} through ${revision2}."
System.exit(-1)
}
String author = opt.a ? (opt.a as String) : null
String search = opt.s ? (opt.s as String) : null
String logTarget = opt.t
String command = "svn log -r ${revision1 ?: 1} ${revision2 ?: 'HEAD'} ${logTarget} --xml"
def proc = command.execute()
StringBuilder standard = new StringBuilder()
StringBuilder error = new StringBuilder()
proc.waitForProcessOutput(standard, error)
def returnedCode = proc.exitValue()
if (returnedCode != 0)
{
println "ERROR: Returned code ${returnedCode}"
}
def xmlLogOutput = standard.toString()
def log = new XmlSlurper().parseText(xmlLogOutput)
def logEntries = new TreeMap<Integer, LogEntry>()
log.logentry.each
{ svnLogEntry ->
Integer logRevision = Integer.valueOf(svnLogEntry.@revision as String)
String message = svnLogEntry.msg as String
String entryAuthor = svnLogEntry.author as String
if ( (!revision1 || revision1 <= logRevision)
&& (!revision2 || revision2 >= logRevision)
&& (!author || author == entryAuthor)
&& (!search || message.toLowerCase().contains(search.toLowerCase()))
)
{
def logEntry =
new LogEntry(logRevision, svnLogEntry.author as String,
svnLogEntry.date as String, message)
logEntries.put(logRevision, logEntry)
}
}
logEntries.each
{ logEntryRevisionId, logEntry ->
println "${logEntryRevisionId} : ${logEntry.author}/${logEntry.date} : ${logEntry.message}"
}
One thing that makes this script much easier to write is the ability of Subversion‘s log command to write its output in XML format with the –xml flag. Although XML has been the subject of significant criticism in recent years, one of the things I’ve liked about its availability is the widespread tool support for writing and reading XML. Subversion’s ability to write certain types of output in XML is a good example of this. Without XML, the script would have required custom parsing code to be written to parse the non-standard SVN log output. Because Subversion supports writing to the standard XML format for its output, any XML-aware tool can read it. In this case, I leveraged Groovy’s incredibly easy XML slurping (XML parsing) capability.
The script also uses Groovy’s enhanced (GDK) Process class as I briefly described in my recent post Sublime Simplicity of Scripting with Groovy.
Groovy’s built-in command-line support (CliBuilder) is used in the script to accept parameters for narrowing the search (such as applicable revisions, authors who committed, or strings to search the commit comments for). The one required parameter is the “target” which can be a file, directory, or URL.
The script references a Groovy class called LogEntry and the code listing for that class is shown next.
LogEntry.groovy
@groovy.transform.Canonical
class LogEntry
{
int revision
String author
String date
String message
}
That simple-looking LogEntry
class is much more powerful than it might first appear. Because it’s Groovy, there are automatically setter/getter methods available for the four attributes. Thanks to the @Canonical annotation, it also supports a constructor, equals, hashCode, and toString methods. In other words, this class of under ten lines total has accessor and mutator methods as well as common class methods overridden appropriately for it.
Conclusion
Groovy offers numerous features to make script writing easier. In this post, I used an example of “searching” Subversion commits via the Subversion log
command (and its --xml
option) to demonstrate some of these useful Groovy scripting features (command line parameter parsing, native operating system integration, and easy XML parsing). Along the way, some of Groovy’s nice syntax advantages (closures, dynamic typing, GString value placeholders) were also used.
Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)
Posted in Groovy, subversion, Syndicated, XML
Comments Off on Searching Subversion Logs with Groovy
Escaping XML with Groovy 2.1
When posting source code to my blog, I often need to convert less than signs (<), and greater than signs (>) to their respective entity references so that they are not confused as HTML tags when the browser renders the output. I have often done t… Continue reading
Posted in Groovy, Syndicated, XML
Comments Off on Escaping XML with Groovy 2.1
[one-liner]: Commenting out a block in an XML file using sed
Background
This issue came up recently where I needed to programmatically comment out a section of tags in an XML file.
1
2
3
4
<login-module code="org.dcm4chex.archive.security.TrustLoginModule"
flag = "required" >
[…] Continue reading
Posted in one-liner, sed, Syndicated, tip, tips & tricks, XML
Comments Off on [one-liner]: Commenting out a block in an XML file using sed
NetBeans (7.0.1) Has An XML Schema Editor!
Just after clicking on the “Publish Post” button to publish my latest blog post (Adding Common Methods to JAXB-Generated Java Classes (JAXB2 Basics Plugins)), I saw Geertjan Wielenga’s post XML Schema Editor in NetBeans IDE 7.0.1. The irony is that I h… Continue reading
Posted in NetBeans, Syndicated, XML
Comments Off on NetBeans (7.0.1) Has An XML Schema Editor!
The New XML Stack in JDK 7
In the summary of new JDK 7 features, one of the categories is called Web and its major subcategory is Update the XML Stack. This support is available as of Milestone 12 (M12 AKA “Developer Preview” AKA “beta release”) and is described as “Upgrade the … Continue reading
Posted in Java SE 7, Syndicated, XML
Comments Off on The New XML Stack in JDK 7
Recent Posts of Significant Interest (Java Security, XML, Cloud Computing)
I maintain a list of topics that I would like to blog on sometime in the future. This list continues to grow as I cannot blog quickly enough to keep up with the ideas. In some cases, I simply cannot write the full blog post I’d like in response to a re… Continue reading
Posted in Cloud Computing, Java (General), Syndicated, XML
Comments Off on Recent Posts of Significant Interest (Java Security, XML, Cloud Computing)
Generating XML Schema with schemagen and Groovy
I have previously blogged on several utilitarian tools that are provided with the Java SE 6 HotSpot SDK such as jstack, javap, and so forth. I focus on another tool in the same $JAVA_HOME/bin (or %JAVA_HOME%\bin directory: schemagen. Although schemagen… Continue reading
Posted in Groovy, Java (General), Java SE 6, Syndicated, XML
Comments Off on Generating XML Schema with schemagen and Groovy
Slurping XML with Groovy
In the early days of using Java in conjunction with XML, it often seemed more difficult than it should be to use the Java programming language with the XML markup language. Besides the non-trivial and often differently implemented DOM and SAX APIs, si… Continue reading
Posted in Groovy, Syndicated, XML
Comments Off on Slurping XML with Groovy