ぼんやりと複雑な作業を処理するためにカスタムのgradleプラグインを作成しています。プラグインが適用されるタスクのいくつかを設定するためにプロパティを使用している間、不満を感じています。次のようにこのファイルを使用してから拡張機能をグラデーションで使用すると、プロパティのレイジー評価を処理できますか?
apply plugin: myPlugin
//Provide properties for the applied plugin
myPluginProps {
message = "Hello"
}
//Define a task that uses my custom task directly
task thisTaskWorksFine(type: MyTask) {
input = myPluginProps.message
}
//Define a plugin that will apply a task of my custom type
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create('myPluginProps', MyPluginExtension)
project.task(type: MyTask, 'thisTaskWorksIncorrectly') {
input = project.myPluginProps.message
}
}
}
//The extension used by my custom plugin to get input
class MyPluginExtension {
def String message
}
//The task used by both the standard build section and the plugin
class MyTask extends DefaultTask {
def String input
@TaskAction
def action() {
println "You gave me this: ${input}"
}
}
結果は以下のとおりです。
$ gradle thisTaskWorksFine thisTaskWorksIncorrectly
:thisTaskWorksFine
You gave me this: Hello
:thisTaskWorksIncorrectly
You gave me this: null
BUILD SUCCESSFUL
私は、これは非常に予想外であると考えています。私の考えでは、プラグインからタスクを適用し、直接入力すると、同じ入力が与えられたときに同じ出力が得られるはずです。この場合、両方のタスクには入力としてmyPluginProps.message
が与えられますが、プラグインによって適用されるタスクは貪欲で、早期にヌルに評価されます。今除いてかなりきれいに貪欲な評価の問題を解決し
//Define a plugin that will apply a task of my custom type
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create('myPluginProps', MyPluginExtension)
project.task(type: MyTask, 'thisTaskWorksIncorrectly') {
input = { project.myPluginProps.message }
}
}
}
:(?適用フェーズ)
私が見つけた唯一の解決策は、そのようなプラグインのタスクの構成ブロックでクロージャを使用することですクロージャを期待して処理するためにカスタムタスクを修正する必要があります。それはすごく難しいことではありませんが、プラグインが「責任を負う」ため、閉鎖に対処するのはタスクの責任ではないと思います。
私はここで間違って拡張子を使用していますか?あるいは、彼らはちょうど十分ではありませんか?公式の姿勢はwe should use extensionsのように見えますが、私はまだ拡張機能が必要なものを実行できる例は見つけていません。私はクロージャーを使用して前進し、クロージャーと通常のタイプを扱うことができるクロージャー評価とセッターを行う定型文法ゲッターの集合を書くことができますが、それはgroovyの哲学、したがってgradleに非常に似ています。拡張機能を使用して自動的に怠惰な評価を得る方法があるなら、私はとても幸せになれます。
慣習マッピングと慣習の違いはありますか?あなたの答えはかなり滑らかに見えるので、私はほぼ確実にそれを使用しますが、コア開発者の一人は「要するに、拡張機能を使用するだけではコンベンションを使用しない」と言いました。たぶん私はそれを文字通り過ぎ去りました。 –
Peterが言及している[規則(convention)](http://www.gradle.org/docs/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:convention)は古いメカニズムです拡張のために。違いは、あなたがdsl( 'myPluginProps {message =" Hello "}')を拡張機能で無償で入手し、あなたがそれを慣習で入手しなかったことです。コンベンションとコンベンションのマッピングは2つの異なるもので、[gradle code](https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/groovy/org/gradle/)で内部的に使用されています。 api/plugins/JavaPlugin.java#L131)がたくさんあります。 – erdi
優れています。私の研究では、コンベンションという言葉に言及したすべてのものを覆していたが、それは急いでいた。助けてくれてありがとう! –