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

# 前提

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

# やりたいこと

- [App Engine Gradle Plugin](https://cloud.google.com/appengine/docs/standard/java/tools/gradle-reference)を使って、デプロイをするときに、コマンドラインから、プロパティーを渡したい。
- 次のような設定を`build.gradle`に書いたとき、コマンドラインから、`gradle -Pport=8888 -Ppromote=false appengineDeploy`のように実行し、`port`と`promote`のプロパティーを設定したい。

```groovy
appengine {
    run {
        port = project.port.toInteger()
    }

    deploy {
        promote = project.promote.toBoolean()
    }
}
```

# appengine.deployクロージャ内の`project.promote`が取得できない

`gradle -Pport=8888 -Ppromote=false appengineDeploy`を実行すると、次のエラーが発生する。

```bash
> 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先を調べるために、次のようなコードに変更して、実行してみる。

```groovy
appengine {
    run {
//        port = project.port.toInteger()
        println 'appengine.runのdelegateクラス = ' + delegate.class
    }

    deploy {
//        promote = project.promote.toBoolean()
        println 'appengine.runのdelegateクラス = ' + delegate.class
    }
}
```

次のような出力になる。

```bash
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](https://github.com/GoogleCloudPlatform/app-gradle-plugin/blob/master/src/main/java/com/google/cloud/tools/gradle/appengine/standard/RunExtension.java)」が設定されており、
appengine.deployクロージャの中では、delegate先として、「[DeployExtension.java](https://github.com/GoogleCloudPlatform/app-gradle-plugin/blob/master/src/main/java/com/google/cloud/tools/gradle/appengine/core/DeployExtension.java)」が設定されている。

# DeployExtension.javaでは、`project`プロパティーが初期化されていない

DeployExtension.javaのコンストラクタを見ると、次のようになっており、`project`プロパティーが初期化されていない。

```java
  public DeployExtension(Project gradleProject) {
    this.gradleProject = gradleProject;
  }
```

対して、RunExtension.javaでは、`project`プロパティーが初期化されている。

```java
  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

よって、次のように書き換えた。

```groovy
appengine {
    run {
        port = this.project.port.toInteger()
    }

    deploy {
        promote = this.project.promote.toBoolean()
    }
}
```

また、コマンドラインから引数を渡さないケースも考慮し、次のように記述した。（`promote`は、デフォルト値をfalseにしている。）

```groovy
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()
        }
    }
}
```