Gradle:既存のタスクにカスタム拡張を追加する

既存タスクの動作を変更したいことがある。例えば

task copyit(type: Copy) {
  thisIsExtraArg = 123
}

のように、元のタスクには存在しないプロパティを作成し、それによって動作を変更したい。

以下はGradle Goodness: Adding Custom Extension To Tasksを参考にしたが、例は大幅に簡単化している。また、所望の結果を得る方法は見つかっていない。以下では、どうしてもクロージャを一つ追加しなければならない。

単純な例

単純にCopyタスクの動作の前後にメッセージを出力するだけのものである。

これを改良して、コピー元やコピー先を変更するといったことはできない。doFirstの実行時点で、それらは既に確定しているからだ。

class CopyExtension {
  String beginning;
  String ending;
}

class CopyPlugin implements Plugin<Project> {     
  void apply(final Project project) {
    project.tasks.withType(Copy) { task ->
      CopyExtension taskExtension = task.extensions.create('msg', CopyExtension)
      task.doFirst {
        println taskExtension.beginning
      }
      task.doLast {
        println taskExtension.ending
      }
    }
  }     
}

apply plugin: CopyPlugin

task copyit(type: Copy) {
  from "test.txt"
  into "folder"
  msg {
    beginning = "I'm beginning"
    ending = "I'm ending"
  }
}

やや実用的な例

やや実用的な例としては以下だ。Copyタスクのfromは指定されておらず、Extensionの方のsourceを使うことになる。

class CopyExtension {
  Task task;
  String source;
  CopyExtension(Task task) {
    this.task = task;
  }
  def ex(Closure closure) {
    closure.delegate = this;
    closure();
    task.from source
  }   
}

class CopyPlugin implements Plugin<Project> {     
  void apply(final Project project) {
    project.tasks.withType(Copy) { task ->
      task.convention.plugins.copyExtension = new CopyExtension(task)
    }
  }     
}

apply plugin: CopyPlugin

task copyit(type: Copy) {
  into "folder"
  ex {
    source = "test.txt"
  }
}