From 15f6bb9506ccc50ea568014136046a5097bb9abb Mon Sep 17 00:00:00 2001 From: Alexander Likhachev Date: Wed, 20 Jan 2021 23:23:38 +0300 Subject: [PATCH] [Gradle, JS] Make NodeJsSetup cc-compatible --- .../targets/js/nodejs/NodeJsRootPlugin.kt | 4 + .../targets/js/nodejs/NodeJsSetupTask.kt | 88 +++++++++++-------- 2 files changed, 53 insertions(+), 39 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt index dd7f34baa09..d073d87681b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt @@ -32,6 +32,10 @@ open class NodeJsRootPlugin : Plugin { val setupTask = registerTask(NodeJsSetupTask.NAME) { it.group = TASKS_GROUP_NAME it.description = "Download and install a local node/npm version" + it.configuration = provider { + this.project.configurations.detachedConfiguration(this.project.dependencies.create(it.ivyDependency)) + .also { conf -> conf.isTransitive = false } + } } val rootClean = project.rootProject.tasks.named(BasePlugin.CLEAN_TASK_NAME) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt index f7c2f1e6bbe..ad30d9578df 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt @@ -1,10 +1,11 @@ package org.jetbrains.kotlin.gradle.targets.js.nodejs import org.gradle.api.DefaultTask -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction +import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.ArchiveOperations +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.* import org.jetbrains.kotlin.gradle.logging.kotlinInfo import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics @@ -15,6 +16,8 @@ import java.net.URI open class NodeJsSetupTask : DefaultTask() { private val settings = NodeJsRootPlugin.apply(project.rootProject) private val env by lazy { settings.requireConfigured() } + private val fs = services.get(FileSystemOperations::class.java) + private val archives = services.get(ArchiveOperations::class.java) val ivyDependency: String @Input get() = env.ivyDependency @@ -22,6 +25,41 @@ open class NodeJsSetupTask : DefaultTask() { val destination: File @OutputDirectory get() = env.nodeDir + @Transient + @get:Internal + internal lateinit var configuration: Provider + + private val _nodeJsDist by lazy { + configuration.get().files.single() + } + + @Suppress("unused") // as it called by Gradle before task execution and used to resolve artifact + @get:Classpath + val nodeJsDist: File + get() { + @Suppress("UnstableApiUsage", "DEPRECATION") + val repo = project.repositories.ivy { repo -> + repo.name = "Node Distributions at ${settings.nodeDownloadBaseUrl}" + repo.url = URI(settings.nodeDownloadBaseUrl) + + repo.patternLayout { + it.artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") + it.ivy("v[revision]/ivy.xml") + } + repo.metadataSources { it.artifact() } + repo.content { it.includeModule("org.nodejs", "node") } + } + val startDownloadTime = System.currentTimeMillis() + val dist = _nodeJsDist + val downloadDuration = System.currentTimeMillis() - startDownloadTime + if (downloadDuration > 0) { + KotlinBuildStatsService.getInstance() + ?.report(NumericalMetrics.ARTIFACTS_DOWNLOAD_SPEED, dist.length() * 1000 / downloadDuration) + } + project.repositories.remove(repo) + return dist + } + init { @Suppress("LeakingThis") onlyIf { @@ -32,37 +70,9 @@ open class NodeJsSetupTask : DefaultTask() { @Suppress("unused") @TaskAction fun exec() { - @Suppress("UnstableApiUsage", "DEPRECATION") - val repo = project.repositories.ivy { repo -> - repo.name = "Node Distributions at ${settings.nodeDownloadBaseUrl}" - repo.url = URI(settings.nodeDownloadBaseUrl) + logger.kotlinInfo("Using node distribution from '$_nodeJsDist'") - repo.patternLayout { - it.artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") - it.ivy("v[revision]/ivy.xml") - } - repo.metadataSources { it.artifact() } - repo.content { it.includeModule("org.nodejs", "node") } - } - - val dep = this.project.dependencies.create(ivyDependency) - val conf = this.project.configurations.detachedConfiguration(dep) - conf.isTransitive = false - - val startDownloadTime = System.currentTimeMillis() - val result = conf.resolve().single() - - val downloadDuration = System.currentTimeMillis() - startDownloadTime - if (downloadDuration > 0) { - KotlinBuildStatsService.getInstance() - ?.report(NumericalMetrics.ARTIFACTS_DOWNLOAD_SPEED, result.length() * 1000 / downloadDuration) - } - - project.repositories.remove(repo) - - project.logger.kotlinInfo("Using node distribution from '$result'") - - unpackNodeArchive(result, destination.parentFile) // parent because archive contains name already + unpackNodeArchive(_nodeJsDist, destination.parentFile) // parent because archive contains name already if (!env.isWindows) { File(env.nodeExecutable).setExecutable(true) @@ -70,16 +80,16 @@ open class NodeJsSetupTask : DefaultTask() { } private fun unpackNodeArchive(archive: File, destination: File) { - project.logger.kotlinInfo("Unpacking $archive to $destination") + logger.kotlinInfo("Unpacking $archive to $destination") when { - archive.name.endsWith("zip") -> project.copy { - it.from(project.zipTree(archive)) + archive.name.endsWith("zip") -> fs.copy { + it.from(archives.zipTree(archive)) it.into(destination) } else -> { - project.copy { - it.from(project.tarTree(archive)) + fs.copy { + it.from(archives.tarTree(archive)) it.into(destination) } }