Skip to content

Commit e5c6f10

Browse files
committed
Refactor the plugin code:
- Change the packages layout - Clean and simplify some code - Change the way exec runner works. Use as many mutable data structures as possible - Remove all the unnecessary after project evaluation's hook usages in tasks (issue #39)
1 parent f069fae commit e5c6f10

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+462
-567
lines changed

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

-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import org.gradle.api.Project
55
import java.io.File
66
import kotlin.properties.Delegates
77

8-
@Suppress("MemberVisibilityCanBePrivate", "unused") // Extension object; properties may be configured in build scripts
98
open class NodeExtension(project: Project) {
10-
119
private val cacheDir = File(project.projectDir, ".gradle")
1210
var workDir = File(cacheDir, "nodejs")
1311
var npmWorkDir = File(cacheDir, "npm")

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

+18-38
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,32 @@
11
package com.github.gradle.node
22

3-
import com.github.gradle.node.npm.NpmInstallTask
4-
import com.github.gradle.node.npm.NpmSetupTask
5-
import com.github.gradle.node.npm.NpmTask
6-
import com.github.gradle.node.npm.NpxTask
3+
import com.github.gradle.node.npm.task.NpmInstallTask
4+
import com.github.gradle.node.npm.task.NpmSetupTask
5+
import com.github.gradle.node.npm.task.NpmTask
6+
import com.github.gradle.node.npm.task.NpxTask
7+
import com.github.gradle.node.task.NodeSetupTask
78
import com.github.gradle.node.task.NodeTask
8-
import com.github.gradle.node.task.SetupTask
99
import com.github.gradle.node.variant.VariantBuilder
10-
import com.github.gradle.node.yarn.YarnInstallTask
11-
import com.github.gradle.node.yarn.YarnSetupTask
12-
import com.github.gradle.node.yarn.YarnTask
10+
import com.github.gradle.node.yarn.task.YarnInstallTask
11+
import com.github.gradle.node.yarn.task.YarnSetupTask
12+
import com.github.gradle.node.yarn.task.YarnTask
1313
import org.gradle.api.Plugin
1414
import org.gradle.api.Project
1515
import org.gradle.kotlin.dsl.create
1616

1717
class NodePlugin : Plugin<Project> {
18-
1918
private lateinit var project: Project
20-
private lateinit var config: NodeExtension
21-
22-
private lateinit var setupTask: SetupTask
23-
private lateinit var npmSetupTask: NpmSetupTask
24-
private lateinit var yarnSetupTask: YarnSetupTask
19+
private lateinit var nodeExtension: NodeExtension
2520

2621
override fun apply(project: Project) {
2722
this.project = project
28-
this.config = NodeExtension.create(project)
23+
this.nodeExtension = NodeExtension.create(project)
2924
addGlobalTypes()
3025
addTasks()
3126
addNpmRule()
3227
addYarnRule()
3328
this.project.afterEvaluate {
34-
config.variant = VariantBuilder(config).build()
35-
configureSetupTask()
36-
configureNpmSetupTask()
37-
configureYarnSetupTask()
29+
nodeExtension.variant = VariantBuilder(nodeExtension).build()
3830
}
3931
}
4032

@@ -45,16 +37,16 @@ class NodePlugin : Plugin<Project> {
4537
addGlobalTaskType(YarnTask::class.java)
4638
}
4739

40+
private fun addGlobalTaskType(type: Class<*>) {
41+
project.extensions.extraProperties[type.simpleName] = type
42+
}
43+
4844
private fun addTasks() {
4945
project.tasks.create(NpmInstallTask.NAME, NpmInstallTask::class)
5046
project.tasks.create(YarnInstallTask.NAME, YarnInstallTask::class)
51-
setupTask = project.tasks.create(SetupTask.NAME, SetupTask::class)
52-
npmSetupTask = project.tasks.create(NpmSetupTask.NAME, NpmSetupTask::class)
53-
yarnSetupTask = project.tasks.create(YarnSetupTask.NAME, YarnSetupTask::class)
54-
}
55-
56-
private fun addGlobalTaskType(type: Class<*>) {
57-
project.extensions.extraProperties[type.simpleName] = type
47+
project.tasks.create(NodeSetupTask.NAME, NodeSetupTask::class)
48+
project.tasks.create(NpmSetupTask.NAME, NpmSetupTask::class)
49+
project.tasks.create(YarnSetupTask.NAME, YarnSetupTask::class)
5850
}
5951

6052
private fun addNpmRule() { // note this rule also makes it possible to specify e.g. "dependsOn npm_install"
@@ -85,18 +77,6 @@ class NodePlugin : Plugin<Project> {
8577
}
8678
}
8779

88-
private fun configureSetupTask() {
89-
setupTask.isEnabled = config.download
90-
}
91-
92-
private fun configureNpmSetupTask() {
93-
npmSetupTask.configureVersion(config.npmVersion)
94-
}
95-
96-
private fun configureYarnSetupTask() {
97-
yarnSetupTask.configureVersion(config.yarnVersion)
98-
}
99-
10080
companion object {
10181
const val NODE_GROUP = "Node"
10282
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.github.gradle.node.exec
2+
3+
import org.gradle.process.ExecSpec
4+
import java.io.File
5+
6+
internal data class ExecConfiguration(
7+
val executable: String,
8+
val args: List<String> = listOf(),
9+
var additionalBinPath: String? = null,
10+
val environment: Map<String, String> = mapOf(),
11+
val workingDir: File? = null,
12+
val ignoreExitValue: Boolean = false,
13+
val execOverrides: (ExecSpec.() -> Unit)? = null
14+
)
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,40 @@
11
package com.github.gradle.node.exec
22

33
import com.github.gradle.node.NodeExtension
4-
import com.github.gradle.node.variant.Variant
5-
import groovy.lang.Closure
64
import org.gradle.api.Project
7-
import org.gradle.api.tasks.Input
8-
import org.gradle.api.tasks.Internal
9-
import org.gradle.kotlin.dsl.getByType
105
import org.gradle.kotlin.dsl.invoke
11-
import org.gradle.process.ExecResult
12-
import org.gradle.process.ExecSpec
136
import java.io.File
14-
import java.util.*
157

16-
abstract class ExecRunner(
17-
@get:Internal protected var project: Project
18-
) {
19-
20-
@get:Internal
21-
protected val ext: NodeExtension = NodeExtension[project]
22-
@get:Internal
23-
protected val variant: Variant by lazy { ext.variant }
24-
25-
@get:Input
26-
val environment = LinkedHashMap<String, String>()
27-
@get:Input
28-
var ignoreExitValue = false
29-
@get:Internal
30-
var workingDir: File? = null
31-
@get:Internal
32-
var arguments: MutableList<String> = ArrayList()
33-
@get:Internal
34-
var execOverrides: (ExecSpec.() -> Unit)? = null
35-
36-
fun execute(): ExecResult {
37-
return doExecute()
38-
}
39-
40-
protected fun run(exec: String, runArgs: List<String>): ExecResult {
41-
return project.exec {
42-
executable = exec
43-
args = runArgs
44-
environment = computeExecEnvironment()
45-
isIgnoreExitValue = ignoreExitValue
46-
workingDir = computeWorkingDir()
47-
execOverrides?.invoke(this)
8+
internal class ExecRunner {
9+
fun execute(project: Project, execConfiguration: ExecConfiguration) {
10+
project.exec {
11+
executable = execConfiguration.executable
12+
args = execConfiguration.args
13+
environment = computeEnvironment(execConfiguration)
14+
isIgnoreExitValue = execConfiguration.ignoreExitValue
15+
workingDir = computeWorkingDir(project, execConfiguration)
16+
execConfiguration.execOverrides?.invoke(this)
4817
}
4918
}
5019

51-
private fun computeWorkingDir(): File? {
52-
val computedWorkingDir = workingDir ?: project.extensions.getByType(NodeExtension::class).nodeModulesDir
53-
computedWorkingDir.mkdirs()
54-
return computedWorkingDir
55-
}
56-
57-
private fun computeExecEnvironment(): Map<String, String> {
58-
val execEnvironment = linkedMapOf<String, String>()
20+
private fun computeEnvironment(execConfiguration: ExecConfiguration): Map<String, String> {
21+
val execEnvironment = mutableMapOf<String, String>()
5922
execEnvironment += System.getenv()
60-
execEnvironment += environment
61-
val path = computeAdditionalBinPath()
62-
if (path.isNotBlank()) {
23+
execEnvironment += execConfiguration.environment
24+
if (execConfiguration.additionalBinPath != null) {
6325
// Take care of Windows environments that may contain "Path" OR "PATH" - both existing
6426
// possibly (but not in parallel as of now)
65-
val envPathName = if (execEnvironment["Path"] != null) "Path" else "PATH"
66-
execEnvironment[envPathName] = path + File.pathSeparator + execEnvironment[envPathName]
27+
val pathEnvironmentVariableName = if (execEnvironment["Path"] != null) "Path" else "PATH"
28+
val actualPath = execEnvironment[pathEnvironmentVariableName]
29+
execEnvironment[pathEnvironmentVariableName] =
30+
"${execConfiguration.additionalBinPath}${File.pathSeparator}${actualPath}"
6731
}
6832
return execEnvironment
6933
}
7034

71-
// Configurable; Groovy support
72-
fun setExecOverrides(execOverrides: Closure<ExecSpec>) {
73-
this.execOverrides = { execOverrides.invoke(this) }
35+
private fun computeWorkingDir(project: Project, execConfiguration: ExecConfiguration): File? {
36+
val workingDir = execConfiguration.workingDir ?: NodeExtension[project].nodeModulesDir
37+
workingDir.mkdirs()
38+
return workingDir
7439
}
75-
76-
protected abstract fun computeAdditionalBinPath(): String
77-
78-
protected abstract fun doExecute(): ExecResult
7940
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.github.gradle.node.exec
2+
3+
import org.gradle.process.ExecSpec
4+
import java.io.File
5+
6+
internal data class NodeExecConfiguration(
7+
val command: List<String> = listOf(),
8+
val environment: Map<String, String> = mapOf(),
9+
val workingDir: File? = null,
10+
val ignoreExitValue: Boolean = false,
11+
val execOverrides: (ExecSpec.() -> Unit)? = null
12+
)
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
package com.github.gradle.node.exec
22

3+
import com.github.gradle.node.NodeExtension
34
import org.gradle.api.Project
4-
import org.gradle.process.ExecResult
55

6-
class NodeExecRunner(project: Project) : ExecRunner(project) {
7-
8-
override fun doExecute(): ExecResult {
9-
val exec = if (ext.download) variant.nodeExec else "node"
10-
return run(exec, arguments)
6+
internal class NodeExecRunner {
7+
fun execute(project: Project, nodeExecConfiguration: NodeExecConfiguration) {
8+
val execConfiguration = buildExecConfiguration(project, nodeExecConfiguration)
9+
val execRunner = ExecRunner()
10+
execRunner.execute(project, execConfiguration)
1111
}
1212

13-
override fun computeAdditionalBinPath(): String {
14-
return if (ext.download) variant.nodeBinDir.absolutePath else ""
13+
private fun buildExecConfiguration(project: Project, nodeExecConfiguration: NodeExecConfiguration): ExecConfiguration {
14+
val nodeExtension = NodeExtension[project]
15+
val variant = nodeExtension.variant
16+
val executable = if (nodeExtension.download) variant.nodeExec else "node"
17+
val additionalBinPath = if (nodeExtension.download) variant.nodeBinDir.absolutePath else null
18+
return ExecConfiguration(executable, nodeExecConfiguration.command, additionalBinPath,
19+
nodeExecConfiguration.environment, nodeExecConfiguration.workingDir,
20+
nodeExecConfiguration.ignoreExitValue, nodeExecConfiguration.execOverrides)
1521
}
1622
}

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

-44
This file was deleted.

src/main/kotlin/com/github/gradle/node/npm/NpmTask.kt

-44
This file was deleted.

src/main/kotlin/com/github/gradle/node/npm/NpxExecRunner.kt

-23
This file was deleted.

0 commit comments

Comments
 (0)