Reputation: 1859
I want to pass a Gradle closure to a custom task.
@CacheableTask
abstract class FooTask : DefaultTask() {
@get:Input
abstract val input: RegularFileProperty
@get:Input
abstract val renamer: Property<Action<Path>>
@TaskAction
fun generate() {
val path = input.get().asFile.toPath()
val result = renamer.get().execute(path)
logger.quiet("original: $path, final: $result")
}
}
The usage in a 'build.gradle.kts' would be something like...
tasks {
register<FooTask>("foo") {
group = "foo"
input.set(fooFile)
renamer.set { filename: String ->
filename.replace(Regex("(.*)\\bar"), "$1.baz")
}
}
}
I am, however, having difficulty getting it to work. For example, it appears that the Action is not serializable which it apparently needs to be.
I have been looking at how the Copy
task does this.
Upvotes: 2
Views: 794
Reputation: 1859
Starting with the rename method in Copy task After digging around in the source I found how the Transformer class is used. The following appears to work in the fashion I wanted.
import org.gradle.api.Transformer
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.SourceTask
import org.gradle.api.tasks.TaskAction
import java.io.File
import java.util.*
@CacheableTask
abstract class FooTask : SourceTask() {
private val copyActions = LinkedList<Transformer<File, File>>()
fun rename(renamer: Transformer<File, File>): FooTask {
copyActions.add(renamer)
return this
}
@TaskAction
fun generate() {
val sourceFileTree = this.source
sourceFileTree.visit {
val fileCopyDetails = this@visit
copyActions.forEach { action ->
val result = action.transform(fileCopyDetails.file)
logger.quiet(" ${fileCopyDetails.path} -> $result")
}
}
}
}
The usage in ‘build.gradle.kts’.
tasks {
register<FooTask>("foo") {
group = "foo"
source(layout.projectDirectory.dir("foo").asFileTree.matching {
include("**/*.foo")
})
rename { file ->
file.parentFile.resolve( file.name.replace(Regex("(.*)\\.foo"), "$1.json") )
}
}
}
Enjoy!
Upvotes: 0