From 3ea8a876119ea9c73a0d2d0896e2d0cf7f23eab6 Mon Sep 17 00:00:00 2001 From: Alex Nordlund Date: Fri, 12 May 2023 17:18:07 +0200 Subject: [PATCH] Move platform computation to NodeExtension This fixes #271 and starts a bunch of refactors, it also re-introduces support for Gradle 6, and deprecates the platform functionality of PlatformHelper (in it's current state) --- .github/workflows/build.yml | 4 +- CHANGELOG.md | 37 ++++---- README.md | 10 +-- build.gradle.kts | 7 +- .../buildlogic/GradleVersionData.groovy | 4 +- gradle.properties | 2 +- .../com/github/gradle/node/NodeExtension.kt | 14 ++- .../com/github/gradle/node/NodePlugin.kt | 60 +++++++++---- .../github/gradle/node/exec/NodeExecRunner.kt | 19 ++-- .../gradle/node/npm/exec/NpmExecRunner.kt | 29 ++++--- .../gradle/node/pnpm/exec/PnpmExecRunner.kt | 9 +- .../com/github/gradle/node/task/BaseTask.kt | 9 +- .../github/gradle/node/task/NodeSetupTask.kt | 20 ++--- .../gradle/node/util/NodeVersionSource.kt | 25 ------ .../com/github/gradle/node/util/Platform.kt | 7 ++ .../github/gradle/node/util/PlatformHelper.kt | 77 ++++++++++------ .../gradle/node/util/ProjectApiHelper.kt | 8 +- .../gradle/node/variant/VariantComputer.kt | 87 ++++++++++++++----- .../github/gradle/AbstractIntegTest.groovy | 1 + .../node/npm/task/NpmInstallTaskTest.groovy | 3 + .../node/npm/task/NpmSetupTaskTest.groovy | 4 + .../gradle/node/npm/task/NpmTaskTest.groovy | 8 ++ .../gradle/node/npm/task/NpxTaskTest.groovy | 7 +- .../gradle/node/pnpm/task/PnpmTaskTest.groovy | 5 +- .../node/task/NodeSetupTask_integTest.groovy | 42 --------- .../gradle/node/task/NodeTaskTest.groovy | 7 ++ .../node/util/PlatformHelperTest.groovy | 15 +++- .../node/variant/VariantComputerTest.groovy | 28 ++++-- .../gradle/node/yarn/task/YarnTaskTest.groovy | 4 + 29 files changed, 343 insertions(+), 209 deletions(-) delete mode 100644 src/main/kotlin/com/github/gradle/node/util/NodeVersionSource.kt create mode 100644 src/main/kotlin/com/github/gradle/node/util/Platform.kt diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b1e47240..fdb6c1af 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,8 +6,8 @@ jobs: strategy: matrix: config: - - {os: ubuntu-latest, params: "'-PtestedGradleVersion=7.5.1|8.1.1' pnpmTests" } - - {os: ubuntu-latest, params: "'-PtestedGradleVersion=7.5.1|8.1.1' build" } + - {os: ubuntu-latest, params: "'-PtestedGradleVersion=6.9.4|7.5.1|8.1.1' pnpmTests" } + - {os: ubuntu-latest, params: "'-PtestedGradleVersion=6.9.4|7.5.1|8.1.1' build" } - {os: windows-latest, params: "build pnpmTests" } - {os: macos-latest, params: "build pnpmTests" } steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 31d2dee6..b5374aee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,15 @@ # Changelog -## Version 4.x *(unreleased)* +## Version 5.x *(unreleased)* + +## Version 5.0.0 *(unreleased)* +* Support configuration-cache on Gradle 8.1 [#271](https://github.com/node-gradle/gradle-node-plugin/issues/271) +* Store node directories on NodeExtension +* Deprecate parts of PlatformHelper that require executing commands during configuration +* Re-introduce support for Gradle 6.6 and newer ## Version 4.0.0 *(2023-04-23)* +* **This version is unfortunately broken, please upgrade directly to 5.0.0** * Drop support for versions lower than Gradle 7.5.1 * Rename `package.json` extension to `packageJson` [#232](https://github.com/node-gradle/gradle-node-plugin/issues/232) * Support configuration-cache on Gradle 8.1 [#271](https://github.com/node-gradle/gradle-node-plugin/issues/271) @@ -39,7 +46,7 @@ ## Version 3.1.0 *(2021-05-07)* * Add support for Linux Power PC [#166](https://github.com/node-gradle/gradle-node-plugin/issues/166) (thanks [akatona84](https://github.com/akatona84) for the [pull request](https://github.com/node-gradle/gradle-node-plugin/issues/167)) * Internal test suite now running against Gradle 7 -* Adds `yarn.lock` as an input to `NpmInstallTask` [#155](https://github.com/node-gradle/gradle-node-plugin/issues/155) +* Adds `yarn.lock` as an input to `NpmInstallTask` [#155](https://github.com/node-gradle/gradle-node-plugin/issues/155) ## Version 3.0.1 *(2021-02-09)* * Fixes a bug with the task rule preventing it from being configured [#145](https://github.com/node-gradle/gradle-node-plugin/issues/145) @@ -74,15 +81,15 @@ Here is what changed: * `com.moowork.gradle.node` (and all children) renamed to `com.github.gradle.node` * `com.moowork.gradle.node.npm` renamed to `com.github.gradle.node.npm.task` * `com.moowork.gradle.node.yarn` renamed to `com.github.gradle.node.yarn.task` -* All the configuration properties (the `node` extension and all tasks) are now some -[lazy properties](https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_properties) as recommended by -Gradle. This makes this plugin fully compatible with lazy configuration (tasks will be configured only if they need to +* All the configuration properties (the `node` extension and all tasks) are now some +[lazy properties](https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_properties) as recommended by +Gradle. This makes this plugin fully compatible with lazy configuration (tasks will be configured only if they need to run and configuration properties are read only at runtime if needed and not at configuration time). * Thanks to the Kotlin rewrite, some properties now have a stronger typing. * `nodeModulesDir` option was renamed to `nodeProjectDir` (name more explicit and less confusing) - (issue [#99](https://github.com/node-gradle/gradle-node-plugin/issues/99)). The former name still works but is + (issue [#99](https://github.com/node-gradle/gradle-node-plugin/issues/99)). The former name still works but is deprecated. -* Change the syntax to configure `nodeModulesOutputFilter` on `npmInstall` and `yarn` tasks. It also affects Groovy DSL +* Change the syntax to configure `nodeModulesOutputFilter` on `npmInstall` and `yarn` tasks. It also affects Groovy DSL users. Use now `nodeModulesOutputFilter { ... }` instead of `nodeModulesOutputFilter = { ... }`. ## Version 2.2.4 *(2020-05-18)* @@ -91,7 +98,7 @@ users. Use now `nodeModulesOutputFilter { ... }` instead of `nodeModulesOutputFi ## Version 2.2.3 *(2020-02-28)* -The previous release (2.2.2) was released by error from the development branch which contains an entire Kotlin rewrite +The previous release (2.2.2) was released by error from the development branch which contains an entire Kotlin rewrite of the plugin code and many backward compatibility breaks. This new version replaces the previous one and adds one fix. * Make npm and npx symlinks relative. PR #68 * NpmSetupTask does not work when using separate http and https proxy settings #69 @@ -110,10 +117,10 @@ of the plugin code and many backward compatibility breaks. This new version repl * `NodeTask`'s `script` now has relative path sensitivity (issue [#41](https://github.com/node-gradle/gradle-node-plugin/issues/41)) * No longer consider the working dir as an input for all tasks (issue [#40](https://github.com/node-gradle/gradle-node-plugin/issues/40)) * Explicitly exclude the `execOverrides` option of tasks from the inputs (issue [#40](https://github.com/node-gradle/gradle-node-plugin/issues/40)) - * Add the ability to remove some files of the `node_modules` directory from the `NpmInstallTask` and `YarnInstallTask` + * Add the ability to remove some files of the `node_modules` directory from the `NpmInstallTask` and `YarnInstallTask` outputs from the task output ; this is necessary when some tasks change some files of the `node_modules` directory ; the `NpmInstallTask` and `YarnInstallTask` are never up-to-date in this case - (issue [#38](https://github.com/node-gradle/gradle-node-plugin/issues/38)) + (issue [#38](https://github.com/node-gradle/gradle-node-plugin/issues/38)) * Deprecate the usage of `NodeTask` with a `script` which is a directory ; Node.js supports that and looks for an `index.js` file in the directory but this is not compliant with a correct input/output declaration (issue [#41](https://github.com/node-gradle/gradle-node-plugin/issues/41)) * No longer use `Project.afterEvaluate` as a first step to support lazy tasks configuration (issue [#39](https://github.com/node-gradle/gradle-node-plugin/issues/39)) @@ -126,17 +133,17 @@ of the plugin code and many backward compatibility breaks. This new version repl * Improve the inputs declarations of the `YarnTask` ## Version 2.1.0 *(2019-09-19)* -* Adds NpxTask for making use of https://www.npmjs.com/package/npx PR #32 -* Improved up-to-date checks PR #32 +* Adds NpxTask for making use of https://www.npmjs.com/package/npx PR #32 +* Improved up-to-date checks PR #32 * Support ARM even if the JDK reports aarch64 #33 -* Setting distBaseUrl to null disables repository adding PR #25 +* Setting distBaseUrl to null disables repository adding PR #25 ## Version 2.0.0 *(2019-07-29)* * Only support Gradle 5.x officially. * Drop support for grunt/gulp plugins. ## Version 1.5.1 *(2019-06-19)* -* Fix inputs/outputs for NpmInstallTask/YarnInstallTask. +* Fix inputs/outputs for NpmInstallTask/YarnInstallTask. ## Version 1.5.0 *(2019-06-19)* * Backport from srs: Added gradle build cache support for npm install (bjornmagnusson) @@ -195,7 +202,7 @@ Version 0.14 *(2016-11-29)* Version 0.13 *(2016-06-27)* --------------------------- -* Bumped gradle wrapper version to 2.14 +* Bumped gradle wrapper version to 2.14 * Implement ARM compatibility _(madmas)_ * Allow node modules to be used when calling npm_run _(jmcampanini)_ * Updated plugin versions and test versions diff --git a/README.md b/README.md index 5e8166b9..34bbe046 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/github/license/node-gradle/gradle-node-plugin.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) ![Version](https://img.shields.io/badge/Version-4.0.0-orange.svg) -This plugin enables you to use a lot of [Node.js](https://nodejs.org)-based technologies as part of your +This plugin enables you to use a lot of [Node.js](https://nodejs.org)-based technologies as part of your build without having Node.js installed locally on your system. It integrates the following Node.js-based system with Gradle: @@ -18,14 +18,14 @@ with Gradle: The plugin is published in the [Gradle plugins portal](https://plugins.gradle.org/plugin/com.github.node-gradle.node) with the `com.github.node-gradle.node` identifier. -It supports Gradle 7.5.1+ and Node.js 10+, for Gradle 5.6.4 support use version 3.x +It supports Gradle 6.6+ and Node.js 10+, for Gradle 5.6.4 support use version 3.x ## Documentation -⚠️ This is the documentation of the development version. See below in the releases history to read the +⚠️ This is the documentation of the development version. See below in the releases history to read the documentation of the version you're using. -Here's how you get started using this plugin. If you do not find what you are looking for, please add an +Here's how you get started using this plugin. If you do not find what you are looking for, please add an issue to [GitHub Issues](https://github.com/node-gradle/gradle-node-plugin/issues). * [Installation](docs/installation.md) @@ -88,7 +88,7 @@ To run the tests against all Gradle versions, use the following option (it is do ## Contributing -Contributions are always welcome! If you'd like to contribute (and we hope you do) please send +Contributions are always welcome! If you'd like to contribute (and we hope you do) please send one of the existing contributors a nudge. ## Support this project :heart: diff --git a/build.gradle.kts b/build.gradle.kts index 572488ed..433aac6e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -43,7 +43,7 @@ repositories { } dependencies { - api("com.fasterxml.jackson.core:jackson-databind:2.13.2.2") + implementation("com.fasterxml.jackson.core:jackson-databind:2.14.2") testImplementation(platform("org.junit:junit-bom:5.6.2")) testImplementation("org.junit.jupiter:junit-jupiter-api") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") @@ -76,7 +76,8 @@ tasks.withType(Test::class) { ) val processorsCount = Runtime.getRuntime().availableProcessors() - maxParallelForks = if (processorsCount > 2) processorsCount.div(2) else processorsCount + val safeMaxForks = if (processorsCount > 2) processorsCount.div(2) else processorsCount + maxParallelForks = safeMaxForks testLogging { events = setOf(TestLogEvent.SKIPPED, TestLogEvent.FAILED) exceptionFormat = TestExceptionFormat.FULL @@ -152,7 +153,7 @@ tasks.jacocoTestReport { tasks.withType().configureEach { dokkaSourceSets { named("main") { - jdkVersion.set(8) + jdkVersion.set(compatibilityVersion.majorVersion.toInt()) } } } diff --git a/buildSrc/src/main/groovy/com/github/gradle/buildlogic/GradleVersionData.groovy b/buildSrc/src/main/groovy/com/github/gradle/buildlogic/GradleVersionData.groovy index 7da8f61b..3780a88d 100644 --- a/buildSrc/src/main/groovy/com/github/gradle/buildlogic/GradleVersionData.groovy +++ b/buildSrc/src/main/groovy/com/github/gradle/buildlogic/GradleVersionData.groovy @@ -25,8 +25,8 @@ class GradleVersionData { .findAll { !it.rcFor || it.activeRc } // filter out inactive rcs .findAll { !it.milestoneFor } // filter out milestones .collectEntries { [(it.version): VersionNumber.parse(it.version as String)] } - .findAll { it.value.major >= 5 } // only 5.6 and above - .findAll { !(it.value.major == 5 && it.value.minor < 6) } // only 5.6 and above + .findAll { it.value.major >= 6 } // only 6.9 and above + .findAll { !(it.value.major == 6 && it.value.minor < 6.9) } // only 6.9 and above .inject([] as List>) { releasesToTest, version -> // only test against latest patch versions if (!releasesToTest.any { it.value.major == version.value.major && it.value.minor == version.value.minor }) { releasesToTest + version diff --git a/gradle.properties b/gradle.properties index bbf5ed99..57c09198 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.unsafe.configuration-cache=true systemProp.gradle.enterprise.testretry.enabled=false -systemProp.org.gradle.unsafe.kotlin.assignment=true \ No newline at end of file +systemProp.org.gradle.unsafe.kotlin.assignment=true diff --git a/src/main/kotlin/com/github/gradle/node/NodeExtension.kt b/src/main/kotlin/com/github/gradle/node/NodeExtension.kt index 9c62e462..559e8169 100644 --- a/src/main/kotlin/com/github/gradle/node/NodeExtension.kt +++ b/src/main/kotlin/com/github/gradle/node/NodeExtension.kt @@ -1,6 +1,7 @@ package com.github.gradle.node import com.github.gradle.node.npm.proxy.ProxySettings +import com.github.gradle.node.util.Platform import org.gradle.api.Project import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.getByType @@ -147,6 +148,17 @@ open class NodeExtension(project: Project) { */ val enableTaskRules = project.objects.property().convention(true) + + /** + * Computed path to nodejs directory + */ + val computedNodeDir = project.objects.directoryProperty() + + /** + * Operating system and architecture + */ + val computedPlatform = project.objects.property() + init { distBaseUrl.set("https://nodejs.org/dist") } @@ -180,7 +192,7 @@ open class NodeExtension(project: Project) { @JvmStatic fun create(project: Project): NodeExtension { - return project.extensions.create(NAME, project) + return project.extensions.create(NAME, project, ) } } } diff --git a/src/main/kotlin/com/github/gradle/node/NodePlugin.kt b/src/main/kotlin/com/github/gradle/node/NodePlugin.kt index 40b53021..ff10e2a1 100644 --- a/src/main/kotlin/com/github/gradle/node/NodePlugin.kt +++ b/src/main/kotlin/com/github/gradle/node/NodePlugin.kt @@ -10,29 +10,30 @@ import com.github.gradle.node.pnpm.task.PnpmSetupTask import com.github.gradle.node.pnpm.task.PnpmTask import com.github.gradle.node.task.NodeSetupTask import com.github.gradle.node.task.NodeTask -import com.github.gradle.node.util.NodeVersionSource +import com.github.gradle.node.util.* +import com.github.gradle.node.variant.computeNodeArchiveDependency +import com.github.gradle.node.variant.computeNodeDir import com.github.gradle.node.yarn.task.YarnInstallTask import com.github.gradle.node.yarn.task.YarnSetupTask import com.github.gradle.node.yarn.task.YarnTask import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.provider.Property -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.named -import org.gradle.kotlin.dsl.of -import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.* import org.gradle.util.GradleVersion +import java.io.ByteArrayOutputStream import java.io.File class NodePlugin : Plugin { private lateinit var project: Project override fun apply(project: Project) { - if (GradleVersion.current() < MINIMAL_SUPPORTED_GRADLE_VERSION) { - project.logger.error("This version of the plugin requires $MINIMAL_SUPPORTED_GRADLE_VERSION or newer.") - } +// if (GradleVersion.current() < MINIMAL_SUPPORTED_GRADLE_VERSION) { +// project.logger.error("This version of the plugin requires $MINIMAL_SUPPORTED_GRADLE_VERSION or newer.") +// } this.project = project val nodeExtension = NodeExtension.create(project) + configureNodeExtension(nodeExtension) project.extensions.create(PackageJsonExtension.NAME, project) addGlobalTypes() addTasks() @@ -47,6 +48,38 @@ class NodePlugin : Plugin { } } + private fun configureNodeExtension(extension: NodeExtension) { + addPlatform(extension) + extension.computedNodeDir.set(computeNodeDir(extension)) + extension.computedNodeDir.finalizeValueOnRead() + } + + private fun addPlatform(extension: NodeExtension) { + val uname = { + if (GradleVersion.current() >= GradleVersion.version("7.5")) { + val cmd = project.providers.exec { + this.executable = "uname" + this.args = listOf("-m") + } + cmd.standardOutput.asText.get().trim() + } else { + val out = ByteArrayOutputStream() + val cmd = project.exec { + this.executable = "uname" + this.args = listOf("-m") + this.standardOutput = out + } + + cmd.assertNormalExitValue() + out.toString().trim() + } + } + val name = System.getProperty("os.name") + val arch = System.getProperty("os.arch") + val platform = parsePlatform(name, arch, uname) + extension.computedPlatform.set(platform) + } + private fun addGlobalTypes() { addGlobalType() addGlobalType() @@ -133,12 +166,9 @@ class NodePlugin : Plugin { } private fun configureNodeSetupTask(nodeExtension: NodeExtension) { - val versionSource = project.providers.of(NodeVersionSource::class) { - parameters.nodeVersion.set(nodeExtension.version) - } - project.tasks.named(NodeSetupTask.NAME) { - val nodeArchiveDependencyProvider = versionSource.get() - val archiveFileProvider = nodeArchiveDependencyProvider + project.tasks.withType().configureEach { + nodeDir.set(nodeExtension.computedNodeDir) + val archiveFileProvider = computeNodeArchiveDependency(nodeExtension) .map { nodeArchiveDependency -> resolveNodeArchiveFile(nodeArchiveDependency) } @@ -154,7 +184,7 @@ class NodePlugin : Plugin { } companion object { - val MINIMAL_SUPPORTED_GRADLE_VERSION: GradleVersion = GradleVersion.version("7.5.1") + val MINIMAL_SUPPORTED_GRADLE_VERSION: GradleVersion = GradleVersion.version("6.6") const val NODE_GROUP = "Node" const val NPM_GROUP = "npm" const val PNPM_GROUP = "pnpm" diff --git a/src/main/kotlin/com/github/gradle/node/exec/NodeExecRunner.kt b/src/main/kotlin/com/github/gradle/node/exec/NodeExecRunner.kt index da3e1755..8c8107a0 100644 --- a/src/main/kotlin/com/github/gradle/node/exec/NodeExecRunner.kt +++ b/src/main/kotlin/com/github/gradle/node/exec/NodeExecRunner.kt @@ -4,6 +4,7 @@ import com.github.gradle.node.NodeExtension import com.github.gradle.node.util.ProjectApiHelper import com.github.gradle.node.util.zip import com.github.gradle.node.variant.VariantComputer +import com.github.gradle.node.variant.computeNodeExec import org.gradle.api.file.Directory import org.gradle.api.provider.Provider import org.gradle.process.ExecResult @@ -11,17 +12,23 @@ import org.gradle.process.ExecResult /** * This function is responsible for setting up the configuration used when running the tasks. */ -fun buildExecConfiguration(nodeExtension: NodeExtension, nodeExecConfiguration: NodeExecConfiguration, variantComputer: VariantComputer): - Provider { - val nodeDirProvider = variantComputer.computeNodeDir(nodeExtension) +fun buildExecConfiguration( + nodeExtension: NodeExtension, + nodeExecConfiguration: NodeExecConfiguration, + variantComputer: VariantComputer +): + Provider { + val nodeDirProvider = nodeExtension.computedNodeDir val nodeBinDirProvider = variantComputer.computeNodeBinDir(nodeDirProvider) - val executableProvider = variantComputer.computeNodeExec(nodeExtension, nodeBinDirProvider) + val executableProvider = computeNodeExec(nodeExtension, nodeBinDirProvider) val additionalBinPathProvider = computeAdditionalBinPath(nodeExtension, nodeBinDirProvider) return zip(executableProvider, additionalBinPathProvider) .map { (executable, additionalBinPath) -> - ExecConfiguration(executable, nodeExecConfiguration.command, additionalBinPath, + ExecConfiguration( + executable, nodeExecConfiguration.command, additionalBinPath, nodeExecConfiguration.environment, nodeExecConfiguration.workingDir, - nodeExecConfiguration.ignoreExitValue, nodeExecConfiguration.execOverrides) + nodeExecConfiguration.ignoreExitValue, nodeExecConfiguration.execOverrides + ) } } diff --git a/src/main/kotlin/com/github/gradle/node/npm/exec/NpmExecRunner.kt b/src/main/kotlin/com/github/gradle/node/npm/exec/NpmExecRunner.kt index 261f6333..26d3a949 100644 --- a/src/main/kotlin/com/github/gradle/node/npm/exec/NpmExecRunner.kt +++ b/src/main/kotlin/com/github/gradle/node/npm/exec/NpmExecRunner.kt @@ -9,6 +9,8 @@ import com.github.gradle.node.npm.proxy.NpmProxy.Companion.computeNpmProxyEnviro import com.github.gradle.node.util.ProjectApiHelper import com.github.gradle.node.util.zip import com.github.gradle.node.variant.VariantComputer +import com.github.gradle.node.variant.computeNodeExec +import com.github.gradle.node.variant.computeNpmScriptFile import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory import org.gradle.process.ExecResult @@ -73,24 +75,31 @@ abstract class NpmExecRunner { } } - private fun computeExecutable(nodeExtension: NodeExtension, npmExecConfiguration: NpmExecConfiguration, variantComputer: VariantComputer): - Provider { - val nodeDirProvider = variantComputer.computeNodeDir(nodeExtension) + private fun computeExecutable( + nodeExtension: NodeExtension, + npmExecConfiguration: NpmExecConfiguration, + variantComputer: VariantComputer + ): + Provider { + val nodeDirProvider = nodeExtension.computedNodeDir val npmDirProvider = variantComputer.computeNpmDir(nodeExtension, nodeDirProvider) val nodeBinDirProvider = variantComputer.computeNodeBinDir(nodeDirProvider) val npmBinDirProvider = variantComputer.computeNpmBinDir(npmDirProvider) - val nodeExecProvider = variantComputer.computeNodeExec(nodeExtension, nodeBinDirProvider) + val nodeExecProvider = computeNodeExec(nodeExtension, nodeBinDirProvider) val executableProvider = - npmExecConfiguration.commandExecComputer(variantComputer, nodeExtension, npmBinDirProvider) + npmExecConfiguration.commandExecComputer(variantComputer, nodeExtension, npmBinDirProvider) + val isWindows = nodeExtension.computedPlatform.get().isWindows() val npmScriptFileProvider = - variantComputer.computeNpmScriptFile(nodeDirProvider, npmExecConfiguration.command) - return zip(nodeExtension.download, nodeExtension.nodeProjectDir, executableProvider, nodeExecProvider, - npmScriptFileProvider).map { + computeNpmScriptFile(nodeDirProvider, npmExecConfiguration.command, isWindows) + return zip( + nodeExtension.download, nodeExtension.nodeProjectDir, executableProvider, nodeExecProvider, + npmScriptFileProvider + ).map { val (download, nodeProjectDir, executable, nodeExec, - npmScriptFile) = it + npmScriptFile) = it if (download) { val localCommandScript = nodeProjectDir.dir("node_modules/npm/bin") - .file("${npmExecConfiguration.command}-cli.js").asFile + .file("${npmExecConfiguration.command}-cli.js").asFile if (localCommandScript.exists()) { return@map ExecutableAndScript(nodeExec, localCommandScript.absolutePath) } else if (!File(executable).exists()) { diff --git a/src/main/kotlin/com/github/gradle/node/pnpm/exec/PnpmExecRunner.kt b/src/main/kotlin/com/github/gradle/node/pnpm/exec/PnpmExecRunner.kt index 3ebbf484..06146fa4 100644 --- a/src/main/kotlin/com/github/gradle/node/pnpm/exec/PnpmExecRunner.kt +++ b/src/main/kotlin/com/github/gradle/node/pnpm/exec/PnpmExecRunner.kt @@ -10,6 +10,7 @@ import com.github.gradle.node.npm.proxy.NpmProxy.Companion.computeNpmProxyEnviro import com.github.gradle.node.util.ProjectApiHelper import com.github.gradle.node.util.zip import com.github.gradle.node.variant.VariantComputer +import com.github.gradle.node.variant.computeNodeExec import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory import org.gradle.process.ExecResult @@ -67,13 +68,17 @@ abstract class PnpmExecRunner { } } - private fun computeExecutable(nodeExtension: NodeExtension, pnpmExecConfiguration: NpmExecConfiguration, variantComputer: VariantComputer): + private fun computeExecutable( + nodeExtension: NodeExtension, + pnpmExecConfiguration: NpmExecConfiguration, + variantComputer: VariantComputer + ): Provider { val nodeDirProvider = variantComputer.computeNodeDir(nodeExtension) val pnpmDirProvider = variantComputer.computePnpmDir(nodeExtension) val nodeBinDirProvider = variantComputer.computeNodeBinDir(nodeDirProvider) val pnpmBinDirProvider = variantComputer.computePnpmBinDir(pnpmDirProvider) - val nodeExecProvider = variantComputer.computeNodeExec(nodeExtension, nodeBinDirProvider) + val nodeExecProvider = computeNodeExec(nodeExtension, nodeBinDirProvider) val executableProvider = pnpmExecConfiguration.commandExecComputer(variantComputer, nodeExtension, pnpmBinDirProvider) diff --git a/src/main/kotlin/com/github/gradle/node/task/BaseTask.kt b/src/main/kotlin/com/github/gradle/node/task/BaseTask.kt index 0cffe6ce..460b0a2c 100644 --- a/src/main/kotlin/com/github/gradle/node/task/BaseTask.kt +++ b/src/main/kotlin/com/github/gradle/node/task/BaseTask.kt @@ -1,10 +1,8 @@ package com.github.gradle.node.task -import com.github.gradle.node.util.GradleHelperExecution import com.github.gradle.node.util.PlatformHelper import com.github.gradle.node.variant.VariantComputer import org.gradle.api.DefaultTask -import org.gradle.api.provider.Property import org.gradle.api.tasks.Internal import org.gradle.process.ExecOperations import org.gradle.process.ExecResult @@ -16,10 +14,7 @@ abstract class BaseTask : DefaultTask() { var result: ExecResult? = null @get:Internal - var platformHelper = PlatformHelper(GradleHelperExecution(execOperations)) - - @get:Inject - abstract val execOperations: ExecOperations + var platformHelper = PlatformHelper() @get:Internal internal val variantComputer by lazy { @@ -27,4 +22,4 @@ abstract class BaseTask : DefaultTask() { } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/github/gradle/node/task/NodeSetupTask.kt b/src/main/kotlin/com/github/gradle/node/task/NodeSetupTask.kt index 8219ee86..a052e582 100644 --- a/src/main/kotlin/com/github/gradle/node/task/NodeSetupTask.kt +++ b/src/main/kotlin/com/github/gradle/node/task/NodeSetupTask.kt @@ -3,7 +3,10 @@ package com.github.gradle.node.task import com.github.gradle.node.NodeExtension import com.github.gradle.node.NodePlugin import com.github.gradle.node.util.DefaultProjectApiHelper +import com.github.gradle.node.variant.computeNodeExec +import com.github.gradle.node.variant.computeNpmScriptFile import org.gradle.api.file.Directory +import org.gradle.api.file.DirectoryProperty import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory @@ -31,9 +34,7 @@ abstract class NodeSetupTask : BaseTask() { val nodeArchiveFile = objects.fileProperty() @get:OutputDirectory - val nodeDir by lazy { - variantComputer.computeNodeDir(nodeExtension) - } + abstract val nodeDir: DirectoryProperty @get:Internal val projectHelper = project.objects.newInstance(DefaultProjectApiHelper::class.java) @@ -61,7 +62,7 @@ abstract class NodeSetupTask : BaseTask() { private fun unpackNodeArchive() { val archiveFile = nodeArchiveFile.get().asFile - val nodeDirProvider = variantComputer.computeNodeDir(nodeExtension) + val nodeDirProvider = nodeExtension.computedNodeDir val nodeBinDirProvider = variantComputer.computeNodeBinDir(nodeDirProvider) val archivePath = nodeDirProvider.map { it.dir("../") } if (archiveFile.name.endsWith("zip")) { @@ -83,17 +84,16 @@ abstract class NodeSetupTask : BaseTask() { private fun fixBrokenSymlink(name: String, nodeBinDirPath: Path, nodeDirProvider: Provider) { val script = nodeBinDirPath.resolve(name) - val scriptFile = variantComputer.computeNpmScriptFile(nodeDirProvider, name).get() + val scriptFile = computeNpmScriptFile(nodeDirProvider, name, nodeExtension.computedPlatform.get().isWindows()) if (Files.deleteIfExists(script)) { - Files.createSymbolicLink(script, nodeBinDirPath.relativize(Paths.get(scriptFile))) + Files.createSymbolicLink(script, nodeBinDirPath.relativize(Paths.get(scriptFile.get()))) } } private fun setExecutableFlag() { - if (!platformHelper.isWindows) { - val nodeDirProvider = variantComputer.computeNodeDir(nodeExtension) - val nodeBinDirProvider = variantComputer.computeNodeBinDir(nodeDirProvider) - val nodeExecProvider = variantComputer.computeNodeExec(nodeExtension, nodeBinDirProvider) + if (!nodeExtension.computedPlatform.get().isWindows()) { + val nodeBinDirProvider = variantComputer.computeNodeBinDir(nodeExtension.computedNodeDir) + val nodeExecProvider = computeNodeExec(nodeExtension, nodeBinDirProvider) File(nodeExecProvider.get()).setExecutable(true) } } diff --git a/src/main/kotlin/com/github/gradle/node/util/NodeVersionSource.kt b/src/main/kotlin/com/github/gradle/node/util/NodeVersionSource.kt deleted file mode 100644 index 18344bc1..00000000 --- a/src/main/kotlin/com/github/gradle/node/util/NodeVersionSource.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.gradle.node.util - -import com.github.gradle.node.variant.VariantComputer -import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider -import org.gradle.api.provider.ValueSource -import org.gradle.api.provider.ValueSourceParameters -import org.gradle.process.ExecOperations -import javax.inject.Inject - -abstract class NodeVersionSource: ValueSource, NodeVersionSource.NodeVersionSourceParameters> { - @get:Inject - abstract val execOperations: ExecOperations - - interface NodeVersionSourceParameters : ValueSourceParameters { - val nodeVersion: Property - } - - override fun obtain(): Provider { - val platformHelper = PlatformHelper(GradleHelperExecution(execOperations)) - val variantComputer = VariantComputer(platformHelper) - return variantComputer.computeNodeArchiveDependency(parameters.nodeVersion) - } -} - diff --git a/src/main/kotlin/com/github/gradle/node/util/Platform.kt b/src/main/kotlin/com/github/gradle/node/util/Platform.kt new file mode 100644 index 00000000..381a0831 --- /dev/null +++ b/src/main/kotlin/com/github/gradle/node/util/Platform.kt @@ -0,0 +1,7 @@ +package com.github.gradle.node.util + +data class Platform(val name: String, val arch: String) { + fun isWindows(): Boolean { + return name == "win" + } +} diff --git a/src/main/kotlin/com/github/gradle/node/util/PlatformHelper.kt b/src/main/kotlin/com/github/gradle/node/util/PlatformHelper.kt index 28291365..58584605 100644 --- a/src/main/kotlin/com/github/gradle/node/util/PlatformHelper.kt +++ b/src/main/kotlin/com/github/gradle/node/util/PlatformHelper.kt @@ -1,44 +1,66 @@ package com.github.gradle.node.util +import java.util.concurrent.Callable + +@Deprecated(message = "This class is no longer needed, the computed output is stored in the NodeExtension") internal class DefaultHelperExecution : HelperExecution { override fun exec(command: String, vararg args: String, timeout: Long): String { return execute(command, *args, timeout = timeout) } } + +@Deprecated(message = "This class is no longer needed, the computed output is stored in the NodeExtension") interface HelperExecution { fun exec(command: String, vararg args: String, timeout: Long = 60): String } + +fun parsePlatform(name: String, arch: String, uname: () -> String): Platform { + return Platform(parseOsName(name.toLowerCase()), parseOsArch(arch.toLowerCase(), uname)) +} + +fun parseOsName(name: String): String { + return when { + name.contains("windows") -> "win" + name.contains("mac") -> "darwin" + name.contains("linux") -> "linux" + name.contains("freebsd") -> "linux" + name.contains("sunos") -> "sunos" + else -> error("Unsupported OS: $name") + } +} + +fun parseOsArch(arch: String, uname: Callable): String { + return when { + /* + * As Java just returns "arm" on all ARM variants, we need a system call to determine the exact arch. Unfortunately some JVMs say aarch32/64, so we need an additional + * conditional. Additionally, the node binaries for 'armv8l' are called 'arm64', so we need to distinguish here. + */ + arch == "arm" || arch.startsWith("aarch") -> uname.call() + .mapIf({ it == "armv8l" || it == "aarch64" }) { "arm64" } + .mapIf({ it == "x86_64" }) {"x64"} + arch == "ppc64le" -> "ppc64le" + arch == "s390x" -> "s390x" + arch.contains("64") -> "x64" + else -> "x86" + } +} + open class PlatformHelper(private val execution: HelperExecution = DefaultHelperExecution()) { + @get:Deprecated(message = "moved to NodeExtension") open val osName: String by lazy { - val name = property("os.name").toLowerCase() - when { - name.contains("windows") -> "win" - name.contains("mac") -> "darwin" - name.contains("linux") -> "linux" - name.contains("freebsd") -> "linux" - name.contains("sunos") -> "sunos" - else -> error("Unsupported OS: $name") - } + parseOsName(property("os.name").toLowerCase()) } + @get:Deprecated(message = "moved to NodeExtension") open val osArch: String by lazy { val arch = property("os.arch").toLowerCase() - when { - /* - * As Java just returns "arm" on all ARM variants, we need a system call to determine the exact arch. Unfortunately some JVMs say aarch32/64, so we need an additional - * conditional. Additionally, the node binaries for 'armv8l' are called 'arm64', so we need to distinguish here. - */ - arch == "arm" || arch.startsWith("aarch") -> property("uname") - .mapIf({ it == "armv8l" || it == "aarch64" }) { "arm64" } - .mapIf({ it == "x86_64" }) {"x64"} - arch == "ppc64le" -> "ppc64le" - arch == "s390x" -> "s390x" - arch.contains("64") -> "x64" - else -> "x86" - } + val uname = { property("uname") } + parseOsArch(arch, uname) } + @get:Deprecated(message = "moved to NodeExtension", + replaceWith = ReplaceWith("nodeExtension.resolvedPlatform.get().isWindows()")) open val isWindows: Boolean by lazy { osName == "win" } private fun property(name: String): String { @@ -58,9 +80,14 @@ open class PlatformHelper(private val execution: HelperExecution = DefaultHelper } fun main(args: Array) { - println("Your os.name is: '${System.getProperty("os.name")}' and is parsed as: '${PlatformHelper.INSTANCE.osName}'") - println("Your os.arch is: '${System.getProperty("os.arch")}' and is parsed as: '${PlatformHelper.INSTANCE.osArch}'") - if (PlatformHelper.INSTANCE.isWindows) { + val osName = System.getProperty("os.name") + val osArch = System.getProperty("os.arch") + val uname = { execute("uname", "-m", timeout = 10) } + val platform = parsePlatform(osName, osArch, uname) + + println("Your os.name is: '${osName}' and is parsed as: '${platform.name}'") + println("Your os.arch is: '${osArch}' and is parsed as: '${platform.arch}'") + if (platform.isWindows()) { println("You're on windows (isWindows == true)") } else { println("You're not on windows (isWindows == false)") diff --git a/src/main/kotlin/com/github/gradle/node/util/ProjectApiHelper.kt b/src/main/kotlin/com/github/gradle/node/util/ProjectApiHelper.kt index 181c6815..5dd860e2 100644 --- a/src/main/kotlin/com/github/gradle/node/util/ProjectApiHelper.kt +++ b/src/main/kotlin/com/github/gradle/node/util/ProjectApiHelper.kt @@ -10,17 +10,16 @@ import org.gradle.api.tasks.WorkResult import org.gradle.process.ExecOperations import org.gradle.process.ExecResult import org.gradle.process.ExecSpec -import org.gradle.util.GradleVersion import java.io.ByteArrayOutputStream import java.io.File import javax.inject.Inject -@Deprecated(message = "Only 7.5.1 and newer is supported") +@Deprecated(message = "Only 6.6 and newer is supported") interface ProjectApiHelper { companion object { @JvmStatic fun newInstance(project: Project): ProjectApiHelper { - return project.objects.newInstance(DefaultProjectApiHelper::class.java, ) + return project.objects.newInstance(DefaultProjectApiHelper::class.java) } } @@ -37,7 +36,8 @@ interface ProjectApiHelper { fun exec(action: Action): ExecResult } -internal class GradleHelperExecution(private val eo: ExecOperations) : HelperExecution { +@Deprecated(message = "This class is no longer needed, the computed output is stored in the NodeExtension") +class GradleHelperExecution(private val eo: ExecOperations) : HelperExecution { override fun exec(command: String, vararg args: String, timeout: Long): String { val out = ByteArrayOutputStream() val cmd = eo.exec { diff --git a/src/main/kotlin/com/github/gradle/node/variant/VariantComputer.kt b/src/main/kotlin/com/github/gradle/node/variant/VariantComputer.kt index 5702d84f..f2443c7b 100644 --- a/src/main/kotlin/com/github/gradle/node/variant/VariantComputer.kt +++ b/src/main/kotlin/com/github/gradle/node/variant/VariantComputer.kt @@ -8,6 +8,50 @@ import org.gradle.api.file.Directory import org.gradle.api.provider.Property import org.gradle.api.provider.Provider +/** + * Get the expected node binary name, node.exe on Windows and node everywhere else. + */ +fun computeNodeExec(nodeExtension: NodeExtension, nodeBinDirProvider: Provider): Provider { + return zip(nodeExtension.download, nodeBinDirProvider).map { + val (download, nodeBinDir) = it + if (download) { + val nodeCommand = if (nodeExtension.computedPlatform.get().isWindows()) "node.exe" else "node" + nodeBinDir.dir(nodeCommand).asFile.absolutePath + } else "node" + } +} +fun computeNpmScriptFile(nodeDirProvider: Provider, command: String, isWindows: Boolean): Provider { + return nodeDirProvider.map { nodeDir -> + if (isWindows) nodeDir.dir("node_modules/npm/bin/$command-cli.js").asFile.path + else nodeDir.dir("lib/node_modules/npm/bin/$command-cli.js").asFile.path + } +} + +fun computeNodeDir(nodeExtension: NodeExtension): Provider { + val osName = nodeExtension.computedPlatform.get().name + val osArch = nodeExtension.computedPlatform.get().arch + return computeNodeDir(nodeExtension, osName, osArch) +} + +fun computeNodeDir(nodeExtension: NodeExtension, osName: String, osArch: String): Provider { + return zip(nodeExtension.workDir, nodeExtension.version).map { (workDir, version) -> + val dirName = "node-v$version-$osName-$osArch" + workDir.dir(dirName) + } +} + +/** + * Get the node archive name in Gradle dependency format, using zip for Windows and tar.gz everywhere else. + * + * Essentially: org.nodejs:node:$version:$osName-$osArch@tar.gz + */ +fun computeNodeArchiveDependency(extension: NodeExtension): Provider { + val osName = extension.computedPlatform.get().name + val osArch = extension.computedPlatform.get().arch + val type = if (extension.computedPlatform.get().isWindows()) "zip" else "tar.gz" + return extension.version.map { version -> "org.nodejs:node:$version:$osName-$osArch@$type" } +} + open class VariantComputer constructor( private val platformHelper: PlatformHelper ) { @@ -18,15 +62,15 @@ open class VariantComputer constructor( * * Essentially: workingDir/node-v$version-$osName-$osArch */ + @Deprecated(message = "moved to NodeExtension", replaceWith = ReplaceWith("nodeExtension.resolvedNodeDir")) fun computeNodeDir(nodeExtension: NodeExtension): Provider { - return zip(nodeExtension.workDir, nodeExtension.version).map { (workDir, version) -> - val osName = platformHelper.osName - val osArch = platformHelper.osArch - val dirName = "node-v$version-$osName-$osArch" - workDir.dir(dirName) - } + val osName = platformHelper.osName + val osArch = platformHelper.osArch + return computeNodeDir(nodeExtension, osName, osArch) } + + /** * Get the expected node binary directory, taking Windows specifics into account. */ @@ -35,14 +79,11 @@ open class VariantComputer constructor( /** * Get the expected node binary name, node.exe on Windows and node everywhere else. */ + @Deprecated(message = "replaced by package-level function", + replaceWith = + ReplaceWith("com.github.gradle.node.variant.computeNodeExec(nodeExtension, nodeBinDirProvider)")) fun computeNodeExec(nodeExtension: NodeExtension, nodeBinDirProvider: Provider): Provider { - return zip(nodeExtension.download, nodeBinDirProvider).map { - val (download, nodeBinDir) = it - if (download) { - val nodeCommand = if (platformHelper.isWindows) "node.exe" else "node" - nodeBinDir.dir(nodeCommand).asFile.absolutePath - } else "node" - } + return com.github.gradle.node.variant.computeNodeExec(nodeExtension, nodeBinDirProvider) } /** @@ -71,18 +112,16 @@ open class VariantComputer constructor( fun computeNpmExec(nodeExtension: NodeExtension, npmBinDirProvider: Provider): Provider { return zip(nodeExtension.download, nodeExtension.npmCommand, npmBinDirProvider).map { val (download, npmCommand, npmBinDir) = it - val command = if (platformHelper.isWindows) { + val command = if (nodeExtension.computedPlatform.get().isWindows()) { npmCommand.mapIf({ it == "npm" }) { "npm.cmd" } } else npmCommand if (download) npmBinDir.dir(command).asFile.absolutePath else command } } + @Deprecated(message = "replaced by package-level function") fun computeNpmScriptFile(nodeDirProvider: Provider, command: String): Provider { - return nodeDirProvider.map { nodeDir -> - if (platformHelper.isWindows) nodeDir.dir("node_modules/npm/bin/$command-cli.js").asFile.path - else nodeDir.dir("lib/node_modules/npm/bin/$command-cli.js").asFile.path - } + return computeNpmScriptFile(nodeDirProvider, command, platformHelper.isWindows) } /** @@ -93,7 +132,7 @@ open class VariantComputer constructor( fun computeNpxExec(nodeExtension: NodeExtension, npmBinDirProvider: Provider): Provider { return zip(nodeExtension.download, nodeExtension.npxCommand, npmBinDirProvider).map { val (download, npxCommand, npmBinDir) = it - val command = if (platformHelper.isWindows) { + val command = if (nodeExtension.computedPlatform.get().isWindows()) { npxCommand.mapIf({ it == "npx" }) { "npx.cmd" } } else npxCommand if (download) npmBinDir.dir(command).asFile.absolutePath else command @@ -116,7 +155,7 @@ open class VariantComputer constructor( fun computePnpmExec(nodeExtension: NodeExtension, pnpmBinDirProvider: Provider): Provider { return zip(nodeExtension.pnpmCommand, nodeExtension.download, pnpmBinDirProvider).map { val (pnpmCommand, download, pnpmBinDir) = it - val command = if (platformHelper.isWindows) { + val command = if (nodeExtension.computedPlatform.get().isWindows()) { pnpmCommand.mapIf({ it == "pnpm" }) { "pnpm.cmd" } } else pnpmCommand if (download) pnpmBinDir.dir(command).asFile.absolutePath else command @@ -139,7 +178,7 @@ open class VariantComputer constructor( fun computeYarnExec(nodeExtension: NodeExtension, yarnBinDirProvider: Provider): Provider { return zip(nodeExtension.yarnCommand, nodeExtension.download, yarnBinDirProvider).map { val (yarnCommand, download, yarnBinDir) = it - val command = if (platformHelper.isWindows) { + val command = if (nodeExtension.computedPlatform.get().isWindows()) { yarnCommand.mapIf({ it == "yarn" }) { "yarn.cmd" } } else yarnCommand if (download) yarnBinDir.dir(command).asFile.absolutePath else command @@ -154,8 +193,10 @@ open class VariantComputer constructor( * * Essentially: org.nodejs:node:$version:$osName-$osArch@tar.gz */ + @Deprecated(message = "replaced by package-level function", + replaceWith = ReplaceWith("com.github.gradle.node.variant.computeNodeArchiveDependency(nodeExtension)")) fun computeNodeArchiveDependency(nodeExtension: NodeExtension): Provider { - return computeNodeArchiveDependency(nodeExtension.version) + return com.github.gradle.node.variant.computeNodeArchiveDependency(nodeExtension) } /** @@ -163,6 +204,8 @@ open class VariantComputer constructor( * * Essentially: org.nodejs:node:$version:$osName-$osArch@tar.gz */ + @Deprecated(message = "replaced by package-level function", + replaceWith = ReplaceWith("com.github.gradle.node.variant.computeNodeArchiveDependency(nodeExtension)")) fun computeNodeArchiveDependency(nodeVersion: Property): Provider { val osName = platformHelper.osName val osArch = platformHelper.osArch diff --git a/src/test/groovy/com/github/gradle/AbstractIntegTest.groovy b/src/test/groovy/com/github/gradle/AbstractIntegTest.groovy index e91991c1..63058189 100644 --- a/src/test/groovy/com/github/gradle/AbstractIntegTest.groovy +++ b/src/test/groovy/com/github/gradle/AbstractIntegTest.groovy @@ -36,6 +36,7 @@ abstract class AbstractIntegTest extends Specification { .withPluginClasspath() .forwardOutput() .withGradleVersion(gradleVersion.version) + .withDebug(false) } protected final BuildResult build(final String... args) { diff --git a/src/test/groovy/com/github/gradle/node/npm/task/NpmInstallTaskTest.groovy b/src/test/groovy/com/github/gradle/node/npm/task/NpmInstallTaskTest.groovy index fc3138b9..bbb401c2 100644 --- a/src/test/groovy/com/github/gradle/node/npm/task/NpmInstallTaskTest.groovy +++ b/src/test/groovy/com/github/gradle/node/npm/task/NpmInstallTaskTest.groovy @@ -3,6 +3,7 @@ package com.github.gradle.node.npm.task import com.github.gradle.node.npm.proxy.GradleProxyHelper import com.github.gradle.node.npm.proxy.ProxySettings import com.github.gradle.node.task.AbstractTaskTest +import com.github.gradle.node.util.PlatformHelperKt class NpmInstallTaskTest extends AbstractTaskTest { def cleanup() { @@ -12,6 +13,7 @@ class NpmInstallTaskTest extends AbstractTaskTest { def "exec npm install task with configured proxy"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) GradleProxyHelper.setHttpsProxyHost("my-super-proxy.net") GradleProxyHelper.setHttpsProxyPort(11235) @@ -32,6 +34,7 @@ class NpmInstallTaskTest extends AbstractTaskTest { def "exec npm install task with configured proxy but disabled"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) GradleProxyHelper.setHttpsProxyHost("my-super-proxy.net") GradleProxyHelper.setHttpsProxyPort(11235) nodeExtension.nodeProxySettings.set(ProxySettings.OFF) diff --git a/src/test/groovy/com/github/gradle/node/npm/task/NpmSetupTaskTest.groovy b/src/test/groovy/com/github/gradle/node/npm/task/NpmSetupTaskTest.groovy index af38a0c5..449cbd4a 100644 --- a/src/test/groovy/com/github/gradle/node/npm/task/NpmSetupTaskTest.groovy +++ b/src/test/groovy/com/github/gradle/node/npm/task/NpmSetupTaskTest.groovy @@ -2,6 +2,7 @@ package com.github.gradle.node.npm.task import com.github.gradle.node.npm.proxy.GradleProxyHelper import com.github.gradle.node.task.AbstractTaskTest +import com.github.gradle.node.util.PlatformHelperKt class NpmSetupTaskTest extends AbstractTaskTest { def cleanup() { @@ -11,6 +12,7 @@ class NpmSetupTaskTest extends AbstractTaskTest { def "disable npmSetup task when no npm version is specified"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) def task = project.tasks.create('simple', NpmSetupTask) mockPlatformHelper(task) @@ -25,6 +27,7 @@ class NpmSetupTaskTest extends AbstractTaskTest { def "exec npmSetup task (version specified)"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.npmVersion.set('6.4.1') def task = project.tasks.create('simple', NpmSetupTask) @@ -47,6 +50,7 @@ class NpmSetupTaskTest extends AbstractTaskTest { def "exec npmSetup task with proxy configured"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.npmVersion.set('6.4.1') GradleProxyHelper.setHttpProxyHost("my-proxy.net") GradleProxyHelper.setHttpProxyPort(1234) diff --git a/src/test/groovy/com/github/gradle/node/npm/task/NpmTaskTest.groovy b/src/test/groovy/com/github/gradle/node/npm/task/NpmTaskTest.groovy index d7e6f9a7..988af4c4 100644 --- a/src/test/groovy/com/github/gradle/node/npm/task/NpmTaskTest.groovy +++ b/src/test/groovy/com/github/gradle/node/npm/task/NpmTaskTest.groovy @@ -1,8 +1,10 @@ package com.github.gradle.node.npm.task + import com.github.gradle.node.npm.proxy.GradleProxyHelper import com.github.gradle.node.npm.proxy.ProxySettings import com.github.gradle.node.task.AbstractTaskTest +import com.github.gradle.node.util.PlatformHelperKt import static com.github.gradle.node.NodeExtension.DEFAULT_NODE_VERSION @@ -14,6 +16,7 @@ class NpmTaskTest extends AbstractTaskTest { def "exec npm task"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) def task = project.tasks.create('simple', NpmTask) mockPlatformHelper(task) @@ -37,6 +40,7 @@ class NpmTaskTest extends AbstractTaskTest { def "exec npm task (windows)"() { given: props.setProperty('os.name', 'Windows') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Windows", "x86_64", {})) def task = project.tasks.create('simple', NpmTask) mockPlatformHelper(task) @@ -60,6 +64,7 @@ class NpmTaskTest extends AbstractTaskTest { def "exec npm task (download)"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.download.set(true) def nodeDir = projectDir.toPath().resolve(".gradle").resolve("nodejs") .resolve("node-v${DEFAULT_NODE_VERSION}-linux-x64") @@ -90,6 +95,7 @@ class NpmTaskTest extends AbstractTaskTest { def "exec npm task (download) with configured proxy"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.download.set(true) def nodeDir = projectDir.toPath().resolve(".gradle").resolve("nodejs") .resolve("node-v${DEFAULT_NODE_VERSION}-linux-x64") @@ -123,6 +129,7 @@ class NpmTaskTest extends AbstractTaskTest { def "exec npm task with configured proxy"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) GradleProxyHelper.setHttpsProxyHost("my-super-proxy.net") GradleProxyHelper.setHttpsProxyPort(11235) @@ -144,6 +151,7 @@ class NpmTaskTest extends AbstractTaskTest { def "exec npm task with configured proxy but disabled"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) GradleProxyHelper.setHttpsProxyHost("my-super-proxy.net") GradleProxyHelper.setHttpsProxyPort(11235) nodeExtension.nodeProxySettings.set(ProxySettings.OFF) diff --git a/src/test/groovy/com/github/gradle/node/npm/task/NpxTaskTest.groovy b/src/test/groovy/com/github/gradle/node/npm/task/NpxTaskTest.groovy index dc587375..8cc2b77d 100644 --- a/src/test/groovy/com/github/gradle/node/npm/task/NpxTaskTest.groovy +++ b/src/test/groovy/com/github/gradle/node/npm/task/NpxTaskTest.groovy @@ -1,12 +1,15 @@ package com.github.gradle.node.npm.task + import com.github.gradle.node.task.AbstractTaskTest +import com.github.gradle.node.util.PlatformHelperKt import com.github.gradle.node.variant.VariantComputer class NpxTaskTest extends AbstractTaskTest { def "exec npx task"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) def task = project.tasks.create('simple', NpxTask) mockPlatformHelper(task) @@ -34,6 +37,7 @@ class NpxTaskTest extends AbstractTaskTest { def "exec npx task (windows)"() { given: props.setProperty('os.name', 'Windows') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Windows", "x86_64", {})) def task = project.tasks.create('simple', NpxTask) mockPlatformHelper(task) @@ -61,9 +65,10 @@ class NpxTaskTest extends AbstractTaskTest { def "exec npx task (download)"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.download.set(true) def variantComputer = new VariantComputer(testPlatformHelper) - def nodeDir = variantComputer.computeNodeDir(nodeExtension) + def nodeDir = nodeExtension.computedNodeDir def nodeBinDir = variantComputer.computeNodeBinDir(nodeDir) def npxScriptFile = variantComputer.computeNpmScriptFile(nodeDir, "npx") diff --git a/src/test/groovy/com/github/gradle/node/pnpm/task/PnpmTaskTest.groovy b/src/test/groovy/com/github/gradle/node/pnpm/task/PnpmTaskTest.groovy index ccddcaf9..1da28b66 100644 --- a/src/test/groovy/com/github/gradle/node/pnpm/task/PnpmTaskTest.groovy +++ b/src/test/groovy/com/github/gradle/node/pnpm/task/PnpmTaskTest.groovy @@ -1,12 +1,13 @@ package com.github.gradle.node.pnpm.task import com.github.gradle.node.task.AbstractTaskTest -import org.gradle.process.ExecSpec +import com.github.gradle.node.util.PlatformHelperKt class PnpmTaskTest extends AbstractTaskTest { def "exec pnpm task"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) def task = project.tasks.create('simple', PnpmTask) mockPlatformHelper(task) @@ -31,6 +32,7 @@ class PnpmTaskTest extends AbstractTaskTest { def "exec pnpm task (windows)"() { given: props.setProperty('os.name', 'Windows') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Windows", "x86_64", {})) def task = project.tasks.create('simple', PnpmTask) mockPlatformHelper(task) @@ -55,6 +57,7 @@ class PnpmTaskTest extends AbstractTaskTest { def "exec pnpm task (download)"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.download.set(true) def task = project.tasks.create('simple', PnpmTask) diff --git a/src/test/groovy/com/github/gradle/node/task/NodeSetupTask_integTest.groovy b/src/test/groovy/com/github/gradle/node/task/NodeSetupTask_integTest.groovy index 2ac7f7ec..ef91ad7d 100644 --- a/src/test/groovy/com/github/gradle/node/task/NodeSetupTask_integTest.groovy +++ b/src/test/groovy/com/github/gradle/node/task/NodeSetupTask_integTest.groovy @@ -15,48 +15,6 @@ class NodeSetupTask_integTest extends AbstractIntegTest { @Rule EnvironmentVariables environmentVariables = new EnvironmentVariables() - // Windows lacks uname - @IgnoreIf({ System.getProperty("os.name").toLowerCase().contains("windows") }) - def 'ensure configuration-cache works with uname (#gv.version)'() { - given: - gradleVersion = gv - - copyResources("fixtures/node") - createFile("gradle.properties") << """ -systemProp.os.arch=aarch64 -systemProp.os.name=Mac OS X -""" - createFile("build.gradle") << ''' -def nodeExtension = com.github.gradle.node.NodeExtension.get(project) -def versionSource = project.providers.of(com.github.gradle.node.util.NodeVersionSource) { - parameters.nodeVersion.set(nodeExtension.version) - } -tasks.register('getVersionFromSource') { - def version = versionSource.get() - doLast { - println "Got version: '${version.get()}'" - } -} -''' - - when: - def result1 = build("getVersionFromSource") - - then: - result1.task(":getVersionFromSource").outcome == TaskOutcome.SUCCESS - result1.output.contains("Got version: 'org.nodejs:node:16.14.2:") - - when: - def result2 = build("getVersionFromSource") - - then: - result2.task(":getVersionFromSource").outcome == TaskOutcome.SUCCESS - result2.output.contains("Got version: 'org.nodejs:node:16.14.2:") - - where: - gv << GRADLE_VERSIONS_UNDER_TEST - } - @IgnoreIf({ System.getProperty("os.name").toLowerCase().contains("windows") }) def 'ensure configuration-cache works with nodeSetup (#gv.version)'() { given: diff --git a/src/test/groovy/com/github/gradle/node/task/NodeTaskTest.groovy b/src/test/groovy/com/github/gradle/node/task/NodeTaskTest.groovy index 95902ec5..fd97fb73 100644 --- a/src/test/groovy/com/github/gradle/node/task/NodeTaskTest.groovy +++ b/src/test/groovy/com/github/gradle/node/task/NodeTaskTest.groovy @@ -1,5 +1,7 @@ package com.github.gradle.node.task +import com.github.gradle.node.util.PlatformHelperKt + class NodeTaskTest extends AbstractTaskTest { def "script not set"() { given: @@ -16,6 +18,7 @@ class NodeTaskTest extends AbstractTaskTest { def "exec node task"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.download.set(false) def task = project.tasks.create('simple', NodeTask) @@ -46,6 +49,7 @@ class NodeTaskTest extends AbstractTaskTest { def "execOverrides test"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.download.set(false) def task = project.tasks.create('simple', NodeTask) @@ -72,6 +76,7 @@ class NodeTaskTest extends AbstractTaskTest { def "exec node task (download)"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.download.set(true) def task = project.tasks.create('simple', NodeTask) @@ -93,6 +98,7 @@ class NodeTaskTest extends AbstractTaskTest { def "exec node task (windows)"() { given: props.setProperty('os.name', 'Windows') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Windows", "x86_64", {})) nodeExtension.download.set(false) def task = project.tasks.create('simple', NodeTask) @@ -118,6 +124,7 @@ class NodeTaskTest extends AbstractTaskTest { def "exec node task (windows download)"() { given: props.setProperty('os.name', 'Windows') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Windows", "x86_64", {})) nodeExtension.download.set(true) def task = project.tasks.create('simple', NodeTask) diff --git a/src/test/groovy/com/github/gradle/node/util/PlatformHelperTest.groovy b/src/test/groovy/com/github/gradle/node/util/PlatformHelperTest.groovy index 4c7b8787..34392911 100644 --- a/src/test/groovy/com/github/gradle/node/util/PlatformHelperTest.groovy +++ b/src/test/groovy/com/github/gradle/node/util/PlatformHelperTest.groovy @@ -17,11 +17,15 @@ class PlatformHelperTest extends Specification { given: this.props.setProperty("os.name", osProp) this.props.setProperty("os.arch", archProp) + def platform = PlatformHelperKt.parsePlatform(osProp, archProp, {}) expect: this.helper.getOsName() == osName this.helper.getOsArch() == osArch this.helper.isWindows() == isWindows + platform.name == osName + platform.arch == osArch + platform.windows == isWindows where: osProp | archProp | osName | osArch | isWindows @@ -43,10 +47,13 @@ class PlatformHelperTest extends Specification { this.props.setProperty("os.name", "Linux") this.props.setProperty("os.arch", archProp) this.props.setProperty("uname", unameProp) + def platform = PlatformHelperKt.parsePlatform("Linux", archProp, { unameProp }) expect: this.helper.getOsName() == "linux" this.helper.getOsArch() == osArch + platform.name == "linux" + platform.arch == osArch where: archProp | unameProp | osArch @@ -64,10 +71,13 @@ class PlatformHelperTest extends Specification { this.props.setProperty("os.name", "Mac OS X") this.props.setProperty("os.arch", archProp) this.props.setProperty("uname", unameProp) + def platform = PlatformHelperKt.parsePlatform("Mac OS X", archProp, { unameProp }) expect: this.helper.getOsName() == "darwin" this.helper.getOsArch() == osArch + platform.name == "darwin" + platform.arch == osArch where: archProp | unameProp | osArch @@ -78,11 +88,8 @@ class PlatformHelperTest extends Specification { } def "throw exception if unsupported os"() { - given: - this.props.setProperty("os.name", 'Nonsense') - when: - this.helper.getOsName() + PlatformHelperKt.parsePlatform('Nonsense', "", {}) then: thrown(IllegalStateException) diff --git a/src/test/groovy/com/github/gradle/node/variant/VariantComputerTest.groovy b/src/test/groovy/com/github/gradle/node/variant/VariantComputerTest.groovy index 0081a476..2d348cb3 100644 --- a/src/test/groovy/com/github/gradle/node/variant/VariantComputerTest.groovy +++ b/src/test/groovy/com/github/gradle/node/variant/VariantComputerTest.groovy @@ -1,7 +1,9 @@ package com.github.gradle.node.variant import com.github.gradle.node.NodeExtension +import com.github.gradle.node.util.Platform import com.github.gradle.node.util.TestablePlatformHelper +import com.github.gradle.node.util.PlatformHelperKt import org.gradle.testfixtures.ProjectBuilder import spock.lang.Specification import spock.lang.Unroll @@ -28,9 +30,11 @@ class VariantComputerTest extends Specification { props.setProperty("os.name", "Windows 8") props.setProperty("os.arch", osArch) + def platform = getPlatform("Windows 8", osArch) def platformHelper = new TestablePlatformHelper(props) def nodeExtension = new NodeExtension(project) + nodeExtension.computedPlatform.set(platform) nodeExtension.download.set(true) nodeExtension.version.set(version) nodeExtension.workDir.set(project.layout.projectDirectory.dir(".gradle/node")) @@ -41,8 +45,8 @@ class VariantComputerTest extends Specification { def variantComputer = new VariantComputer(platformHelper) when: - def computedArchiveDependency = variantComputer.computeNodeArchiveDependency(nodeExtension) - def computedNodeDir = variantComputer.computeNodeDir(nodeExtension) + def computedArchiveDependency = VariantComputerKt.computeNodeArchiveDependency(nodeExtension) + def computedNodeDir = VariantComputerKt.computeNodeDir(nodeExtension) def computedNodeBinDir = variantComputer.computeNodeBinDir(computedNodeDir) def computedNodeExec = variantComputer.computeNodeExec(nodeExtension, computedNodeBinDir) def computedNpmScriptFile = variantComputer.computeNpmScriptFile(computedNodeDir, "npm") @@ -72,10 +76,12 @@ class VariantComputerTest extends Specification { given: props.setProperty("os.name", osName) props.setProperty("os.arch", osArch) + def platform = getPlatform(osName, osArch) def platformHelper = new TestablePlatformHelper(props) def project = ProjectBuilder.builder().build() def nodeExtension = new NodeExtension(project) + nodeExtension.computedPlatform.set(platform) nodeExtension.download.set(true) nodeExtension.version.set('5.12.0') nodeExtension.workDir.set(project.layout.projectDirectory.dir(".gradle/node")) @@ -83,8 +89,8 @@ class VariantComputerTest extends Specification { def variantComputer = new VariantComputer(platformHelper) when: - def computedArchiveDependency = variantComputer.computeNodeArchiveDependency(nodeExtension) - def computedNodeDir = variantComputer.computeNodeDir(nodeExtension) + def computedArchiveDependency = VariantComputerKt.computeNodeArchiveDependency(nodeExtension) + def computedNodeDir = VariantComputerKt.computeNodeDir(nodeExtension) def computedNodeBinDir = variantComputer.computeNodeBinDir(computedNodeDir) def computedNodeExec = variantComputer.computeNodeExec(nodeExtension, computedNodeBinDir) def computedNpmScriptFile = variantComputer.computeNpmScriptFile(computedNodeDir, "npm") @@ -118,10 +124,12 @@ class VariantComputerTest extends Specification { props.setProperty("os.name", osName) props.setProperty("os.arch", osArch) props.setProperty("uname", sysOsArch) + def platform = getPlatform(osName, osArch, sysOsArch) def platformHelper = new TestablePlatformHelper(props) def project = ProjectBuilder.builder().build() def nodeExtension = new NodeExtension(project) + nodeExtension.computedPlatform.set(platform) nodeExtension.download.set(true) nodeExtension.version.set('5.12.0') nodeExtension.workDir.set(project.layout.projectDirectory.dir(".gradle/node")) @@ -129,8 +137,8 @@ class VariantComputerTest extends Specification { def variantComputer = new VariantComputer(platformHelper) when: - def computedArchiveDependency = variantComputer.computeNodeArchiveDependency(nodeExtension) - def computedNodeDir = variantComputer.computeNodeDir(nodeExtension) + def computedArchiveDependency = VariantComputerKt.computeNodeArchiveDependency(nodeExtension) + def computedNodeDir = VariantComputerKt.computeNodeDir(nodeExtension) def computedNodeBinDir = variantComputer.computeNodeBinDir(computedNodeDir) def computedNodeExec = variantComputer.computeNodeExec(nodeExtension, computedNodeBinDir) def computedNpmScriptFile = variantComputer.computeNpmScriptFile(computedNodeDir, "npm") @@ -158,10 +166,12 @@ class VariantComputerTest extends Specification { given: props.setProperty("os.name", "Windows 8") props.setProperty("os.arch", "x86") + def platform = getPlatform("Windows 8", "x86") def platformHelper = new TestablePlatformHelper(props) def project = ProjectBuilder.builder().build() def nodeExtension = new NodeExtension(project) + nodeExtension.computedPlatform.set(platform) nodeExtension.download.set(download) nodeExtension.npmVersion.set(npmVersion) @@ -211,9 +221,11 @@ class VariantComputerTest extends Specification { props.setProperty("os.name", "Linux") props.setProperty("os.arch", "x86") def platformHelper = new TestablePlatformHelper(props) + def platform = getPlatform("Linux", "x86") def project = ProjectBuilder.builder().build() def nodeExtension = new NodeExtension(project) + nodeExtension.computedPlatform.set(platform) nodeExtension.download.set(download) nodeExtension.npmVersion.set(npmVersion) @@ -258,4 +270,8 @@ class VariantComputerTest extends Specification { false | "4.0.2" false | "" } + + private Platform getPlatform(String osName, String osArch, uname = null) { + return PlatformHelperKt.parsePlatform(osName, osArch, { uname }) + } } diff --git a/src/test/groovy/com/github/gradle/node/yarn/task/YarnTaskTest.groovy b/src/test/groovy/com/github/gradle/node/yarn/task/YarnTaskTest.groovy index 855b008b..b13e737d 100644 --- a/src/test/groovy/com/github/gradle/node/yarn/task/YarnTaskTest.groovy +++ b/src/test/groovy/com/github/gradle/node/yarn/task/YarnTaskTest.groovy @@ -3,6 +3,7 @@ package com.github.gradle.node.yarn.task import com.github.gradle.node.npm.proxy.GradleProxyHelper import com.github.gradle.node.npm.proxy.ProxySettings import com.github.gradle.node.task.AbstractTaskTest +import com.github.gradle.node.util.PlatformHelperKt class YarnTaskTest extends AbstractTaskTest { def cleanup() { @@ -32,6 +33,7 @@ class YarnTaskTest extends AbstractTaskTest { def "exec yarn task (download)"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.download.set(true) def task = project.tasks.create('simple', YarnTask) @@ -55,6 +57,7 @@ class YarnTaskTest extends AbstractTaskTest { def "exec yarn task (download) with configured proxy"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.download.set(true) GradleProxyHelper.setHttpsProxyHost("1.2.3.4") GradleProxyHelper.setHttpsProxyPort(443) @@ -83,6 +86,7 @@ class YarnTaskTest extends AbstractTaskTest { def "exec yarn task (download) with configured proxy but disabled"() { given: props.setProperty('os.name', 'Linux') + nodeExtension.computedPlatform.set(PlatformHelperKt.parsePlatform("Linux", "x86_64", {})) nodeExtension.download.set(true) GradleProxyHelper.setHttpsProxyHost("1.2.3.4") GradleProxyHelper.setHttpsProxyPort(443)