[Gradle, JS] Yarn as a dependency with ivy repository like Node.js

^KT-34985 fixed
This commit is contained in:
Ilya Goncharov
2021-07-01 10:49:31 +03:00
committed by TeamCityServer
parent 1507f1a9c0
commit 54d47de008
4 changed files with 56 additions and 19 deletions
@@ -11,5 +11,6 @@ import java.io.File
data class YarnEnv( data class YarnEnv(
val downloadUrl: String, val downloadUrl: String,
val cleanableStore: CleanableStore, val cleanableStore: CleanableStore,
val home: File val home: File,
val ivyDependency: String
) )
@@ -32,6 +32,11 @@ open class YarnPlugin : Plugin<Project> {
registerTask<YarnSetupTask>(YarnSetupTask.NAME) { registerTask<YarnSetupTask>(YarnSetupTask.NAME) {
it.dependsOn(nodeJs.nodeJsSetupTaskProvider) it.dependsOn(nodeJs.nodeJsSetupTaskProvider)
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) val rootClean = project.rootProject.tasks.named(BasePlugin.CLEAN_TASK_NAME)
@@ -76,9 +76,10 @@ open class YarnRootExtension(
val cleanableStore = CleanableStore[installationDir.path] val cleanableStore = CleanableStore[installationDir.path]
return YarnEnv( return YarnEnv(
downloadUrl = "$downloadBaseUrl/v$version/yarn-v$version.tar.gz", downloadUrl = downloadBaseUrl,
cleanableStore = cleanableStore, cleanableStore = cleanableStore,
home = cleanableStore["yarn-v$version"].use() home = cleanableStore["yarn-v$version"].use(),
ivyDependency = "com.yarnpkg:yarn:$version@tar.gz"
) )
} }
@@ -5,17 +5,20 @@
package org.jetbrains.kotlin.gradle.targets.js.yarn package org.jetbrains.kotlin.gradle.targets.js.yarn
import de.undercouch.gradle.tasks.download.DownloadAction
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.tasks.CacheableTask import org.gradle.api.artifacts.Configuration
import org.gradle.api.tasks.Input import org.gradle.api.provider.Provider
import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.*
import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.gradle.logging.kotlinInfo
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics
import java.io.File import java.io.File
import java.net.URI
@CacheableTask @CacheableTask
open class YarnSetupTask : DefaultTask() { open class YarnSetupTask : DefaultTask() {
@Transient
private val settings = project.yarn private val settings = project.yarn
private val env by lazy { settings.requireConfigured() } private val env by lazy { settings.requireConfigured() }
@@ -32,19 +35,46 @@ open class YarnSetupTask : DefaultTask() {
description = "Download and install a local yarn version" description = "Download and install a local yarn version"
} }
@TaskAction val ivyDependency: String
fun setup() { @Input get() = env.ivyDependency
val dir = temporaryDir
val tar = download(dir) @Transient
extract(tar, destination) @get:Internal
internal lateinit var configuration: Provider<Configuration>
private val _yarnDist by lazy {
configuration.get().files.single()
} }
private fun download(tar: File): File { @Suppress("unused") // as it called by Gradle before task execution and used to resolve artifact
val action = DownloadAction(project) @get:Classpath
action.src(downloadUrl) val yarnDist: File
action.dest(tar) get() {
action.execute() val repo = project.repositories.ivy { repo ->
return action.outputFiles.singleOrNull() ?: error("Cannot get downloaded file $downloadUrl") repo.name = "Yarn Distributions at ${downloadUrl}"
repo.url = URI(downloadUrl)
repo.patternLayout {
it.artifact("v[revision]/[artifact](-v[revision]).[ext]")
}
repo.metadataSources { it.artifact() }
repo.content { it.includeModule("com.yarnpkg", "yarn") }
}
val startDownloadTime = System.currentTimeMillis()
val dist = _yarnDist
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
}
@TaskAction
fun setup() {
logger.kotlinInfo("Using node distribution from '$yarnDist'")
extract(yarnDist, destination.parentFile) // parent because archive contains name already
} }
private fun extract(archive: File, destination: File) { private fun extract(archive: File, destination: File) {