[Gradle, Wasm] Standartize binaryen and d8 download instead of download task

^KT-65686 fixed
This commit is contained in:
Ilya Goncharov
2024-02-09 11:18:37 +00:00
committed by Space Team
parent 5bd0bbb159
commit b4e1fa8569
31 changed files with 308 additions and 177 deletions
-6
View File
@@ -1506,12 +1506,6 @@
<sha256 value="61fc639d7c60d80f523c76867b4d83ebb54a4740e8ca1d9c61216668ceb25988" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="de.undercouch" name="gradle-download-task" version="4.1.1">
<artifact name="gradle-download-task-4.1.1.jar">
<md5 value="5da00a4a96829700216768887a8f3051" origin="Generated by Gradle"/>
<sha256 value="eb08b570e408d4646705e70a949614d439ea2b11455f1652ab0330de8954dab9" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="dev.gradleplugins" name="gradle-api" version="6.9">
<artifact name="gradle-api-6.9.jar">
<md5 value="54b9007742dec27e80c6623d11e57ed4" origin="Generated by Gradle"/>
@@ -19,11 +19,7 @@ class KotlinWasmGradlePluginIT : KGPBaseTest() {
@DisplayName("Check wasi target")
@GradleTest
fun wasiTarget(gradleVersion: GradleVersion) {
project(
"new-mpp-wasm-wasi-test",
gradleVersion,
dependencyManagement = DependencyManagement.DisabledDependencyManagement // requires custom d8 repository during build
) {
project("new-mpp-wasm-wasi-test", gradleVersion) {
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
build(":wasmWasiTest") {
@@ -57,15 +53,10 @@ class KotlinWasmGradlePluginIT : KGPBaseTest() {
@DisplayName("Check js target")
@GradleTest
fun jsTarget(gradleVersion: GradleVersion) {
project(
"new-mpp-wasm-test",
gradleVersion,
dependencyManagement = DependencyManagement.DisabledDependencyManagement // requires custom repository for :kotlinNodeJsSetup during build
) {
project("new-mpp-wasm-test", gradleVersion) {
buildGradleKts.modify {
transformBuildScriptWithPluginsDsl(it)
.replace("<JsEngine>", "nodejs")
.replace("<ApplyBinaryen>", "")
}
kotlinSourcesDir("wasmJsTest").resolve("Test.kt").writeText(
@@ -101,10 +92,7 @@ class KotlinWasmGradlePluginIT : KGPBaseTest() {
@DisplayName("Check wasi target run")
@GradleTest
fun wasiRun(gradleVersion: GradleVersion) {
project(
"new-mpp-wasm-wasi-test", gradleVersion,
dependencyManagement = DependencyManagement.DisabledDependencyManagement // requires d8 custom repository during build
) {
project("new-mpp-wasm-wasi-test", gradleVersion) {
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
build(":wasmWasiNodeRun") {
@@ -1669,22 +1669,18 @@ open class NewMultiplatformIT : BaseGradleIT() {
}
}
private fun testWasmTest(engine: String, name: String, useBinaryen: Boolean) = with(
private fun testWasmTest(engine: String, name: String) = with(
Project("new-mpp-wasm-test", gradleVersionRequirement = GradleVersionRequired.AtLeast(TestVersions.Gradle.G_7_0))
) {
setupWorkingDir()
gradleBuildScript().modify {
transformBuildScriptWithPluginsDsl(it)
.replace("<JsEngine>", engine)
.replace("<ApplyBinaryen>", if (useBinaryen) "applyBinaryen()" else "")
}
build(":wasmJs${name}Test") {
assertTasksExecuted(":compileKotlinWasmJs")
if (useBinaryen) {
assertTasksExecuted(":compileTestDevelopmentExecutableKotlinWasmJsOptimize")
} else {
assertTasksNotExecuted(":compileTestDevelopmentExecutableKotlinWasmJsOptimize")
}
assertTasksNotExecuted(":compileTestDevelopmentExecutableKotlinWasmJsOptimize")
assertTasksFailed(":wasmJs${name}Test")
assertTestResults(
"testProject/new-mpp-wasm-test/TEST-${engine}.xml",
@@ -1694,16 +1690,10 @@ open class NewMultiplatformIT : BaseGradleIT() {
}
@Test
fun testWasmNodeTest() = testWasmTest("nodejs", "Node", useBinaryen = false)
fun testWasmNodeTest() = testWasmTest("nodejs", "Node")
@Test
fun testWasmWithBinaryenNodeTest() = testWasmTest("nodejs", "Node", useBinaryen = true)
@Test
fun testWasmD8Test() = testWasmTest("d8", "D8", useBinaryen = false)
@Test
fun testWasmWithBinaryenD8Test() = testWasmTest("d8", "D8", useBinaryen = true)
fun testWasmD8Test() = testWasmTest("d8", "D8")
@Test
fun testResolveMetadataCompileClasspathKt50925() {
@@ -118,6 +118,45 @@ internal fun getGroovyDependencyManagementBlock(
includeModule("org.nodejs", "node")
}
}
ivy {
url = uri("https://nodejs.org/download/v8-canary")
patternLayout {
artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]")
}
metadataSources {
artifact()
}
content {
includeModule("org.nodejs", "node")
}
}
ivy {
url = uri("https://github.com/WebAssembly/binaryen/releases/download")
patternLayout {
artifact("version_[revision]/binaryen-version_[revision]-[classifier].[ext]")
}
metadataSources {
artifact()
}
content {
includeModule("com.github.webassembly", "binaryen")
}
}
ivy {
url = uri("https://storage.googleapis.com/chromium-v8/official/canary")
patternLayout {
artifact("[artifact]-[revision].[ext]")
}
metadataSources {
artifact()
}
content {
includeModule("google.d8", "v8")
}
}
${additionalDependencyRepositories.map { repo -> "maven{ url = \"$repo\" }" }.joinToString("\n")}
${localRepo?.absolutePathString()?.let { repo -> "maven{ url = \"${repo.replace("\\", "\\\\")}\" }" } ?: ""}
}
@@ -232,6 +271,45 @@ internal fun getKotlinDependencyManagementBlock(
includeModule("org.nodejs", "node")
}
}
ivy {
url = uri("https://nodejs.org/download/v8-canary")
patternLayout {
artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]")
}
metadataSources {
artifact()
}
content {
includeModule("org.nodejs", "node")
}
}
ivy {
url = uri("https://github.com/WebAssembly/binaryen/releases/download")
patternLayout {
artifact("version_[revision]/binaryen-version_[revision]-[classifier].[ext]")
}
metadataSources {
artifact()
}
content {
includeModule("com.github.webassembly", "binaryen")
}
}
ivy {
url = uri("https://storage.googleapis.com/chromium-v8/official/canary")
patternLayout {
artifact("[artifact]-[revision].[ext]")
}
metadataSources {
artifact()
}
content {
includeModule("google.d8", "v8")
}
}
maven {
url = uri("https://packages.jetbrains.team/maven/p/ij/intellij-dependencies/")
}
@@ -39,7 +39,7 @@ rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJ
tasks.register("runWebpack", Exec) {
dependsOn(tasks.named('browserProductionWebpack'))
executable(kotlinNodeJs.requireConfigured().nodeExecutable)
executable(kotlinNodeJs.requireConfigured().executable)
workingDir = "${rootProject.buildDir}/js/packages/kotlin-js-dce-mainProject"
args = ["../../node_modules/webpack/bin/webpack.js"]
@@ -39,7 +39,6 @@ kotlin {
}
}
}
<ApplyBinaryen>
}
sourceSets {
@@ -70,7 +70,6 @@ dependencies {
commonCompileOnly(commonDependency("org.jetbrains.teamcity:serviceMessages"))
commonCompileOnly(libs.gradle.enterprise.gradlePlugin)
commonCompileOnly(commonDependency("com.google.code.gson:gson"))
commonCompileOnly("de.undercouch:gradle-download-task:4.1.1")
commonCompileOnly("com.github.gundy:semver4j:0.16.4:nodeps") {
exclude(group = "*")
}
@@ -99,7 +98,6 @@ dependencies {
embedded(libs.guava) { isTransitive = false }
embedded(commonDependency("org.jetbrains.teamcity:serviceMessages")) { isTransitive = false }
embedded(project(":kotlin-tooling-metadata")) { isTransitive = false }
embedded("de.undercouch:gradle-download-task:4.1.1")
embedded("com.github.gundy:semver4j:0.16.4:nodeps") {
exclude(group = "*")
}
@@ -148,13 +146,6 @@ tasks {
withType<ShadowJar>().configureEach {
relocate("com.github.gundy", "$kotlinEmbeddableRootPackage.com.github.gundy")
relocate("de.undercouch.gradle.tasks.download", "$kotlinEmbeddableRootPackage.de.undercouch.gradle.tasks.download")
// don't expose external Gradle plugin marker
// workaround from https://github.com/johnrengelman/shadow/issues/505#issuecomment-644098082
transform(DontIncludeResourceTransformer::class.java) {
resource = "META-INF/gradle-plugins/de.undercouch.download.properties"
}
}
}
@@ -1,5 +1,6 @@
package org.jetbrains.kotlin.gradle.targets.js
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
import java.io.File
interface AbstractEnv {
@@ -11,4 +12,8 @@ interface AbstractEnv {
val ivyDependency: String
val dir: File
val executable: String
val cleanableStore: CleanableStore
}
@@ -1,6 +1,5 @@
package org.jetbrains.kotlin.gradle.targets.js
import org.gradle.work.DisableCachingByDefault
import org.jetbrains.kotlin.gradle.internal.ConfigurationPhaseAware
import java.io.File
@@ -131,7 +131,7 @@ abstract class AbstractSetupTask<Env : AbstractEnv, Settings : AbstractSettings<
destinationHashFile: File,
dist: File,
fileHasher: FileHasher,
extract: (File, File) -> Unit,
extract: (File) -> Unit,
) {
var distHash: String? = null
val upToDate = destinationHashFile.let { file ->
@@ -154,7 +154,7 @@ abstract class AbstractSetupTask<Env : AbstractEnv, Settings : AbstractSettings<
destination.deleteRecursively()
}
extract(dist, destination.parentFile)
extract(dist)
destinationHashFile.writeText(
CACHE_VERSION +
@@ -165,7 +165,7 @@ abstract class AbstractSetupTask<Env : AbstractEnv, Settings : AbstractSettings<
)
}
abstract fun extract(archive: File, destination: File)
abstract fun extract(archive: File)
companion object {
const val CACHE_VERSION = "2"
@@ -1,14 +1,18 @@
package org.jetbrains.kotlin.gradle.targets.js.binaryen
import org.jetbrains.kotlin.gradle.targets.js.AbstractEnv
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
import java.io.File
import java.net.URL
data class BinaryenEnv(
val cleanableStore: CleanableStore,
val zipPath: File,
val targetPath: File,
val executablePath: File,
override val download: Boolean,
override val downloadBaseUrl: String?,
override val ivyDependency: String,
override val executable: String,
override val dir: File,
override val cleanableStore: CleanableStore,
val isWindows: Boolean,
val downloadUrl: URL
)
) : AbstractEnv {
val executablePath: File
get() = File(executable)
}
@@ -20,10 +20,6 @@ import javax.inject.Inject
abstract class BinaryenExec
@Inject
constructor() : AbstractExecTask<BinaryenExec>(BinaryenExec::class.java) {
@Transient
@get:Internal
lateinit var binaryen: BinaryenRootExtension
@get:Inject
abstract val fs: FileSystemOperations
@@ -68,8 +64,7 @@ constructor() : AbstractExecTask<BinaryenExec>(BinaryenExec::class.java) {
return project.registerTask(
name,
) {
it.binaryen = binaryen
it.executable = binaryen.requireConfigured().executablePath.absolutePath
it.executable = binaryen.requireConfigured().executable
it.dependsOn(binaryen.setupTaskProvider)
it.dependsOn(compilation.compileTaskProvider)
it.configuration()
@@ -6,15 +6,14 @@
package org.jetbrains.kotlin.gradle.targets.js.binaryen
import org.gradle.api.Project
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.internal.ConfigurationPhaseAware
import org.jetbrains.kotlin.gradle.logging.kotlinInfo
import org.jetbrains.kotlin.gradle.targets.js.AbstractSettings
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
import java.io.Serializable
import java.net.URL
open class BinaryenRootExtension(@Transient val rootProject: Project) : ConfigurationPhaseAware<BinaryenEnv>(), Serializable {
open class BinaryenRootExtension(
@Transient val rootProject: Project
) : AbstractSettings<BinaryenEnv>() {
init {
check(rootProject.rootProject == rootProject)
}
@@ -23,30 +22,41 @@ open class BinaryenRootExtension(@Transient val rootProject: Project) : Configur
rootProject.logger.kotlinInfo("Storing cached files in $it")
}
var installationPath by Property(gradleHome.resolve("binaryen"))
var downloadBaseUrl by Property("https://github.com/WebAssembly/binaryen/releases/download/")
var version by Property("116")
override var installationDir by Property(gradleHome.resolve("binaryen"))
override var downloadBaseUrl: String? by Property("https://github.com/WebAssembly/binaryen/releases/download")
override var version: String by Property("116")
override var download: Boolean by Property(true)
override var command: String by Property("wasm-opt")
val setupTaskProvider: TaskProvider<out Copy>
get() = rootProject.tasks.withType(Copy::class.java).named(BinaryenRootPlugin.INSTALL_TASK_NAME)
val setupTaskProvider: TaskProvider<BinaryenSetupTask>
get() = rootProject.tasks.withType(BinaryenSetupTask::class.java).named(BinaryenSetupTask.NAME)
override fun finalizeConfiguration(): BinaryenEnv {
val requiredVersionName = "binaryen-version_$version-${BinaryenPlatform.platform}"
val requiredZipName = "$requiredVersionName.tar.gz"
val cleanableStore = CleanableStore[installationPath.absolutePath]
val platform = BinaryenPlatform.platform
val requiredVersionName = "binaryen-version_$version"
val cleanableStore = CleanableStore[installationDir.absolutePath]
val targetPath = cleanableStore[requiredVersionName].use()
val isWindows = BinaryenPlatform.name == BinaryenPlatform.WIN
fun getExecutable(command: String, customCommand: String, windowsExtension: String): String {
val finalCommand = if (isWindows && customCommand == command) "$command.$windowsExtension" else customCommand
return if (download)
targetPath
.resolve("bin")
.resolve(finalCommand)
.absolutePath
else
finalCommand
}
return BinaryenEnv(
download = download,
downloadBaseUrl = downloadBaseUrl,
ivyDependency = "com.github.webassembly:binaryen:$version:$platform@tar.gz",
executable = getExecutable("wasm-opt", command, "exe"),
dir = targetPath,
cleanableStore = cleanableStore,
zipPath = cleanableStore[requiredZipName].use(),
targetPath = targetPath,
executablePath = targetPath
.resolve("binaryen-version_$version")
.resolve("bin")
.resolve(if (isWindows) "wasm-opt.exe" else "wasm-opt"),
isWindows = isWindows,
downloadUrl = URL("${downloadBaseUrl.trimEnd('/')}/version_$version/$requiredZipName"),
)
}
@@ -5,15 +5,14 @@
package org.jetbrains.kotlin.gradle.targets.js.binaryen
import de.undercouch.gradle.tasks.download.Download
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.tasks.Copy
import org.jetbrains.kotlin.gradle.targets.js.MultiplePluginDeclarationDetector
import org.jetbrains.kotlin.gradle.targets.js.binaryen.BinaryenRootExtension.Companion.EXTENSION_NAME
import org.jetbrains.kotlin.gradle.tasks.CleanDataTask
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.castIsolatedKotlinPluginClassLoaderAware
open class BinaryenRootPlugin : Plugin<Project> {
override fun apply(project: Project) {
@@ -27,23 +26,13 @@ open class BinaryenRootPlugin : Plugin<Project> {
val settings = project.extensions.create(EXTENSION_NAME, BinaryenRootExtension::class.java, project)
val downloadTask = project.registerTask<Download>("${TASKS_GROUP_NAME}Download") {
val env = settings.requireConfigured()
project.registerTask<BinaryenSetupTask>(BinaryenSetupTask.NAME) {
it.group = TASKS_GROUP_NAME
it.src(env.downloadUrl)
it.dest(env.zipPath)
it.overwrite(false)
it.description = "Download local binaryen version"
}
project.registerTask<Copy>(INSTALL_TASK_NAME) {
val env = settings.requireConfigured()
it.onlyIf { env.zipPath.exists() && !env.executablePath.exists() }
it.group = TASKS_GROUP_NAME
it.from(project.tarTree(env.zipPath))
it.into(env.targetPath)
it.dependsOn(downloadTask)
it.description = "Install local binaryen version"
it.description = "Download and install a binaryen"
it.configuration = project.provider {
project.configurations.detachedConfiguration(project.dependencies.create(it.ivyDependency))
.also { conf -> conf.isTransitive = false }
}
}
project.registerTask<CleanDataTask>("binaryen" + CleanDataTask.NAME_SUFFIX) {
@@ -55,12 +44,14 @@ open class BinaryenRootPlugin : Plugin<Project> {
companion object {
const val TASKS_GROUP_NAME: String = "binaryen"
const val INSTALL_TASK_NAME: String = "${TASKS_GROUP_NAME}Install"
fun apply(rootProject: Project): BinaryenRootExtension {
check(rootProject == rootProject.rootProject)
rootProject.plugins.apply(BinaryenRootPlugin::class.java)
return rootProject.extensions.getByName(EXTENSION_NAME) as BinaryenRootExtension
}
val Project.kotlinBinaryenExtension: BinaryenRootExtension
get() = extensions.getByName(EXTENSION_NAME).castIsolatedKotlinPluginClassLoaderAware()
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.targets.js.binaryen
import org.gradle.api.tasks.Internal
import org.gradle.work.DisableCachingByDefault
import org.jetbrains.kotlin.gradle.targets.js.AbstractSetupTask
import org.jetbrains.kotlin.gradle.targets.js.binaryen.BinaryenRootPlugin.Companion.kotlinBinaryenExtension
import java.io.File
@DisableCachingByDefault
abstract class BinaryenSetupTask : AbstractSetupTask<BinaryenEnv, BinaryenRootExtension>() {
@Transient
@Internal
override val settings = project.kotlinBinaryenExtension
@get:Internal
override val artifactPattern: String
get() = "version_[revision]/binaryen-version_[revision]-[classifier].[ext]"
@get:Internal
override val artifactModule: String
get() = "com.github.webassembly"
@get:Internal
override val artifactName: String
get() = "binaryen"
override fun extract(archive: File) {
fs.copy {
it.from(archiveOperations.tarTree(archive))
it.into(destination.parentFile)
}
if (!env.isWindows) {
File(env.executable).setExecutable(true)
}
}
companion object {
const val NAME: String = "kotlinBinaryenSetup"
}
}
@@ -1,15 +1,18 @@
package org.jetbrains.kotlin.gradle.targets.js.d8
import org.jetbrains.kotlin.gradle.targets.js.AbstractEnv
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
import java.io.File
import java.net.URL
data class D8Env(
val cleanableStore: CleanableStore,
val zipPath: File,
val targetPath: File,
val executablePath: File,
override val download: Boolean,
override val downloadBaseUrl: String?,
override val ivyDependency: String,
override val executable: String,
override val dir: File,
override val cleanableStore: CleanableStore,
val isWindows: Boolean,
val downloadUrl: URL,
val ivyDependency: String
)
) : AbstractEnv {
val executablePath: File
get() = File(executable)
}
@@ -63,7 +63,7 @@ open class D8Exec : AbstractExecTask<D8Exec>(D8Exec::class.java) {
return project.registerTask(
name
) {
it.executable = d8.requireConfigured().executablePath.absolutePath
it.executable = d8.requireConfigured().executable
it.dependsOn(d8.setupTaskProvider)
it.dependsOn(compilation.compileTaskProvider)
if (compilation.platformType == KotlinPlatformType.wasm) {
@@ -6,15 +6,12 @@
package org.jetbrains.kotlin.gradle.targets.js.d8
import org.gradle.api.Project
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.internal.ConfigurationPhaseAware
import org.jetbrains.kotlin.gradle.logging.kotlinInfo
import org.jetbrains.kotlin.gradle.targets.js.AbstractSettings
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
import java.io.Serializable
import java.net.URL
open class D8RootExtension(@Transient val rootProject: Project) : ConfigurationPhaseAware<D8Env>(), Serializable {
open class D8RootExtension(@Transient val rootProject: Project) : AbstractSettings<D8Env>() {
init {
check(rootProject.rootProject == rootProject)
}
@@ -23,8 +20,9 @@ open class D8RootExtension(@Transient val rootProject: Project) : ConfigurationP
rootProject.logger.kotlinInfo("Storing cached files in $it")
}
var installationPath by Property(gradleHome.resolve("d8"))
var downloadBaseUrl by Property("https://storage.googleapis.com/chromium-v8/official/canary/")
override var download: Boolean by Property(true)
override var downloadBaseUrl: String? by Property("https://storage.googleapis.com/chromium-v8/official/canary")
override var installationDir by Property(gradleHome.resolve("d8"))
// Latest version number could be found here https://storage.googleapis.com/chromium-v8/official/canary/v8-linux64-rel-latest.json
// Bash script/command to check that version specified in `VER` is available for all platforms, just copy-paste and run it in terminal:
@@ -41,27 +39,37 @@ open class D8RootExtension(@Transient val rootProject: Project) : ConfigurationP
fi;
done;
*/
var version by Property("11.9.85")
override var version by Property("11.9.85")
var edition by Property("rel") // rel or dbg
override var command by Property("d8")
val setupTaskProvider: TaskProvider<out Copy>
get() = rootProject.tasks.withType(Copy::class.java).named(D8RootPlugin.INSTALL_TASK_NAME)
val setupTaskProvider: TaskProvider<D8SetupTask>
get() = rootProject.tasks.withType(D8SetupTask::class.java).named(D8SetupTask.NAME)
override fun finalizeConfiguration(): D8Env {
val requiredVersionName = "v8-${D8Platform.platform}-$edition-$version"
val requiredZipName = "$requiredVersionName.zip"
val cleanableStore = CleanableStore[installationPath.absolutePath]
val cleanableStore = CleanableStore[installationDir.absolutePath]
val targetPath = cleanableStore[requiredVersionName].use()
val isWindows = D8Platform.name == D8Platform.WIN
fun getExecutable(command: String, customCommand: String, windowsExtension: String): String {
val finalCommand = if (isWindows && customCommand == command) "$command.$windowsExtension" else customCommand
return if (download)
targetPath
.resolve(finalCommand)
.absolutePath
else
finalCommand
}
return D8Env(
download = download,
downloadBaseUrl = downloadBaseUrl,
ivyDependency = "google.d8:v8:${D8Platform.platform}-$edition-$version@zip",
executable = getExecutable("d8", command, "exe"),
dir = targetPath,
cleanableStore = cleanableStore,
zipPath = cleanableStore[requiredZipName].use(),
targetPath = targetPath,
executablePath = targetPath.resolve(if (isWindows) "d8.exe" else "d8"),
isWindows = isWindows,
downloadUrl = URL(downloadBaseUrl),
ivyDependency = "google.d8:v8:${D8Platform.platform}-$edition-$version@zip"
)
}
@@ -8,11 +8,11 @@ package org.jetbrains.kotlin.gradle.targets.js.d8
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.tasks.Copy
import org.jetbrains.kotlin.gradle.targets.js.MultiplePluginDeclarationDetector
import org.jetbrains.kotlin.gradle.targets.js.d8.D8RootExtension.Companion.EXTENSION_NAME
import org.jetbrains.kotlin.gradle.tasks.CleanDataTask
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.castIsolatedKotlinPluginClassLoaderAware
open class D8RootPlugin : Plugin<Project> {
@@ -27,39 +27,15 @@ open class D8RootPlugin : Plugin<Project> {
val settings = project.extensions.create(EXTENSION_NAME, D8RootExtension::class.java, project)
project.gradle.projectsEvaluated {
val downloadUrl = settings.requireConfigured().downloadUrl
project.repositories.ivy { repo ->
repo.name = "D8 Distributions at $downloadUrl"
repo.url = downloadUrl.toURI()
repo.patternLayout {
it.artifact("[artifact]-[revision].[ext]")
}
repo.metadataSources { it.artifact() }
repo.content { it.includeModule("google.d8", "v8") }
project.registerTask<D8SetupTask>(D8SetupTask.NAME) {
it.group = TASKS_GROUP_NAME
it.description = "Download and install a D8"
it.configuration = project.provider {
project.configurations.detachedConfiguration(project.dependencies.create(it.ivyDependency))
.also { conf -> conf.isTransitive = false }
}
}
val downloadTask = project.registerTask<Copy>("${TASKS_GROUP_NAME}Download") {
it.group = TASKS_GROUP_NAME
it.description = "Download local d8 version"
val env = settings.requireConfigured()
val configuration = project.configurations.detachedConfiguration(project.dependencies.create(env.ivyDependency))
it.from(project.provider { configuration.singleFile })
it.into(env.zipPath.parentFile)
}
project.registerTask<Copy>(INSTALL_TASK_NAME) {
val env = settings.requireConfigured()
it.onlyIf { env.zipPath.exists() && !env.executablePath.exists() }
it.group = TASKS_GROUP_NAME
it.from(project.zipTree(env.zipPath))
it.into(env.targetPath)
it.dependsOn(downloadTask)
it.description = "Install local d8 version"
}
project.registerTask<CleanDataTask>("d8" + CleanDataTask.NAME_SUFFIX) {
it.cleanableStoreProvider = project.provider { settings.requireConfigured().cleanableStore }
it.group = TASKS_GROUP_NAME
@@ -69,12 +45,14 @@ open class D8RootPlugin : Plugin<Project> {
companion object {
const val TASKS_GROUP_NAME: String = "d8"
const val INSTALL_TASK_NAME: String = "${TASKS_GROUP_NAME}Install"
fun apply(rootProject: Project): D8RootExtension {
check(rootProject == rootProject.rootProject)
rootProject.plugins.apply(D8RootPlugin::class.java)
return rootProject.extensions.getByName(EXTENSION_NAME) as D8RootExtension
}
val Project.kotlinD8Extension: D8RootExtension
get() = extensions.getByName(EXTENSION_NAME).castIsolatedKotlinPluginClassLoaderAware()
}
}
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.targets.js.d8
import org.gradle.api.tasks.Internal
import org.gradle.work.DisableCachingByDefault
import org.jetbrains.kotlin.gradle.targets.js.AbstractSetupTask
import org.jetbrains.kotlin.gradle.targets.js.d8.D8RootPlugin.Companion.kotlinD8Extension
import java.io.File
@DisableCachingByDefault
abstract class D8SetupTask : AbstractSetupTask<D8Env, D8RootExtension>() {
@Transient
@Internal
override val settings = project.kotlinD8Extension
@get:Internal
override val artifactPattern: String
get() = "[artifact]-[revision].[ext]"
@get:Internal
override val artifactModule: String
get() = "google.d8"
@get:Internal
override val artifactName: String
get() = "v8"
override fun extract(archive: File) {
fs.copy {
it.from(archiveOperations.zipTree(archive))
//
it.into(destination)
}
if (!env.isWindows) {
File(env.executable).setExecutable(true)
}
}
companion object {
const val NAME: String = "kotlinD8Setup"
}
}
@@ -7,11 +7,11 @@ import java.io.File
data class NodeJsEnv(
override val download: Boolean,
val cleanableStore: CleanableStore,
override val cleanableStore: CleanableStore,
val rootPackageDir: File,
override val dir: File,
val nodeBinDir: File,
val nodeExecutable: String,
override val executable: String,
val platformName: String,
val architectureName: String,
override val ivyDependency: String,
@@ -21,4 +21,8 @@ data class NodeJsEnv(
) : AbstractEnv {
val isWindows: Boolean
get() = platformName == "win"
@Deprecated("Use executable instead", ReplaceWith("executable"))
val nodeExecutable
get() = executable
}
@@ -108,7 +108,7 @@ constructor(
listOf(compilation)
) {
it.nodeJs = nodeJs
it.executable = nodeJs.requireConfigured().nodeExecutable
it.executable = nodeJs.requireConfigured().executable
if ((compilation.target as? KotlinJsIrTarget)?.wasmTargetType != KotlinWasmTargetType.WASI) {
it.workingDir(npmProject.dir)
it.dependsOn(
@@ -158,7 +158,7 @@ open class NodeJsRootExtension(
rootPackageDir = rootPackageDirectory.getFile(),
dir = nodeDir,
nodeBinDir = nodeBinDir,
nodeExecutable = getExecutable("node", command, "exe"),
executable = getExecutable("node", command, "exe"),
platformName = name,
architectureName = architecture,
ivyDependency = getIvyDependency(),
@@ -27,7 +27,7 @@ abstract class NodeJsSetupTask : AbstractSetupTask<NodeJsEnv, NodeJsRootExtensio
override val artifactName: String
get() = "node"
override fun extract(archive: File, destination: File) {
override fun extract(archive: File) {
var fixBrokenSymLinks = false
fs.copy {
@@ -40,13 +40,13 @@ abstract class NodeJsSetupTask : AbstractSetupTask<NodeJsEnv, NodeJsRootExtensio
}
}
)
it.into(destination)
it.into(destination.parentFile)
}
fixBrokenSymlinks(this.destination, env.isWindows, fixBrokenSymLinks)
if (!env.isWindows) {
File(env.nodeExecutable).setExecutable(true)
File(env.executable).setExecutable(true)
}
}
@@ -51,6 +51,6 @@ data class NodeJsEnvironment(
internal val NodeJsEnv.asNodeJsEnvironment
get() = NodeJsEnvironment(
rootPackageDir,
nodeExecutable,
executable,
packageManager
)
@@ -87,7 +87,7 @@ open class NpmProject(@Transient val compilation: KotlinJsIrCompilation) : Seria
}
private val nodeExecutable by lazy {
nodeJs.requireConfigured().nodeExecutable
nodeJs.requireConfigured().executable
}
fun useTool(
@@ -38,7 +38,7 @@ constructor(
@Transient
private val nodeJs = project.rootProject.kotlinNodeJsExtension
private val nodeExecutable by project.provider { nodeJs.requireConfigured().nodeExecutable }
private val nodeExecutable by project.provider { nodeJs.requireConfigured().executable }
@Input
var environment = mutableMapOf<String, String>()
@@ -31,7 +31,7 @@ internal class KotlinWasmD8(private val kotlinJsTest: KotlinJsTest) : KotlinJsTe
private val project: Project = compilation.target.project
private val d8 = D8RootPlugin.apply(project.rootProject)
private val d8Executable by project.provider { d8.requireConfigured().executablePath }
private val d8Executable by project.provider { d8.requireConfigured().executable }
private val npmProjectDir by project.provider { compilation.npmProject.dir }
override val workingDir: Provider<Directory>
@@ -45,7 +45,7 @@ internal class KotlinWasmD8(private val kotlinJsTest: KotlinJsTest) : KotlinJsTe
): TCServiceMessagesTestExecutionSpec {
val testRunnerFile = writeWasmUnitTestRunner(task.inputFileProperty.get().asFile)
forkOptions.executable = d8Executable.absolutePath
forkOptions.executable = d8Executable
forkOptions.workingDir = testRunnerFile.parentFile
val clientSettings = TCServiceMessagesClientSettings(
@@ -12,9 +12,9 @@ import java.io.File
data class YarnEnv(
override val download: Boolean,
override val downloadBaseUrl: String?,
val cleanableStore: CleanableStore,
override val cleanableStore: CleanableStore,
override val dir: File,
val executable: String,
override val executable: String,
override val ivyDependency: String,
val ignoreScripts: Boolean,
val yarnLockMismatchReport: YarnLockMismatchReport,
@@ -28,11 +28,11 @@ abstract class YarnSetupTask : AbstractSetupTask<YarnEnv, YarnRootExtension>() {
override val artifactName: String
get() = "yarn"
override fun extract(archive: File, destination: File) {
override fun extract(archive: File) {
val dirInTar = archive.name.removeSuffix(".tar.gz")
fs.copy {
it.from(archiveOperations.tarTree(archive))
it.into(destination)
it.into(destination.parentFile)
it.includeEmptyDirs = false
it.eachFile { fileCopy ->
fileCopy.path = fileCopy.path.removePrefix(dirInTar)
@@ -45,6 +45,7 @@ fun Project.useNodeJsPlugin() {
NodeJsUtils.useNodeJsPlugin(this)
}
@Suppress("DEPRECATION")
fun Test.setupNodeJs() {
dependsOn(NodeJsUtils.nodeJsPlugin.nodeJsSetupTaskProvider)
val nodeJsExecutablePath = project.provider {