[Gradle, JS] Fix composite build to not depend package json task on full aggregated configuration
^KT-57604 fixed
This commit is contained in:
committed by
Space Team
parent
1f0d56e157
commit
4fabe8b29a
+14
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockCopyTask.Companion.YA
|
||||
import org.jetbrains.kotlin.gradle.tasks.USING_JS_INCREMENTAL_COMPILATION_MESSAGE
|
||||
import org.jetbrains.kotlin.gradle.tasks.USING_JS_IR_BACKEND_MESSAGE
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.jetbrains.kotlin.gradle.testbase.TestVersions.Gradle.G_7_6
|
||||
import org.jetbrains.kotlin.gradle.util.jsCompilerType
|
||||
import org.jetbrains.kotlin.gradle.util.normalizePath
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
@@ -81,6 +82,7 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) {
|
||||
|
||||
@DisplayName("js composite build works")
|
||||
@GradleTest
|
||||
@GradleTestVersions(minVersion = G_7_6)
|
||||
fun testJsCompositeBuild(gradleVersion: GradleVersion) {
|
||||
project("js-composite-build", gradleVersion) {
|
||||
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
||||
@@ -470,6 +472,18 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) {
|
||||
assertEquals(fingerprints[0], fingerprints[1], "fingerprints must be stable")
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Klib runtime dependency on module which already depends on dependent")
|
||||
@GradleTest
|
||||
fun testKlibRuntimeDependency(gradleVersion: GradleVersion) {
|
||||
project("kotlin-js-ir-runtime-dependency", gradleVersion) {
|
||||
build("assemble") {
|
||||
assertTasksExecuted(":lib:otherKlib")
|
||||
assertTasksExecuted(":lib:compileOtherKotlinJs")
|
||||
assertTasksExecuted(":app:compileProductionExecutableKotlinJs")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JsGradlePluginTests
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.JsIrBinary
|
||||
|
||||
plugins {
|
||||
kotlin("js")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":lib"))
|
||||
testImplementation(kotlin("test-js"))
|
||||
}
|
||||
|
||||
kotlin {
|
||||
js {
|
||||
browser {
|
||||
}
|
||||
binaries.executable()
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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 com.example
|
||||
|
||||
fun main() {
|
||||
println("Sheldon: ${sheldon()}")
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class MainTest {
|
||||
@Test
|
||||
fun testHello() {
|
||||
assertEquals(true, true)
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
plugins {
|
||||
kotlin("js").apply(false)
|
||||
}
|
||||
|
||||
group = "com.example"
|
||||
version = "1.0"
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
plugins {
|
||||
kotlin("js")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
js {
|
||||
val otherCompilation = compilations.create("other")
|
||||
tasks.register<Zip>("otherKlib") {
|
||||
from(otherCompilation.output.allOutputs)
|
||||
archiveExtension.set("klib")
|
||||
}
|
||||
|
||||
useCommonJs()
|
||||
browser {
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
val main by getting {
|
||||
kotlin.exclude("**/other/**")
|
||||
dependencies {
|
||||
runtimeOnly(files(tasks.named("otherKlib")))
|
||||
}
|
||||
}
|
||||
val other by getting {
|
||||
kotlin.srcDirs("src/main/kotlin/other")
|
||||
dependencies {
|
||||
implementation(project(path = project.path))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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 com.example
|
||||
|
||||
fun answer(): Int {
|
||||
return 42
|
||||
}
|
||||
|
||||
fun sheldon(): Int {
|
||||
return 73
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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 com.example.other
|
||||
|
||||
@JsExport
|
||||
fun foo(): Int {
|
||||
return 3
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
rootProject.name = "kotlin-js-ir-runtime-dependency"
|
||||
|
||||
include("lib")
|
||||
include("app")
|
||||
-2
@@ -7,8 +7,6 @@ package org.jetbrains.kotlin.gradle.targets.js
|
||||
|
||||
import org.gradle.api.Named
|
||||
import org.gradle.api.attributes.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
|
||||
import java.io.Serializable
|
||||
|
||||
// For Gradle attributes
|
||||
|
||||
+6
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.ir
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCompilationFactory
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationFriendPathsResolver
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.JsIrCompilationSourceSetsContainerFactory
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.JsKotlinCompilationDependencyConfigurationsFactory
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory
|
||||
@@ -20,6 +21,11 @@ class KotlinJsIrCompilationFactory internal constructor(
|
||||
|
||||
private val compilationImplFactory: KotlinCompilationImplFactory = KotlinCompilationImplFactory(
|
||||
compilerOptionsFactory = KotlinJsCompilerOptionsFactory,
|
||||
compilationFriendPathsResolver = DefaultKotlinCompilationFriendPathsResolver(
|
||||
friendArtifactResolver = DefaultKotlinCompilationFriendPathsResolver.FriendArtifactResolver { _ ->
|
||||
target.project.files()
|
||||
}
|
||||
),
|
||||
compilationSourceSetsContainerFactory = JsIrCompilationSourceSetsContainerFactory,
|
||||
compilationDependencyConfigurationsFactory = JsKotlinCompilationDependencyConfigurationsFactory
|
||||
)
|
||||
|
||||
+3
@@ -34,6 +34,9 @@ internal class GradleNodeModuleBuilder(
|
||||
srcFiles.forEach { srcFile ->
|
||||
when {
|
||||
isKotlinJsRuntimeFile(srcFile) -> files.add(srcFile)
|
||||
srcFile.name == NpmProject.PACKAGE_JSON -> {
|
||||
srcPackageJsonFile = srcFile
|
||||
}
|
||||
srcFile.isCompatibleArchive -> {
|
||||
archiveOperations.zipTree(srcFile).forEach { innerFile ->
|
||||
when {
|
||||
|
||||
+1
-10
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.resolver
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.TasksRequirements
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.*
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject.Companion.PACKAGE_JSON
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.PreparedKotlinCompilationNpmResolution
|
||||
import java.io.Serializable
|
||||
import java.io.File
|
||||
|
||||
class KotlinCompilationNpmResolution(
|
||||
var internalDependencies: Collection<InternalDependency>,
|
||||
var internalCompositeDependencies: Collection<CompositeDependency>,
|
||||
var externalGradleDependencies: Collection<FileExternalGradleDependency>,
|
||||
var externalNpmDependencies: Collection<NpmDependencyDeclaration>,
|
||||
var fileCollectionDependencies: Collection<FileCollectionExternalGradleDependency>,
|
||||
@@ -171,13 +171,4 @@ class KotlinCompilationNpmResolution(
|
||||
}
|
||||
return direct + unique
|
||||
}
|
||||
|
||||
internal fun CompositeDependency.getPackages(): List<File> {
|
||||
val packages = includedBuildDir.resolve(projectPackagesDir.relativeTo(rootDir))
|
||||
return packages
|
||||
.list()
|
||||
?.map { packages.resolve(it) }
|
||||
?.map { it.resolve(PACKAGE_JSON) }
|
||||
?: emptyList()
|
||||
}
|
||||
}
|
||||
+65
-1
@@ -10,6 +10,7 @@ import org.gradle.api.artifacts.FileCollectionDependency
|
||||
import org.gradle.api.artifacts.ResolvedArtifact
|
||||
import org.gradle.api.artifacts.ResolvedDependency
|
||||
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.attributes.Category
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.internal.artifacts.DefaultProjectComponentIdentifier
|
||||
@@ -78,6 +79,9 @@ class KotlinCompilationNpmResolver(
|
||||
it.npmProjectName.set(npmProject.name)
|
||||
it.npmProjectMain.set(npmProject.main)
|
||||
}.also { packageJsonTask ->
|
||||
project.dependencies.attributesSchema {
|
||||
it.attribute(publicPackageJsonAttribute)
|
||||
}
|
||||
if (compilation.isMain()) {
|
||||
project.tasks
|
||||
.withType(Zip::class.java)
|
||||
@@ -85,7 +89,15 @@ class KotlinCompilationNpmResolver(
|
||||
.configure {
|
||||
it.dependsOn(packageJsonTask)
|
||||
}
|
||||
|
||||
val publicPackageJsonConfiguration = createPublicPackageJsonConfiguration()
|
||||
|
||||
target.project.artifacts.add(publicPackageJsonConfiguration.name, packageJsonTask.map { it.packageJsonFile }) {
|
||||
it.builtBy(packageJsonTask)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +131,7 @@ class KotlinCompilationNpmResolver(
|
||||
all.usesPlatformOf(target)
|
||||
all.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
|
||||
all.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
|
||||
all.attributes.attribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE)
|
||||
all.isVisible = false
|
||||
all.isCanBeConsumed = false
|
||||
all.isCanBeResolved = true
|
||||
@@ -142,8 +155,23 @@ class KotlinCompilationNpmResolver(
|
||||
return all
|
||||
}
|
||||
|
||||
private fun createPublicPackageJsonConfiguration(): Configuration {
|
||||
val all = project.configurations.create(compilation.disambiguateName("publicPackageJsonConfiguration"))
|
||||
|
||||
all.usesPlatformOf(target)
|
||||
all.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
|
||||
all.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
|
||||
all.attributes.attribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE)
|
||||
all.isVisible = false
|
||||
all.isCanBeConsumed = true
|
||||
all.isCanBeResolved = false
|
||||
|
||||
return all
|
||||
}
|
||||
|
||||
inner class ConfigurationVisitor {
|
||||
private val internalDependencies = mutableSetOf<InternalDependency>()
|
||||
private val internalCompositeDependencies = mutableSetOf<CompositeDependency>()
|
||||
private val externalGradleDependencies = mutableSetOf<ExternalGradleDependency>()
|
||||
private val externalNpmDependencies = mutableSetOf<NpmDependencyDeclaration>()
|
||||
private val fileCollectionDependencies = mutableSetOf<FileCollectionExternalGradleDependency>()
|
||||
@@ -215,6 +243,10 @@ class KotlinCompilationNpmResolver(
|
||||
val artifactId = artifact.id
|
||||
val componentIdentifier = artifactId.componentIdentifier
|
||||
|
||||
if (artifactId `is` CompositeProjectComponentArtifactMetadata) {
|
||||
visitCompositeProjectDependency(dependency, componentIdentifier as ProjectComponentIdentifier)
|
||||
}
|
||||
|
||||
if (componentIdentifier is ProjectComponentIdentifier && !(artifactId `is` CompositeProjectComponentArtifactMetadata)) {
|
||||
visitProjectDependency(componentIdentifier)
|
||||
return
|
||||
@@ -223,6 +255,28 @@ class KotlinCompilationNpmResolver(
|
||||
externalGradleDependencies.add(ExternalGradleDependency(dependency, artifact))
|
||||
}
|
||||
|
||||
private fun visitCompositeProjectDependency(
|
||||
dependency: ResolvedDependency,
|
||||
componentIdentifier: ProjectComponentIdentifier
|
||||
) {
|
||||
check(target is KotlinJsIrTarget) {
|
||||
"""
|
||||
Composite builds for Kotlin/JS are supported only for IR compiler.
|
||||
Use kotlin.js.compiler=ir in gradle.properties or
|
||||
js(IR) {
|
||||
...
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
(componentIdentifier as DefaultProjectComponentIdentifier).let { identifier ->
|
||||
val includedBuild = project.gradle.includedBuild(identifier.identityPath.topRealPath().name!!)
|
||||
internalCompositeDependencies.add(
|
||||
CompositeDependency(dependency.moduleName, dependency.moduleVersion, includedBuild.projectDir, includedBuild)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun visitProjectDependency(
|
||||
componentIdentifier: ProjectComponentIdentifier
|
||||
) {
|
||||
@@ -243,6 +297,7 @@ class KotlinCompilationNpmResolver(
|
||||
|
||||
fun toPackageJsonProducer() = KotlinCompilationNpmResolution(
|
||||
internalDependencies,
|
||||
internalCompositeDependencies,
|
||||
externalGradleDependencies.map {
|
||||
FileExternalGradleDependency(
|
||||
it.dependency.moduleName,
|
||||
@@ -264,4 +319,13 @@ class KotlinCompilationNpmResolver(
|
||||
rootResolver.tasksRequirements
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val publicPackageJsonAttribute = Attribute.of(
|
||||
"org.jetbrains.kotlin.js.public.package.json",
|
||||
String::class.java
|
||||
)
|
||||
|
||||
const val PUBLIC_PACKAGE_JSON_ATTR_VALUE = "public-package-json"
|
||||
}
|
||||
}
|
||||
+22
-6
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.work.NormalizeLineEndings
|
||||
@@ -16,10 +16,10 @@ import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.kotlinNodeJsExtension
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.kotlinNpmResolutionManager
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.*
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.PackageJsonProducerInputs
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
import org.jetbrains.kotlin.gradle.utils.CompositeProjectComponentArtifactMetadata
|
||||
import org.jetbrains.kotlin.gradle.utils.`is`
|
||||
import java.io.File
|
||||
|
||||
abstract class KotlinPackageJsonTask :
|
||||
@@ -41,6 +41,9 @@ abstract class KotlinPackageJsonTask :
|
||||
private fun findDependentTasks(): Collection<Any> =
|
||||
compilationResolver.compilationNpmResolution.internalDependencies.map { dependency ->
|
||||
nodeJs.resolver[dependency.projectPath][dependency.compilationName].npmProject.packageJsonTaskPath
|
||||
} + compilationResolver.compilationNpmResolution.internalCompositeDependencies.map { dependency ->
|
||||
dependency.includedBuild?.task(":$PACKAGE_JSON_UMBRELLA_TASK_NAME") ?: error("includedBuild instance is not available")
|
||||
dependency.includedBuild.task(":${RootPackageJsonTask.NAME}")
|
||||
}
|
||||
|
||||
// -----
|
||||
@@ -75,8 +78,21 @@ abstract class KotlinPackageJsonTask :
|
||||
@get:NormalizeLineEndings
|
||||
@get:InputFiles
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
internal val aggregatedConfiguration: FileCollection by lazy {
|
||||
compilationResolver.aggregatedConfiguration
|
||||
internal val compositeFiles: Set<File> by lazy {
|
||||
val map = compilationResolver.aggregatedConfiguration
|
||||
.incoming
|
||||
.artifactView { artifactView ->
|
||||
artifactView.componentFilter { componentIdentifier ->
|
||||
componentIdentifier is ProjectComponentIdentifier
|
||||
}
|
||||
}
|
||||
.artifacts
|
||||
.filter {
|
||||
it.id `is` CompositeProjectComponentArtifactMetadata
|
||||
}
|
||||
.map { it.file }
|
||||
.toSet()
|
||||
map
|
||||
}
|
||||
|
||||
// nested inputs are processed in configuration phase
|
||||
|
||||
Reference in New Issue
Block a user