GoogleAppEngine
gradle

Gradleでコマンドラインからプロパティーを渡すときは、this.projectを使うとよい

前提

  • Gradle、Groovyを触るのがはじめてなので、内容が間違っている可能性がありますので、ご指摘をお願いいたします。

やりたいこと

  • App Engine Gradle Pluginを使って、デプロイをするときに、コマンドラインから、プロパティーを渡したい。
  • 次のような設定をbuild.gradleに書いたとき、コマンドラインから、gradle -Pport=8888 -Ppromote=false appengineDeployのように実行し、portpromoteのプロパティーを設定したい。
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()
        }
    }
}