Skip to content

Commit

Permalink
Make Klib-related Gradle tasks public (Kotlin#204)
Browse files Browse the repository at this point in the history
  • Loading branch information
fzhinkin authored Jun 24, 2024
1 parent 465efe0 commit ee129a1
Show file tree
Hide file tree
Showing 18 changed files with 583 additions and 511 deletions.
85 changes: 55 additions & 30 deletions api/binary-compatibility-validator.api
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,13 @@ public final class kotlinx/validation/BinaryCompatibilityValidatorPlugin : org/g
}

public abstract class kotlinx/validation/BuildTaskBase : org/gradle/api/DefaultTask {
public field outputApiFile Ljava/io/File;
public fun <init> ()V
public final fun getIgnoredClasses ()Ljava/util/Set;
public final fun getIgnoredPackages ()Ljava/util/Set;
public final fun getNonPublicMarkers ()Ljava/util/Set;
public final fun getOutputApiFile ()Ljava/io/File;
public final fun getPublicClasses ()Ljava/util/Set;
public final fun getPublicMarkers ()Ljava/util/Set;
public final fun getPublicPackages ()Ljava/util/Set;
public final fun setIgnoredClasses (Ljava/util/Set;)V
public final fun setIgnoredPackages (Ljava/util/Set;)V
public final fun setNonPublicMarkers (Ljava/util/Set;)V
public final fun setOutputApiFile (Ljava/io/File;)V
public final fun setPublicClasses (Ljava/util/Set;)V
public final fun setPublicMarkers (Ljava/util/Set;)V
public final fun setPublicPackages (Ljava/util/Set;)V
public final fun getIgnoredClasses ()Lorg/gradle/api/provider/SetProperty;
public final fun getIgnoredPackages ()Lorg/gradle/api/provider/SetProperty;
public final fun getNonPublicMarkers ()Lorg/gradle/api/provider/SetProperty;
public final fun getPublicClasses ()Lorg/gradle/api/provider/SetProperty;
public final fun getPublicMarkers ()Lorg/gradle/api/provider/SetProperty;
public final fun getPublicPackages ()Lorg/gradle/api/provider/SetProperty;
}

