[Gradle] ExternalTargetApi: Implement ExternalKotlinTargetSourcesJarUtils
This utils are intended to be used external target authors exclusively and shall help to create sources.jar files using regular Kotlin Multiplatform conventions. ^KT-58109 Verification Pending
This commit is contained in:
committed by
Space Team
parent
3f1faa26ac
commit
24debfd9b7
@@ -831,6 +831,13 @@ public final class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotli
|
|||||||
public static final fun ExternalKotlinTargetDescriptor (Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetDescriptor;
|
public static final fun ExternalKotlinTargetDescriptor (Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetSourcesJarUtilsKt {
|
||||||
|
public static final fun includeSources (Lorg/gradle/jvm/tasks/Jar;Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinCompilation;)V
|
||||||
|
public static final fun publishSources (Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinTarget;Lorg/gradle/api/tasks/TaskProvider;)V
|
||||||
|
public static final fun publishSources (Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinTarget;Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinCompilation;)V
|
||||||
|
public static final fun sourcesJarTask (Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinTarget;Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinCompilation;)Lorg/gradle/api/tasks/TaskProvider;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/SourceSetTreeClassifier {
|
public abstract class org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/SourceSetTreeClassifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
|||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.await
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationConfigurationsContainer
|
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationConfigurationsContainer
|
||||||
import org.jetbrains.kotlin.gradle.utils.ObservableSet
|
import org.jetbrains.kotlin.gradle.utils.ObservableSet
|
||||||
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
|
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
|
||||||
@@ -25,4 +27,9 @@ internal interface InternalKotlinCompilation<out T : KotlinCommonOptions> : Kotl
|
|||||||
internal val <T : KotlinCommonOptions> KotlinCompilation<T>.internal: InternalKotlinCompilation<T>
|
internal val <T : KotlinCommonOptions> KotlinCompilation<T>.internal: InternalKotlinCompilation<T>
|
||||||
get() = (this as? InternalKotlinCompilation<T>) ?: throw IllegalArgumentException(
|
get() = (this as? InternalKotlinCompilation<T>) ?: throw IllegalArgumentException(
|
||||||
"KotlinCompilation($name) ${this::class} does not implement ${InternalKotlinCompilation::class}"
|
"KotlinCompilation($name) ${this::class} does not implement ${InternalKotlinCompilation::class}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
internal suspend fun InternalKotlinCompilation<*>.awaitAllKotlinSourceSets(): Set<KotlinSourceSet> {
|
||||||
|
KotlinPluginLifecycle.Stage.AfterFinaliseCompilations.await()
|
||||||
|
return allKotlinSourceSets
|
||||||
|
}
|
||||||
+4
-64
@@ -7,14 +7,11 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
|||||||
|
|
||||||
import org.gradle.api.Plugin
|
import org.gradle.api.Plugin
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.file.DuplicatesStrategy
|
|
||||||
import org.gradle.api.plugins.BasePlugin
|
|
||||||
import org.gradle.api.plugins.JavaBasePlugin
|
import org.gradle.api.plugins.JavaBasePlugin
|
||||||
import org.gradle.api.tasks.TaskProvider
|
|
||||||
import org.gradle.jvm.tasks.Jar
|
|
||||||
import org.gradle.util.GradleVersion
|
import org.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.gradle.dsl.*
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.dsl.explicitApiModeAsCompilerArg
|
import org.jetbrains.kotlin.gradle.dsl.explicitApiModeAsCompilerArg
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
|
import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
@@ -37,14 +34,12 @@ import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinWasmTargetPreset
|
|||||||
import org.jetbrains.kotlin.gradle.targets.native.createFatFrameworks
|
import org.jetbrains.kotlin.gradle.targets.native.createFatFrameworks
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.artifact.registerKotlinArtifactsExtension
|
import org.jetbrains.kotlin.gradle.targets.native.tasks.artifact.registerKotlinArtifactsExtension
|
||||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool
|
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool
|
||||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility
|
||||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheck
|
||||||
import org.jetbrains.kotlin.gradle.utils.*
|
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
||||||
import org.jetbrains.kotlin.konan.target.presetName
|
import org.jetbrains.kotlin.konan.target.presetName
|
||||||
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class KotlinMultiplatformPlugin : Plugin<Project> {
|
class KotlinMultiplatformPlugin : Plugin<Project> {
|
||||||
|
|
||||||
@@ -259,62 +254,7 @@ internal fun applyUserDefinedAttributes(target: AbstractKotlinTarget) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun sourcesJarTask(compilation: KotlinCompilation<*>, componentName: String, artifactNameAppendix: String): TaskProvider<Jar> =
|
|
||||||
sourcesJarTask(
|
|
||||||
compilation.target.project,
|
|
||||||
compilation.target.project.future {
|
|
||||||
KotlinPluginLifecycle.Stage.AfterFinaliseCompilations.await()
|
|
||||||
compilation.allKotlinSourceSets.associate { it.name to it.kotlin }
|
|
||||||
},
|
|
||||||
componentName,
|
|
||||||
artifactNameAppendix
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun sourcesJarTask(
|
|
||||||
project: Project,
|
|
||||||
sourceSets: Future<Map<String, Iterable<File>>>,
|
|
||||||
taskNamePrefix: String,
|
|
||||||
artifactNameAppendix: String,
|
|
||||||
): TaskProvider<Jar> =
|
|
||||||
sourcesJarTaskNamed(lowerCamelCaseName(taskNamePrefix, "sourcesJar"), taskNamePrefix, project, sourceSets, artifactNameAppendix)
|
|
||||||
|
|
||||||
internal fun sourcesJarTaskNamed(
|
|
||||||
taskName: String,
|
|
||||||
componentName: String,
|
|
||||||
project: Project,
|
|
||||||
sourceSets: Future<Map<String, Iterable<File>>>,
|
|
||||||
artifactNameAppendix: String,
|
|
||||||
componentTypeName: String = "target",
|
|
||||||
): TaskProvider<Jar> {
|
|
||||||
project.locateTask<Jar>(taskName)?.let {
|
|
||||||
return it
|
|
||||||
}
|
|
||||||
|
|
||||||
val result = project.registerTask<Jar>(taskName) { sourcesJar ->
|
|
||||||
sourcesJar.archiveAppendix.set(artifactNameAppendix)
|
|
||||||
sourcesJar.archiveClassifier.set("sources")
|
|
||||||
sourcesJar.isPreserveFileTimestamps = false
|
|
||||||
sourcesJar.isReproducibleFileOrder = true
|
|
||||||
sourcesJar.group = BasePlugin.BUILD_GROUP
|
|
||||||
sourcesJar.description = "Assembles a jar archive containing the sources of $componentTypeName '$componentName'."
|
|
||||||
}
|
|
||||||
|
|
||||||
result.configure {
|
|
||||||
project.launch {
|
|
||||||
sourceSets.await().forEach { (sourceSetName, sourceSetFiles) ->
|
|
||||||
it.from(sourceSetFiles) { copySpec ->
|
|
||||||
copySpec.into(sourceSetName)
|
|
||||||
// Duplicates are coming from `SourceSets` that `sourceSet` depends on.
|
|
||||||
// Such dependency was added by Kotlin compilation.
|
|
||||||
// TODO: rethink approach for adding dependent `SourceSets` to Kotlin compilation `SourceSet`
|
|
||||||
copySpec.duplicatesStrategy = DuplicatesStrategy.WARN
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun Project.setupGeneralKotlinExtensionParameters() {
|
internal fun Project.setupGeneralKotlinExtensionParameters() {
|
||||||
project.launch {
|
project.launch {
|
||||||
|
|||||||
+78
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.mpp.external
|
||||||
|
|
||||||
|
import org.gradle.api.tasks.TaskProvider
|
||||||
|
import org.gradle.jvm.tasks.Jar
|
||||||
|
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.includeSources
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.internal
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTask
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will add all sources (including transitive dependsOn edges) from the compilation into this jar task given
|
||||||
|
* the multiplatform convention.
|
||||||
|
*
|
||||||
|
* e.g.
|
||||||
|
* ```
|
||||||
|
* src/commonMain/kotlin/CommonMain.kt
|
||||||
|
* src/jvmMain/kotlin/JvmMain.kt
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* will be packaged like
|
||||||
|
* ```
|
||||||
|
* /commonMain/CommonMain.kt
|
||||||
|
* /jvmMain/JvmMain.kt
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @since 1.9.20
|
||||||
|
*/
|
||||||
|
@ExternalKotlinTargetApi
|
||||||
|
fun Jar.includeSources(compilation: DecoratedExternalKotlinCompilation) {
|
||||||
|
includeSources(compilation.internal)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers, or returns if already existing, a sources jar task that contains
|
||||||
|
* all sources of the given compilation (see [includeSources])
|
||||||
|
*
|
||||||
|
* @since 1.9.20
|
||||||
|
*/
|
||||||
|
@ExternalKotlinTargetApi
|
||||||
|
fun DecoratedExternalKotlinTarget.sourcesJarTask(compilation: DecoratedExternalKotlinCompilation): TaskProvider<Jar> {
|
||||||
|
return sourcesJarTask(
|
||||||
|
compilation,
|
||||||
|
componentName = lowerCamelCaseName(targetName, compilation.name.takeUnless { compilation.isMain() }),
|
||||||
|
artifactNameAppendix = targetName.toLowerCaseAsciiOnly()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publishes the sources packaged by the given [jarTask] in this targets' publication.
|
||||||
|
*
|
||||||
|
* @since 1.9.20
|
||||||
|
*/
|
||||||
|
@ExternalKotlinTargetApi
|
||||||
|
fun DecoratedExternalKotlinTarget.publishSources(jarTask: TaskProvider<Jar>) {
|
||||||
|
delegate.sourcesElementsPublishedConfiguration.outgoing.artifact(jarTask) { artifact ->
|
||||||
|
artifact.classifier = "sources"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publishes the sources associated with the given [compilation] in this targets' publication.
|
||||||
|
* Will register the corresponding [sourcesJarTask] if necessary.
|
||||||
|
*
|
||||||
|
* @since 1.9.20
|
||||||
|
*/
|
||||||
|
@ExternalKotlinTargetApi
|
||||||
|
fun DecoratedExternalKotlinTarget.publishSources(compilation: DecoratedExternalKotlinCompilation) {
|
||||||
|
publishSources(sourcesJarTask(compilation))
|
||||||
|
}
|
||||||
+92
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.file.DuplicatesStrategy
|
||||||
|
import org.gradle.api.plugins.BasePlugin
|
||||||
|
import org.gradle.api.tasks.TaskProvider
|
||||||
|
import org.gradle.jvm.tasks.Jar
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.launch
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.Future
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.future
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
|
internal fun sourcesJarTask(compilation: KotlinCompilation<*>, componentName: String, artifactNameAppendix: String): TaskProvider<Jar> =
|
||||||
|
sourcesJarTask(
|
||||||
|
project = compilation.target.project,
|
||||||
|
sourceSets = compilation.target.project.future {
|
||||||
|
compilation.internal.awaitAllKotlinSourceSets().associate { it.name to it.kotlin }
|
||||||
|
},
|
||||||
|
componentName = componentName,
|
||||||
|
artifactNameAppendix = artifactNameAppendix
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun sourcesJarTask(
|
||||||
|
project: Project,
|
||||||
|
sourceSets: Future<Map<String, Iterable<File>>>,
|
||||||
|
componentName: String,
|
||||||
|
artifactNameAppendix: String,
|
||||||
|
): TaskProvider<Jar> =
|
||||||
|
sourcesJarTaskNamed(
|
||||||
|
taskName = lowerCamelCaseName(componentName, "sourcesJar"),
|
||||||
|
componentName = componentName,
|
||||||
|
project = project,
|
||||||
|
sourceSets = sourceSets,
|
||||||
|
artifactNameAppendix = artifactNameAppendix
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun sourcesJarTaskNamed(
|
||||||
|
taskName: String,
|
||||||
|
componentName: String,
|
||||||
|
project: Project,
|
||||||
|
sourceSets: Future<Map<String, Iterable<File>>>,
|
||||||
|
artifactNameAppendix: String,
|
||||||
|
componentTypeName: String = "target",
|
||||||
|
): TaskProvider<Jar> {
|
||||||
|
project.locateTask<Jar>(taskName)?.let {
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = project.registerTask<Jar>(taskName) { sourcesJar ->
|
||||||
|
sourcesJar.archiveAppendix.set(artifactNameAppendix)
|
||||||
|
sourcesJar.archiveClassifier.set("sources")
|
||||||
|
sourcesJar.isPreserveFileTimestamps = false
|
||||||
|
sourcesJar.isReproducibleFileOrder = true
|
||||||
|
sourcesJar.group = BasePlugin.BUILD_GROUP
|
||||||
|
sourcesJar.description = "Assembles a jar archive containing the sources of $componentTypeName '$componentName'."
|
||||||
|
project.launch {
|
||||||
|
sourcesJar.includeSources(sourceSets.await())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun Jar.includeSources(compilation: KotlinCompilation<*>) {
|
||||||
|
compilation.internal.allKotlinSourceSets.forAll { sourceSet ->
|
||||||
|
includeSources(sourceSet.name, sourceSet.kotlin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun Jar.includeSources(sourceSets: Map<String, Iterable<File>>) {
|
||||||
|
sourceSets.forEach { (name, sources) -> includeSources(name, sources) }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun Jar.includeSources(name: String, sources: Iterable<File>) {
|
||||||
|
from(sources) { spec ->
|
||||||
|
spec.into(name)
|
||||||
|
// Duplicates are coming from `SourceSets` that `sourceSet` depends on.
|
||||||
|
// Such dependency was added by Kotlin compilation.
|
||||||
|
// TODO: rethink approach for adding dependent `SourceSets` to Kotlin compilation `SourceSet`
|
||||||
|
spec.duplicatesStrategy = DuplicatesStrategy.WARN
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-21
@@ -17,39 +17,24 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier
|
import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier
|
||||||
import org.jetbrains.kotlin.gradle.plugin.hierarchy.orNull
|
import org.jetbrains.kotlin.gradle.plugin.hierarchy.orNull
|
||||||
import org.jetbrains.kotlin.gradle.plugin.launchInStage
|
import org.jetbrains.kotlin.gradle.plugin.launchInStage
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.*
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.CompilationFactory
|
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.CompilationFactory
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetDescriptor.TargetFactory
|
import org.jetbrains.kotlin.gradle.plugin.mpp.external.createCompilation
|
||||||
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
|
import org.jetbrains.kotlin.gradle.plugin.mpp.external.createExternalKotlinTarget
|
||||||
import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest
|
import org.jetbrains.kotlin.gradle.util.*
|
||||||
import org.jetbrains.kotlin.gradle.utils.property
|
import org.jetbrains.kotlin.gradle.utils.property
|
||||||
import org.jetbrains.kotlin.gradle.utils.toMap
|
import org.jetbrains.kotlin.gradle.utils.toMap
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
class ExternalKotlinTargetApiTests {
|
class ExternalKotlinTargetApiTests {
|
||||||
|
|
||||||
class FakeTarget(delegate: Delegate) : DecoratedExternalKotlinTarget(delegate)
|
|
||||||
class FakeCompilation(delegate: Delegate) : DecoratedExternalKotlinCompilation(delegate)
|
|
||||||
|
|
||||||
val project = buildProjectWithMPP()
|
val project = buildProjectWithMPP()
|
||||||
val kotlin = project.multiplatformExtension
|
val kotlin = project.multiplatformExtension
|
||||||
|
|
||||||
private fun ExternalKotlinTargetDescriptorBuilder<FakeTarget>.defaults() {
|
|
||||||
targetName = "fake"
|
|
||||||
platformType = KotlinPlatformType.jvm
|
|
||||||
targetFactory = TargetFactory(::FakeTarget)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ExternalKotlinCompilationDescriptorBuilder<FakeCompilation>.defaults() {
|
|
||||||
compilationName = "fake"
|
|
||||||
compilationFactory = CompilationFactory(::FakeCompilation)
|
|
||||||
defaultSourceSet = kotlin.sourceSets.maybeCreate("fake")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test - sourceSetClassifier - default`() = buildProjectWithMPP().runLifecycleAwareTest {
|
fun `test - sourceSetClassifier - default`() = buildProjectWithMPP().runLifecycleAwareTest {
|
||||||
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
|
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
|
||||||
val compilation = target.createCompilation<FakeCompilation> { defaults() }
|
val compilation = target.createCompilation<FakeCompilation> { defaults(kotlin) }
|
||||||
|
|
||||||
assertEquals(KotlinSourceSetTree("fake"), KotlinSourceSetTree.orNull(compilation))
|
assertEquals(KotlinSourceSetTree("fake"), KotlinSourceSetTree.orNull(compilation))
|
||||||
}
|
}
|
||||||
@@ -58,7 +43,7 @@ class ExternalKotlinTargetApiTests {
|
|||||||
fun `test - sourceSetClassifier - custom name`() = buildProjectWithMPP().runLifecycleAwareTest {
|
fun `test - sourceSetClassifier - custom name`() = buildProjectWithMPP().runLifecycleAwareTest {
|
||||||
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
|
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
|
||||||
val compilation = target.createCompilation<FakeCompilation> {
|
val compilation = target.createCompilation<FakeCompilation> {
|
||||||
defaults()
|
defaults(kotlin)
|
||||||
sourceSetTreeClassifierV2 = KotlinSourceSetTreeClassifier.Name("mySourceSetTree")
|
sourceSetTreeClassifierV2 = KotlinSourceSetTreeClassifier.Name("mySourceSetTree")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +58,7 @@ class ExternalKotlinTargetApiTests {
|
|||||||
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
|
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
|
||||||
|
|
||||||
val mainCompilation = target.createCompilation<FakeCompilation> {
|
val mainCompilation = target.createCompilation<FakeCompilation> {
|
||||||
defaults()
|
defaults(kotlin)
|
||||||
sourceSetTreeClassifierV2 = KotlinSourceSetTreeClassifier.Property(myProperty)
|
sourceSetTreeClassifierV2 = KotlinSourceSetTreeClassifier.Property(myProperty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+104
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("FunctionName")
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.unitTests
|
||||||
|
|
||||||
|
import org.gradle.api.file.SourceDirectorySet
|
||||||
|
import org.gradle.api.internal.file.copy.SingleParentCopySpec
|
||||||
|
import org.gradle.jvm.tasks.Jar
|
||||||
|
import org.gradle.kotlin.dsl.create
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.configurationResult
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.external.*
|
||||||
|
import org.jetbrains.kotlin.gradle.util.*
|
||||||
|
import org.jetbrains.kotlin.tooling.core.withClosure
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
import kotlin.test.fail
|
||||||
|
|
||||||
|
class ExternalKotlinTargetSourcesJarUtilsTest {
|
||||||
|
@Test
|
||||||
|
fun `test - includeSources`() = buildProjectWithMPP().runLifecycleAwareTest {
|
||||||
|
val target = multiplatformExtension.createExternalKotlinTarget<FakeTarget> { defaults() }
|
||||||
|
val compilation = target.createCompilation<FakeCompilation> {
|
||||||
|
defaults(multiplatformExtension)
|
||||||
|
defaultSourceSet = multiplatformExtension.sourceSets.maybeCreate("testSourceSet")
|
||||||
|
sourceSetTreeClassifierV2 = KotlinSourceSetTreeClassifier.Value(KotlinSourceSetTree.main)
|
||||||
|
}
|
||||||
|
|
||||||
|
val jar = tasks.create<Jar>("forTest")
|
||||||
|
jar.includeSources(compilation)
|
||||||
|
configurationResult.await()
|
||||||
|
|
||||||
|
val allSpecs = jar.rootSpec.withClosure { it.children }
|
||||||
|
|
||||||
|
val testSourceSetSpec = allSpecs.filterIsInstance<SingleParentCopySpec>().find { it.destPath == "testSourceSet" }
|
||||||
|
?: fail("Missing 'testSourceSet' in jar")
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
setOf(file("src/testSourceSet/kotlin")),
|
||||||
|
(testSourceSetSpec.sourcePaths.single() as SourceDirectorySet).srcDirs
|
||||||
|
)
|
||||||
|
|
||||||
|
val commonMainSpec = allSpecs.filterIsInstance<SingleParentCopySpec>().find { it.destPath == "commonMain" }
|
||||||
|
?: fail("Missing 'commonMain' in jar")
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
setOf(file("src/commonMain/kotlin")),
|
||||||
|
(commonMainSpec.sourcePaths.single() as SourceDirectorySet).srcDirs
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test - sourcesJarTask`() = buildProjectWithMPP().runLifecycleAwareTest {
|
||||||
|
val target = multiplatformExtension.createExternalKotlinTarget<FakeTarget> { defaults() }
|
||||||
|
|
||||||
|
val mainCompilation = target.createCompilation<FakeCompilation> {
|
||||||
|
defaults(multiplatformExtension)
|
||||||
|
compilationName = "main"
|
||||||
|
}
|
||||||
|
|
||||||
|
val auxCompilation = target.createCompilation<FakeCompilation> {
|
||||||
|
defaults(multiplatformExtension)
|
||||||
|
compilationName = "aux"
|
||||||
|
}
|
||||||
|
|
||||||
|
val mainJar = target.sourcesJarTask(mainCompilation)
|
||||||
|
assertEquals(mainJar, target.sourcesJarTask(mainCompilation))
|
||||||
|
assertEquals("fakeSourcesJar", mainJar.name)
|
||||||
|
|
||||||
|
val auxJar = target.sourcesJarTask(auxCompilation)
|
||||||
|
assertNotEquals(mainJar, auxJar)
|
||||||
|
assertEquals(auxJar, target.sourcesJarTask(auxCompilation))
|
||||||
|
assertEquals("fakeAuxSourcesJar", auxJar.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test - publishSources`() = buildProjectWithMPP().runLifecycleAwareTest {
|
||||||
|
val target = multiplatformExtension.createExternalKotlinTarget<FakeTarget> { defaults() }
|
||||||
|
|
||||||
|
val mainCompilation = target.createCompilation<FakeCompilation> {
|
||||||
|
defaults(multiplatformExtension)
|
||||||
|
compilationName = "main"
|
||||||
|
}
|
||||||
|
|
||||||
|
target.publishSources(mainCompilation)
|
||||||
|
configurationResult.await()
|
||||||
|
|
||||||
|
val sourcesArtifacts = target.sourcesElementsPublishedConfiguration.outgoing.artifacts.filter { artifact ->
|
||||||
|
artifact.classifier == "sources"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourcesArtifacts.isEmpty()) fail("Missing 'sources' artifacts")
|
||||||
|
if (sourcesArtifacts.size > 1) fail("Expected single 'sources' artifact. Found $sourcesArtifacts")
|
||||||
|
val sourcesArtifact = sourcesArtifacts.single()
|
||||||
|
assertEquals(target.sourcesJarTask(mainCompilation).get().archiveFile.get().asFile, sourcesArtifact.file)
|
||||||
|
}
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.external.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.CompilationFactory
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetDescriptor.TargetFactory
|
||||||
|
|
||||||
|
class FakeCompilation(delegate: Delegate) : DecoratedExternalKotlinCompilation(delegate)
|
||||||
|
class FakeTarget(delegate: Delegate) : DecoratedExternalKotlinTarget(delegate)
|
||||||
|
|
||||||
|
fun ExternalKotlinTargetDescriptorBuilder<FakeTarget>.defaults() {
|
||||||
|
targetName = "fake"
|
||||||
|
platformType = KotlinPlatformType.jvm
|
||||||
|
targetFactory = TargetFactory(::FakeTarget)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ExternalKotlinCompilationDescriptorBuilder<FakeCompilation>.defaults(kotlin: KotlinMultiplatformExtension) {
|
||||||
|
compilationName = "fake"
|
||||||
|
compilationFactory = CompilationFactory(::FakeCompilation)
|
||||||
|
defaultSourceSet = kotlin.sourceSets.maybeCreate("fake")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user