用Groovy搜索Subversion日志

有时候,我想按作者,修订范围和/或提交消息快速搜索Subversion存储库。 Krzysztof Kotowicz 用svn-grep发布了博客文章Grep Subversion日志消息,其中引入了svn-grep ,这是一个bash脚本,使用了命令行XML工具包xmlstarlet在Windows上可以使用 xmlstarlet)。 这本身就是一个非常有用的脚本,但是它为我提供了一个基于Groovy的脚本的想法,该脚本可以在多个(所有JVM支持的)平台上运行。

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}"
}

使该脚本更易于编写的一件事是Subversionlog命令具有使用–xml标志XML格式写入其输出的功能。 尽管近年来XML一直受到广泛的批评,但是我对XML可用性的满意之处之一是广泛的工具支持编写和读取XML。 Subversion用XML编写某些类型的输出的能力就是一个很好的例子。 如果没有XML,该脚本将需要编写自定义的解析代码以解析非标准SVN日志输出。 因为Subversion支持为其输出写入标准XML格式,所以任何支持XML的工具都可以读取它。 在这种情况下,我利用了Groovy极其简单的XML Slurping (XML解析)功能。

该脚本还使用了Groovy的增强型(GDK)Process类,正如我在最近的文章《 使用Groovy编写脚本的崇高简单性》中所简要描述的那样。

脚本中使用了Groovy的内置命令行支持CliBuilder )来接受用于缩小搜索范围的参数(例如适用的修订版,提交的作者或用于搜索提交注释的字符串)。 一个必需的参数是“目标”,可以是文件,目录或URL。

该脚本引用了一个名为LogEntry的Groovy类,然后显示该类的代码清单。

LogEntry.groovy

@groovy.transform.Canonical
class LogEntry
{
   int revision
   String author
   String date
   String message
}

外观简单的LogEntry它最初出现时要强大得多。 因为是Groovy,所以自动为四个属性提供了setter / getter方法。 感谢@Canonical批注 ,它还支持构造函数equalshashCodetoString方法。 换句话说,总共少于十行的此类具有存取器和更改器方法以及为此适当覆盖的通用类方法。

结论

Groovy提供了许多功能来简化脚本编写。 在本文中,我使用了一个通过Subversion log命令(及其--xml选项)“搜索” Subversion提交的示例,以演示其中一些有用的Groovy脚本功能(命令行参数解析,本机操作系统集成和简单的XML)。解析)。 在此过程中,还使用了Groovy的一些不错的语法优势(闭包,动态类型,GString值占位符)。

参考:Inspired by Actual Events博客上,我们的JCG合作伙伴 Dustin Marx 使用Groovy搜索Subversion日志

翻译自: https://www.javacodegeeks.com/2014/01/searching-subversion-logs-with-groovy.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值