前提
- Gradle、Groovyを触るのがはじめてなので、内容が間違っている可能性がありますので、ご指摘をお願いいたします。
やりたいこと
- App Engine Gradle Pluginを使って、デプロイをするときに、コマンドラインから、プロパティーを渡したい。
- 次のような設定を
build.gradle
に書いたとき、コマンドラインから、gradle -Pport=8888 -Ppromote=false appengineDeploy
のように実行し、port
とpromote
のプロパティーを設定したい。
appengine {
run {
port = project.port.toInteger()
}
deploy {
promote = project.promote.toBoolean()
}
}
appengine.deployクロージャ内のproject.promote
が取得できない
gradle -Pport=8888 -Ppromote=false appengineDeploy
を実行すると、次のエラーが発生する。
> Cannot get property 'promote' on null object
appengine.deployクロージャ内で、project
プロパティーがnullになっている。
クロージャのdelegate先を調べる
delegateについて、次のサイトを参考にしました。
https://qiita.com/opengl-8080/items/a0bb31fb20cb6505188b#%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3%E3%81%8C%E6%9A%97%E9%BB%99%E7%9A%84%E3%81%AB%E6%8C%81%E3%81%A4-delegate-%E5%A4%89%E6%95%B0
delegate先を調べるために、次のようなコードに変更して、実行してみる。
appengine {
run {
// port = project.port.toInteger()
println 'appengine.runのdelegateクラス = ' + delegate.class
}
deploy {
// promote = project.promote.toBoolean()
println 'appengine.runのdelegateクラス = ' + delegate.class
}
}
次のような出力になる。
appengine.runのdelegateクラス = class com.google.cloud.tools.gradle.appengine.standard.RunExtension_Decorated
appengine.deployのdelegateクラス = class com.google.cloud.tools.gradle.appengine.core.DeployExtension_Decorated
appengine.runクロージャの中では、delegate先として、「RunExtension.java」が設定されており、
appengine.deployクロージャの中では、delegate先として、「DeployExtension.java」が設定されている。
DeployExtension.javaでは、project
プロパティーが初期化されていない
DeployExtension.javaのコンストラクタを見ると、次のようになっており、project
プロパティーが初期化されていない。
public DeployExtension(Project gradleProject) {
this.gradleProject = gradleProject;
}
対して、RunExtension.javaでは、project
プロパティーが初期化されている。
public RunExtension(Project project) {
this.project = project;
}
結論
appengine.runクロージャ内では、project
プロパティーは、初期化されているが、
appengine.deployクロージャ内では、project
プロパティーは、初期化されていないことがわかった。
解決策として、クロージャのdelegate先のproject
プロパティーを使うのではなく、プロジェクトのインスタンスを使えばよい。
そのためには、this.project
と記述する。
Groovyのクロージャでのthisは、次のサイトを参考にした。
https://qiita.com/saba1024/items/b57c412961e1a2779881
よって、次のように書き換えた。
appengine {
run {
port = this.project.port.toInteger()
}
deploy {
promote = this.project.promote.toBoolean()
}
}
また、コマンドラインから引数を渡さないケースも考慮し、次のように記述した。(promote
は、デフォルト値をfalseにしている。)
appengine {
run {
if (this.project.hasProperty('port')) {
port = this.project.port.toInteger()
}
}
deploy {
promote = false
if (this.project.hasProperty('promote')) {
promote = this.project.promote.toBoolean()
}
}
}