diff --git a/crd-generator/gradle-plugin/pom.xml b/crd-generator/gradle-plugin/pom.xml new file mode 100644 index 00000000000..5ce15a77c45 --- /dev/null +++ b/crd-generator/gradle-plugin/pom.xml @@ -0,0 +1,234 @@ + + + + 4.0.0 + + + crd-generator-parent + io.fabric8 + 7.2-SNAPSHOT + + + + io.fabric8.crd-generator + io.fabric8.crd-generator.gradle.plugin + Fabric8 :: CRD generator :: Gradle Plugin + + jar + + + + maven-central + https://repo1.maven.org/maven2/ + + + repo.gradle.org + https://repo.gradle.org/gradle/libs-releases-local/ + + false + + + + ext.repo.gradle.org + https://repo.gradle.org/gradle/ext-releases-local/ + + false + + + + + + + org.apache.groovy + groovy-all + ${groovy-api.version} + pom + provided + + + org.jetbrains.kotlin + kotlin-stdlib + provided + + + org.gradle + gradle-all + ${gradle-api.version} + provided + + + javax.inject + javax.inject + 1 + + + + io.fabric8 + crd-generator-api-v2 + + + + io.fabric8 + crd-generator-collector + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-params + test + + + org.slf4j + slf4j-simple + test + + + org.mockito + mockito-core + test + + + commons-io + commons-io + test + + + com.google.guava + guava + test + 33.2.0-jre + + + io.kotest + kotest-assertions-core-jvm + 5.9.1 + + + + + + + org.jetbrains.kotlin + kotlin-bom + ${gradle.kotlin.version} + pom + import + + + + + + 1.9.10 + + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/test/kotlin + + + src/test/resources + + + src/it/resources + + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${gradle.kotlin.version} + + + test-compile + test-compile + + test-compile + + + + src/test/kotlin + src/it/kotlin + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + generate-test-sources + + add-source + + + + ${project.basedir}/src/test/kotlin + ${project.basedir}/src/it/kotlin + + + + + + + com.marcnuri.plugins + gradle-api-maven-plugin + true + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven.surefire.plugin.version} + + + integration-tests + + integration-test + verify + + + ${project.basedir}/src/it/kotlin + + + + + + + fabric8-client.version + ${project.version} + + + + + + + \ No newline at end of file diff --git a/crd-generator/gradle-plugin/src/it/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorPluginIntegrationTest.kt b/crd-generator/gradle-plugin/src/it/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorPluginIntegrationTest.kt new file mode 100644 index 00000000000..93b10a1c3b1 --- /dev/null +++ b/crd-generator/gradle-plugin/src/it/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorPluginIntegrationTest.kt @@ -0,0 +1,38 @@ +package io.fabric8.crd.generator.gradle.plugin + +import io.kotest.matchers.collections.containAll +import io.kotest.matchers.should +import io.kotest.matchers.shouldBe +import org.gradle.testkit.runner.GradleRunner +import org.gradle.testkit.runner.TaskOutcome +import org.junit.jupiter.api.Test + +class CrdGeneratorPluginIntegrationTest : GradlePluginIntegrationTest() { + override val projectFiles = + mapOf( + "settings.gradle.kts" to "/", + "gradle.properties" to "/", + "src/integrationTest/kotlin/io/fabric8/crd/generator/example/GreetingResource.kt" to + "/src/main/kotlin/io/fabric8/crd/generator/example", + "src/functionalTest/resources/base/build.gradle.kts" to + "/", + ) + + @Test + fun `it should compile and generate from sources`() { + // WHEN: running task + val result = + GradleRunner + .create() + .withProjectDir(projectDir) + .withArguments("generateCRDs") + .withPluginClasspath() + .build() + // THEN: kotlin sources have been build + result.tasks.find { it.path == ":compileKotlin" }?.outcome shouldBe TaskOutcome.SUCCESS + // AND: main crds have been generated + result.tasks.find { it.path == ":generateCRDsMain" }?.outcome shouldBe TaskOutcome.SUCCESS + // AND: generated file exists in the correct directory + buildDirOf("crds/main").list()!!.toList() should containAll("greetings.example.com-v1.yml") + } +} diff --git a/crd-generator/gradle-plugin/src/it/kotlin/io/fabric8/crd/generator/gradle/plugin/GradlePluginIntegrationTest.kt b/crd-generator/gradle-plugin/src/it/kotlin/io/fabric8/crd/generator/gradle/plugin/GradlePluginIntegrationTest.kt new file mode 100644 index 00000000000..0b413377c93 --- /dev/null +++ b/crd-generator/gradle-plugin/src/it/kotlin/io/fabric8/crd/generator/gradle/plugin/GradlePluginIntegrationTest.kt @@ -0,0 +1,35 @@ +package io.fabric8.crd.generator.gradle.plugin + +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.io.TempDir +import java.io.File + +abstract class GradlePluginIntegrationTest { + @TempDir + lateinit var projectDir: File + + protected abstract val projectFiles: Map + + protected val buildDir by lazy { File(projectDir, "build") } + + fun buildDirOf(subDir: String) = File(buildDir, subDir) + + private fun File.copyToProjectDir(targetDir: String) { + File(projectDir, targetDir.trimStart('/') + name).let { targetFile -> + if (!exists()) { + throw IllegalArgumentException("source '$absolutePath' does not exist") + } + targetFile.parentFile.mkdirs() + if (isDirectory) { + copyRecursively(targetFile) + } else { + copyTo(targetFile) + } + } + } + + @BeforeEach + fun prepareProjectDir() { + projectFiles.forEach { File(it.key).copyToProjectDir(it.value) } + } +} diff --git a/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorConfig.kt b/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorConfig.kt new file mode 100644 index 00000000000..ec09db4a1c8 --- /dev/null +++ b/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorConfig.kt @@ -0,0 +1,76 @@ +package io.fabric8.crd.generator.gradle.plugin + +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Nested +import org.gradle.api.tasks.Optional + +/** + * Configuration used by the [CrdGeneratorTask]. + */ +abstract class CrdGeneratorConfig { + /** + * Directive configuring the collection of the classes + */ + @get:Nested + abstract val collect: CollectDirective + + /** + * Directive configuring the emission of the CRDs. + */ + @get:Nested + abstract val emit: EmitDirective + + abstract class CollectDirective { + /** + * enforce the creation of a jandex index, even if one is found. + */ + @get:Input + @get:Optional + abstract val forceIndex: Property + + /** + * names of the classes to be scanned + */ + @get:Input + @get:Optional + val classes = mutableSetOf() + + /** + * package filter for the classes + */ + @get:Nested + @get:Optional + abstract val packages: Packages + + abstract class Packages { + /** + * include the provided packages by name. + */ + @get:Input + val include = mutableSetOf() + + /** + * exclude the provided packages by name. + */ + @get:Input + val exclude = mutableSetOf() + } + } + + abstract class EmitDirective { + /** + * if to parallelize the generation of the CRDs + */ + @get:Input + @get:Optional + abstract val parallel: Property + + /** + * apiVersions of the CRDs to be generated + */ + @get:Input + @get:Optional + val crdVersions = mutableSetOf() + } +} diff --git a/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorExtension.kt b/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorExtension.kt new file mode 100644 index 00000000000..475b225aef4 --- /dev/null +++ b/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorExtension.kt @@ -0,0 +1,10 @@ +package io.fabric8.crd.generator.gradle.plugin + +import org.gradle.api.tasks.Internal + +/** + * Extension object decorating [CrdGeneratorConfig]. + */ +abstract class CrdGeneratorExtension( + @Internal val generatorTask: CrdGeneratorTask, +) : CrdGeneratorConfig() diff --git a/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorPlugin.kt b/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorPlugin.kt new file mode 100644 index 00000000000..8e287571aee --- /dev/null +++ b/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorPlugin.kt @@ -0,0 +1,52 @@ +package io.fabric8.crd.generator.gradle.plugin + +import org.gradle.api.DefaultTask +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.SourceSetContainer +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.generateCRDsFor +import org.gradle.kotlin.dsl.getByType + +/** + * [Plugin] which generates CRDs from the compiled files of the [SourceSet.MAIN_SOURCE_SET_NAME]. + */ +class CrdGeneratorPlugin : Plugin { + companion object { + /** + * Name of task to be created. + */ + const val TASK_NAME = "generateCRDs" + + /** + * Group of the task + */ + const val GROUP = "build" + + /** + * Name of the extension object. + */ + const val EXTENSION_NAME = "crds" + + /** + * Aggregation task for generating all CRDs + */ + val Project.generateCRDsTask: Task get() = tasks.getByName(TASK_NAME) + } + + override fun apply(target: Project) { + // Apply the java plugin, in order to have the main source set + target.plugins.apply(JavaPlugin::class.java) + // Create an aggregation task + target.tasks.create(TASK_NAME) { + group = GROUP + description = "generates CRDs from all source sets registered" + } + target.generateCRDsFor( + target.extensions.getByType().getByName(SourceSet.MAIN_SOURCE_SET_NAME), + ) + } +} diff --git a/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorTask.kt b/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorTask.kt new file mode 100644 index 00000000000..7537747c554 --- /dev/null +++ b/crd-generator/gradle-plugin/src/main/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorTask.kt @@ -0,0 +1,101 @@ +package io.fabric8.crd.generator.gradle.plugin + +import io.fabric8.crd.generator.collector.CustomResourceCollector +import io.fabric8.crdv2.generator.CRDGenerator +import io.fabric8.kubernetes.api.model.HasMetadata +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileCollection +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Classpath +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.Nested +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import java.net.URLClassLoader + +/** + * [DefaultTask] which generates the CRDs. + */ +abstract class CrdGeneratorTask : DefaultTask() { + companion object { + /** + * File extension for class files. + */ + const val CLASS_FILE_EXTENSION = "class" + } + + /** + * Input files + */ + @get:InputFiles + abstract val input: Property + + /** + * Classpath for the analysis + */ + @get:Classpath + abstract val classpath: Property + + /** + * Output directory. + */ + @get:OutputDirectory + abstract val output: DirectoryProperty + + /** + * Configuration for the collection of the sources and generation of the CRDs. + */ + @get:Nested + abstract val configuration: CrdGeneratorConfig + + /** + * Extension [CrdGeneratorTask], with a replaceable [CrdGeneratorTask.configuration]. + */ + internal abstract class Extension : CrdGeneratorTask() { + override lateinit var configuration: CrdGeneratorConfig + } + + @TaskAction + fun generateCRDs() { + emitCRDs(crdSources()) + } + + private fun crdSources(): List> { + logger.debug("creating classloader for the classpath") + val inputDirsURLs = input.get().files + val classpathURLs = (classpath.get().files + inputDirsURLs).map { it.toURI().toURL() } + // Kindly note: in order to load the classes correctly, we need the CRDGenerator's classloader to be the parent + val classloader = URLClassLoader(classpathURLs.toTypedArray(), CRDGenerator::class.java.classLoader) + logger.debug("scanning input directory for CRD classes") + val classFiles = + input + .get() + .asFileTree.files + .filter { it.extension == CLASS_FILE_EXTENSION } + val crCollector = + CustomResourceCollector() + .withParentClassLoader(classloader) + .withCustomResourceClasses(configuration.collect.classes) + .withForceIndex(configuration.collect.forceIndex.getOrElse(false)) + .withIncludePackages(configuration.collect.packages.include) + .withExcludePackages(configuration.collect.packages.exclude) + .withFilesToScan(classFiles) + return crCollector.findCustomResourceClasses() + } + + private fun emitCRDs(sources: List>) { + logger.debug("creating target directory") + val outputDir = output.get().asFile.absoluteFile + outputDir.mkdirs() + logger.debug("emitting CRDs using the generator") + val generatedFiles = + CRDGenerator() + .withParallelGenerationEnabled(configuration.emit.parallel.getOrElse(true)) + .forCRDVersions(configuration.emit.crdVersions.toList()) + .inOutputDir(outputDir) + .customResourceClasses(sources) + .generate() + logger.info("emitted $generatedFiles CRD(s)") + } +} diff --git a/crd-generator/gradle-plugin/src/main/kotlin/org/gradle/kotlin/dsl/CrdGeneratorDsl.kt b/crd-generator/gradle-plugin/src/main/kotlin/org/gradle/kotlin/dsl/CrdGeneratorDsl.kt new file mode 100644 index 00000000000..67f0010567d --- /dev/null +++ b/crd-generator/gradle-plugin/src/main/kotlin/org/gradle/kotlin/dsl/CrdGeneratorDsl.kt @@ -0,0 +1,82 @@ +package org.gradle.kotlin.dsl + +import io.fabric8.crd.generator.gradle.plugin.CrdGeneratorConfig +import io.fabric8.crd.generator.gradle.plugin.CrdGeneratorExtension +import io.fabric8.crd.generator.gradle.plugin.CrdGeneratorPlugin +import io.fabric8.crd.generator.gradle.plugin.CrdGeneratorPlugin.Companion.generateCRDsTask +import io.fabric8.crd.generator.gradle.plugin.CrdGeneratorTask +import org.gradle.api.Action +import org.gradle.api.NamedDomainObjectProvider +import org.gradle.api.Project +import org.gradle.api.tasks.SourceSet +import org.gradle.kotlin.dsl.support.uppercaseFirstChar + +/** + * Add CRD generation for a [SourceSet]. + * @param sourceSet to add to + * @receiver the project (necessary + */ +fun Project.generateCRDsFor(sourceSet: SourceSet): CrdGeneratorConfig { + val nameSuffix = sourceSet.name.uppercaseFirstChar() + val task = + tasks.create("${CrdGeneratorPlugin.TASK_NAME}$nameSuffix") { + val extension = + extensions.create("${CrdGeneratorPlugin.EXTENSION_NAME}$nameSuffix", this) + configuration = extension + sourceSet.extensions.add(CrdGeneratorPlugin.EXTENSION_NAME, extension) + input.set(sourceSet.output) + classpath.set(sourceSet.compileClasspath) + output.set(layout.buildDirectory.dir("crds/${sourceSet.name}").get()) + group = CrdGeneratorPlugin.GROUP + description = "Generate CRDs from the compiled classes of '${sourceSet.name}'" + dependsOn(sourceSet.classesTaskName) + } + generateCRDsTask.dependsOn(task) + return task.configuration +} + +/** + * Acquire the [CrdGeneratorConfig] for a [SourceSet]. + * @receiver [SourceSet] the CRDs are generated from + */ +val SourceSet.crds: CrdGeneratorExtension + get() = extensions.getByType() + +/** + * @see SourceSet.crds but for [NamedDomainObjectProvider] + * @receiver [NamedDomainObjectProvider] for the [SourceSet] the CRDs are generated from + */ +val NamedDomainObjectProvider.crds: CrdGeneratorExtension + get() = this.get().crds + +/** + * Configure the [CrdGeneratorConfig] for a [SourceSet]. + * @receiver [SourceSet] the CRDs are generated from + */ +fun SourceSet.crds(configure: CrdGeneratorConfig.() -> Unit) { + configure(crds) +} + +/** + * @see SourceSet.crds but for [NamedDomainObjectProvider] + * @receiver [NamedDomainObjectProvider] for the [SourceSet] the CRDs are generated from + */ +fun NamedDomainObjectProvider.crds(configure: CrdGeneratorConfig.() -> Unit) { + configure(crds) +} + +/** + * Configure the [CrdGeneratorConfig] for a [SourceSet]. + * @receiver [SourceSet] the CRDs are generated from + */ +fun SourceSet.crds(configure: Action) { + crds(configure::execute) +} + +/** + * @see SourceSet.crds but for [NamedDomainObjectProvider] + * @receiver [NamedDomainObjectProvider] for the [SourceSet] the CRDs are generated from + */ +fun NamedDomainObjectProvider.crds(configure: Action) { + crds(configure::execute) +} diff --git a/crd-generator/gradle-plugin/src/test/kotlin/io/fabric8/crd/generator/example/GreetingResource.kt b/crd-generator/gradle-plugin/src/test/kotlin/io/fabric8/crd/generator/example/GreetingResource.kt new file mode 100644 index 00000000000..183ad3c7f81 --- /dev/null +++ b/crd-generator/gradle-plugin/src/test/kotlin/io/fabric8/crd/generator/example/GreetingResource.kt @@ -0,0 +1,19 @@ +package io.fabric8.crd.generator.example + +import io.fabric8.kubernetes.client.CustomResource +import io.fabric8.kubernetes.model.annotation.Group +import io.fabric8.kubernetes.model.annotation.Kind +import io.fabric8.kubernetes.model.annotation.Version + +@Group("example.com") +@Version("v1") +@Kind("Greeting") +class GreetingResource : CustomResource() { + data class Spec( + val hello: String = "", + ) + + class Status( + val greeting: String = "", + ) +} diff --git a/crd-generator/gradle-plugin/src/test/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorPluginTest.kt b/crd-generator/gradle-plugin/src/test/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorPluginTest.kt new file mode 100644 index 00000000000..e1e53d9b34f --- /dev/null +++ b/crd-generator/gradle-plugin/src/test/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorPluginTest.kt @@ -0,0 +1,32 @@ +package io.fabric8.crd.generator.gradle.plugin + +import io.fabric8.crd.generator.gradle.plugin.CrdGeneratorPlugin.Companion.generateCRDsTask +import io.kotest.matchers.nulls.beNull +import io.kotest.matchers.shouldNot +import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.SourceSetContainer +import org.gradle.kotlin.dsl.crds +import org.gradle.kotlin.dsl.getByType +import org.gradle.testfixtures.ProjectBuilder +import org.junit.jupiter.api.Test + +class CrdGeneratorPluginTest { + private val project = ProjectBuilder.builder().build() + + @Test + fun `should add task to main source set`() { + // WHEN: applying plugin + project.plugins.apply(CrdGeneratorPlugin::class.java) + // THEN: extension object is present + val extObj = + project.extensions + .getByType() + .named(SourceSet.MAIN_SOURCE_SET_NAME) + .crds + extObj shouldNot beNull() + // AND: generator task is present + extObj.generatorTask shouldNot beNull() + // AND: aggregation task is present + project.generateCRDsTask shouldNot beNull() + } +} diff --git a/crd-generator/gradle-plugin/src/test/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorTaskTest.kt b/crd-generator/gradle-plugin/src/test/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorTaskTest.kt new file mode 100644 index 00000000000..ac5a2990448 --- /dev/null +++ b/crd-generator/gradle-plugin/src/test/kotlin/io/fabric8/crd/generator/gradle/plugin/CrdGeneratorTaskTest.kt @@ -0,0 +1,35 @@ +package io.fabric8.crd.generator.gradle.plugin + +import io.kotest.matchers.collections.containAll +import io.kotest.matchers.should +import org.gradle.kotlin.dsl.create +import org.gradle.testfixtures.ProjectBuilder +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir +import java.io.File + +class CrdGeneratorTaskTest { + companion object { + private val testBuildPath = File("build/classes/kotlin/integrationTest").normalize().absolutePath + } + + private val project = ProjectBuilder.builder().build() + + @TempDir + protected lateinit var tmpDir: File + + @Test + fun `should generate the custom resources`() { + // WHEN: creating a task + val task = + project.tasks.create("test") { + input.set(project.layout.files(testBuildPath)) + output.set(project.layout.dir(project.provider { tmpDir.absoluteFile })) + classpath.set(project.layout.files(tmpDir.absolutePath)) + } + // AND: running it + task.actions.forEach { it.execute(task) } + // THEN: the CRDs are generated + tmpDir.list()?.toList()!! should containAll("greetings.example.com-v1.yml") + } +} diff --git a/crd-generator/gradle-plugin/src/test/kotlin/org/gradle/kotlin/dsl/CrdGeneratorDslTest.kt b/crd-generator/gradle-plugin/src/test/kotlin/org/gradle/kotlin/dsl/CrdGeneratorDslTest.kt new file mode 100644 index 00000000000..e4e3a5b034c --- /dev/null +++ b/crd-generator/gradle-plugin/src/test/kotlin/org/gradle/kotlin/dsl/CrdGeneratorDslTest.kt @@ -0,0 +1,103 @@ +package org.gradle.kotlin.dsl + +import io.fabric8.crd.generator.gradle.plugin.CrdGeneratorConfig +import io.fabric8.crd.generator.gradle.plugin.CrdGeneratorPlugin +import io.fabric8.crd.generator.gradle.plugin.CrdGeneratorPlugin.Companion.generateCRDsTask +import io.kotest.matchers.booleans.shouldBeTrue +import io.kotest.matchers.collections.contain +import io.kotest.matchers.nulls.beNull +import io.kotest.matchers.should +import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNot +import io.kotest.matchers.types.instanceOf +import org.gradle.api.Action +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.SourceSetContainer +import org.gradle.testfixtures.ProjectBuilder +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class CrdGeneratorDslTest { + private val project = ProjectBuilder.builder().build() + + @BeforeEach + fun applyPlugin() { + project.plugins.apply(CrdGeneratorPlugin::class.java) + } + + @Test + fun generateCRDsFor() { + // WHEN: adding generation for another source set + project.generateCRDsFor(project.sourceSets[SourceSet.TEST_SOURCE_SET_NAME]) + // THEN: a task is added + val newTask = project.tasks.findByName("generateCRDsTest") + newTask shouldNot beNull() + // AND: the aggregation task depends on the task + project.generateCRDsTask.ownDependencies should contain(newTask) + } + + @Test + fun `crds extension value`() { + // EXPECT: the source set has the extension + project.sourceSets[SourceSet.MAIN_SOURCE_SET_NAME].crds shouldNot beNull() + // EXPECT: the source set provider has the extension + project.sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME).crds shouldNot beNull() + } + + @Test + fun `crds configuration from source set with closure`() { + // WHEN: configuring using the action + val action = CrdAction() + project.sourceSets[SourceSet.MAIN_SOURCE_SET_NAME].crds(action.asClosure) + // THEN: action is called + action.shouldHaveBeenCalled() + } + + @Test + fun `crds configuration from source set with action`() { + // WHEN: configuring using the action + val action = CrdAction() + project.sourceSets[SourceSet.MAIN_SOURCE_SET_NAME].crds(action) + // THEN: action is called + action.shouldHaveBeenCalled() + } + + @Test + fun `crds configuration from source provider set with closure`() { + // WHEN: configuring using the action + val action = CrdAction() + project.sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME).crds(action.asClosure) + // THEN: action is called + action.shouldHaveBeenCalled() + } + + @Test + fun `crds configuration from source set provider with action`() { + // WHEN: configuring using the action + val action = CrdAction() + project.sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME).crds(action) + // THEN: action is called + action.shouldHaveBeenCalled() + } + + val Project.sourceSets + get() = extensions.getByType() + + val Task.ownDependencies + get() = taskDependencies.getDependencies(this) + + class CrdAction : Action { + private var called = false + + val asClosure: CrdGeneratorConfig.() -> Unit get() = { execute(this) } + + fun shouldHaveBeenCalled() = called.shouldBeTrue() + + override fun execute(t: CrdGeneratorConfig) { + t shouldBe instanceOf() + called = true + } + } +} diff --git a/crd-generator/pom.xml b/crd-generator/pom.xml index a6cfd1e7d6f..5c678d4e5b3 100644 --- a/crd-generator/pom.xml +++ b/crd-generator/pom.xml @@ -36,6 +36,7 @@ apt collector maven-plugin + gradle-plugin cli test test-apt