I have a custom task, in a custom plugin, constructed using the kotlin-dsl
plugin.
Here is an example:
@CacheableTask
abstract class FooTask : DefaultTask(), CopySourceSpec {
@get:InputFiles
@get:Optional
@get:SkipWhenEmpty
@get:IgnoreEmptyDirectories
@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val sourceFiles: ConfigurableFileCollection
@get:Input
@get:Optional
abstract val renameFile: Property<Action<String>>
@get:OutputDirectory
@get:Optional
abstract val targetDir: DirectoryProperty
fun generate() {
val sourceFileTree = sourceFiles.asFileTree
val (outputDir, rawFilename) =
if (targetDir.isPresent) {
Pair(targetDir.get(), input.name)
} else {
Pair(project.layout.projectDirectory.dir(input.canonicalFile.parentFile.path),
input.canonicalFile.name)
}
val outputFileString = if (renameFile.isPresent) {
var wipFilename = rawFilename.toString()
renameFile.get().execute(wipFilename)
wipFilename
} else {
rawFilename
}
val outputFile = outputDir.file(outputFileString).asFile
outputFile.bufferedWriter().use { appendable ->
appendable.append(result)
}
}
// I do not think the following are relevant to the problem but I have included them for completeness.
override fun from(vararg sourcePaths: Any?): ProtobufGenerateTask {
this.sourceFiles.from(sourcePaths)
return this
}
override fun from(sourcePath: Any, closure: Closure<*>): ProtobufGenerateTask {
this.sourceFiles.from(sourcePath, closure)
return this
}
override fun from(sourcePath: Any, configureAction: Action<in CopySpec>): ProtobufGenerateTask {
this.sourceFiles.from(sourcePath, configureAction)
return this
}
open fun into(destPath: Directory?): ProtobufGenerateTask? {
this.targetDir.set(destPath)
return this
}
open fun into(destPath: Provider<Directory>?): ProtobufGenerateTask? {
if (destPath != null) {
this.targetDir.set(destPath.get())
}
return this
}
}
This task is then exercised with something in the build.gradle.kts
that looks like this…
fun renameSuffix(str: String, suffix: String) : String {
return str
.removeSuffix(".foo")
.replace("\\.", "_")
.plus(suffix)
}
tasks.register<FooTask>("generateFoo") {
group = "gen-foo"
from(layout.projectDirectory.dir("fooDir").asFileTree.matching {
include("**/*.foo")
})
into(layout.buildDirectory.dir("fooDir"))
renameFile.set { renameSuffix(this, "$1") }
}
The property of interest here is renameFile.set().
When I try to run generateFoo task…
./gradlew :generateFoo --debug --stacktrace
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] FAILURE: Build failed with an exception.
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
2022-10-06T14:55:55.325-0500 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] * What went wrong:
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] Build_gradle$5$7
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] > Build_gradle$5$7
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] * Try:
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] > Run with --scan to get full insights.
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] * Exception is:
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] java.lang.NoClassDefFoundError: Build_gradle$5$7
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.logging.text.TreeFormatter.appendOuter(TreeFormatter.java:139)
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.logging.text.TreeFormatter.appendType(TreeFormatter.java:117)
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.snapshot.impl.AbstractValueProcessor.newValueSerializationException(AbstractValueProcessor.java:182)
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.snapshot.impl.AbstractValueProcessor.javaSerialization(AbstractValueProcessor.java:174)
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.snapshot.impl.AbstractValueProcessor.processValue(AbstractValueProcessor.java:153)
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.snapshot.impl.DefaultValueSnapshotter.snapshot(DefaultValueSnapshotter.java:47)
...
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] Caused by: java.lang.ClassNotFoundException: Build_gradle$5$7
[ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] ... 72 more
This was working before I added the abstract val renameFile: Property<Action>.
What is the correct way to pass an Action as input to a custom task?