[Gradle, JS] Add descriptors to dependencies in configurations phase

- Add file collection dependencies to gradle node module building

^KT-42339 fixed
This commit is contained in:
Ilya Goncharov
2020-10-06 14:21:42 +03:00
parent af65365d6a
commit 0a86beeb64
9 changed files with 85 additions and 44 deletions
@@ -5,10 +5,13 @@
package org.jetbrains.kotlin.gradle.targets.js.dukat package org.jetbrains.kotlin.gradle.targets.js.dukat
import org.gradle.api.artifacts.FileCollectionDependency
import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
import org.jetbrains.kotlin.gradle.targets.js.npm.isCompatibleArchive
import org.jetbrains.kotlin.gradle.targets.js.npm.plugins.CompilationResolverPlugin import org.jetbrains.kotlin.gradle.targets.js.npm.plugins.CompilationResolverPlugin
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinRootNpmResolution import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinRootNpmResolution
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver
@@ -28,6 +31,8 @@ internal class DukatCompilationResolverPlugin(
init { init {
val dukatMode = compilation.dukatMode val dukatMode = compilation.dukatMode
gradleModelPostProcess(dukatMode, npmProject)
val integratedTask = project.registerTask<IntegratedDukatTask>( val integratedTask = project.registerTask<IntegratedDukatTask>(
integratedTaskName, integratedTaskName,
listOf(compilation) listOf(compilation)
@@ -66,7 +71,8 @@ internal class DukatCompilationResolverPlugin(
internalDependencies: Set<KotlinCompilationNpmResolver>, internalDependencies: Set<KotlinCompilationNpmResolver>,
internalCompositeDependencies: Set<KotlinCompilationNpmResolver.CompositeDependency>, internalCompositeDependencies: Set<KotlinCompilationNpmResolver.CompositeDependency>,
externalGradleDependencies: Set<KotlinCompilationNpmResolver.ExternalGradleDependency>, externalGradleDependencies: Set<KotlinCompilationNpmResolver.ExternalGradleDependency>,
externalNpmDependencies: Set<NpmDependency> externalNpmDependencies: Set<NpmDependency>,
fileCollectionDependencies: Set<FileCollectionDependency>
) { ) {
if (nodeJs.experimental.discoverTypes) { if (nodeJs.experimental.discoverTypes) {
// todo: discoverTypes // todo: discoverTypes
@@ -93,4 +99,27 @@ internal class DukatCompilationResolverPlugin(
companion object { companion object {
const val VERSION = "2" const val VERSION = "2"
} }
}
internal fun gradleModelPostProcess(
dukatMode: DukatMode,
npmProject: NpmProject
) {
val compilation = npmProject.compilation
val project = npmProject.project
when (dukatMode) {
DukatMode.SOURCE -> compilation.defaultSourceSet.kotlin.srcDir(npmProject.externalsDir)
DukatMode.BINARY -> {
npmProject.externalsDir
.listFiles()
?.filter { it.isCompatibleArchive }
?.forEach {
project.dependencies.add(
compilation.compileDependencyConfigurationName,
project.files(it)
)
}
}
}
} }
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.gradle.targets.js.dukat
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
import org.jetbrains.kotlin.gradle.targets.js.npm.isCompatibleArchive
class DukatExecutor( class DukatExecutor(
val nodeJs: NodeJsRootExtension, val nodeJs: NodeJsRootExtension,
@@ -61,26 +60,6 @@ class DukatExecutor(
versionFile.writeText(version) versionFile.writeText(version)
gradleModelPostProcess() gradleModelPostProcess(dukatMode, npmProject)
}
private fun gradleModelPostProcess() {
val compilation = npmProject.compilation
val project = npmProject.project
when (dukatMode) {
DukatMode.SOURCE -> compilation.defaultSourceSet.kotlin.srcDir(npmProject.externalsDir)
DukatMode.BINARY -> {
npmProject.externalsDir
.listFiles()
?.filter { it.isCompatibleArchive }
?.forEach {
project.dependencies.add(
compilation.compileDependencyConfigurationName,
project.files(it)
)
}
}
}
} }
} }
@@ -26,16 +26,18 @@ internal abstract class AbstractNodeModulesCache(val nodeJs: NodeJsRootExtension
@Synchronized @Synchronized
fun get( fun get(
dependency: ResolvedDependency, name: String,
version: String,
file: File file: File
): GradleNodeModule? = cache.getOrCompute(file) { ): GradleNodeModule? = cache.getOrCompute(file) {
buildImportedPackage(dependency, file) buildImportedPackage(name, version, file)
}?.let { }?.let {
GradleNodeModule(it) GradleNodeModule(it)
} }
abstract fun buildImportedPackage( abstract fun buildImportedPackage(
dependency: ResolvedDependency, name: String,
version: String,
file: File file: File
): File? ): File?
@@ -14,7 +14,6 @@ import java.io.File
*/ */
internal class CompositeNodeModuleBuilder( internal class CompositeNodeModuleBuilder(
val project: Project, val project: Project,
val dependency: ResolvedDependency,
val srcDir: File, val srcDir: File,
val cache: CompositeNodeModulesCache val cache: CompositeNodeModulesCache
) { ) {
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.gradle.targets.js.npm package org.jetbrains.kotlin.gradle.targets.js.npm
import org.gradle.api.artifacts.ResolvedDependency
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
import java.io.File import java.io.File
@@ -14,10 +13,11 @@ import java.io.File
*/ */
internal class CompositeNodeModulesCache(nodeJs: NodeJsRootExtension) : AbstractNodeModulesCache(nodeJs) { internal class CompositeNodeModulesCache(nodeJs: NodeJsRootExtension) : AbstractNodeModulesCache(nodeJs) {
override fun buildImportedPackage( override fun buildImportedPackage(
dependency: ResolvedDependency, name: String,
version: String,
file: File file: File
): File? { ): File? {
val module = CompositeNodeModuleBuilder(project, dependency, file, this) val module = CompositeNodeModuleBuilder(project, file, this)
return module.rebuild() return module.rebuild()
} }
} }
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.gradle.targets.js.npm package org.jetbrains.kotlin.gradle.targets.js.npm
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.ResolvedDependency
import org.jetbrains.kotlin.gradle.targets.js.JS import org.jetbrains.kotlin.gradle.targets.js.JS
import org.jetbrains.kotlin.gradle.targets.js.JS_MAP import org.jetbrains.kotlin.gradle.targets.js.JS_MAP
import org.jetbrains.kotlin.gradle.targets.js.META_JS import org.jetbrains.kotlin.gradle.targets.js.META_JS
@@ -18,7 +17,8 @@ import java.io.File
*/ */
internal class GradleNodeModuleBuilder( internal class GradleNodeModuleBuilder(
val project: Project, val project: Project,
val dependency: ResolvedDependency, val moduleName: String,
val moduleVersion: String,
val srcFiles: Collection<File>, val srcFiles: Collection<File>,
val cache: GradleNodeModulesCache val cache: GradleNodeModulesCache
) { ) {
@@ -45,8 +45,8 @@ internal class GradleNodeModuleBuilder(
val packageJson = fromSrcPackageJson(srcPackageJsonFile)?.apply { val packageJson = fromSrcPackageJson(srcPackageJsonFile)?.apply {
// Gson set nulls reflectively no matter on default values and non-null types // Gson set nulls reflectively no matter on default values and non-null types
@Suppress("USELESS_ELVIS") @Suppress("USELESS_ELVIS")
version = version ?: dependency.moduleVersion version = version ?: moduleVersion
} ?: PackageJson(dependency.moduleName, dependency.moduleVersion) } ?: PackageJson(moduleName, moduleVersion)
val metaFiles = files.filter { it.name.endsWith(".$META_JS") } val metaFiles = files.filter { it.name.endsWith(".$META_JS") }
if (metaFiles.size == 1) { if (metaFiles.size == 1) {
@@ -14,10 +14,11 @@ import java.io.File
*/ */
internal class GradleNodeModulesCache(nodeJs: NodeJsRootExtension) : AbstractNodeModulesCache(nodeJs) { internal class GradleNodeModulesCache(nodeJs: NodeJsRootExtension) : AbstractNodeModulesCache(nodeJs) {
override fun buildImportedPackage( override fun buildImportedPackage(
dependency: ResolvedDependency, name: String,
version: String,
file: File file: File
): File? { ): File? {
val module = GradleNodeModuleBuilder(project, dependency, listOf(file), this) val module = GradleNodeModuleBuilder(project, name, version, listOf(file), this)
module.visitArtifacts() module.visitArtifacts()
return module.rebuild() return module.rebuild()
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.plugins package org.jetbrains.kotlin.gradle.targets.js.npm.plugins
import org.gradle.api.artifacts.FileCollectionDependency
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver
@@ -13,6 +14,7 @@ internal interface CompilationResolverPlugin {
internalDependencies: Set<KotlinCompilationNpmResolver>, internalDependencies: Set<KotlinCompilationNpmResolver>,
internalCompositeDependencies: Set<KotlinCompilationNpmResolver.CompositeDependency>, internalCompositeDependencies: Set<KotlinCompilationNpmResolver.CompositeDependency>,
externalGradleDependencies: Set<KotlinCompilationNpmResolver.ExternalGradleDependency>, externalGradleDependencies: Set<KotlinCompilationNpmResolver.ExternalGradleDependency>,
externalNpmDependencies: Set<NpmDependency> externalNpmDependencies: Set<NpmDependency>,
fileCollectionDependencies: Set<FileCollectionDependency>
) )
} }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.resolver package org.jetbrains.kotlin.gradle.targets.js.npm.resolver
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.FileCollectionDependency
import org.gradle.api.artifacts.ResolvedArtifact import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.artifacts.ResolvedDependency import org.gradle.api.artifacts.ResolvedDependency
import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.artifacts.component.ProjectComponentIdentifier
@@ -149,6 +150,16 @@ internal class KotlinCompilationNpmResolver(
// We don't have `kotlin-js-test-runner` in NPM yet // We don't have `kotlin-js-test-runner` in NPM yet
all.dependencies.add(nodeJs.versions.kotlinJsTestRunner.createDependency(project)) all.dependencies.add(nodeJs.versions.kotlinJsTestRunner.createDependency(project))
npmProject.externalsDir
.listFiles()
?.filter { it.isCompatibleArchive }
?.forEach {
project.dependencies.add(
all.name,
project.files(it)
)
}
return all return all
} }
@@ -167,6 +178,7 @@ internal class KotlinCompilationNpmResolver(
private val internalCompositeDependencies = mutableSetOf<CompositeDependency>() private val internalCompositeDependencies = mutableSetOf<CompositeDependency>()
private val externalGradleDependencies = mutableSetOf<ExternalGradleDependency>() private val externalGradleDependencies = mutableSetOf<ExternalGradleDependency>()
private val externalNpmDependencies = mutableSetOf<NpmDependency>() private val externalNpmDependencies = mutableSetOf<NpmDependency>()
private val fileCollectionDependencies = mutableSetOf<FileCollectionDependency>()
fun visit(configuration: Configuration) { fun visit(configuration: Configuration) {
configuration.resolvedConfiguration.firstLevelModuleDependencies.forEach { configuration.resolvedConfiguration.firstLevelModuleDependencies.forEach {
@@ -176,6 +188,7 @@ internal class KotlinCompilationNpmResolver(
configuration.allDependencies.forEach { dependency -> configuration.allDependencies.forEach { dependency ->
when (dependency) { when (dependency) {
is NpmDependency -> externalNpmDependencies.add(dependency) is NpmDependency -> externalNpmDependencies.add(dependency)
is FileCollectionDependency -> fileCollectionDependencies.add(dependency)
} }
} }
@@ -201,7 +214,8 @@ internal class KotlinCompilationNpmResolver(
internalDependencies, internalDependencies,
internalCompositeDependencies, internalCompositeDependencies,
externalGradleDependencies, externalGradleDependencies,
externalNpmDependencies externalNpmDependencies,
fileCollectionDependencies
) )
} }
} }
@@ -277,7 +291,8 @@ internal class KotlinCompilationNpmResolver(
internalDependencies, internalDependencies,
internalCompositeDependencies, internalCompositeDependencies,
externalGradleDependencies, externalGradleDependencies,
externalNpmDependencies externalNpmDependencies,
fileCollectionDependencies
) )
} }
@@ -292,7 +307,10 @@ internal class KotlinCompilationNpmResolver(
val externalGradleDependencies: Collection<File>, val externalGradleDependencies: Collection<File>,
@get:Input @get:Input
val externalDependencies: Collection<String> val externalDependencies: Collection<String>,
@get:Input
val fileCollectionDependencies: Collection<File>
) : Serializable ) : Serializable
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
@@ -300,14 +318,16 @@ internal class KotlinCompilationNpmResolver(
val internalDependencies: Collection<KotlinCompilationNpmResolver>, val internalDependencies: Collection<KotlinCompilationNpmResolver>,
val internalCompositeDependencies: Collection<CompositeDependency>, val internalCompositeDependencies: Collection<CompositeDependency>,
val externalGradleDependencies: Collection<ExternalGradleDependency>, val externalGradleDependencies: Collection<ExternalGradleDependency>,
val externalNpmDependencies: Collection<NpmDependency> val externalNpmDependencies: Collection<NpmDependency>,
val fileCollectionDependencies: Collection<FileCollectionDependency>
) { ) {
val inputs: PackageJsonProducerInputs val inputs: PackageJsonProducerInputs
get() = PackageJsonProducerInputs( get() = PackageJsonProducerInputs(
internalDependencies.map { it.npmProject.name }, internalDependencies.map { it.npmProject.name },
internalCompositeDependencies.flatMap { it.getPackages() }, internalCompositeDependencies.flatMap { it.getPackages() },
externalGradleDependencies.map { it.artifact.file }, externalGradleDependencies.map { it.artifact.file },
externalNpmDependencies.map { it.uniqueRepresentation() } externalNpmDependencies.map { it.uniqueRepresentation() },
fileCollectionDependencies.map { it.files }.flatMap { it.files }
) )
fun createPackageJson(skipWriting: Boolean): KotlinCompilationNpmResolution { fun createPackageJson(skipWriting: Boolean): KotlinCompilationNpmResolution {
@@ -316,14 +336,23 @@ internal class KotlinCompilationNpmResolver(
?: error("Unresolved dependent npm package: ${this@KotlinCompilationNpmResolver} -> $it") ?: error("Unresolved dependent npm package: ${this@KotlinCompilationNpmResolver} -> $it")
} }
val importedExternalGradleDependencies = externalGradleDependencies.mapNotNull { val importedExternalGradleDependencies = externalGradleDependencies.mapNotNull {
resolver.gradleNodeModules.get(it.dependency, it.artifact.file) resolver.gradleNodeModules.get(it.dependency.moduleName, it.dependency.moduleVersion, it.artifact.file)
} + fileCollectionDependencies.mapNotNull {
val file = it.files.singleFile
resolver.gradleNodeModules.get(
it.name,
it.version ?: "0.0.1",
file
)
} }
val compositeDependencies = internalCompositeDependencies.flatMap { dependency -> val compositeDependencies = internalCompositeDependencies.flatMap { dependency ->
dependency.getPackages() dependency.getPackages()
.map { file -> .map { file ->
resolver.compositeNodeModules.get( resolver.compositeNodeModules.get(
dependency.dependency, dependency.dependency.moduleName,
dependency.dependency.moduleVersion,
file file
) )
} }