Gradleを試行してみて

ここ最近、ビルドツールにGradleを使ってます。Mavenは柔軟性がなく、複雑なことをやろうとすると結局maven-antrun-pluginでAntスクリプトをPOMに埋め込むなんてことになってしまうけど、Gradleはその点自由度はかなり高い。だってGroovyでそのまま書けますからね。

Antで書くくらいならGradleでいいんじゃない?と思ってます。理由は以下。

  • GradleだとAntタスクをそのまま使える。
    • ant.タスク名(…)でそのまま使えるので、Antになれた人でもとっつきやすい。独自に作りこんだAntタスク資産もそのまま使えますしね。
  • Groovyが書けるので、条件分岐や繰り返しも思いのまま。
    • ant-contribを使ってAntでもできるけど、XMLで書くくらないならGroovyでさくっと書いた方が楽だし見やすいでしょ。
  • Java、Groovyの色んな外部ライブラリも簡単に使える。
    • コードがそのまま書けるので簡単に組み込めます。Antタスク化しなくても良い。メソッド化して共通化処理化も簡単にできます。

複雑なビルド手順が必要であればGradleの方が素直に書けると思います。逆にシンプルなビルドで十分な物であれば、MavenでPOMを定義して終わり、が良いと思う。

例えば、最近自動化した処理が以下なのですが、、、

  • SVNから最新のタグをチェックアウト
  • HEADをチェックアウト
  • 上記2つの変更行数を計算する(これは専用のプログラムで処理)

というものがありました。Antでもがんばればできるのかもしれないですけど、Antタスクを自作した方が楽そうです(特に、最新のタグ名を判別するあたり)。でもGradleであれば、Groovyのパワーを借りて数行で実現できます。

workDir = '/tmp'
moduleName = 'sample'
trunkBaseUrl = "http://example.org/svn/${moduleName}/trunk"
tagBaseUrl = "http://example.org/svn/${moduleName}/tags"

task diff << {
    //svn listでタグ一覧を取得(残念ながらantタスクでは未実装なのでexecタスクで)
    ant.exec(executable: "svn", dir: ".", output: 'svnlist.log') {
        arg(line: "list --xml ${tagBaseUrl}")
    }

    //svn listの結果をパース
    root = new XmlParser().parseText('svnlist.log')
    entries = root.list.entry.collect{ [it.name.text(), it.commit.date.text()] }
    //日付でソート
    tagNames = entries.sort{ x, y -> y[1] <=> x[1] }.collect{ it[0] }

    //最新のタグURL
    latestTagName = tagNames[0]

    //タグをチェックアウト
    ant.svn(username: SVN_USER, password: SVN_PASS) {
        checkout(url: "${tagBaseUrl}/${latestTagName}", revision: 'HEAD', destPath: "${workDir}/${latestTagName}/${moduleName}")
    }

    //trunkをチェックアウト
    ant.svn(username: SVN_USER, password: SVN_PASS) {
        checkout(url: "${trunkBaseUrl}", revision: 'HEAD', destPath: "${workDir}/latest/${moduleName}")
    }

    //別ツールで変更行数を集計
    ・・・
}}


また、外部ライブラリの使用例として、以下のようにTracからXML-RPCで情報引っ張ってきてごにょごにょすることも簡単にできますよ。

//groovy-xmlrpc-0.7.jarを使用するのでビルド時のクラスパスに追加
buildscript  {
    dependencies {
        classpath files('lib/groovy-xmlrpc-0.7.jar')
    }
}

task trac << {
    def serverProxy = new groovy.net.xmlrpc.XMLRPCServerProxy("http://example.org/trac/sample/xmlrpc", true)

    //Ticket情報を取得
    ticket = serverProxy.ticket.get(ticket_id)

    //取得したTicketの概要を標準出力に出力
    println ticket[3]['summary']
}

というわけで、複雑なことをやりたい場合はGradleが今のところ個人的にはオススメです。