diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 9a9e5e6066d..fbf98cc3fce 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1506,12 +1506,6 @@ - - - - - - diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinWasmGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinWasmGradlePluginIT.kt index 481023b64d0..6452a8f6720 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinWasmGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinWasmGradlePluginIT.kt @@ -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("", "nodejs") - .replace("", "") } 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") { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt index ac1f960bcf8..d7fdce1ac3d 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt @@ -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("", engine) - .replace("", 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() { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/projectSetupDefaults.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/projectSetupDefaults.kt index f148e018474..54b8eea41eb 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/projectSetupDefaults.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/projectSetupDefaults.kt @@ -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/") } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-dce/mainProject/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-dce/mainProject/build.gradle index 6faa604a32b..db51fbabb38 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-dce/mainProject/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-dce/mainProject/build.gradle @@ -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"] diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-wasm-test/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-wasm-test/build.gradle.kts index e0489f4e4e1..71b2d895b5a 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-wasm-test/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-wasm-test/build.gradle.kts @@ -39,7 +39,6 @@ kotlin { } } } - } sourceSets { diff --git a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts index 5a78de666c5..b51f32d6b20 100644 --- a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts @@ -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().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" - } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractEnv.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractEnv.kt index 816293a5666..bc5675dda52 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractEnv.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractEnv.kt @@ -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 } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSettings.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSettings.kt index 542b51095a0..2b5afef2287 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSettings.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSettings.kt @@ -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 diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSetupTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSetupTask.kt index a8108c5843a..d7abca1026f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSetupTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSetupTask.kt @@ -131,7 +131,7 @@ abstract class AbstractSetupTask Unit, + extract: (File) -> Unit, ) { var distHash: String? = null val upToDate = destinationHashFile.let { file -> @@ -154,7 +154,7 @@ abstract class AbstractSetupTask(BinaryenExec::class.java) { - @Transient - @get:Internal - lateinit var binaryen: BinaryenRootExtension - @get:Inject abstract val fs: FileSystemOperations @@ -68,8 +64,7 @@ constructor() : AbstractExecTask(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() diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenRootExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenRootExtension.kt index c0ddbe85e89..8c271eb5ffe 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenRootExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenRootExtension.kt @@ -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(), Serializable { +open class BinaryenRootExtension( + @Transient val rootProject: Project +) : AbstractSettings() { 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 - get() = rootProject.tasks.withType(Copy::class.java).named(BinaryenRootPlugin.INSTALL_TASK_NAME) + val setupTaskProvider: TaskProvider + 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"), ) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenRootPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenRootPlugin.kt index 5adadce7cb2..2fc7f903578 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenRootPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenRootPlugin.kt @@ -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 { override fun apply(project: Project) { @@ -27,23 +26,13 @@ open class BinaryenRootPlugin : Plugin { val settings = project.extensions.create(EXTENSION_NAME, BinaryenRootExtension::class.java, project) - val downloadTask = project.registerTask("${TASKS_GROUP_NAME}Download") { - val env = settings.requireConfigured() + project.registerTask(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(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("binaryen" + CleanDataTask.NAME_SUFFIX) { @@ -55,12 +44,14 @@ open class BinaryenRootPlugin : Plugin { 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() } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenSetupTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenSetupTask.kt new file mode 100644 index 00000000000..298c55da815 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenSetupTask.kt @@ -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() { + @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" + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8Env.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8Env.kt index 68706cef86c..8e456aa52ee 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8Env.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8Env.kt @@ -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 -) \ No newline at end of file +) : AbstractEnv { + val executablePath: File + get() = File(executable) +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8Exec.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8Exec.kt index 0bbb06d3587..356a45936ca 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8Exec.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8Exec.kt @@ -63,7 +63,7 @@ open class D8Exec : AbstractExecTask(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) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8RootExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8RootExtension.kt index be63ce4c0f1..b8662074bf4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8RootExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8RootExtension.kt @@ -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(), Serializable { +open class D8RootExtension(@Transient val rootProject: Project) : AbstractSettings() { 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 - get() = rootProject.tasks.withType(Copy::class.java).named(D8RootPlugin.INSTALL_TASK_NAME) + val setupTaskProvider: TaskProvider + 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" ) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8RootPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8RootPlugin.kt index 168613d45ac..efdcf9ae09c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8RootPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8RootPlugin.kt @@ -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 { @@ -27,39 +27,15 @@ open class D8RootPlugin : Plugin { 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.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("${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(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("d8" + CleanDataTask.NAME_SUFFIX) { it.cleanableStoreProvider = project.provider { settings.requireConfigured().cleanableStore } it.group = TASKS_GROUP_NAME @@ -69,12 +45,14 @@ open class D8RootPlugin : Plugin { 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() } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8SetupTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8SetupTask.kt new file mode 100644 index 00000000000..ac40c926f9a --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/d8/D8SetupTask.kt @@ -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() { + @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" + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsEnv.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsEnv.kt index 17957f6fff1..0574e560c81 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsEnv.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsEnv.kt @@ -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 } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExec.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExec.kt index 0a9d4baaf0e..c0a05b42fd5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExec.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExec.kt @@ -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( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootExtension.kt index 628ac3fef07..2db990bbc1f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootExtension.kt @@ -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(), diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt index 46811526e66..a918eab4f76 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt @@ -27,7 +27,7 @@ abstract class NodeJsSetupTask : AbstractSetupTask() diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinWasmD8.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinWasmD8.kt index 4e28c7b86dc..f8d6b0fc458 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinWasmD8.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinWasmD8.kt @@ -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 @@ -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( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnEnv.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnEnv.kt index dd20fa38bb7..4c88f206445 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnEnv.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnEnv.kt @@ -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, diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt index 73c406daf4c..b6045bd6bc0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt @@ -28,11 +28,11 @@ abstract class YarnSetupTask : AbstractSetupTask() { 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) diff --git a/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/setupV8.kt b/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/setupV8.kt index 59583128fc0..4974638d2a5 100644 --- a/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/setupV8.kt +++ b/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/setupV8.kt @@ -45,6 +45,7 @@ fun Project.useNodeJsPlugin() { NodeJsUtils.useNodeJsPlugin(this) } +@Suppress("DEPRECATION") fun Test.setupNodeJs() { dependsOn(NodeJsUtils.nodeJsPlugin.nodeJsSetupTaskProvider) val nodeJsExecutablePath = project.provider {