Skip to content

Commit

Permalink
fix(abigen-plugin): clear previous task outputs if its inputs have ch…
Browse files Browse the repository at this point in the history
…anged

Old task outputs are not automatically cleared when task inputs change, leading
to corrupted task cache which includes both new and old task outputs. This is
solved by manually removing old inputs - if any - before storing new ouputs
  • Loading branch information
ArtificialPB committed Dec 29, 2023
1 parent f7df0e7 commit 8a494b6
Show file tree
Hide file tree
Showing 4 changed files with 1,322 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ abstract class EthersAbigenTask @Inject constructor(private val executor: Worker

@TaskAction
fun run() {
// Since the task action is being executed, it means that inputs of the task have been changed. In this case
// first delete previous outputs if any exist. This prevents a case where user changes inputs without changing
// "destinationDir" and does not run the "clean" task before the next build, and the old outputs are still
// present. Gradle task will include both new and old task outputs in the new build cache. Now even if we
// manually run "clean" task or delete the old output files, they will always get restored from the build cache.
//
// Solution: https://discuss.gradle.org/t/is-there-a-way-to-delete-prior-runs-output-for-a-task/28834
outputs.previousOutputFiles.forEach { it.delete() }

val destDir = destinationDir.get().asFile

var loaderPrefix = project.path.split(":")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,64 @@ class EthersAbigenPluginTest : FunSpec({
val result = runner.withArguments("clean", taskName, "--build-cache", "--info").build()
result.tasks.filter { it.path.endsWith(taskName) }.forEach { it.outcome shouldBe TaskOutcome.SUCCESS }

val previousGeneratedFiles = project.layout.buildDirectory.dir(customOutputDir).get().asFile
.walkTopDown()
.filter(File::isFile)
.toList()

val generatedFiles = project.layout.buildDirectory.dir(newOutputDir).get().asFile
.walkTopDown()
.filter(File::isFile)
.toList()

previousGeneratedFiles.size shouldBe 0
generatedFiles.size shouldBe 3
}

test("changing task inputs removes previous outputs and generates new ones") {
@Language("gradle")
val newBuildFile = """
plugins {
id 'base'
id 'org.jetbrains.kotlin.jvm'
id 'io.kriptal.ethers.abigen-plugin'
}
ethersAbigen {
directorySource('$customAbiPath')
outputDir = '$customOutputDir'
}
""".trimIndent()

project.layout.projectDirectory.file("build.gradle").asFile.writeText(newBuildFile)

// old task results are loaded from cache
val oldResult = runner.withArguments(taskName, "--build-cache", "--info").build()
oldResult.tasks.filter { it.path.endsWith(taskName) }.forEach { it.outcome shouldBe TaskOutcome.FROM_CACHE }

val oldGeneratedFiles = project.layout.buildDirectory.dir(customOutputDir).get().asFile
.walkTopDown()
.filter(File::isFile)
.toList()

oldGeneratedFiles.size shouldBe 3
oldGeneratedFiles.filter { it.path.contains("io/ethers/contracts") }.size shouldBe 2

// delete previous ABI files, and copy new ones, keeping the wrappers in build folder
abiDir.deleteRecursively()
File(EthersAbigenPlugin::class.java.getResource("/abi-alt-package")!!.toURI()).copyRecursively(abiDir, true)

// new task results are not from cache, and the old output files are deleted because inputs changed
val result = runner.withArguments(taskName, "--build-cache", "--info").build()
result.tasks.filter { it.path.endsWith(taskName) }.forEach { it.outcome shouldBe TaskOutcome.SUCCESS }

val generatedFiles = project.layout.buildDirectory.dir(customOutputDir).get().asFile
.walkTopDown()
.filter(File::isFile)
.toList()

generatedFiles.size shouldBe 3
generatedFiles.filter { it.path.contains("io/ethers/moved") }.size shouldBe 2
}
}
})
Loading

0 comments on commit 8a494b6

Please sign in to comment.