へんてこのブログ

日々気づいたことや、最近やっていることを書いています

Gradleプラグインでの入れ子構造引数による動的タスク生成

前回のエントリのやつが解決した

こんなことがしたい

sample {
  configKey = "test config key"

  books {
    quickStart {
      title = "quick start book"
      body = "quick start book body"
    }
    userGuide {
      title = "user guide book"
      body = "user guide book body"
    }
  }
}

といったbuild.gradleがあった場合、動的にbooks内のquickStartやuserGuideごとのタスクを生成したい
具体的に書くと、quickStartBookReadとかuserGuideBookReadとかいうタスクを動的に生成したい

ソースコード

henteko/gradle-samplebooks-plugin · GitHub
アップデートしたのでこれを参照してもらいたい

結論

applyメソッド内に以下の様な感じで書いたら出来た

def books = project.container(BookTarget) {
  String bookName = it.toString()
  def subTask = project.task("${bookName}BookRead", type: SubBookTask)
  subTask.group = 'Sample' 
  subTask.description = "${bookName} book read"
  subTask.bookName = bookName

  project.extensions.create(it, BookTarget, bookName)
}
def sample = new SampleExtension(books)

project.containerのクロージャー内で、itにより自身(?)を参照することにより、それぞれのbookNameを取得することが出来る
その後、動的にタスクを生成後各タスクに渡すようにsubTask.bookName = bookNameで名前を渡している

ちなみにSubBookTask.groovyはこんな感じ

package com.henteko07.gradle.plugins

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

class SubBookTask extends DefaultTask {
    String bookName
    
    @TaskAction
    def subBookRead() {
        println "your config key: ${project.sample.configKey}"
        println ""

        def books = project.sampleBooks
        for(book in books) {
            if(bookName != book.name) continue

            println "setting name: ${book.name}"
            println "title: ${book.title}"
            println "body: ${book.body}"
            println ""
        }
    }
}

bookNameってやつが動的にくる名前となる
bookNameごとにifで振り分けるみたいなことすると、今回の目的が達成出来た

参考