Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Klib-related Gradle tasks public #204

Merged
merged 26 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3b2dcb7
Cleanup build task
fzhinkin Mar 26, 2024
31311b2
Cleanup merge task
fzhinkin Mar 26, 2024
6081700
Cleanup extract and infer tasks
fzhinkin Mar 26, 2024
f968b33
Continue cleaning tasks up
fzhinkin Mar 26, 2024
54c14e8
Renamed tasks and its properties
fzhinkin Mar 26, 2024
cc3b34d
Use properties for task inputs and outputs
fzhinkin Mar 26, 2024
a09b259
Make tasks public
fzhinkin Mar 26, 2024
308224d
Use properties in CopyFile task
fzhinkin Mar 27, 2024
853fabb
Renamed a class holding target name and path to a dump
fzhinkin Mar 27, 2024
a3f077c
Use all supported targets when extracting dump
fzhinkin Apr 5, 2024
2d260c4
Avoid using hasAnySourcesPredicate-predicate to filter klib-related t…
fzhinkin Apr 5, 2024
e9a65fe
Use RegularFileProperties instead of File vars in the check task
fzhinkin Apr 5, 2024
d91fa97
Cleanup
fzhinkin Apr 5, 2024
1d15504
Enable conf cache for JVM tests
fzhinkin Apr 5, 2024
b1df69a
Added missing annotations, cleaned up the code
fzhinkin May 13, 2024
ca37fa6
Update KDoc
fzhinkin May 13, 2024
792a409
Replaced ListProperties with SetProperties
fzhinkin May 13, 2024
2a30a46
Update compare task after rebase on dev branch
fzhinkin Jun 6, 2024
8420f77
Remove some explicit dependencies between tasks
fzhinkin Jun 6, 2024
1d40fa2
Rely on file providers as much as possible
fzhinkin Jun 6, 2024
69f94f3
Get rid of object factory in compare-task's ctor
fzhinkin Jun 6, 2024
cd2a320
Align JVM- and KLib-validation behavior for empty projects
fzhinkin Jun 6, 2024
d8271ab
Update tasks
fzhinkin Jun 21, 2024
8411246
Use Gradle properties for all task settings
fzhinkin Jun 21, 2024
e306d73
Make KotlinApiCompareTask non cachable
fzhinkin Jun 21, 2024
df5c4f9
Fixed property kind
fzhinkin Jun 21, 2024
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
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