@@ -8,19 +8,47 @@ import org.gradle.api.file.Directory
88import org.gradle.api.file.DirectoryProperty
99import org.gradle.api.provider.Property
1010import org.gradle.api.provider.Provider
11+ import java.io.File
12+
13+ /* *
14+ * Helper function to find the best matching executable in the system PATH.
15+ *
16+ * @param executableName The name of the executable to search for.
17+ * @return The best matching executable path as a String.
18+ */
19+ fun findBestExecutableMatch (
20+ executableName : String ,
21+ environmentProvider : Provider <Map <String , String >>,
22+ ): String {
23+ val environment = environmentProvider.orNull ? : return executableName
24+ val pathEnvironmentVariableName = if (environment[" Path" ] != null ) " Path" else " PATH"
25+ val pathVariable = environment[pathEnvironmentVariableName] ? : return executableName
26+ val paths = pathVariable.split(File .pathSeparator)
27+ for (path in paths) {
28+ val executableFile = File (path, executableName)
29+ if (executableFile.exists() && executableFile.canExecute()) {
30+ return executableFile.absolutePath
31+ }
32+ }
33+ return executableName // Return the original executable if no match is found
34+ }
1135
1236/* *
1337 * Get the expected node binary name, node.exe on Windows and node everywhere else.
1438 */
15- fun computeNodeExec (nodeExtension : NodeExtension , nodeBinDirProvider : Provider <Directory >): Provider <String > {
39+ fun computeNodeExec (
40+ nodeExtension : NodeExtension ,
41+ nodeBinDirProvider : Provider <Directory >,
42+ ): Provider <String > {
1643 return zip(nodeExtension.download, nodeBinDirProvider).map {
1744 val (download, nodeBinDir) = it
1845 if (download) {
1946 val nodeCommand = if (nodeExtension.resolvedPlatform.get().isWindows()) " node.exe" else " node"
2047 nodeBinDir.dir(nodeCommand).asFile.absolutePath
21- } else " node"
48+ } else findBestExecutableMatch( " node" , nodeExtension.environment)
2249 }
2350}
51+
2452fun computeNpmScriptFile (nodeDirProvider : Provider <Directory >, command : String , isWindows : Boolean ): Provider <String > {
2553 return nodeDirProvider.map { nodeDir ->
2654 if (isWindows) nodeDir.dir(" node_modules/npm/bin/$command -cli.js" ).asFile.path
@@ -44,21 +72,27 @@ fun computeNodeDir(nodeExtension: NodeExtension, osName: String, osArch: String)
4472/* *
4573 * Compute the path for a given command, from a given binary directory, taking Windows into account
4674 */
47- internal fun computeExec (nodeExtension : NodeExtension , binDirProvider : Provider <Directory >,
48- configurationCommand : Property <String >, unixCommand : String , windowsCommand : String ): Provider <String > {
75+ internal fun computeExec (
76+ nodeExtension : NodeExtension , binDirProvider : Provider <Directory >,
77+ configurationCommand : Property <String >, unixCommand : String , windowsCommand : String
78+ ): Provider <String > {
4979 return zip(nodeExtension.download, configurationCommand, binDirProvider).map {
5080 val (download, cfgCommand, binDir) = it
5181 val command = if (nodeExtension.resolvedPlatform.get().isWindows()) {
5282 cfgCommand.mapIf({ it == unixCommand }) { windowsCommand }
5383 } else cfgCommand
54- if (download) binDir.dir(command).asFile.absolutePath else command
84+ if (download) binDir.dir(command).asFile.absolutePath else findBestExecutableMatch( command, nodeExtension.environment)
5585 }
5686}
5787
5888/* *
5989 * Compute the path for a given package, taken versions and user-configured working directories into account
6090 */
61- internal fun computePackageDir (packageName : String , packageVersion : Property <String >, packageWorkDir : DirectoryProperty ): Provider <Directory > {
91+ internal fun computePackageDir (
92+ packageName : String ,
93+ packageVersion : Property <String >,
94+ packageWorkDir : DirectoryProperty
95+ ): Provider <Directory > {
6296 return zip(packageVersion, packageWorkDir).map {
6397 val (version, workDir) = it
6498 val dirnameSuffix = if (version.isNotBlank()) {
@@ -85,14 +119,17 @@ open class VariantComputer {
85119 /* *
86120 * Get the expected node binary directory, taking Windows specifics into account.
87121 */
88- fun computeNodeBinDir (nodeDirProvider : Provider <Directory >, platform : Property <Platform >) = computeProductBinDir(nodeDirProvider, platform)
122+ fun computeNodeBinDir (nodeDirProvider : Provider <Directory >, platform : Property <Platform >) =
123+ computeProductBinDir(nodeDirProvider, platform)
89124
90125 /* *
91126 * Get the expected node binary name, node.exe on Windows and node everywhere else.
92127 */
93- @Deprecated(message = " replaced by package-level function" ,
128+ @Deprecated(
129+ message = " replaced by package-level function" ,
94130 replaceWith =
95- ReplaceWith (" com.github.gradle.node.variant.computeNodeExec(nodeExtension, nodeBinDirProvider)" ))
131+ ReplaceWith (" com.github.gradle.node.variant.computeNodeExec(nodeExtension, nodeBinDirProvider)" )
132+ )
96133 fun computeNodeExec (nodeExtension : NodeExtension , nodeBinDirProvider : Provider <Directory >): Provider <String > {
97134 return com.github.gradle.node.variant.computeNodeExec(nodeExtension, nodeBinDirProvider)
98135 }
@@ -113,16 +150,19 @@ open class VariantComputer {
113150 /* *
114151 * Get the expected npm binary directory, taking Windows specifics into account.
115152 */
116- fun computeNpmBinDir (npmDirProvider : Provider <Directory >, platform : Property <Platform >) = computeProductBinDir(npmDirProvider, platform)
153+ fun computeNpmBinDir (npmDirProvider : Provider <Directory >, platform : Property <Platform >) =
154+ computeProductBinDir(npmDirProvider, platform)
117155
118156 /* *
119157 * Get the expected node binary name, npm.cmd on Windows and npm everywhere else.
120158 *
121159 * Can be overridden by setting npmCommand.
122160 */
123161 fun computeNpmExec (nodeExtension : NodeExtension , npmBinDirProvider : Provider <Directory >): Provider <String > {
124- return computeExec(nodeExtension, npmBinDirProvider,
125- nodeExtension.npmCommand, " npm" , " npm.cmd" )
162+ return computeExec(
163+ nodeExtension, npmBinDirProvider,
164+ nodeExtension.npmCommand, " npm" , " npm.cmd"
165+ )
126166 }
127167
128168 /* *
@@ -131,26 +171,32 @@ open class VariantComputer {
131171 * Can be overridden by setting npxCommand.
132172 */
133173 fun computeNpxExec (nodeExtension : NodeExtension , npmBinDirProvider : Provider <Directory >): Provider <String > {
134- return computeExec(nodeExtension, npmBinDirProvider,
135- nodeExtension.npxCommand, " npx" , " npx.cmd" )
174+ return computeExec(
175+ nodeExtension, npmBinDirProvider,
176+ nodeExtension.npxCommand, " npx" , " npx.cmd"
177+ )
136178 }
137179
138180 fun computePnpmDir (nodeExtension : NodeExtension ): Provider <Directory > {
139181 return computePackageDir(" pnpm" , nodeExtension.pnpmVersion, nodeExtension.pnpmWorkDir)
140182 }
141183
142- fun computePnpmBinDir (pnpmDirProvider : Provider <Directory >, platform : Property <Platform >) = computeProductBinDir(pnpmDirProvider, platform)
184+ fun computePnpmBinDir (pnpmDirProvider : Provider <Directory >, platform : Property <Platform >) =
185+ computeProductBinDir(pnpmDirProvider, platform)
143186
144187 fun computePnpmExec (nodeExtension : NodeExtension , pnpmBinDirProvider : Provider <Directory >): Provider <String > {
145- return computeExec(nodeExtension, pnpmBinDirProvider,
146- nodeExtension.pnpmCommand, " pnpm" , " pnpm.cmd" )
188+ return computeExec(
189+ nodeExtension, pnpmBinDirProvider,
190+ nodeExtension.pnpmCommand, " pnpm" , " pnpm.cmd"
191+ )
147192 }
148193
149194 fun computeYarnDir (nodeExtension : NodeExtension ): Provider <Directory > {
150195 return computePackageDir(" yarn" , nodeExtension.yarnVersion, nodeExtension.yarnWorkDir)
151196 }
152197
153- fun computeYarnBinDir (yarnDirProvider : Provider <Directory >, platform : Property <Platform >) = computeProductBinDir(yarnDirProvider, platform)
198+ fun computeYarnBinDir (yarnDirProvider : Provider <Directory >, platform : Property <Platform >) =
199+ computeProductBinDir(yarnDirProvider, platform)
154200
155201 fun computeYarnExec (nodeExtension : NodeExtension , yarnBinDirProvider : Provider <Directory >): Provider <String > {
156202 return zip(nodeExtension.yarnCommand, yarnBinDirProvider).map {
@@ -167,11 +213,14 @@ open class VariantComputer {
167213 return computePackageDir(" bun" , nodeExtension.bunVersion, nodeExtension.bunWorkDir)
168214 }
169215
170- fun computeBunBinDir (bunDirProvider : Provider <Directory >, platform : Property <Platform >) = computeProductBinDir(bunDirProvider, platform)
216+ fun computeBunBinDir (bunDirProvider : Provider <Directory >, platform : Property <Platform >) =
217+ computeProductBinDir(bunDirProvider, platform)
171218
172219 fun computeBunExec (nodeExtension : NodeExtension , bunBinDirProvider : Provider <Directory >): Provider <String > {
173- return computeExec(nodeExtension, bunBinDirProvider,
174- nodeExtension.bunCommand, " bun" , " bun.cmd" )
220+ return computeExec(
221+ nodeExtension, bunBinDirProvider,
222+ nodeExtension.bunCommand, " bun" , " bun.cmd"
223+ )
175224 }
176225
177226 /* *
@@ -180,20 +229,24 @@ open class VariantComputer {
180229 * Can be overridden by setting bunxCommand.
181230 */
182231 fun computeBunxExec (nodeExtension : NodeExtension , bunBinDirProvider : Provider <Directory >): Provider <String > {
183- return computeExec(nodeExtension, bunBinDirProvider,
184- nodeExtension.bunxCommand, " bunx" , " bunx.cmd" )
232+ return computeExec(
233+ nodeExtension, bunBinDirProvider,
234+ nodeExtension.bunxCommand, " bunx" , " bunx.cmd"
235+ )
185236 }
186237
187238 private fun computeProductBinDir (productDirProvider : Provider <Directory >, platform : Property <Platform >) =
188- if (platform.get().isWindows()) productDirProvider else productDirProvider.map { it.dir(" bin" ) }
239+ if (platform.get().isWindows()) productDirProvider else productDirProvider.map { it.dir(" bin" ) }
189240
190241 /* *
191242 * Get the node archive name in Gradle dependency format, using zip for Windows and tar.gz everywhere else.
192243 *
193244 * Essentially: org.nodejs:node:$version:$osName-$osArch@tar.gz
194245 */
195- @Deprecated(message = " replaced by package-level function" ,
196- replaceWith = ReplaceWith (" com.github.gradle.node.variant.computeNodeArchiveDependency(nodeExtension)" ))
246+ @Deprecated(
247+ message = " replaced by package-level function" ,
248+ replaceWith = ReplaceWith (" com.github.gradle.node.variant.computeNodeArchiveDependency(nodeExtension)" )
249+ )
197250 fun computeNodeArchiveDependency (nodeExtension : NodeExtension ): Provider <String > {
198251 return com.github.gradle.node.variant.computeNodeArchiveDependency(nodeExtension)
199252 }
0 commit comments