Skip to content

Commit 876331d

Browse files
authored
Merge pull request #236 from node-gradle/packagejson-extension
Read package.json into extension #232
2 parents d15f7ee + 12e2bd1 commit 876331d

File tree

5 files changed

+168
-0
lines changed

5 files changed

+168
-0
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ repositories {
3838
}
3939

4040
dependencies {
41+
api("com.fasterxml.jackson.core:jackson-databind:2.13.2.2")
4142
testImplementation(platform("org.junit:junit-bom:5.6.2"))
4243
testImplementation("org.junit.jupiter:junit-jupiter-api")
4344
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class NodePlugin : Plugin<Project> {
2525
override fun apply(project: Project) {
2626
this.project = project
2727
val nodeExtension = NodeExtension.create(project)
28+
project.extensions.create<PackageJsonExtension>(PackageJsonExtension.NAME, project)
2829
addGlobalTypes()
2930
addTasks()
3031
addNpmRule()
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.github.gradle.node
2+
3+
import com.fasterxml.jackson.databind.JsonNode
4+
import com.fasterxml.jackson.databind.ObjectMapper
5+
import org.gradle.api.Project
6+
import org.gradle.kotlin.dsl.property
7+
import org.gradle.util.GradleVersion
8+
9+
/**
10+
* Provides a parsed view of package.json
11+
*/
12+
open class PackageJsonExtension(project: Project) {
13+
14+
/**
15+
* Raw JsonNode returned by Jackson, this may be removed in a future release
16+
*/
17+
val node = project.objects.property<JsonNode>()
18+
19+
init {
20+
if (GradleVersion.current() >= GradleVersion.version("6.1")) {
21+
node.finalizeValueOnRead()
22+
}
23+
node.set(project.provider { project.file("package.json").let(ObjectMapper()::readTree) })
24+
}
25+
26+
val name = project.provider { node.get().get("name")?.asText() }
27+
28+
val version = project.provider { node.get().get("version")?.asText() }
29+
30+
val description = project.provider { node.get().get("description")?.asText() }
31+
32+
val homepage = project.provider { node.get().get("homepage")?.asText() }
33+
34+
val license = project.provider { node.get().get("license")?.asText() }
35+
36+
val private = project.provider { node.get().get("private")?.asBoolean() }
37+
38+
/**
39+
* Get the text value of a given field
40+
*/
41+
fun get(name: String): String? {
42+
return node.get().get(name)?.asText()
43+
}
44+
45+
/**
46+
* Get the boolean value of a given field
47+
*/
48+
fun getBoolean(name: String): Boolean? {
49+
return node.get().get(name)?.asBoolean()
50+
}
51+
52+
/**
53+
* Get the text value of a field containing nested objects
54+
*
55+
* e.g. <pre>{ "outer": { "inner": "nested } }</pre>
56+
*/
57+
fun get(vararg name: String): String {
58+
return name.fold(node.get()) { acc, next -> acc.get(next) }.asText()
59+
}
60+
61+
companion object {
62+
/**
63+
* Extension name in Gradle
64+
*/
65+
const val NAME = "package.json"
66+
}
67+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//file:noinspection GroovyPointlessBoolean
2+
package com.github.gradle.node
3+
4+
import com.github.gradle.AbstractProjectTest
5+
import org.gradle.api.internal.provider.MissingValueException
6+
7+
class PackageJsonExtensionTest extends AbstractProjectTest {
8+
def 'check standard attributes'() {
9+
when:
10+
temporaryFolder.newFile("package.json") << """
11+
{ "name": "test", "version": "1.10.2", "private": false }
12+
"""
13+
project.apply plugin: 'com.github.node-gradle.node'
14+
project.evaluate()
15+
16+
then:
17+
def ext = project.extensions.getByName('package.json') as PackageJsonExtension
18+
ext.name.get() == "test"
19+
ext.version.get() == "1.10.2"
20+
ext.private.get() == false
21+
}
22+
23+
def 'get missing attribute'() {
24+
when:
25+
temporaryFolder.newFile("package.json") << """
26+
{ "name": "test", "version": "1.10.2", "private": false }
27+
"""
28+
project.apply plugin: 'com.github.node-gradle.node'
29+
project.evaluate()
30+
def ext = project.extensions.getByName('package.json') as PackageJsonExtension
31+
ext.homepage.get() == null
32+
33+
then:
34+
thrown(MissingValueException)
35+
}
36+
37+
def 'get raw attributes'() {
38+
when:
39+
temporaryFolder.newFile("package.json") << """
40+
{ "name": "test", "version": "1.10.2", "private": false }
41+
"""
42+
project.apply plugin: 'com.github.node-gradle.node'
43+
project.evaluate()
44+
45+
then:
46+
def ext = project.extensions.getByName('package.json') as PackageJsonExtension
47+
ext.get("name") == "test"
48+
ext.getBoolean("private") == false
49+
}
50+
51+
def 'get nested attributes'() {
52+
when:
53+
temporaryFolder.newFile("package.json") << """
54+
{
55+
"upper": { "lower": { "end": "done" } }
56+
}
57+
"""
58+
project.apply plugin: 'com.github.node-gradle.node'
59+
project.evaluate()
60+
61+
then:
62+
def ext = project.extensions.getByName('package.json') as PackageJsonExtension
63+
ext.get("upper", "lower", "end") == "done"
64+
}
65+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.github.gradle.node
2+
3+
import com.github.gradle.AbstractIntegTest
4+
import com.github.gradle.RunWithMultipleGradleVersions
5+
import org.gradle.testkit.runner.TaskOutcome
6+
import org.junit.Assume
7+
8+
@RunWithMultipleGradleVersions
9+
class PackageJsonExtension_integTest extends AbstractIntegTest {
10+
11+
def 'check standard attribute'() {
12+
given:
13+
Assume.assumeTrue(isConfigurationCacheEnabled())
14+
copyResources("fixtures/npm-env/")
15+
copyResources("fixtures/env/")
16+
createFile("build.gradle") << """
17+
def nameProvider = project.extensions.getByName("${PackageJsonExtension.NAME}").name
18+
tasks.register('printPackageJsonName') {
19+
inputs.property('name', nameProvider)
20+
doLast {
21+
println nameProvider.get()
22+
}
23+
}
24+
"""
25+
26+
when:
27+
def result1 = build(":printPackageJsonName")
28+
def result2 = build(":printPackageJsonName")
29+
30+
then:
31+
result1.task(":printPackageJsonName").outcome == TaskOutcome.SUCCESS
32+
result2.task(":printPackageJsonName").outcome == TaskOutcome.SUCCESS
33+
}
34+
}

0 commit comments

Comments
 (0)