Skip to content

Commit b2d379d

Browse files
authored
[Kotlin] Add Kotlin plugin support to generate classes from Kotlin classes (#57)
This adds support for Kotlin compiled sources to be utilized in the assertj generator. This closes #48.
1 parent 24e5c47 commit b2d379d

File tree

5 files changed

+185
-28
lines changed

5 files changed

+185
-28
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
- uses: gradle/gradle-build-action@v2
2121

2222
- name: Verify all checks pass
23-
run: ./gradlew check
23+
run: ./gradlew test
2424

2525
- name: Publish plugin
2626
run: ./gradlew publishPlugins

build.gradle.kts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,15 @@ repositories {
6262
}
6363

6464
dependencies {
65+
implementation(kotlin("stdlib"))
66+
6567
api(gradleApi())
6668
api("com.google.code.findbugs:jsr305:3.0.2")
6769
api("org.assertj:assertj-assertions-generator:2.2.1")
6870

6971
implementation(gradleKotlinDsl())
7072
implementation("com.google.guava:guava:31.1-jre")
73+
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10")
7174

7275
testApi("junit:junit:4.13.2")
7376

@@ -90,14 +93,6 @@ tasks.check {
9093
dependsOn(tasks.named("projectHealth"))
9194
}
9295

93-
tasks.compileGroovy {
94-
classpath += files(tasks.compileKotlin.flatMap { it.destinationDirectory })
95-
}
96-
97-
tasks.classes {
98-
dependsOn(tasks.compileGroovy)
99-
}
100-
10196
detekt {
10297
parallel = true
10398
autoCorrect = true

src/main/kotlin/org/assertj/generator/gradle/AssertJGeneratorGradlePlugin.kt

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@ import org.gradle.api.logging.Logging
2020
import org.gradle.api.model.ObjectFactory
2121
import org.gradle.api.plugins.JavaPluginExtension
2222
import org.gradle.api.tasks.SourceSet
23+
import org.gradle.api.tasks.TaskProvider
2324
import org.gradle.kotlin.dsl.create
2425
import org.gradle.kotlin.dsl.getByType
26+
import org.gradle.kotlin.dsl.named
2527
import org.gradle.kotlin.dsl.register
28+
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
29+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2630
import javax.inject.Inject
2731

2832
private val logger = Logging.getLogger(AssertJGeneratorGradlePlugin::class.java)
@@ -45,34 +49,67 @@ open class AssertJGeneratorGradlePlugin @Inject internal constructor(
4549
// For each sourceSet we're enacting an action on each one that adds an assertJ generation task to it
4650
logger.info("sourceSet: $sourceSet creating tasks")
4751

52+
sourceSet.extensions.create<AssertJGeneratorExtension>(
53+
"assertJ",
54+
objects,
55+
project,
56+
sourceSet,
57+
)
58+
4859
sourceSet.addAndConfigureAssertJGenerate(project, javaPluginExtension)
4960
}
61+
62+
// If we don't have the java plugin, we can't compile the generated sources. Thus, this is in the
63+
// withPlugin() block
64+
project.pluginManager.withPlugin("org.jetbrains.kotlin.jvm") {
65+
project.applyForKotlin(javaPluginExtension)
66+
}
5067
}
5168
}
5269

53-
private fun SourceSet.addAndConfigureAssertJGenerate(
54-
project: Project,
55-
javaPlugin: JavaPluginExtension,
56-
) {
57-
extensions.create<AssertJGeneratorExtension>(
58-
"assertJ",
59-
objects,
60-
project,
61-
this,
62-
)
63-
64-
val generateTaskName = getTaskName("generate", "assertJ")
65-
66-
logger.info("generationTask: $generateTaskName, sourceSet: $this")
67-
68-
// Create a new task for the source set
69-
val generationTask = project.tasks.register<AssertJGenerationTask>(generateTaskName, objects, this)
70-
generationTask.configure { task ->
71-
task.classDirectories.srcDir(this.java.classesDirectory)
70+
private fun Project.applyForKotlin(javaPluginExtension: JavaPluginExtension) {
71+
kotlinExtension.sourceSets.configureEach { kotlinSourceSet ->
72+
if (kotlinSourceSet.name == "test") return@configureEach
73+
74+
javaPluginExtension.sourceSets.named(kotlinSourceSet.name) { javaSourceSet ->
75+
val kotlinCompile = project.tasks.named<KotlinCompile>(javaSourceSet.getCompileTaskName("kotlin"))
76+
77+
project.configureGenerateTask(javaSourceSet) {
78+
dependsOn(kotlinCompile)
79+
80+
classDirectories.srcDir(kotlinCompile.flatMap { it.destinationDirectory })
81+
}
82+
}
83+
}
84+
}
85+
86+
private fun SourceSet.addAndConfigureAssertJGenerate(project: Project, javaPlugin: JavaPluginExtension) {
87+
val generationTask = project.registerGenerateTask(this) {
88+
classDirectories.srcDir(this@addAndConfigureAssertJGenerate.java.classesDirectory)
7289
}
7390

7491
javaPlugin.sourceSets.named("test").configure { sourceSet ->
7592
sourceSet.java.srcDir(generationTask.flatMap { it.outputDir })
7693
}
7794
}
95+
96+
private fun Project.registerGenerateTask(
97+
sourceSet: SourceSet,
98+
configureBlock: AssertJGenerationTask.() -> Unit,
99+
): TaskProvider<AssertJGenerationTask> {
100+
return tasks.register<AssertJGenerationTask>(sourceSet.generateAssertJTaskName, objects, sourceSet).apply {
101+
configure(configureBlock)
102+
}
103+
}
104+
105+
private fun Project.configureGenerateTask(
106+
sourceSet: SourceSet,
107+
configureBlock: AssertJGenerationTask.() -> Unit,
108+
): TaskProvider<AssertJGenerationTask> {
109+
return tasks.named<AssertJGenerationTask>(sourceSet.generateAssertJTaskName) {
110+
configureBlock()
111+
}
112+
}
78113
}
114+
115+
private val SourceSet.generateAssertJTaskName: String get() = getTaskName("generate", "assertJ")
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2023. assertj-generator-gradle-plugin contributors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5+
* the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*/
13+
package org.assertj.generator.gradle
14+
15+
import org.assertj.core.api.Assertions.assertThat
16+
import org.assertj.generator.gradle.TestUtils.writeDefaultBuildKts
17+
import org.gradle.testkit.runner.GradleRunner
18+
import org.junit.Rule
19+
import org.junit.Test
20+
import org.junit.rules.TemporaryFolder
21+
import java.nio.file.Paths
22+
23+
internal class KotlinSourcesBuild {
24+
25+
@get:Rule
26+
val testProjectDir = TemporaryFolder()
27+
28+
@Test
29+
fun `only have kotlin sources`() {
30+
testProjectDir.newFile("build.gradle.kts").writeDefaultBuildKts()
31+
32+
val srcDir = testProjectDir.newFolder("src", "main", "kotlin")
33+
34+
val packagePath = Paths.get("org/example/")
35+
36+
val srcPackagePath = srcDir.toPath().resolve(packagePath)
37+
srcPackagePath.toFile().mkdirs()
38+
val helloWorldKt = srcPackagePath.resolve("HelloWorld2.kt").toFile()
39+
40+
helloWorldKt.writeKotlin(
41+
"""
42+
package org.example
43+
44+
class HelloWorld2 {
45+
// Getter & Setter
46+
val isBrains = false
47+
48+
// Getter
49+
val foo = -1
50+
}
51+
"""
52+
)
53+
54+
val testDir = testProjectDir.newFolder("src", "test", "kotlin")
55+
56+
testDir.toPath().resolve(packagePath).toFile().mkdirs()
57+
val testPackagePath = testDir.toPath().resolve(packagePath)
58+
testPackagePath.toFile().mkdirs()
59+
val helloWorldTestKt = testPackagePath.resolve("HelloWorldTest.kt").toFile()
60+
61+
helloWorldTestKt.writeKotlin(
62+
"""
63+
package org.example
64+
65+
import org.junit.Test
66+
import org.example.Assertions.assertThat
67+
68+
internal class HelloWorldTest {
69+
@Test
70+
fun check() {
71+
val hw = HelloWorld2()
72+
assertThat(hw).hasFoo(-1)
73+
.isNotBrains()
74+
}
75+
}
76+
"""
77+
)
78+
79+
val result = GradleRunner.create()
80+
.withProjectDir(testProjectDir.root)
81+
.withDebug(true)
82+
.withPluginClasspath()
83+
.withArguments("-i", "-s", "test")
84+
.build()
85+
86+
assertThat(result.task(":generateAssertJ")).isSuccessful()
87+
assertThat(result.task(":test")).isSuccessful()
88+
89+
val generatedPackagePath = testProjectDir.root.toPath()
90+
.resolve("build/generated-src/main-test/java")
91+
.resolve("org/example")
92+
93+
assertThat(generatedPackagePath)
94+
.isDirectoryContaining("glob:**/Assertions.java")
95+
.isDirectoryContaining("glob:**/HelloWorld2Assert.java")
96+
}
97+
}

src/test/kotlin/org/assertj/generator/gradle/TestUtils.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,32 @@ internal object TestUtils {
5353

5454
@JvmStatic
5555
fun File.writeDefaultBuildFile(): Unit = this.writeBuildFile("")
56+
57+
fun File.writeBuildKts(@Language("Kotlin") content: String = "") {
58+
writeKotlin(
59+
"""
60+
plugins {
61+
id("org.assertj.generator")
62+
`java`
63+
id("org.jetbrains.kotlin.jvm") version "1.8.10"
64+
}
65+
66+
$content
67+
68+
repositories {
69+
mavenCentral()
70+
}
71+
72+
dependencies {
73+
implementation(kotlin("stdlib"))
74+
implementation("javax.annotation:javax.annotation-api:1.3.2")
75+
76+
testImplementation("org.assertj:assertj-core:3.24.2")
77+
testImplementation("junit:junit:4.13.1")
78+
}
79+
""".trimIndent()
80+
)
81+
}
82+
83+
fun File.writeDefaultBuildKts(): Unit = this.writeBuildKts("")
5684
}

0 commit comments

Comments
 (0)