public abstract interface annotation class kotlinx/validation/ExperimentalBCVApi : java/lang/annotation/Annotation {
Expand All @@ -55,6 +46,12 @@ public abstract interface annotation class kotlinx/validation/ExperimentalBCVApi
public abstract interface annotation class kotlinx/validation/ExternalApi : java/lang/annotation/Annotation {
}

public final class kotlinx/validation/KlibDumpMetadata : java/io/Serializable {
public fun <init> (Lkotlinx/validation/api/klib/KlibTarget;Lorg/gradle/api/file/RegularFileProperty;)V
public final fun getDumpFile ()Lorg/gradle/api/file/RegularFileProperty;
public final fun getTarget ()Lkotlinx/validation/api/klib/KlibTarget;
}

public class kotlinx/validation/KlibValidationSettings {
public fun <init> ()V
public final fun getEnabled ()Z
Expand All @@ -65,24 +62,52 @@ public class kotlinx/validation/KlibValidationSettings {
public final fun setStrictValidation (Z)V
}

public class kotlinx/validation/KotlinApiBuildTask : kotlinx/validation/BuildTaskBase {
public field inputDependencies Lorg/gradle/api/file/FileCollection;
public abstract class kotlinx/validation/KotlinApiBuildTask : kotlinx/validation/BuildTaskBase {
public fun <init> ()V
public final fun getInputClassesDirs ()Lorg/gradle/api/file/FileCollection;
public final fun getInputDependencies ()Lorg/gradle/api/file/FileCollection;
public final fun getInputJar ()Lorg/gradle/api/file/RegularFileProperty;
public final fun setInputClassesDirs (Lorg/gradle/api/file/FileCollection;)V
public final fun setInputDependencies (Lorg/gradle/api/file/FileCollection;)V
public abstract fun getInputClassesDirs ()Lorg/gradle/api/file/ConfigurableFileCollection;
public abstract fun getInputDependencies ()Lorg/gradle/api/file/ConfigurableFileCollection;
public abstract fun getInputJar ()Lorg/gradle/api/file/RegularFileProperty;
public abstract fun getOutputApiFile ()Lorg/gradle/api/file/RegularFileProperty;
}

public class kotlinx/validation/KotlinApiCompareTask : org/gradle/api/DefaultTask {
public field generatedApiFile Ljava/io/File;
public field projectApiFile Ljava/io/File;
public fun <init> ()V
public final fun getGeneratedApiFile ()Ljava/io/File;
public final fun getProjectApiFile ()Ljava/io/File;
public final fun setGeneratedApiFile (Ljava/io/File;)V
public final fun setProjectApiFile (Ljava/io/File;)V
public final fun getGeneratedApiFile ()Lorg/gradle/api/file/RegularFileProperty;
public final fun getProjectApiFile ()Lorg/gradle/api/file/RegularFileProperty;
}

public abstract class kotlinx/validation/KotlinKlibAbiBuildTask : kotlinx/validation/BuildTaskBase {
public fun <init> ()V
public abstract fun getKlibFile ()Lorg/gradle/api/file/ConfigurableFileCollection;
public abstract fun getOutputAbiFile ()Lorg/gradle/api/file/RegularFileProperty;
public final fun getSignatureVersion ()Lorg/gradle/api/provider/Property;
public abstract fun getTarget ()Lorg/gradle/api/provider/Property;
}

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

public abstract class kotlinx/validation/KotlinKlibInferAbiTask : org/gradle/api/DefaultTask {
public fun <init> ()V
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 fun <init> ()V
public abstract fun getDumps ()Lorg/gradle/api/provider/SetProperty;
public abstract fun getMergedApiFile ()Lorg/gradle/api/file/RegularFileProperty;
}

public final class kotlinx/validation/_UtilsKt {
public static final fun toKlibTarget (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTarget;)Lkotlinx/validation/api/klib/KlibTarget;
}

public final class kotlinx/validation/api/ClassBinarySignature {
Expand Down Expand Up @@ -162,7 +187,7 @@ public final class kotlinx/validation/api/klib/KlibDumpKt {
public static final fun saveTo (Lkotlinx/validation/api/klib/KlibDump;Ljava/io/File;)V
}

public final class kotlinx/validation/api/klib/KlibSignatureVersion {
public final class kotlinx/validation/api/klib/KlibSignatureVersion : java/io/Serializable {
public static final field Companion Lkotlinx/validation/api/klib/KlibSignatureVersion$Companion;
public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I
Expand All @@ -174,7 +199,7 @@ public final class kotlinx/validation/api/klib/KlibSignatureVersion$Companion {
public final fun of (I)Lkotlinx/validation/api/klib/KlibSignatureVersion;
}

public final class kotlinx/validation/api/klib/KlibTarget {
public final class kotlinx/validation/api/klib/KlibTarget : java/io/Serializable {
public static final field Companion Lkotlinx/validation/api/klib/KlibTarget$Companion;
public fun equals (Ljava/lang/Object;)Z
public final fun getConfigurableName ()Ljava/lang/String;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@ internal class DefaultConfigTests : BaseKotlinGradleTest() {
}
}

val projectName = rootProjectDir.name
runner.buildAndFail().apply {
assertTrue { output.contains("Please ensure that ':apiDump' was executed") }
Assertions.assertThat(output).contains(
"Expected file with API declarations 'api/$projectName.api' does not exist."
).contains(
"Please ensure that ':apiDump' was executed in order to get an API dump to compare the build against"
)
assertTaskFailure(":apiCheck")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ class JvmProjectTests : BaseKotlinGradleTest() {
resolve("/examples/gradle/base/withPlugin.gradle.kts")
resolve("/examples/gradle/configuration/generatedSources/generatedJvmSources.gradle.kts")
}
// TODO: enable configuration cache back when we start skipping tasks correctly
runner(withConfigurationCache = false) {
runner {
arguments.add(":apiDump")
}
}
Expand All @@ -42,8 +41,7 @@ class JvmProjectTests : BaseKotlinGradleTest() {
apiFile(projectName = rootProjectDir.name) {
resolve("/examples/classes/GeneratedSources.dump")
}
// TODO: enable configuration cache back when we start skipping tasks correctly
runner(withConfigurationCache = false) {
runner {
arguments.add(":apiCheck")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ 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 @@ -48,27 +50,32 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
resolve("/examples/gradle/base/withNativePlugin.gradle.kts")
}
}

private fun BaseKotlinScope.additionalBuildConfig(config: String) {
buildGradleKts {
resolve(config)
}
}

private fun BaseKotlinScope.addToSrcSet(pathTestFile: String, sourceSet: String = "commonMain") {
val fileName = Paths.get(pathTestFile).fileName.toString()
kotlin(fileName, sourceSet) {
resolve(pathTestFile)
}
}

private fun BaseKotlinScope.runApiCheck() {
runner {
arguments.add(":apiCheck")
}
}

private fun BaseKotlinScope.runApiDump() {
runner {
arguments.add(":apiDump")
}
}

private fun assertApiCheckPassed(buildResult: BuildResult) {
buildResult.assertTaskSuccess(":apiCheck")
}
Expand Down Expand Up @@ -451,7 +458,7 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
}

@Test
fun `klibCheck if all klib-targets are unavailable`() {
fun `klibCheck should not fail if all klib-targets are unavailable`() {
val runner = test {
baseProjectSetting()
addToSrcSet("/examples/classes/TopLevelDeclarations.kt")
Expand All @@ -468,10 +475,32 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
}
}

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

@Test
fun `klibCheck should fail with strict validation if all klib-targets are unavailable`() {
val runner = test {
baseProjectSetting()
additionalBuildConfig("/examples/gradle/configuration/unsupported/enforce.gradle.kts")
addToSrcSet("/examples/classes/TopLevelDeclarations.kt")
abiFile(projectName = "testproject") {
// note that the regular dump is used, where linuxArm64 is presented
resolve("/examples/classes/TopLevelDeclarations.klib.dump")
}
runner {
arguments.add(
"-P$BANNED_TARGETS_PROPERTY_NAME=linuxArm64,linuxX64,mingwX64," +
"androidNativeArm32,androidNativeArm64,androidNativeX64,androidNativeX86"
)
arguments.add(":klibApiCheck")
}
}

runner.buildAndFail().apply {
Assertions.assertThat(output).contains(
"KLib ABI dump/validation requires at least one enabled klib target, but none were found."
)
assertTaskFailure(":klibApiExtractForValidation")
}
}

Expand Down Expand Up @@ -580,8 +609,10 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
checkKlibDump(runner.build(), "/examples/classes/AnotherBuildConfig.klib.dump")

// Update the source file by adding a declaration
val updatedSourceFile = File(this::class.java.getResource(
"/examples/classes/AnotherBuildConfigModified.kt")!!.toURI()
val updatedSourceFile = File(
this::class.java.getResource(
"/examples/classes/AnotherBuildConfigModified.kt"
)!!.toURI()
)
val existingSource = runner.projectDir.resolve(
"src/commonMain/kotlin/AnotherBuildConfig.kt"
Expand All @@ -601,8 +632,10 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
checkKlibDump(runner.build(), "/examples/classes/AnotherBuildConfig.klib.dump")

// Update the source file by adding a declaration
val updatedSourceFile = File(this::class.java.getResource(
"/examples/classes/AnotherBuildConfigLinuxArm64.kt")!!.toURI()
val updatedSourceFile = File(
this::class.java.getResource(
"/examples/classes/AnotherBuildConfigLinuxArm64.kt"
)!!.toURI()
)
val existingSource = runner.projectDir.resolve(
"src/linuxArm64Main/kotlin/AnotherBuildConfigLinuxArm64.kt"
Expand All @@ -626,8 +659,10 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
assertApiCheckPassed(runner.build())

// Update the source file by adding a declaration
val updatedSourceFile = File(this::class.java.getResource(
"/examples/classes/AnotherBuildConfigModified.kt")!!.toURI()
val updatedSourceFile = File(
this::class.java.getResource(
"/examples/classes/AnotherBuildConfigModified.kt"
)!!.toURI()
)
val existingSource = runner.projectDir.resolve(
"src/commonMain/kotlin/AnotherBuildConfig.kt"
Expand Down Expand Up @@ -665,12 +700,29 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
runApiDump()
}

runner.build().apply {
runner.withDebug(true).build().apply {
assertTaskSkipped(":klibApiDump")
}
assertFalse(runner.projectDir.resolve("api").exists())
}

@Test
fun `apiDump should remove dump file if the project does not contain sources anymore`() {
val runner = test {
baseProjectSetting()
addToSrcSet("/examples/classes/AnotherBuildConfig.kt", sourceSet = "commonTest")
abiFile(projectName = "testproject") {
resolve("/examples/classes/AnotherBuildConfig.klib.dump")
}
runApiDump()
}

runner.build().apply {
assertTaskSuccess(":klibApiDump")
}
assertFalse(runner.projectDir.resolve("api").resolve("testproject.klib.api").exists())
}

@Test
fun `apiDump should not fail if there is only one target`() {
val runner = test {
Expand All @@ -683,22 +735,26 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
}

@Test
fun `apiCheck should not fail for empty project`() {
fun `apiCheck should fail for empty project`() {
val runner = test {
baseProjectSetting()
addToSrcSet("/examples/classes/AnotherBuildConfig.kt", sourceSet = "commonTest")
runApiCheck()
}
runner.build()
runner.buildAndFail().apply {
assertTaskFailure(":klibApiExtractForValidation")
Assertions.assertThat(output).contains(
"File with project's API declarations 'api/testproject.klib.api' does not exist."
)
}
}

@Test
fun `apiDump for a project with generated sources only`() {
val runner = test {
baseProjectSetting()
additionalBuildConfig("/examples/gradle/configuration/generatedSources/generatedSources.gradle.kts")
// TODO: enable configuration cache back when we start skipping tasks correctly
runner(withConfigurationCache = false) {
runner {
arguments.add(":apiDump")
}
}
Expand All @@ -713,11 +769,26 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
abiFile(projectName = "testproject") {
resolve("/examples/classes/GeneratedSources.klib.dump")
}
// TODO: enable configuration cache back when we start skipping tasks correctly
runner(withConfigurationCache = false) {
runner {
arguments.add(":apiCheck")
}
}
assertApiCheckPassed(runner.build())
}

@Test
fun `apiCheck should fail after a source set was removed`() {
val runner = test {
baseProjectSetting()
addToSrcSet("/examples/classes/AnotherBuildConfig.kt", "linuxX64Main")
addToSrcSet("/examples/classes/AnotherBuildConfig.kt", "linuxArm64Main")
abiFile(projectName = "testproject") {
resolve("/examples/classes/AnotherBuildConfig.klib.dump")
}
runApiCheck()
}
runner.buildAndFail().apply {
assertTaskFailure(":klibApiCheck")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package kotlinx.validation.test

import kotlinx.validation.api.*
import org.assertj.core.api.Assertions.assertThat
import org.gradle.testkit.runner.TaskOutcome
import org.junit.Test
import java.io.File

Expand Down
Loading

0 comments on commit ee129a1

Please sign in to comment.