Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
*/
Expand Down Expand Up @@ -540,6 +546,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() {
Expand All @@ -550,7 +564,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).")
Expand Down Expand Up @@ -849,3 +863,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) }
}
}
Original file line number Diff line number Diff line change
@@ -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
)
}
}