Skip to content

Commit 6a956dd

Browse files
committed
initial hacky implementation
Everything is duplicated into NpmExecSource
1 parent 8be3a19 commit 6a956dd

File tree

11 files changed

+894
-204
lines changed

11 files changed

+894
-204
lines changed

src/main/kotlin/com/github/gradle/node/NodeExtension.kt

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
11
package com.github.gradle.node
22

3+
import com.github.gradle.node.npm.exec.NpmExecResult
4+
import com.github.gradle.node.npm.exec.NpmExecSource
5+
import com.github.gradle.node.npm.exec.NpmExecSpec
36
import com.github.gradle.node.npm.proxy.ProxySettings
47
import com.github.gradle.node.util.Platform
8+
import com.github.gradle.node.variant.VariantComputer
9+
import com.github.gradle.node.variant.computeNodeExec
510
import org.gradle.api.Project
11+
import org.gradle.api.file.DirectoryProperty
12+
import org.gradle.api.provider.Property
13+
import org.gradle.api.provider.Provider
14+
import org.gradle.api.provider.ProviderFactory
615
import org.gradle.kotlin.dsl.create
716
import org.gradle.kotlin.dsl.getByType
17+
import org.gradle.kotlin.dsl.of
818
import org.gradle.kotlin.dsl.property
9-
10-
open class NodeExtension(project: Project) {
19+
import javax.inject.Inject
20+
21+
abstract class NodeExtension
22+
@Inject
23+
internal constructor(
24+
project: Project,
25+
private val providers: ProviderFactory,
26+
) {
1127
private val cacheDir = project.layout.projectDirectory.dir(".gradle")
1228

1329
/**
@@ -18,7 +34,7 @@ open class NodeExtension(project: Project) {
1834
/**
1935
* The directory where npm is installed (when a specific version is defined)
2036
*/
21-
val npmWorkDir = project.objects.directoryProperty().convention(cacheDir.dir("npm"))
37+
val npmWorkDir: DirectoryProperty = project.objects.directoryProperty().convention(cacheDir.dir("npm"))
2238

2339
/**
2440
* The directory where pnpm is installed (when a pnpm task is used)
@@ -53,7 +69,7 @@ open class NodeExtension(project: Project) {
5369
* If specified, installs it in the npmWorkDir
5470
* If empty, the plugin will use the npm command bundled with Node.js
5571
*/
56-
val npmVersion = project.objects.property<String>().convention("")
72+
val npmVersion: Property<String> = project.objects.property<String>().convention("")
5773

5874
/**
5975
* Version of pnpm to use
@@ -111,7 +127,7 @@ open class NodeExtension(project: Project) {
111127
* If true, it will download node using above parameters
112128
* Note that npm is bundled with Node.js
113129
*/
114-
val download = project.objects.property<Boolean>().convention(false)
130+
val download: Property<Boolean> = project.objects.property<Boolean>().convention(false)
115131

116132
/**
117133
* Whether the plugin automatically should add the proxy configuration to npm and yarn commands
@@ -168,7 +184,7 @@ open class NodeExtension(project: Project) {
168184
/**
169185
* Computed path to nodejs directory
170186
*/
171-
val resolvedNodeDir = project.objects.directoryProperty()
187+
val resolvedNodeDir: DirectoryProperty = project.objects.directoryProperty()
172188

173189
/**
174190
* Operating system and architecture
@@ -179,7 +195,7 @@ open class NodeExtension(project: Project) {
179195
/**
180196
* Operating system and architecture
181197
*/
182-
val resolvedPlatform = project.objects.property<Platform>()
198+
val resolvedPlatform: Property<Platform> = project.objects.property<Platform>()
183199

184200
init {
185201
distBaseUrl.set("https://nodejs.org/dist")
@@ -193,6 +209,30 @@ open class NodeExtension(project: Project) {
193209
nodeProxySettings.set(if (value) ProxySettings.SMART else ProxySettings.OFF)
194210
}
195211

212+
@Suppress("UnstableApiUsage")
213+
fun npmExec(
214+
configuration: NpmExecSpec.() -> Unit
215+
): Provider<NpmExecResult> {
216+
217+
val vc = VariantComputer()
218+
val nodeDirProvider = resolvedNodeDir
219+
val npmDirProvider = vc.computeNpmDir(this, nodeDirProvider)
220+
val nodeBinDirProvider = vc.computeNodeBinDir(nodeDirProvider, resolvedPlatform)
221+
val npmBinDirProvider = vc.computeNpmBinDir(npmDirProvider, resolvedPlatform)
222+
val nodeExecProvider = computeNodeExec(this, nodeBinDirProvider)
223+
224+
vc.computeNpmExec(this, npmBinDirProvider)
225+
226+
return providers.of(NpmExecSource::class) {
227+
parameters.apply(configuration)
228+
// parameters {
229+
// executable
230+
// ignoreExitValue
231+
// workingDir
232+
// }
233+
}
234+
}
235+
196236
companion object {
197237
/**
198238
* Extension name in Gradle
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.github.gradle.node.npm.exec
2+
3+
import org.gradle.api.GradleException
4+
import org.gradle.process.ExecResult
5+
6+
class NpmExecResult internal constructor(
7+
val exitValue: Int,
8+
val failure: GradleException?,
9+
val capturedOutput: String,
10+
) {
11+
12+
internal fun asExecResult(): ExecResult = object : ExecResult {
13+
14+
override fun assertNormalExitValue(): ExecResult {
15+
if (failure != null) {
16+
throw failure
17+
}
18+
return this
19+
}
20+
21+
override fun getExitValue(): Int = exitValue
22+
23+
override fun rethrowFailure(): ExecResult {
24+
assertNormalExitValue()
25+
return this
26+
}
27+
}
28+
29+
override fun toString(): String = "NpmExecResult(exitValue=$exitValue, failure=$failure)"
30+
}

src/main/kotlin/com/github/gradle/node/npm/exec/NpmExecRunner.kt

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,26 @@ abstract class NpmExecRunner {
2424
project: ProjectApiHelper,
2525
extension: NodeExtension,
2626
nodeExecConfiguration: NodeExecConfiguration,
27-
variants: VariantComputer
27+
variants: VariantComputer,
2828
): ExecResult {
2929
val npmExecConfiguration = NpmExecConfiguration(
30-
"npm"
31-
) { variantComputer, nodeExtension, npmBinDir -> variantComputer.computeNpmExec(nodeExtension, npmBinDir) }
30+
command = "npm",
31+
commandExecComputer = { variantComputer, nodeExtension, npmBinDir ->
32+
variantComputer.computeNpmExec(
33+
nodeExtension,
34+
npmBinDir
35+
)
36+
}
37+
)
3238
return executeCommand(
33-
project,
34-
extension,
35-
NpmProxy.addProxyEnvironmentVariables(extension.nodeProxySettings.get(), nodeExecConfiguration),
36-
npmExecConfiguration,
37-
variants
39+
project = project,
40+
extension = extension,
41+
nodeExecConfiguration = NpmProxy.addProxyEnvironmentVariables(
42+
proxySettings = extension.nodeProxySettings.get(),
43+
nodeExecConfiguration = nodeExecConfiguration
44+
),
45+
npmExecConfiguration = npmExecConfiguration,
46+
variantComputer = variants
3847
)
3948
}
4049

@@ -78,9 +87,13 @@ abstract class NpmExecRunner {
7887
if (executableAndScript.script != null) listOf(executableAndScript.script) else listOf()
7988
val args = argsPrefix.plus(nodeExecConfiguration.command)
8089
ExecConfiguration(
81-
executableAndScript.executable, args, additionalBinPath,
82-
nodeExecConfiguration.environment, nodeExecConfiguration.workingDir,
83-
nodeExecConfiguration.ignoreExitValue, nodeExecConfiguration.execOverrides
90+
executable = executableAndScript.executable,
91+
args = args,
92+
additionalBinPaths = additionalBinPath,
93+
environment = nodeExecConfiguration.environment,
94+
workingDir = nodeExecConfiguration.workingDir,
95+
ignoreExitValue = nodeExecConfiguration.ignoreExitValue,
96+
execOverrides = nodeExecConfiguration.execOverrides,
8497
)
8598
}
8699
}
@@ -97,18 +110,34 @@ abstract class NpmExecRunner {
97110
val nodeExecProvider = computeNodeExec(nodeExtension, nodeBinDirProvider)
98111
val executableProvider =
99112
npmExecConfiguration.commandExecComputer(variantComputer, nodeExtension, npmBinDirProvider)
100-
val isWindows = nodeExtension.resolvedPlatform.get().isWindows()
101113
val npmScriptFileProvider =
102-
computeNpmScriptFile(nodeDirProvider, npmExecConfiguration.command, isWindows)
114+
computeNpmScriptFile(nodeDirProvider, npmExecConfiguration.command, nodeExtension.resolvedPlatform)
115+
return computeExecutable(
116+
npmExecConfiguration.command,
117+
nodeExtension,
118+
executableProvider,
119+
nodeExecProvider,
120+
npmScriptFileProvider
121+
)
122+
}
123+
124+
private fun computeExecutable(
125+
command: String,
126+
nodeExtension: NodeExtension,
127+
executableProvider: Provider<String>,
128+
nodeExecProvider: Provider<String>,
129+
npmScriptFileProvider: Provider<String>,
130+
): Provider<ExecutableAndScript> {
103131
return zip(
104-
nodeExtension.download, nodeExtension.nodeProjectDir, executableProvider, nodeExecProvider,
132+
nodeExtension.download,
133+
nodeExtension.nodeProjectDir,
134+
executableProvider,
135+
nodeExecProvider,
105136
npmScriptFileProvider
106-
).map {
107-
val (download, nodeProjectDir, executable, nodeExec,
108-
npmScriptFile) = it
137+
).map { (download, nodeProjectDir, executable, nodeExec, npmScriptFile) ->
109138
if (download) {
110139
val localCommandScript = nodeProjectDir.dir("node_modules/npm/bin")
111-
.file("${npmExecConfiguration.command}-cli.js").asFile
140+
.file("${command}-cli.js").asFile
112141
if (localCommandScript.exists()) {
113142
return@map ExecutableAndScript(nodeExec, localCommandScript.absolutePath)
114143
} else if (!File(executable).exists()) {
@@ -121,7 +150,7 @@ abstract class NpmExecRunner {
121150

122151
private data class ExecutableAndScript(
123152
val executable: String,
124-
val script: String? = null
153+
val script: String? = null,
125154
)
126155

127156
private fun computeAdditionalBinPath(

0 commit comments

Comments
 (0)