Skip to content

Commit 4d21585

Browse files
committed
wip
1 parent 832ad11 commit 4d21585

File tree

11 files changed

+311
-134
lines changed

11 files changed

+311
-134
lines changed

modules/bcv-gradle-plugin-functional-tests/build.gradle.kts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ testing.suites {
5959
"devMavenRepoDir",
6060
devPublish.devMavenRepo.asFile.get().invariantSeparatorsPath,
6161
)
62+
val tmpDir = layout.buildDirectory.dir("test-temp").get().asFile
63+
systemProperty(
64+
"java.io.tmpdir",
65+
tmpDir.absoluteFile.invariantSeparatorsPath
66+
)
67+
doFirst {
68+
tmpDir.mkdirs()
69+
}
6270
}
6371
}
6472
}

modules/bcv-gradle-plugin-functional-tests/src/functionalTest/kotlin/kotlinx/validation/test/KlibVerificationTests.kt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package kotlinx.validation.test
22

33
import dev.adamko.kotlin.binary_compatibility_validator.test.utils.*
44
import dev.adamko.kotlin.binary_compatibility_validator.test.utils.api.*
5+
import io.kotest.assertions.withClue
56
import io.kotest.inspectors.shouldForAll
67
import io.kotest.matchers.comparables.shouldBeEqualComparingTo
78
import io.kotest.matchers.file.shouldExist
89
import io.kotest.matchers.file.shouldNotExist
10+
import io.kotest.matchers.shouldBe
911
import io.kotest.matchers.string.shouldContain
1012
import java.io.File
1113
import java.nio.file.Files
@@ -790,14 +792,16 @@ internal class KlibVerificationTests : BaseKotlinGradleTest() {
790792
projectName: String = "testproject",
791793
dumpTask: String = ":apiDump",
792794
) {
793-
shouldHaveRunTask(dumpTask, SUCCESS)
795+
withClue(output) {
796+
shouldHaveRunTask(dumpTask, SUCCESS)
794797

795-
val generatedDump = rootProjectAbiDump(projectName)
798+
val generatedDump = rootProjectAbiDump(projectName)
796799

797-
generatedDump.shouldExist()
800+
generatedDump.shouldExist()
798801

799-
val expected = readResourceFile(expectedDumpFileName)
800-
generatedDump.readText().invariantNewlines().shouldBeEqualComparingTo(expected)
802+
val expected = readResourceFile(expectedDumpFileName)
803+
generatedDump.readText().invariantNewlines() shouldBe expected
804+
}
801805
}
802806

