Gradle で環境ごとに構成を変更する

残念ながら ユーザガイドを見る限り、 現バージョン (1.0-milestone-1) の Gradle には 環境毎に構成を変更できるような機能 (Maven の profile のような機能) は 実装されていないようです。
実際に実務で使う場合、絶対に必要な機能だと思うのですが なぜないんだろう...

と思ったら、Groovy にあるじゃないですか!!
Groovy にはとっても便利な ConfigSlurper があります。
ConfigSlurper を使えば、簡単に 環境毎に構成を変更できます。
ConfigSlurper については id:fumokmm さんの GroovyのConfigSlurperがめっちゃ便利 が非常に参考になります。

ConfigSlurper では

environment.groovy
environments {
    deveropment {
        server {
            url = 'http://app:8080/settings
        }
    }
    test {
        server {
            url = 'http://app/settings
        }
    }
    production {
        server {
            url = 'https://app/settings
        }
    }
}
のように 1ファイルで全環境の構成を設定できるのですが、 ある程度の規模になるとファイルが肥大化して管理が難しくなります。
そこで 今回は
development.gradle
server {
    url = 'http://app:8080/settings
}
test.gradle
server {
    url = 'http://app/settings
}
production.gradle
server {
    url = 'https://app/settings
}
のように環境毎にファイルを分けてみました。
これらのファイルは プロジェクト直下の environment ディレクトリの下に作成します。

ちなみに 環境毎にファイルを分ける利点は それぞれのファイルの diff がとれるところではないでしょうか。
diff がとれれば、環境毎の設定の差異が一目で把握できるため、 自分はこの方法を使うことが多いです。

各環境毎にファイルを分けた場合

DEFAULT_ENV = 'development' 

if (!hasProperty('env')) {
    env = System.env['GRADLE_ENV'] ?: DEFAULT_ENV
}

url = file("environment/${env}.gradle").toURL()
config = new ConfigSlurper().parse(url);
のように config 変数に設定を読み込みます。
読み込んだ設定は
println config.server.url
のように各タスクで利用できます。

環境の切り替えは

  1. 実行時に -P オプションで指定
  2. ${user.home}/.gradle/gradle.properties で指定
  3. 環境変数 GRADLE_ENV で指定
で可能です。

実行時に -P オプションで指定する場合
$ gradle -Penv=test
のように実行します。

${user.home}/.gradle/gradle.properties で指定する場合
env=test
を ${user.home}/.gradle/gradle.properties に追加して
$ gradle
のように実行します。

環境変数 GRADLE_ENV で指定する場合
$ GRADLE_ENV=test gradle
のように実行します。
もちろん、環境変数は あらかじめ設定しておいてもよいです。
特に サーバ環境では 環境変数で設定できないといやな顔されます...

もし、興味のある方は

https://github.com/bluepapa32/gradle-environment-sample/tree/20110310
にサンプルがありますので試してみてください。

しかし、これぐらいは標準で用意してくれても良い気がするのですが...
毎回 プロジェクトで書くのも面倒だし、Maven みたいにプラグインで何とかしろってことなのだろうか?
そんな大したプラグインでもないし 時間のあるときに 作ってみるかな...