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
4 changes: 4 additions & 0 deletions .github/workflows/build-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
- run: |
./gradlew build
./gradlew -p tests build
./gradlew -p test-kgp-1-9 verifyCompatibility
sed -i.bak 's/.version("1.9.0")/.version("2.2.0")/' test-kgp-1-9/build.gradle.kts
./gradlew -p test-kgp-1-9 verifyCompatibility
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.kotlin
.fleet
.gradle
*.bak

# Build outputs
build
Expand Down
135 changes: 135 additions & 0 deletions test-kgp-1-9/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import cast.cast
import com.nfeld.jsonpathkt.kotlinx.resolvePathOrNull
import java.util.zip.ZipInputStream
import kotlinx.metadata.jvm.KotlinModuleMetadata
import kotlinx.metadata.jvm.UnstableMetadataApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.jsonPrimitive
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.Opcodes

plugins {
id("org.jetbrains.kotlin.jvm").version("1.9.0")
id("com.gradleup.compat.patrouille")
id("maven-publish")
}

buildscript {
dependencies {
classpath("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.0")
classpath("com.eygraber:jsonpathkt-kotlinx:3.0.2")
classpath("net.mbonnin.cast:cast:0.0.1")
classpath("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.9.0")
classpath("org.ow2.asm:asm:9.8")
}
}

compatPatrouille {
java(11)
kotlin("1.9.0")
}
abstract class VerifyCompatibility : DefaultTask() {
@get:InputFiles
abstract val m2Dir: ConfigurableFileCollection

/**
* Verifies that:
* - Gradle metadata contains has "org.gradle.jvm.version" set to "11"
* - The .class files have a version of 55 (java 11).
* - The .kotlin_module files have a Kotlin version of 1.9.0.
*
* A future version could test KMP.
* .klib files can be read using "org.jetbrains.kotlin:kotlin-util-klib".
* Not sure how to read the commonMetadata .jar artifact, though; it's a .jar that contains .kn data.
* Interestingly, when using KMP, "org.gradle.jvm.version" is not set, not really sure why.
*/
@OptIn(UnstableMetadataApi::class)
@TaskAction
fun taskAction() {
val moduleFiles = m2Dir.files.filter { it.extension == "module" }.toList()

check(moduleFiles.size == 1) {
"Expected exactly one module file, got ${moduleFiles.size}: $moduleFiles"
}

moduleFiles.single().readText().let {
Json.parseToJsonElement(it)
}.resolvePathOrNull("$.variants.*.attributes[\"org.gradle.jvm.version\"]")!!
.cast<JsonArray>()
.map {
it.jsonPrimitive.content
}
.forEach {
check(it == "11") {
"Expected all modules to be built with Java 11, got $it"
}
}

val jarFiles = m2Dir.files.filter { it.extension == "jar" }.toList()
check(moduleFiles.size == 1) {
"Expected exactly one jar file, got ${jarFiles.size}: $jarFiles"
}
jarFiles.forEach { jarFile ->
ZipInputStream(jarFile.inputStream()).use { zis ->
var entry = zis.nextEntry
while (entry != null) {
if (entry.name.endsWith(".class")) {

ClassReader(zis).accept(object : ClassVisitor(Opcodes.ASM9) {
override fun visit(
version: Int,
access: Int,
name: String?,
signature: String?,
superName: String?,
interfaces: Array<out String?>?
) {
check(version == 55) {
"Expected class files be of version 55, got $version"
}
}
}, 0)
} else if (entry.name.endsWith(".kotlin_module")) {
val metadata = KotlinModuleMetadata.read(zis.readAllBytes())
metadata.version.apply {
check("$major.$minor.$patch" == "1.9.0") {
"Expected Kotlin version 1.9.0, got $major.$minor.$patch."
}
}
}
entry = zis.nextEntry
}
}
}
}
}

group = "com.example"
version = "0.0.0-SNAPSHOT"
publishing {
repositories {
maven {
name = "test"
url = uri(file("build/m2"))
}
}
publications {
create<MavenPublication>("maven") {
from(components["java"])
}
}
}

tasks.register("cleanM2", Delete::class.java) {
delete(file("build/m2"))
}
tasks.named("publishAllPublicationsToTestRepository") {
dependsOn("cleanM2")
}
tasks.register("verifyCompatibility", VerifyCompatibility::class.java) {
m2Dir.from(fileTree(layout.buildDirectory.dir("m2")))
dependsOn("publishAllPublicationsToTestRepository")
}

1 change: 1 addition & 0 deletions test-kgp-1-9/gradle
1 change: 1 addition & 0 deletions test-kgp-1-9/gradlew

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions test-kgp-1-9/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pluginManagement {
listOf(repositories, dependencyResolutionManagement.repositories).forEach {
it.mavenCentral()
}
}


includeBuild("../")
1 change: 1 addition & 0 deletions test-kgp-1-9/src/main/kotlin/hello.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
val hello = "Hello"
1 change: 1 addition & 0 deletions tests/check-api-dependencies/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ compatPatrouille {
}

dependencies {
// Uncomment to make `compatPatrouilleCheckApiDependencies` fail because incompatible metadata was exposed to consumers.
// api("org.jetbrains.kotlin:kotlin-stdlib:2.1.21")
api(libs.kotlinx.metadata)
}