803807
companion object {

modules/bcv-gradle-plugin-functional-tests/src/testFixtures/kotlin/api/BaseKotlinGradleTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import org.junit.jupiter.api.io.TempDir
66

77
open class BaseKotlinGradleTest {
88
@TempDir(cleanup = ON_SUCCESS)
9-
lateinit var testProjectDir: File
9+
lateinit var testTempDir: File
1010

11-
val rootProjectDir: File get() = testProjectDir
11+
val rootProjectDir: File get() = testTempDir.resolve("bcv-test-project")
1212

1313
val rootProjectApiDump: File get() = rootProjectDir.resolve("$API_DIR/${rootProjectDir.name}.api")
1414

modules/bcv-gradle-plugin-functional-tests/src/testFixtures/kotlin/api/TestDsl.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ class Runner {
221221
var configurationCache: Boolean = true
222222
var rerunTasks: Boolean = false
223223
var rerunTask: Boolean = false
224-
var buildCache: Boolean = true
224+
var buildCache: Boolean = false
225225
var stacktrace: Boolean = true
226226
var continues: Boolean = true
227227

modules/bcv-gradle-plugin/api/bcv-gradle-plugin.api

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public abstract class dev/adamko/kotlin/binary_compatibility_validator/BCVProjec
2121
public abstract fun getIgnoredClasses ()Lorg/gradle/api/provider/SetProperty;
2222
public abstract fun getIgnoredMarkers ()Lorg/gradle/api/provider/SetProperty;
2323
public abstract fun getIgnoredPackages ()Lorg/gradle/api/provider/SetProperty;
24+
public abstract fun getKotlinCompilerEmbeddableVersion ()Lorg/gradle/api/provider/Property;
2425
public abstract fun getKotlinxBinaryCompatibilityValidatorVersion ()Lorg/gradle/api/provider/Property;
2526
public abstract fun getNonPublicMarkers ()Lorg/gradle/api/provider/SetProperty;
2627
public abstract fun getOutputApiDir ()Lorg/gradle/api/file/DirectoryProperty;
@@ -86,13 +87,11 @@ public abstract class dev/adamko/kotlin/binary_compatibility_validator/targets/B
8687
public final fun getPlatformType ()Ljava/lang/String;
8788
}
8889

89-
public abstract class dev/adamko/kotlin/binary_compatibility_validator/targets/BCVKLibTarget : dev/adamko/kotlin/binary_compatibility_validator/targets/BCVTarget, dev/adamko/kotlin/binary_compatibility_validator/targets/KLibValidationSpec, org/gradle/api/Named {
90+
public abstract class dev/adamko/kotlin/binary_compatibility_validator/targets/BCVKLibTarget : dev/adamko/kotlin/binary_compatibility_validator/targets/BCVTarget, dev/adamko/kotlin/binary_compatibility_validator/targets/KLibValidationSpec, java/io/Serializable, org/gradle/api/Named {
9091
public abstract fun getCompilationDependencies ()Lorg/gradle/api/file/ConfigurableFileCollection;
9192
public abstract fun getCurrentPlatform ()Lorg/gradle/api/provider/Property;
9293
public abstract fun getHasKotlinSources ()Lorg/gradle/api/provider/Property;
93-
public abstract fun getInputAbiFile ()Lorg/gradle/api/file/RegularFileProperty;
9494
public abstract fun getKlibFile ()Lorg/gradle/api/file/ConfigurableFileCollection;
95-
public abstract fun getOutputAbiFile ()Lorg/gradle/api/file/RegularFileProperty;
9695
public abstract fun getSupportedByCurrentHost ()Lorg/gradle/api/provider/Property;
9796
public final fun getTargetName ()Ljava/lang/String;
9897
}
@@ -150,11 +149,14 @@ public abstract class dev/adamko/kotlin/binary_compatibility_validator/tasks/BCV
150149

151150
public abstract class dev/adamko/kotlin/binary_compatibility_validator/tasks/BCVApiGenerateTask : dev/adamko/kotlin/binary_compatibility_validator/tasks/BCVDefaultTask {
152151
public final fun generate ()V
152+
public abstract fun getExtantApiDumpDir ()Lorg/gradle/api/file/DirectoryProperty;
153153
public abstract fun getInputDependencies ()Lorg/gradle/api/file/ConfigurableFileCollection;
154154
public abstract fun getOutputApiBuildDir ()Lorg/gradle/api/file/DirectoryProperty;
155155
public abstract fun getProjectName ()Lorg/gradle/api/provider/Property;
156156
public abstract fun getRuntimeClasspath ()Lorg/gradle/api/file/ConfigurableFileCollection;
157+
public final fun getSupportedTargetsDir ()Ljava/io/File;
157158
public final fun getTargets ()Lorg/gradle/api/NamedDomainObjectContainer;
159+
public final fun getUnsupportedTargetsDir ()Ljava/io/File;
158160
}
159161

160162
public abstract class dev/adamko/kotlin/binary_compatibility_validator/tasks/BCVDefaultTask : org/gradle/api/DefaultTask {

modules/bcv-gradle-plugin/src/main/kotlin/BCVProjectPlugin.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.API_
55
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.API_DUMP_TASK_NAME
66
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.API_GENERATE_TASK_NAME
77
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.EXTENSION_NAME
8+
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.PREPARE_API_GENERATE_TASK_NAME
89
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.RUNTIME_CLASSPATH_CONFIGURATION_NAME
910
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.RUNTIME_CLASSPATH_RESOLVER_CONFIGURATION_NAME
1011
import dev.adamko.kotlin.binary_compatibility_validator.adapters.createJavaTestFixtureTargets
@@ -193,12 +194,12 @@ constructor(
193194

194195

195196
private fun registerBcvTasks(project: Project) {
196-
// val prepareApiGenerateTask =
197-
// project.tasks.register(PREPARE_API_GENERATE_TASK_NAME, BCVApiGeneratePreparationTask::class)
198-
//
197+
val prepareApiGenerateTask =
198+
project.tasks.register(PREPARE_API_GENERATE_TASK_NAME, BCVApiGeneratePreparationTask::class)
199+
199200
val apiGenerateTask =
200201
project.tasks.register(API_GENERATE_TASK_NAME, BCVApiGenerateTask::class) {
201-
// extantApiDumpDir.convention(prepareApiGenerateTask.flatMap { it.apiDirectory })
202+
extantApiDumpDir.convention(prepareApiGenerateTask.flatMap { it.apiDirectory })
202203
}
203204

204205
project.tasks.register(API_DUMP_TASK_NAME, BCVApiDumpTask::class) {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package dev.adamko.kotlin.binary_compatibility_validator.internal
2+
3+
import kotlin.time.Duration
4+
import kotlin.time.Duration.Companion.nanoseconds
5+
6+
// can't use kotlin.time.measureTime {} because Gradle forces the language level to be low.
7+
internal fun measureTime(block: () -> Unit): Duration =
8+
System.nanoTime().let { startTime ->
9+
block()
10+
(System.nanoTime() - startTime).nanoseconds
11+
}

modules/bcv-gradle-plugin/src/main/kotlin/tasks/BCVApiGenerateTask.kt

Lines changed: 107 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
package dev.adamko.kotlin.binary_compatibility_validator.tasks
22

3-
import dev.adamko.kotlin.binary_compatibility_validator.internal.BCVExperimentalApi
4-
import dev.adamko.kotlin.binary_compatibility_validator.internal.BCVInternalApi
5-
import dev.adamko.kotlin.binary_compatibility_validator.internal.adding
6-
import dev.adamko.kotlin.binary_compatibility_validator.internal.domainObjectContainer
3+
import dev.adamko.kotlin.binary_compatibility_validator.internal.*
74
import dev.adamko.kotlin.binary_compatibility_validator.targets.BCVJvmTarget
85
import dev.adamko.kotlin.binary_compatibility_validator.targets.BCVKLibTarget
96
import dev.adamko.kotlin.binary_compatibility_validator.targets.BCVTarget
107
import dev.adamko.kotlin.binary_compatibility_validator.workers.JvmSignaturesWorker
8+
import dev.adamko.kotlin.binary_compatibility_validator.workers.KLibInferSignaturesWorker
9+
import dev.adamko.kotlin.binary_compatibility_validator.workers.KLibMergeWorker
1110
import dev.adamko.kotlin.binary_compatibility_validator.workers.KLibSignaturesWorker
1211
import java.io.File
1312
import javax.inject.Inject
@@ -19,6 +18,7 @@ import org.gradle.api.file.FileSystemOperations
1918
import org.gradle.api.model.ObjectFactory
2019
import org.gradle.api.provider.Property
2120
import org.gradle.api.tasks.*
21+
import org.gradle.api.tasks.PathSensitivity.RELATIVE
2222
import org.gradle.kotlin.dsl.*
2323
import org.gradle.workers.WorkQueue
2424
import org.gradle.workers.WorkerExecutor
@@ -47,17 +47,25 @@ constructor(
4747

4848
@get:Input
4949
abstract val projectName: Property<String>
50-
//
51-
// /**
52-
// * A directory containing a copy of any currently existing API Dump files.
53-
// * Provided by [BCVApiGeneratePreparationTask].
54-
// */
55-
// @get:InputFiles
56-
// abstract val extantApiDumpDir: DirectoryProperty
50+
51+
/**
52+
* A directory containing a copy of any currently existing API Dump files.
53+
* Provided by [BCVApiGeneratePreparationTask].
54+
*/
55+
@get:InputDirectory
56+
@get:PathSensitive(RELATIVE)
57+
@get:Optional
58+
abstract val extantApiDumpDir: DirectoryProperty
5759

5860
@get:OutputDirectory
5961
abstract val outputApiBuildDir: DirectoryProperty
6062

63+
@get:LocalState
64+
val supportedTargetsDir: File get() = temporaryDir.resolve("klib-supported")
65+
66+
@get:LocalState
67+
val unsupportedTargetsDir: File get() = temporaryDir.resolve("klib-unsupported")
68+
6169
@TaskAction
6270
fun generate() {
6371
val workQueue = prepareWorkQueue()
@@ -66,6 +74,12 @@ constructor(
6674
fs.delete { delete(outputApiBuildDir) }
6775
outputApiBuildDir.asFile.mkdirs()
6876

77+
fs.delete { delete(supportedTargetsDir) }
78+
supportedTargetsDir.mkdirs()
79+
80+
fs.delete { delete(unsupportedTargetsDir) }
81+
unsupportedTargetsDir.mkdirs()
82+
6983
logger.lifecycle("[$path] got ${targets.size} targets : ${targets.joinToString { it.name }}")
7084

7185
val enabledTargets = targets.matching { it.enabled.getOrElse(true) }
@@ -166,24 +180,52 @@ constructor(
166180
klibTargets.partition { it.supportedByCurrentHost.get() }
167181
logger.lifecycle("[$path] generating ${supportedKLibTargets.size} supported KLib targets : ${supportedKLibTargets.joinToString { it.name }}")
168182

169-
supportedKLibTargets.forEach { target ->
170-
workQueue.submit(
171-
target = target,
172-
outputDir = outputApiBuildDir.asFile,
173-
)
183+
val supportedKLibGenDuration = measureTime {
184+
supportedKLibTargets.forEach { target ->
185+
workQueue.submit(
186+
target = target,
187+
outputDir = supportedTargetsDir,
188+
)
189+
}
190+
workQueue.await()
174191
}
175-
176-
workQueue.await()
177-
logger.lifecycle("[$path] finished generating supported KLib targets.")
192+
logger.lifecycle("[$path] finished generating supported KLib targets in $supportedKLibGenDuration")
178193

179194
logger.lifecycle("[$path] generating ${unsupportedKLibTargets.size} unsupported KLib targets : ${unsupportedKLibTargets.joinToString { it.name }}")
180195

181-
supportedKLibTargets.forEach { target ->
182-
workQueue.submit(
183-
target = target,
184-
outputDir = outputApiBuildDir.asFile,
185-
)
196+
val unsupportedKLibGenDuration = measureTime {
197+
unsupportedKLibTargets.forEach { target ->
198+
workQueue.inferKLib(
199+
target = target,
200+
supportedTargetDumpFiles = supportedTargetsDir.walk().filter { it.isFile }.toSet(),
201+
extantApiDumpFile = extantApiDumpDir.asFile.orNull?.walk()?.filter { it.isFile }
202+
?.firstOrNull(),
203+
outputDir = unsupportedTargetsDir,
204+
)
205+
}
186206
}
207+
logger.lifecycle("[$path] finished generating unsupported KLib targets in $unsupportedKLibGenDuration")
208+
209+
workQueue.await()
210+
211+
val allTargetDumpFiles =
212+
supportedTargetsDir.walk().filter { it.isFile }.toSet() union
213+
unsupportedTargetsDir.walk().filter { it.isFile }.toSet()
214+
215+
logger.lifecycle("[$path] merging ${allTargetDumpFiles.size} dump files : ${allTargetDumpFiles.joinToString { it.name }}")
216+
217+
workQueue.merge(
218+
projectName.get(),
219+
targetDumpFiles = allTargetDumpFiles,
220+
outputDir = outputApiBuildDir.asFile,
221+
)
222+
workQueue.await()
223+
224+
logger.lifecycle(
225+
"[$path] merged ${allTargetDumpFiles.size} dump files : ${
226+
outputApiBuildDir.asFile.walk().filter { it.isFile }.toList()
227+
}"
228+
)
187229
}
188230

189231
@OptIn(BCVExperimentalApi::class)
@@ -202,7 +244,7 @@ constructor(
202244

203245
this@worker.klib.set(target.klibFile.singleFile)
204246
this@worker.signatureVersion.set(target.signatureVersion)
205-
this@worker.supportedByCurrentHost.set(target.supportedByCurrentHost)
247+
// this@worker.supportedByCurrentHost.set(target.supportedByCurrentHost)
206248

207249
// this@worker.targets.addAll(klibTargets)
208250

@@ -211,5 +253,45 @@ constructor(
211253
this@worker.ignoredClasses.set(target.ignoredClasses)
212254
}
213255
}
256+
257+
@OptIn(BCVExperimentalApi::class)
258+
private fun WorkQueue.inferKLib(
259+
target: BCVKLibTarget,
260+
supportedTargetDumpFiles: Set<File>,
261+
extantApiDumpFile: File?,
262+
outputDir: File,
263+
) {
264+
val task = this@BCVApiGenerateTask
265+
266+
@OptIn(BCVInternalApi::class)
267+
submit(KLibInferSignaturesWorker::class) worker@{
268+
this@worker.targetName.set(target.name)
269+
this@worker.taskPath.set(task.path)
270+
271+
this@worker.outputApiDir.set(outputDir)
272+
273+
this@worker.supportedTargetDumpFiles.from(supportedTargetDumpFiles)
274+
this@worker.extantApiDumpFile.set(extantApiDumpFile)
275+
}
276+
}
277+
278+
@OptIn(BCVExperimentalApi::class)
279+
private fun WorkQueue.merge(
280+
projectName: String,
281+
targetDumpFiles: Set<File>,
282+
outputDir: File,
283+
) {
284+
val task = this@BCVApiGenerateTask
285+
286+
@OptIn(BCVInternalApi::class)
287+
submit(KLibMergeWorker::class) worker@{
288+
this@worker.projectName.set(projectName)
289+
this@worker.taskPath.set(task.path)
290+
291+
this@worker.outputApiDir.set(outputDir)
292+
293+
this@worker.targetDumpFiles.from(targetDumpFiles)
294+
}
295+
}
214296
//endregion
215297
}

0 commit comments

Comments
 (0)