Skip to content

Commit a22f0c6

Browse files
cortinicofacebook-github-bot
authored andcommitted
RNGP - Autolinking - Add model classes for parsing the config output
Summary: This diff is part of RFC0759 react-native-community/discussions-and-proposals#759 Here I'm creating data classes that will allow us to parse the `config` JSON output. Code is pretty straightforward and follows the structure as the `config` command output. Changelog: [Internal] [Changed] - RNGP - Autolinking - Add model classes for parsing the `config` output Differential Revision: D55475595
1 parent 734168c commit a22f0c6

9 files changed

+330
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.model
9+
10+
data class ModelAutolinkingAndroidProjectJson(
11+
val sourceDir: String,
12+
val appName: String,
13+
val packageName: String,
14+
val applicationId: String,
15+
val mainActivity: String,
16+
val watchModeCommandParams: List<String>?,
17+
val dependencyConfiguration: String?
18+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.model
9+
10+
data class ModelAutolinkingConfigJson(
11+
val reactNativeVersion: String,
12+
val dependencies: Map<String, ModelAutolinkingDependenciesJson>?,
13+
val project: ModelAutolinkingProjectJson?,
14+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.model
9+
10+
data class ModelAutolinkingDependenciesJson(
11+
val root: String,
12+
val name: String,
13+
val platforms: ModelAutolinkingDependenciesPlatformJson?
14+
) {
15+
16+
val nameCleansed: String
17+
get() = name.replace(Regex("[~*!'()]+"), "_").replace(Regex("^@([\\w-.]+)/"), "$1_")
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.model
9+
10+
data class ModelAutolinkingDependenciesPlatformAndroidJson(
11+
val sourceDir: String,
12+
val packageImportPath: String,
13+
val packageInstance: String,
14+
val buildTypes: List<String>,
15+
val libraryName: String,
16+
val componentDescriptors: List<String>,
17+
val cmakeListsPath: String,
18+
val cxxModuleCMakeListsModuleName: String?,
19+
val cxxModuleCMakeListsPath: String?,
20+
val cxxModuleHeaderName: String?,
21+
val dependencyConfiguration: String?
22+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.model
9+
10+
data class ModelAutolinkingDependenciesPlatformJson(
11+
val android: ModelAutolinkingDependenciesPlatformAndroidJson?
12+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.model
9+
10+
data class ModelAutolinkingProjectJson(val android: ModelAutolinkingAndroidProjectJson?)

packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/JsonUtils.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
package com.facebook.react.utils
99

10+
import com.facebook.react.model.ModelAutolinkingConfigJson
1011
import com.facebook.react.model.ModelPackageJson
1112
import com.google.gson.Gson
1213
import java.io.File
@@ -18,4 +19,10 @@ object JsonUtils {
1819
input.bufferedReader().use {
1920
runCatching { gsonConverter.fromJson(it, ModelPackageJson::class.java) }.getOrNull()
2021
}
22+
23+
fun fromAutolinkingConfigJson(input: File): ModelAutolinkingConfigJson? =
24+
input.bufferedReader().use {
25+
runCatching { gsonConverter.fromJson(it, ModelAutolinkingConfigJson::class.java) }
26+
.getOrNull()
27+
}
2128
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.model
9+
10+
import org.junit.Assert.assertEquals
11+
import org.junit.Test
12+
13+
class ModelAutolinkingDependenciesJsonTest {
14+
15+
@Test
16+
fun nameCleansed_withoutScope() {
17+
assertEquals("name", ModelAutolinkingDependenciesJson("", "name", null).nameCleansed)
18+
assertEquals(
19+
"react_native", ModelAutolinkingDependenciesJson("", "react~native", null).nameCleansed)
20+
assertEquals(
21+
"react_native", ModelAutolinkingDependenciesJson("", "react*native", null).nameCleansed)
22+
assertEquals(
23+
"react_native", ModelAutolinkingDependenciesJson("", "react!native", null).nameCleansed)
24+
assertEquals(
25+
"react_native", ModelAutolinkingDependenciesJson("", "react'native", null).nameCleansed)
26+
assertEquals(
27+
"react_native", ModelAutolinkingDependenciesJson("", "react(native", null).nameCleansed)
28+
assertEquals(
29+
"react_native", ModelAutolinkingDependenciesJson("", "react)native", null).nameCleansed)
30+
assertEquals(
31+
"react_native",
32+
ModelAutolinkingDependenciesJson("", "react~*!'()native", null).nameCleansed)
33+
}
34+
35+
@Test
36+
fun nameCleansed_withScope() {
37+
assertEquals(
38+
"react-native_package",
39+
ModelAutolinkingDependenciesJson("", "@react-native/package", null).nameCleansed)
40+
assertEquals(
41+
"this_is_a_more_complicated_example_of_weird_packages",
42+
ModelAutolinkingDependenciesJson(
43+
"", "@this*is~a(more)complicated/example!of~weird)packages", null)
44+
.nameCleansed)
45+
}
46+
}

packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/JsonUtilsTest.kt

Lines changed: 183 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ class JsonUtilsTest {
1818
@get:Rule val tempFolder = TemporaryFolder()
1919

2020
@Test
21-
fun withInvalidJson_returnsNull() {
21+
fun fromPackageJson_withInvalidJson_returnsNull() {
2222
val invalidJson = createJsonFile("""¯\_(ツ)_/¯""")
2323

2424
assertNull(JsonUtils.fromPackageJson(invalidJson))
2525
}
2626

2727
@Test
28-
fun withEmptyJson_returnsEmptyObject() {
28+
fun fromPackageJson_withEmptyJson_returnsEmptyObject() {
2929
val invalidJson = createJsonFile("""{}""")
3030

3131
val parsed = JsonUtils.fromPackageJson(invalidJson)
@@ -35,7 +35,7 @@ class JsonUtilsTest {
3535
}
3636

3737
@Test
38-
fun withOldJsonConfig_returnsAnEmptyLibrary() {
38+
fun fromPackageJson_withOldJsonConfig_returnsAnEmptyLibrary() {
3939
val oldJsonConfig =
4040
createJsonFile(
4141
"""
@@ -62,7 +62,7 @@ class JsonUtilsTest {
6262
}
6363

6464
@Test
65-
fun withValidJson_parsesCorrectly() {
65+
fun fromPackageJson_withValidJson_parsesCorrectly() {
6666
val validJson =
6767
createJsonFile(
6868
"""
@@ -121,6 +121,185 @@ class JsonUtilsTest {
121121
assertEquals("1000.0.0", parsed.version)
122122
}
123123

124+
@Test
125+
fun fromAutolinkingConfigJson_withInvalidJson_returnsNull() {
126+
val invalidJson = createJsonFile("""¯\_(ツ)_/¯""")
127+
128+
assertNull(JsonUtils.fromAutolinkingConfigJson(invalidJson))
129+
}
130+
131+
@Test
132+
fun fromAutolinkingConfigJson_withSimpleJson_returnsIt() {
133+
val validJson =
134+
createJsonFile(
135+
"""
136+
{
137+
"reactNativeVersion": "1000.0.0"
138+
}
139+
"""
140+
.trimIndent())
141+
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
142+
143+
assertEquals("1000.0.0", parsed.reactNativeVersion)
144+
}
145+
146+
@Test
147+
fun fromAutolinkingConfigJson_withProjectSpecified_canParseIt() {
148+
val validJson =
149+
createJsonFile(
150+
"""
151+
{
152+
"reactNativeVersion": "1000.0.0",
153+
"project": {
154+
"ios": {
155+
"sourceDir": "./packages/rn-tester",
156+
"xcodeProject": {
157+
"name": "RNTesterPods.xcworkspace",
158+
"isWorkspace": true
159+
},
160+
"automaticPodsInstallation": false
161+
},
162+
"android": {
163+
"sourceDir": "./packages/rn-tester",
164+
"appName": "RN-Tester",
165+
"packageName": "com.facebook.react.uiapp",
166+
"applicationId": "com.facebook.react.uiapp",
167+
"mainActivity": ".RNTesterActivity",
168+
"watchModeCommandParams": [
169+
"--mode HermesDebug"
170+
],
171+
"dependencyConfiguration": "implementation"
172+
}
173+
}
174+
}
175+
"""
176+
.trimIndent())
177+
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
178+
179+
assertEquals("./packages/rn-tester", parsed.project!!.android!!.sourceDir)
180+
assertEquals("RN-Tester", parsed.project!!.android!!.appName)
181+
assertEquals("com.facebook.react.uiapp", parsed.project!!.android!!.packageName)
182+
assertEquals("com.facebook.react.uiapp", parsed.project!!.android!!.applicationId)
183+
assertEquals(".RNTesterActivity", parsed.project!!.android!!.mainActivity)
184+
assertEquals("--mode HermesDebug", parsed.project!!.android!!.watchModeCommandParams!![0])
185+
assertEquals("implementation", parsed.project!!.android!!.dependencyConfiguration)
186+
}
187+
188+
@Test
189+
fun fromAutolinkingConfigJson_withDependenciesSpecified_canParseIt() {
190+
val validJson =
191+
createJsonFile(
192+
"""
193+
{
194+
"reactNativeVersion": "1000.0.0",
195+
"dependencies": {
196+
"@react-native/oss-library-example": {
197+
"root": "./node_modules/@react-native/oss-library-example",
198+
"name": "@react-native/oss-library-example",
199+
"platforms": {
200+
"ios": {
201+
"podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
202+
"version": "0.0.1",
203+
"configurations": [],
204+
"scriptPhases": []
205+
},
206+
"android": {
207+
"sourceDir": "./node_modules/@react-native/oss-library-example/android",
208+
"packageImportPath": "import com.facebook.react.osslibraryexample.OSSLibraryExamplePackage;",
209+
"packageInstance": "new OSSLibraryExamplePackage()",
210+
"buildTypes": ["staging", "debug", "release"],
211+
"libraryName": "OSSLibraryExampleSpec",
212+
"componentDescriptors": [
213+
"SampleNativeComponentComponentDescriptor"
214+
],
215+
"cmakeListsPath": "./node_modules/@react-native/oss-library-example/android/build/generated/source/codegen/jni/CMakeLists.txt",
216+
"cxxModuleCMakeListsModuleName": null,
217+
"cxxModuleCMakeListsPath": null,
218+
"cxxModuleHeaderName": null,
219+
"dependencyConfiguration": "implementation"
220+
}
221+
}
222+
}
223+
}
224+
}
225+
"""
226+
.trimIndent())
227+
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
228+
229+
assertEquals(
230+
"./node_modules/@react-native/oss-library-example",
231+
parsed.dependencies!!["@react-native/oss-library-example"]!!.root)
232+
assertEquals(
233+
"@react-native/oss-library-example",
234+
parsed.dependencies!!["@react-native/oss-library-example"]!!.name)
235+
assertEquals(
236+
"react-native_oss-library-example",
237+
parsed.dependencies!!["@react-native/oss-library-example"]!!.nameCleansed)
238+
assertEquals(
239+
"./node_modules/@react-native/oss-library-example/android",
240+
parsed.dependencies!!["@react-native/oss-library-example"]!!
241+
.platforms!!
242+
.android!!
243+
.sourceDir)
244+
assertEquals(
245+
"import com.facebook.react.osslibraryexample.OSSLibraryExamplePackage;",
246+
parsed.dependencies!!["@react-native/oss-library-example"]!!
247+
.platforms!!
248+
.android!!
249+
.packageImportPath)
250+
assertEquals(
251+
"new OSSLibraryExamplePackage()",
252+
parsed.dependencies!!["@react-native/oss-library-example"]!!
253+
.platforms!!
254+
.android!!
255+
.packageInstance)
256+
assertEquals(
257+
listOf("staging", "debug", "release"),
258+
parsed.dependencies!!["@react-native/oss-library-example"]!!
259+
.platforms!!
260+
.android!!
261+
.buildTypes)
262+
assertEquals(
263+
"OSSLibraryExampleSpec",
264+
parsed.dependencies!!["@react-native/oss-library-example"]!!
265+
.platforms!!
266+
.android!!
267+
.libraryName)
268+
assertEquals(
269+
listOf("SampleNativeComponentComponentDescriptor"),
270+
parsed.dependencies!!["@react-native/oss-library-example"]!!
271+
.platforms!!
272+
.android!!
273+
.componentDescriptors)
274+
assertEquals(
275+
"./node_modules/@react-native/oss-library-example/android/build/generated/source/codegen/jni/CMakeLists.txt",
276+
parsed.dependencies!!["@react-native/oss-library-example"]!!
277+
.platforms!!
278+
.android!!
279+
.cmakeListsPath)
280+
assertNull(
281+
parsed.dependencies!!["@react-native/oss-library-example"]!!
282+
.platforms!!
283+
.android!!
284+
.cxxModuleHeaderName)
285+
assertNull(
286+
parsed.dependencies!!["@react-native/oss-library-example"]!!
287+
.platforms!!
288+
.android!!
289+
.cxxModuleCMakeListsPath)
290+
assertNull(
291+
parsed.dependencies!!["@react-native/oss-library-example"]!!
292+
.platforms!!
293+
.android!!
294+
.cxxModuleCMakeListsModuleName)
295+
assertEquals(
296+
"implementation",
297+
parsed.dependencies!!["@react-native/oss-library-example"]!!
298+
.platforms!!
299+
.android!!
300+
.dependencyConfiguration)
301+
}
302+
124303
private fun createJsonFile(@Language("JSON") input: String) =
125304
tempFolder.newFile().apply { writeText(input) }
126305
}

0 commit comments

Comments
 (0)