Skip to content

Commit

Permalink
Merge branch 'master' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
fzhinkin committed Oct 18, 2024
2 parents 91dc2a9 + 18cd0df commit ecb23fe
Show file tree
Hide file tree
Showing 20 changed files with 660 additions and 96 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ The tool allows dumping binary API of a JVM part of a Kotlin library that is pub

## Requirements

Binary compatibility validator plugin requires Gradle `6.0` or newer.
Binary compatibility validator plugin requires Gradle `6.1.1` or newer.

Kotlin version `1.6.20` or newer.

## Setup

Expand All @@ -35,15 +37,15 @@ Binary compatibility validator is a Gradle plugin that can be added to your buil
- in `build.gradle.kts`
```kotlin
plugins {
id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.15.1"
id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.16.3"
}
```

- in `build.gradle`

```groovy
plugins {
id 'org.jetbrains.kotlinx.binary-compatibility-validator' version '0.15.1'
id 'org.jetbrains.kotlinx.binary-compatibility-validator' version '0.16.3'
}
```

Expand Down
16 changes: 12 additions & 4 deletions api/binary-compatibility-validator.api
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public final class kotlinx/validation/BinaryCompatibilityValidatorPlugin : org/g
public fun apply (Lorg/gradle/api/Project;)V
}

public abstract class kotlinx/validation/BuildTaskBase : org/gradle/api/DefaultTask {
public abstract class kotlinx/validation/BuildTaskBase : kotlinx/validation/WorkerAwareTaskBase {
public fun <init> ()V
public final fun getIgnoredClasses ()Lorg/gradle/api/provider/SetProperty;
public final fun getIgnoredPackages ()Lorg/gradle/api/provider/SetProperty;
Expand Down Expand Up @@ -86,28 +86,36 @@ public abstract class kotlinx/validation/KotlinKlibAbiBuildTask : kotlinx/valida
public abstract fun getTarget ()Lorg/gradle/api/provider/Property;
}

public abstract class kotlinx/validation/KotlinKlibExtractAbiTask : org/gradle/api/DefaultTask {
public abstract class kotlinx/validation/KotlinKlibExtractAbiTask : kotlinx/validation/WorkerAwareTaskBase {
public fun <init> ()V
public abstract fun getExecutor ()Lorg/gradle/workers/WorkerExecutor;
public abstract fun getInputAbiFile ()Lorg/gradle/api/file/RegularFileProperty;
public abstract fun getOutputAbiFile ()Lorg/gradle/api/file/RegularFileProperty;
public final fun getStrictValidation ()Lorg/gradle/api/provider/Property;
public abstract fun getTargetsToRemove ()Lorg/gradle/api/provider/SetProperty;
}

public abstract class kotlinx/validation/KotlinKlibInferAbiTask : org/gradle/api/DefaultTask {
public abstract class kotlinx/validation/KotlinKlibInferAbiTask : kotlinx/validation/WorkerAwareTaskBase {
public fun <init> ()V
public abstract fun getExecutor ()Lorg/gradle/workers/WorkerExecutor;
public abstract fun getInputDumps ()Lorg/gradle/api/provider/SetProperty;
public abstract fun getOldMergedKlibDump ()Lorg/gradle/api/file/RegularFileProperty;
public abstract fun getOutputAbiFile ()Lorg/gradle/api/file/RegularFileProperty;
public abstract fun getTarget ()Lorg/gradle/api/provider/Property;
}

public abstract class kotlinx/validation/KotlinKlibMergeAbiTask : org/gradle/api/DefaultTask {
public abstract class kotlinx/validation/KotlinKlibMergeAbiTask : kotlinx/validation/WorkerAwareTaskBase {
public fun <init> ()V
public abstract fun getDumps ()Lorg/gradle/api/provider/SetProperty;
public abstract fun getExecutor ()Lorg/gradle/workers/WorkerExecutor;
public abstract fun getMergedApiFile ()Lorg/gradle/api/file/RegularFileProperty;
}

public abstract class kotlinx/validation/WorkerAwareTaskBase : org/gradle/api/DefaultTask {
public fun <init> ()V
public abstract fun getRuntimeClasspath ()Lorg/gradle/api/file/ConfigurableFileCollection;
}

public final class kotlinx/validation/_UtilsKt {
public static final fun toKlibTarget (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTarget;)Lkotlinx/validation/api/klib/KlibTarget;
}
Expand Down
15 changes: 11 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ val createClasspathManifest = tasks.register("createClasspathManifest") {

dependencies {
implementation(gradleApi())
implementation(libs.kotlinx.metadata)
compileOnly(libs.kotlinx.metadata)
compileOnly(libs.kotlin.compiler.embeddable)
implementation(libs.ow2.asm)
implementation(libs.ow2.asmTree)
compileOnly(libs.ow2.asm)
compileOnly(libs.ow2.asmTree)
implementation(libs.javaDiffUtils)
compileOnly(libs.gradlePlugin.kotlin)

Expand Down Expand Up @@ -169,12 +169,17 @@ testing {
implementation(project())
implementation(libs.assertJ.core)
implementation(libs.kotlin.test)
implementation(libs.kotlin.compiler.embeddable)
}
}

val test by getting(JvmTestSuite::class) {
description = "Regular unit tests"
dependencies {
implementation(libs.kotlinx.metadata)
implementation(libs.kotlin.compiler.embeddable)
implementation(libs.ow2.asm)
implementation(libs.ow2.asmTree)
}
}

val functionalTest by creating(JvmTestSuite::class) {
Expand All @@ -184,6 +189,8 @@ testing {
dependencies {
implementation(files(createClasspathManifest))

implementation(libs.kotlinx.metadata)
implementation(libs.kotlin.compiler.embeddable)
implementation(gradleApi())
implementation(gradleTestKit())
}
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
version=0.15.0-SNAPSHOT
version=0.16.4-SNAPSHOT

kotlin.stdlib.default.dependency=false
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ internal class AppendableScope(val filePath: String) {

internal class Runner(withConfigurationCache: Boolean = true) {
val arguments: MutableList<String> = mutableListOf<String>().apply {
add("--stacktrace")
if (!koverEnabled && withConfigurationCache) {
// Configuration cache is incompatible with javaagents being enabled for Gradle
// See https://github.com/gradle/gradle/issues/25979
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,29 @@ internal class DefaultConfigTests : BaseKotlinGradleTest() {
}
}

@Test
fun `apiCheck should succeed when public classes match api file with K2`() {
val runner = test {
buildGradleKts {
resolve("/examples/gradle/base/withPluginK2.gradle.kts")
}
kotlin("AnotherBuildConfig.kt") {
resolve("/examples/classes/AnotherBuildConfig.kt")
}
apiFile(projectName = rootProjectDir.name) {
resolve("/examples/classes/AnotherBuildConfig.dump")
}

runner {
arguments.add(":apiCheck")
}
}

runner.build().apply {
assertTaskSuccess(":apiCheck")
}
}

@Test
fun `apiCheck should fail when public classes match api file ignoring case`() {
Assume.assumeTrue(underlyingFsIsCaseSensitive())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2016-2024 JetBrains s.r.o.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

package kotlinx.validation.test

import kotlinx.validation.api.*
import org.assertj.core.api.Assertions
import org.gradle.testkit.runner.GradleRunner
import org.junit.Assume
import org.junit.Test
import kotlin.test.assertTrue

class GradleCompatibilityTest : BaseKotlinGradleTest() {

@Test
fun test8Dot0() {
checkDumpWithGradle("8.0")
}

@Test
fun test7Dot0() {
checkDumpWithGradle("7.0")
}

@Test
fun testMin() {
val runner = test(gradleVersion = "6.1.1", injectPluginClasspath = false) {
buildGradleKts {
resolve("/examples/gradle/base/withPluginMinKotlin.gradle.kts")
}
kotlin("AnotherBuildConfig.kt") {
resolve("/examples/classes/AnotherBuildConfig.kt")
}

runner(withConfigurationCache = false) {
arguments.add(":apiDump")
}
}

skipInDebug(runner)

runner.build().apply {
assertTaskSuccess(":apiDump")

assertTrue(rootProjectApiDump.exists(), "api dump file should exist")

val expected = readFileList("/examples/classes/AnotherBuildConfig.dump")
Assertions.assertThat(rootProjectApiDump.readText()).isEqualToIgnoringNewLines(expected)
}
}

private fun skipInDebug(runner: GradleRunner) {
Assume.assumeFalse(
"The test requires a separate Gradle distributive " +
"so it could not be executed with debug turned on.",
runner.isDebug
)
}

private fun checkDumpWithGradle(gradleVersion: String) {
val runner = test(gradleVersion = gradleVersion, injectPluginClasspath = false) {
buildGradleKts {
resolve("/examples/gradle/base/withPlugin.gradle.kts")
}
kotlin("AnotherBuildConfig.kt") {
resolve("/examples/classes/AnotherBuildConfig.kt")
}

runner {
arguments.add(":apiDump")
}
}

skipInDebug(runner)

runner.build().apply {
assertTaskSuccess(":apiDump")

assertTrue(rootProjectApiDump.exists(), "api dump file should exist")

val expected = readFileList("/examples/classes/AnotherBuildConfig.dump")
Assertions.assertThat(rootProjectApiDump.readText()).isEqualToIgnoringNewLines(expected)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import org.assertj.core.api.Assertions
import org.gradle.testkit.runner.BuildResult
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.utils.addToStdlib.butIf
import org.junit.Assert
import org.junit.Assume
import org.junit.Test
import java.io.File
Expand Down Expand Up @@ -91,6 +89,22 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
checkKlibDump(runner.build(), "/examples/classes/TopLevelDeclarations.klib.with.linux.dump")
}

@Test
fun `apiDump for native targets in K2`() {
val runner = test {
settingsGradleKts {
resolve("/examples/gradle/settings/settings-name-testproject.gradle.kts")
}
buildGradleKts {
resolve("/examples/gradle/base/withNativePluginK2.gradle.kts")
}
addToSrcSet("/examples/classes/TopLevelDeclarations.kt")
runApiDump()
}

checkKlibDump(runner.build(), "/examples/classes/TopLevelDeclarations.klib.with.linux.dump")
}

@Test
fun `apiCheck for native targets`() {
val runner = test {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2016-2023 JetBrains s.r.o.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

plugins {
kotlin("multiplatform") version "2.0.0"
id("org.jetbrains.kotlinx.binary-compatibility-validator")
}

repositories {
mavenCentral()
}

kotlin {
linuxX64()
linuxArm64()
mingwX64()
androidNativeArm32()
androidNativeArm64()
androidNativeX64()
androidNativeX86()

sourceSets {
val commonMain by getting
val commonTest by getting {
dependencies {
implementation(kotlin("stdlib"))
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
}
}

apiValidation {
klib.enabled = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2016-2020 JetBrains s.r.o.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

plugins {
kotlin("jvm") version "2.0.0"
id("org.jetbrains.kotlinx.binary-compatibility-validator")
}

repositories {
mavenCentral()
}

dependencies {
implementation(kotlin("stdlib-jdk8"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2016-2020 JetBrains s.r.o.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

plugins {
kotlin("jvm") version "1.6.20"
id("org.jetbrains.kotlinx.binary-compatibility-validator")
}

repositories {
mavenCentral()
}

dependencies {
implementation(kotlin("stdlib-jdk8"))
}
7 changes: 7 additions & 0 deletions src/main/kotlin/-Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import java.io.File
import java.io.Serializable

/**
Expand Down Expand Up @@ -60,3 +61,9 @@ public class KlibDumpMetadata(
@get:PathSensitive(PathSensitivity.RELATIVE)
public val dumpFile: RegularFileProperty
) : Serializable

// Workaround for serialization exception occurring when KlibDumpMetadata is supplied to WorkerParameters.
internal class KlibMetadataLocal(
val target: KlibTarget,
val dumpFile: File
) : Serializable
Loading

0 comments on commit ecb23fe

Please sign in to comment.