Allow configuration cache compatibility (#15693)

* Allow configuration cache compatibility

Use FileSystemOperations to delete output folder if Gradle Version >= 6

* Skip Gradle legacy test if JDK is not compatible
This commit is contained in:
Jérôme Prinet 2023-06-09 03:24:04 +02:00 committed by GitHub
parent 02790f987e
commit 113cf9db40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 165 additions and 2 deletions

View File

@ -16,8 +16,12 @@
package org.openapitools.generator.gradle.plugin.tasks
import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
@ -35,6 +39,7 @@ import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.gradle.kotlin.dsl.listProperty
import org.gradle.kotlin.dsl.mapProperty
import org.gradle.kotlin.dsl.property
import org.gradle.util.GradleVersion
import org.openapitools.codegen.CodegenConstants
import org.openapitools.codegen.DefaultGenerator
import org.openapitools.codegen.config.CodegenConfigurator
@ -52,7 +57,8 @@ import org.openapitools.codegen.config.MergedSpecBuilder
*/
@Suppress("UnstableApiUsage")
@CacheableTask
open class GenerateTask : DefaultTask() {
open class GenerateTask @Inject constructor(private val objectFactory: ObjectFactory) : DefaultTask() {
/**
* The verbosity of generation
*/
@ -547,6 +553,14 @@ open class GenerateTask : DefaultTask() {
protected open fun createDefaultCodegenConfigurator(): CodegenConfigurator = CodegenConfigurator()
private fun createFileSystemManager(): FileSystemManager {
return if(GradleVersion.current() >= GradleVersion.version("6.0")) {
objectFactory.newInstance(FileSystemManagerDefault::class.java)
} else {
objectFactory.newInstance(FileSystemManagerLegacy::class.java, project)
}
}
@Suppress("unused")
@TaskAction
fun doWork() {
@ -557,7 +571,7 @@ open class GenerateTask : DefaultTask() {
cleanupOutput.ifNotEmpty { cleanup ->
if (cleanup) {
project.delete(outputDir)
createFileSystemManager().delete(outputDir)
val out = services.get(StyledTextOutputFactory::class.java).create("openapi")
out.withStyle(StyledTextOutput.Style.Success)
out.println("Cleaned up output directory ${outputDir.get()} before code generation (cleanupOutput set to true).")
@ -861,3 +875,23 @@ open class GenerateTask : DefaultTask() {
}
}
}
internal interface FileSystemManager {
fun delete(outputDir: Property<String>)
}
internal open class FileSystemManagerLegacy @Inject constructor(private val project: Project): FileSystemManager {
override fun delete(outputDir: Property<String>) {
project.delete(outputDir)
}
}
internal open class FileSystemManagerDefault @Inject constructor(private val fs: FileSystemOperations) : FileSystemManager {
override fun delete(outputDir: Property<String>) {
fs.delete { delete(outputDir) }
}
}

View File

@ -0,0 +1,129 @@
package org.openapitools.generator.gradle.plugin
import org.gradle.testkit.runner.TaskOutcome
import org.testng.SkipException
import org.testng.annotations.BeforeMethod
import org.testng.annotations.DataProvider
import org.testng.annotations.Test
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class GenerateTaskConfigurationCacheTest : TestBase() {
private lateinit var projectDirCC: File
@BeforeMethod
override fun before() {
initialize()
projectDirCC = temp.resolve("projectDirCC").apply { mkdir() }
}
@DataProvider(name = "gradle_version_provider")
private fun gradleVersionProviderWithConfigurationCache(): Array<Array<String>> = arrayOf(arrayOf("8.1.1"), arrayOf("7.6"))
@DataProvider(name = "gradle_version_provider_without_cc")
private fun gradleVersionProviderWithoutConfigurationCache(): Array<Array<String>> = arrayOf(arrayOf("5.6.1"))
// inputSpec tests
private val inputSpecExtensionContents = """
generatorName = "kotlin"
inputSpec = file("spec.yaml").absolutePath
cleanupOutput.set(true)
""".trimIndent()
@Test(dataProvider = "gradle_version_provider")
fun `openApiGenerate should reuse configuration cache`(gradleVersion: String) {
// Arrange
withProject(inputSpecExtensionContents)
// Act
val result1 = build {
withProjectDir(projectDirCC)
withArguments("--configuration-cache", "clean", "openApiGenerate")
withGradleVersion(gradleVersion)
}
val expectedRelativeFilePathSet = projectDirCC.toRelativeFilePathSet()
val result2 = build {
withProjectDir(projectDirCC)
withArguments("--configuration-cache", "clean", "openApiGenerate")
withGradleVersion(gradleVersion)
}
// Assert
assertEquals(TaskOutcome.SUCCESS, result1.task(":openApiGenerate")?.outcome)
assertTrue(result1.output.contains("Configuration cache entry stored."))
assertEquals(TaskOutcome.SUCCESS, result2.task(":openApiGenerate")?.outcome)
assertTrue(result2.output.contains("Configuration cache entry reused."))
assertEquals(expectedRelativeFilePathSet, projectDirCC.toRelativeFilePathSet())
}
private fun getJavaVersion(): Int {
val version = System.getProperty("java.version")
val parts = version.split('.')
if (parts.first() == "1") return parts.getOrElse(1) { "0" }.toInt()
return parts.first().toInt()
}
@Test(dataProvider = "gradle_version_provider_without_cc")
fun `openApiGenerate should work with Gradle legacy versions`(gradleVersion: String) {
if(getJavaVersion() > 12) {
// https://docs.gradle.org/current/userguide/compatibility.html
throw SkipException("Skipping test as Gradle ${gradleVersion} is not compatible with Java ${getJavaVersion()}")
}
// Arrange
withProject(inputSpecExtensionContents)
// Act
val result1 = build {
withProjectDir(projectDirCC)
withArguments("clean", "openApiGenerate")
withGradleVersion(gradleVersion)
}
val expectedRelativeFilePathSet = projectDirCC.toRelativeFilePathSet()
val result2 = build {
withProjectDir(projectDirCC)
withArguments("clean", "openApiGenerate")
withGradleVersion(gradleVersion)
}
// Assert
assertEquals(TaskOutcome.SUCCESS, result1.task(":openApiGenerate")?.outcome)
assertEquals(TaskOutcome.SUCCESS, result2.task(":openApiGenerate")?.outcome)
assertEquals(expectedRelativeFilePathSet, projectDirCC.toRelativeFilePathSet())
}
// Helper methods & test fixtures
private fun File.toRelativeFilePathSet() =
resolve("build").walk().map { it.toRelativeString(resolve("build")) }.toSet()
private fun withProject(extensionContents: String) {
val settingsContents = """
rootProject.name = "openapi-generator"
""".trimIndent()
val buildContents = """
plugins {
id 'base'
id 'org.openapi.generator'
}
openApiGenerate {
$extensionContents
}
""".trimIndent()
val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")!!
)
withProject(
projectDir = projectDirCC,
settingsContents = settingsContents,
buildContents = buildContents,
projectFiles = projectFiles
)
}
}