@ohos-ports/react-native-gradle-plugin 0.71.19-beta.0 → 0.86.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +11 -4
  2. package/build.gradle.kts +33 -41
  3. package/gradle/libs.versions.toml +22 -0
  4. package/gradle/wrapper/gradle-wrapper.jar +0 -0
  5. package/gradle/wrapper/gradle-wrapper.properties +3 -1
  6. package/gradle.properties +2 -0
  7. package/gradlew +32 -18
  8. package/gradlew.bat +22 -18
  9. package/package.json +21 -11
  10. package/react-native-gradle-plugin/README.md +17 -0
  11. package/react-native-gradle-plugin/build.gradle.kts +83 -0
  12. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/ReactExtension.kt +78 -10
  13. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +320 -0
  14. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactRootProjectPlugin.kt +86 -0
  15. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/TaskConfiguration.kt +36 -25
  16. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/internal/PrivateReactExtension.kt +11 -4
  17. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/BundleHermesCTask.kt +60 -50
  18. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTask.kt +252 -0
  19. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt +8 -3
  20. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/GenerateCodegenSchemaTask.kt +11 -18
  21. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateEntryPointTask.kt +108 -0
  22. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GeneratePackageListTask.kt +214 -0
  23. package/{src/main/kotlin/com/facebook/react/tasks → react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/internal}/BuildCodegenCLITask.kt +24 -17
  24. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/internal/CustomExecTask.kt +46 -0
  25. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/PrepareBoostTask.kt +10 -4
  26. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/internal/PrepareGflagsTask.kt +119 -0
  27. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/PrepareGlogTask.kt +26 -18
  28. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTask.kt +28 -12
  29. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/utils/PrefabPreprocessingEntry.kt +4 -3
  30. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/AgpConfiguratorUtils.kt +163 -0
  31. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/BackwardCompatUtils.kt +71 -0
  32. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt +299 -0
  33. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/JdkConfiguratorUtils.kt +64 -0
  34. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt +59 -65
  35. package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/PathUtils.kt +44 -30
  36. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt +119 -0
  37. package/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt +96 -0
  38. package/settings-plugin/build.gradle.kts +73 -0
  39. package/settings-plugin/src/main/kotlin/com/facebook/react/ReactSettingsExtension.kt +217 -0
  40. package/settings-plugin/src/main/kotlin/com/facebook/react/ReactSettingsPlugin.kt +23 -0
  41. package/settings-plugin/src/test/kotlin/com/facebook/react/ReactSettingsExtensionTest.kt +475 -0
  42. package/settings.gradle.kts +10 -1
  43. package/shared/build.gradle.kts +52 -0
  44. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingAndroidProjectJson.kt +18 -0
  45. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingConfigJson.kt +14 -0
  46. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingDependenciesJson.kt +18 -0
  47. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingDependenciesPlatformAndroidJson.kt +23 -0
  48. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingDependenciesPlatformJson.kt +12 -0
  49. package/shared/src/main/kotlin/com/facebook/react/model/ModelAutolinkingProjectJson.kt +10 -0
  50. package/{src → shared/src}/main/kotlin/com/facebook/react/model/ModelCodegenConfig.kt +2 -1
  51. package/{src → shared/src}/main/kotlin/com/facebook/react/model/ModelPackageJson.kt +1 -1
  52. package/shared/src/main/kotlin/com/facebook/react/utils/JsonUtils.kt +43 -0
  53. package/shared/src/main/kotlin/com/facebook/react/utils/KotlinStdlibCompatUtils.kt +32 -0
  54. package/{src → shared/src}/main/kotlin/com/facebook/react/utils/Os.kt +7 -6
  55. package/{src → shared/src}/main/kotlin/com/facebook/react/utils/TaskUtils.kt +4 -5
  56. package/shared/src/test/kotlin/com/facebook/react/utils/JsonUtilsTest.kt +382 -0
  57. package/shared/src/test/kotlin/com/facebook/react/utils/KotlinStdlibCompatUtilsTest.kt +82 -0
  58. package/shared/src/test/kotlin/com/facebook/react/utils/OsTest.kt +87 -0
  59. package/shared/src/test/kotlin/com/facebook/react/utils/TaskUtilsTest.kt +76 -0
  60. package/shared-testutil/build.gradle.kts +46 -0
  61. package/shared-testutil/src/main/kotlin/com/facebook/react/tests/OsRule.kt +52 -0
  62. package/shared-testutil/src/main/kotlin/com/facebook/react/tests/WithOs.kt +17 -0
  63. package/build/libs/react-native-gradle-plugin.jar +0 -0
  64. package/index.js +0 -73
  65. package/src/main/kotlin/com/facebook/react/ReactPlugin.kt +0 -212
  66. package/src/main/kotlin/com/facebook/react/tasks/internal/PrepareJSCTask.kt +0 -50
  67. package/src/main/kotlin/com/facebook/react/tasks/internal/PrepareLibeventTask.kt +0 -51
  68. package/src/main/kotlin/com/facebook/react/utils/AgpConfiguratorUtils.kt +0 -54
  69. package/src/main/kotlin/com/facebook/react/utils/BackwardCompatUtils.kt +0 -48
  70. package/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt +0 -109
  71. package/src/main/kotlin/com/facebook/react/utils/JsonUtils.kt +0 -21
  72. package/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt +0 -55
  73. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/FileUtils.kt +0 -0
  74. /package/{src → shared/src}/main/kotlin/com/facebook/react/model/ModelCodegenConfigAndroid.kt +0 -0
@@ -0,0 +1,475 @@
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
9
+
10
+ import com.facebook.react.ReactSettingsExtension.Companion.checkAndUpdateCache
11
+ import com.facebook.react.ReactSettingsExtension.Companion.checkAndUpdateLockfiles
12
+ import com.facebook.react.ReactSettingsExtension.Companion.computeSha256
13
+ import com.facebook.react.ReactSettingsExtension.Companion.getLibrariesToAutolink
14
+ import com.facebook.react.ReactSettingsExtension.GenerateConfig
15
+ import java.io.File
16
+ import org.assertj.core.api.Assertions.assertThat
17
+ import org.gradle.testfixtures.ProjectBuilder
18
+ import org.intellij.lang.annotations.Language
19
+ import org.junit.Rule
20
+ import org.junit.Test
21
+ import org.junit.rules.TemporaryFolder
22
+
23
+ class ReactSettingsExtensionTest {
24
+
25
+ @get:Rule val tempFolder = TemporaryFolder()
26
+
27
+ @Test
28
+ fun computeSha256_worksCorrectly() {
29
+ val validFile =
30
+ createJsonFile(
31
+ """
32
+ {
33
+ "value": "¯\\_(ツ)_/¯"
34
+ }
35
+ """
36
+ .trimIndent()
37
+ )
38
+ assertThat(computeSha256(validFile))
39
+ .isEqualTo("838aa9a72a16fdd55b0d49b510a82e264a30f59333b5fdd97c7798a29146f6a8")
40
+ }
41
+
42
+ @Test
43
+ fun getLibrariesToAutolink_withEmptyFile_returnsEmptyMap() {
44
+ val validJsonFile =
45
+ createJsonFile(
46
+ """
47
+ {
48
+ "reactNativeVersion": "1000.0.0"
49
+ }
50
+ """
51
+ .trimIndent()
52
+ )
53
+
54
+ val map = getLibrariesToAutolink(validJsonFile)
55
+ assertThat(map.keys).isEmpty()
56
+ }
57
+
58
+ @Test
59
+ fun getLibrariesToAutolink_withLibraryToAutolink_returnsValidMap() {
60
+ val validJsonFile =
61
+ createJsonFile(
62
+ """
63
+ {
64
+ "reactNativeVersion": "1000.0.0",
65
+ "dependencies": {
66
+ "@react-native/oss-library-example": {
67
+ "root": "./node_modules/@react-native/oss-library-example",
68
+ "name": "@react-native/oss-library-example",
69
+ "platforms": {
70
+ "ios": {
71
+ "podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
72
+ "version": "0.0.1",
73
+ "configurations": [],
74
+ "scriptPhases": []
75
+ },
76
+ "android": {
77
+ "sourceDir": "./node_modules/@react-native/oss-library-example/android",
78
+ "packageImportPath": "import com.facebook.react.osslibraryexample.OSSLibraryExamplePackage;",
79
+ "packageInstance": "new OSSLibraryExamplePackage()",
80
+ "buildTypes": ["staging", "debug", "release"],
81
+ "libraryName": "OSSLibraryExampleSpec",
82
+ "componentDescriptors": [
83
+ "SampleNativeComponentComponentDescriptor"
84
+ ],
85
+ "cmakeListsPath": "./node_modules/@react-native/oss-library-example/android/build/generated/source/codegen/jni/CMakeLists.txt",
86
+ "cxxModuleCMakeListsModuleName": null,
87
+ "cxxModuleCMakeListsPath": null,
88
+ "cxxModuleHeaderName": null,
89
+ "dependencyConfiguration": "implementation",
90
+ "isPureCxxDependency": false
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+ """
97
+ .trimIndent()
98
+ )
99
+
100
+ val map = getLibrariesToAutolink(validJsonFile)
101
+ assertThat(map.keys).containsExactly(":react-native_oss-library-example")
102
+ assertThat(map[":react-native_oss-library-example"])
103
+ .isEqualTo(File("./node_modules/@react-native/oss-library-example/android"))
104
+ }
105
+
106
+ @Test
107
+ fun getLibrariesToAutolink_withiOSOnlyLibrary_returnsEmptyMap() {
108
+ val validJsonFile =
109
+ createJsonFile(
110
+ """
111
+ {
112
+ "reactNativeVersion": "1000.0.0",
113
+ "dependencies": {
114
+ "@react-native/oss-library-example": {
115
+ "root": "./node_modules/@react-native/oss-library-example",
116
+ "name": "@react-native/oss-library-example",
117
+ "platforms": {
118
+ "ios": {
119
+ "podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
120
+ "version": "0.0.1",
121
+ "configurations": [],
122
+ "scriptPhases": []
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ """
129
+ .trimIndent()
130
+ )
131
+
132
+ val map = getLibrariesToAutolink(validJsonFile)
133
+ assertThat(map.keys).isEmpty()
134
+ }
135
+
136
+ @Test
137
+ fun checkAndUpdateLockfiles_withNothingToCheck_returnsFalse() {
138
+ val project = ProjectBuilder.builder().build()
139
+ val noFiles = project.files()
140
+ assertThat(checkAndUpdateLockfiles(noFiles, tempFolder.root)).isFalse()
141
+ }
142
+
143
+ @Test
144
+ fun checkAndUpdateLockfiles_withOneLockfileNoHash_returnsTrue() {
145
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
146
+ val buildFolder = tempFolder.newFolder("build")
147
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
148
+ val lockfileCollection = project.files("yarn.lock")
149
+
150
+ assertThat(checkAndUpdateLockfiles(lockfileCollection, buildFolder)).isTrue()
151
+ assertThat(File(buildFolder, "yarn.lock.sha").exists()).isTrue()
152
+ assertThat(File(buildFolder, "yarn.lock.sha").readText())
153
+ .isEqualTo("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
154
+ }
155
+
156
+ @Test
157
+ fun checkAndUpdateLockfiles_withOneLockfileInvalidHash_returnsTrue() {
158
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
159
+ val buildFolder =
160
+ tempFolder.newFolder("build").apply {
161
+ File(this, "yarn.lock.sha").writeText("Just a stale hash")
162
+ }
163
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
164
+ val lockfileCollection = project.files("yarn.lock")
165
+
166
+ assertThat(checkAndUpdateLockfiles(lockfileCollection, buildFolder)).isTrue()
167
+ assertThat(File(buildFolder, "yarn.lock.sha").exists()).isTrue()
168
+ assertThat(File(buildFolder, "yarn.lock.sha").readText())
169
+ .isEqualTo("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
170
+ }
171
+
172
+ @Test
173
+ fun checkAndUpdateLockfiles_withOneLockfileValidHash_returnsFalse() {
174
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
175
+ val buildFolder =
176
+ tempFolder.newFolder("build").apply {
177
+ File(this, "yarn.lock.sha")
178
+ .writeText("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
179
+ }
180
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
181
+ val lockfileCollection = project.files("yarn.lock")
182
+
183
+ assertThat(checkAndUpdateLockfiles(lockfileCollection, buildFolder)).isFalse()
184
+ assertThat(File(buildFolder, "yarn.lock.sha").exists()).isTrue()
185
+ assertThat(File(buildFolder, "yarn.lock.sha").readText())
186
+ .isEqualTo("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
187
+ }
188
+
189
+ @Test
190
+ fun checkAndUpdateLockfiles_withMultipleLockfilesInvalidHash_returnsTrue() {
191
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
192
+ val buildFolder =
193
+ tempFolder.newFolder("build").apply {
194
+ File(this, "yarn.lock.sha").writeText("I'm an invalid hash")
195
+ }
196
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
197
+ tempFolder.newFile("package-lock.json").apply { writeText("and I'm another lockfile") }
198
+ val lockfileCollection = project.files("yarn.lock", "package-lock.json")
199
+
200
+ assertThat(checkAndUpdateLockfiles(lockfileCollection, buildFolder)).isTrue()
201
+ assertThat(File(buildFolder, "yarn.lock.sha").exists()).isTrue()
202
+ assertThat(File(buildFolder, "package-lock.json.sha").exists()).isTrue()
203
+ assertThat(File(buildFolder, "yarn.lock.sha").readText())
204
+ .isEqualTo("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
205
+ assertThat(File(buildFolder, "package-lock.json.sha").readText())
206
+ .isEqualTo("9be5bca432b81becf4f54451aea021add68376330581eaa93ab9a0b3e4e29a3b")
207
+ }
208
+
209
+ @Test
210
+ fun checkAndUpdateLockfiles_withMultipleLockfilesValidHash_returnsFalse() {
211
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
212
+ val buildFolder =
213
+ tempFolder.newFolder("build").apply {
214
+ File(this, "yarn.lock.sha")
215
+ .writeText("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
216
+ File(this, "package-lock.json.sha")
217
+ .writeText("9be5bca432b81becf4f54451aea021add68376330581eaa93ab9a0b3e4e29a3b")
218
+ }
219
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
220
+ tempFolder.newFile("package-lock.json").apply { writeText("and I'm another lockfile") }
221
+ val lockfileCollection = project.files("yarn.lock", "package-lock.json")
222
+
223
+ assertThat(checkAndUpdateLockfiles(lockfileCollection, buildFolder)).isFalse()
224
+ assertThat(File(buildFolder, "yarn.lock.sha").exists()).isTrue()
225
+ assertThat(File(buildFolder, "package-lock.json.sha").exists()).isTrue()
226
+ assertThat(File(buildFolder, "yarn.lock.sha").readText())
227
+ .isEqualTo("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
228
+ assertThat(File(buildFolder, "package-lock.json.sha").readText())
229
+ .isEqualTo("9be5bca432b81becf4f54451aea021add68376330581eaa93ab9a0b3e4e29a3b")
230
+ }
231
+
232
+ @Test
233
+ fun skipUpdateIfConfigInCacheIsValid() {
234
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
235
+ val buildFolder = tempFolder.newFolder("build")
236
+ val generatedFolder = tempFolder.newFolder("build", "generated")
237
+ val outputFile =
238
+ File(generatedFolder, "autolinking.json").apply {
239
+ writeText(
240
+ """
241
+ {
242
+ "root": "/",
243
+ "reactNativePath": "/node_modules/react-native",
244
+ "reactNativeVersion": "0.75",
245
+ "dependencies": {},
246
+ "healthChecks": [],
247
+ "platforms": {
248
+ "ios": {},
249
+ "android": {}
250
+ },
251
+ "assets": [],
252
+ "project": {
253
+ "ios": {},
254
+ "android": {
255
+ "sourceDir": "/",
256
+ "appName": "app",
257
+ "packageName": "com.TestApp",
258
+ "applicationId": "com.TestApp",
259
+ "mainActivity": ".MainActivity",
260
+ "assets": []
261
+ }
262
+ }
263
+ }
264
+ """
265
+ .trimIndent()
266
+ )
267
+ }
268
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
269
+ val lockfileCollection = project.files("yarn.lock")
270
+
271
+ // Prebuild the shas with the invalid empty autolinking.json
272
+ checkAndUpdateLockfiles(lockfileCollection, buildFolder)
273
+
274
+ val monitoredUpdateConfig = createMonitoredUpdateConfig()
275
+
276
+ checkAndUpdateCache(monitoredUpdateConfig, outputFile, buildFolder, lockfileCollection)
277
+
278
+ // The autolinking.json file is valid, SHA's are untouched therefore config should NOT be
279
+ // refreshed
280
+ assertThat(monitoredUpdateConfig.run).isFalse()
281
+ }
282
+
283
+ @Test
284
+ fun checkAndUpdateConfigIfEmpty() {
285
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
286
+ val buildFolder = tempFolder.newFolder("build")
287
+ val generatedFolder = tempFolder.newFolder("build", "generated")
288
+ val outputFile = File(generatedFolder, "autolinking.json").apply { writeText("") }
289
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
290
+ val lockfileCollection = project.files("yarn.lock")
291
+
292
+ // Prebuild the shas with the invalid empty autolinking.json
293
+ checkAndUpdateLockfiles(lockfileCollection, buildFolder)
294
+
295
+ val monitoredUpdateConfig = createMonitoredUpdateConfig()
296
+
297
+ checkAndUpdateCache(monitoredUpdateConfig, outputFile, buildFolder, lockfileCollection)
298
+
299
+ // The autolinking.json file is invalid and should be refreshed
300
+ assertThat(monitoredUpdateConfig.run).isTrue()
301
+ }
302
+
303
+ @Test
304
+ fun checkAndUpdateConfigIfCachedConfigInvalid() {
305
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
306
+ val buildFolder = tempFolder.newFolder("build")
307
+ val generatedFolder = tempFolder.newFolder("build", "generated")
308
+ val outputFile =
309
+ File(generatedFolder, "autolinking.json").apply {
310
+ writeText(
311
+ """
312
+ {
313
+ "project": {
314
+ "ios": {},
315
+ "android": {}
316
+ }
317
+ }
318
+ """
319
+ .trimIndent()
320
+ )
321
+ }
322
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
323
+ val lockfileCollection = project.files("yarn.lock")
324
+
325
+ // Prebuild the shas with the invalid empty autolinking.json
326
+ checkAndUpdateLockfiles(lockfileCollection, buildFolder)
327
+
328
+ val monitoredUpdateConfig = createMonitoredUpdateConfig()
329
+
330
+ checkAndUpdateCache(monitoredUpdateConfig, outputFile, buildFolder, lockfileCollection)
331
+
332
+ // The autolinking.json file is invalid and should be refreshed
333
+ assertThat(monitoredUpdateConfig.run).isTrue()
334
+ }
335
+
336
+ @Test
337
+ fun isCacheDirty_withMissingAutolinkingFile_returnsTrue() {
338
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
339
+ val buildFolder =
340
+ tempFolder.newFolder("build").apply {
341
+ File(this, "yarn.lock.sha")
342
+ .writeText("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
343
+ }
344
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
345
+ val lockfiles = project.files("yarn.lock")
346
+ val emptyConfigFile = File(tempFolder.newFolder("build", "autolinking"), "autolinking.json")
347
+
348
+ assertThat(ReactSettingsExtension.isCacheDirty(emptyConfigFile, buildFolder, lockfiles))
349
+ .isTrue()
350
+ }
351
+
352
+ @Test
353
+ fun isCacheDirty_withInvalidAutolinkingFile_returnsTrue() {
354
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
355
+ val buildFolder =
356
+ tempFolder.newFolder("build").apply {
357
+ File(this, "yarn.lock.sha")
358
+ .writeText("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
359
+ }
360
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
361
+ val lockfiles = project.files("yarn.lock")
362
+ val invalidConfigFile =
363
+ createJsonFile(
364
+ """
365
+ {}
366
+ """
367
+ .trimIndent()
368
+ )
369
+
370
+ assertThat(ReactSettingsExtension.isCacheDirty(invalidConfigFile, buildFolder, lockfiles))
371
+ .isTrue()
372
+ }
373
+
374
+ @Test
375
+ fun isCacheDirty_withMissingDependenciesInJson_returnsFalse() {
376
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
377
+ val buildFolder =
378
+ tempFolder.newFolder("build").apply {
379
+ File(this, "yarn.lock.sha")
380
+ .writeText("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
381
+ }
382
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
383
+ val lockfiles = project.files("yarn.lock")
384
+ val invalidConfigFile =
385
+ createJsonFile(
386
+ """
387
+ {
388
+ "reactNativeVersion": "1000.0.0"
389
+ }
390
+ """
391
+ .trimIndent()
392
+ )
393
+
394
+ assertThat(ReactSettingsExtension.isCacheDirty(invalidConfigFile, buildFolder, lockfiles))
395
+ .isTrue()
396
+ }
397
+
398
+ @Test
399
+ fun isCacheDirty_withExistingEmptyDependenciesInJson_returnsTrue() {
400
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
401
+ val buildFolder =
402
+ tempFolder.newFolder("build").apply {
403
+ File(this, "yarn.lock.sha")
404
+ .writeText("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
405
+ }
406
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
407
+ val lockfiles = project.files("yarn.lock")
408
+ val invalidConfigFile =
409
+ createJsonFile(
410
+ """
411
+ {
412
+ "reactNativeVersion": "1000.0.0",
413
+ "dependencies": {}
414
+ }
415
+ """
416
+ .trimIndent()
417
+ )
418
+
419
+ assertThat(ReactSettingsExtension.isCacheDirty(invalidConfigFile, buildFolder, lockfiles))
420
+ .isTrue()
421
+ }
422
+
423
+ @Test
424
+ fun isCacheDirty_withExistingDependenciesInJson_returnsTrue() {
425
+ val project = ProjectBuilder.builder().withProjectDir(tempFolder.root).build()
426
+ val buildFolder =
427
+ tempFolder.newFolder("build").apply {
428
+ File(this, "yarn.lock.sha")
429
+ .writeText("76046b72442ee7eb130627e56c3db7c9907eef4913b17ad130335edc0eb702a8")
430
+ }
431
+ tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
432
+ val lockfiles = project.files("yarn.lock")
433
+ val invalidConfigFile =
434
+ createJsonFile(
435
+ """
436
+ {
437
+ "reactNativeVersion": "1000.0.0",
438
+ "dependencies": {
439
+ "@react-native/oss-library-example": {
440
+ "root": "./node_modules/@react-native/oss-library-example",
441
+ "name": "@react-native/oss-library-example",
442
+ "platforms": {
443
+ "ios": {
444
+ "podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
445
+ "version": "0.0.1",
446
+ "configurations": [],
447
+ "scriptPhases": []
448
+ }
449
+ }
450
+ }
451
+ }
452
+ }
453
+ """
454
+ .trimIndent()
455
+ )
456
+
457
+ assertThat(ReactSettingsExtension.isCacheDirty(invalidConfigFile, buildFolder, lockfiles))
458
+ .isTrue()
459
+ }
460
+
461
+ private fun createJsonFile(@Language("JSON") input: String) =
462
+ tempFolder.newFile().apply { writeText(input) }
463
+
464
+ private fun createMonitoredUpdateConfig() =
465
+ object : GenerateConfig {
466
+ var run = false
467
+
468
+ override fun execute(): Int {
469
+ run = true
470
+ return 0
471
+ }
472
+
473
+ override fun command(): List<String> = listOf("true")
474
+ }
475
+ }
@@ -13,4 +13,13 @@ pluginManagement {
13
13
  }
14
14
  }
15
15
 
16
- rootProject.name = "react-native-gradle-plugin"
16
+ plugins { id("org.gradle.toolchains.foojay-resolver-convention").version("1.0.0") }
17
+
18
+ include(
19
+ ":react-native-gradle-plugin",
20
+ ":settings-plugin",
21
+ ":shared",
22
+ ":shared-testutil",
23
+ )
24
+
25
+ rootProject.name = "gradle-plugin-root"
@@ -0,0 +1,52 @@
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
+ import org.gradle.api.tasks.testing.logging.TestExceptionFormat
9
+ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
10
+ import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
11
+ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
12
+
13
+ plugins {
14
+ alias(libs.plugins.kotlin.jvm)
15
+ alias(libs.plugins.ktfmt)
16
+ }
17
+
18
+ repositories { mavenCentral() }
19
+
20
+ group = "com.facebook.react"
21
+
22
+ dependencies {
23
+ implementation(libs.gson)
24
+ implementation(libs.guava)
25
+ testImplementation(libs.junit)
26
+ testImplementation(libs.assertj)
27
+ testImplementation(project(":shared-testutil"))
28
+ }
29
+
30
+ java { targetCompatibility = JavaVersion.VERSION_11 }
31
+
32
+ kotlin { jvmToolchain(26) }
33
+
34
+ tasks.withType<KotlinCompile>().configureEach {
35
+ compilerOptions {
36
+ apiVersion.set(KotlinVersion.KOTLIN_1_8)
37
+ // See comment above on JDK 11 support
38
+ jvmTarget.set(JvmTarget.JVM_11)
39
+ allWarningsAsErrors.set(
40
+ project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false
41
+ )
42
+ }
43
+ }
44
+
45
+ tasks.withType<Test>().configureEach {
46
+ testLogging {
47
+ exceptionFormat = TestExceptionFormat.FULL
48
+ showExceptions = true
49
+ showCauses = true
50
+ showStackTraces = true
51
+ }
52
+ }
@@ -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
+ )
@@ -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
+ )
@@ -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
+ }
@@ -0,0 +1,23 @@
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? = null,
16
+ val componentDescriptors: List<String> = emptyList(),
17
+ val cmakeListsPath: String? = null,
18
+ val cxxModuleCMakeListsModuleName: String? = null,
19
+ val cxxModuleCMakeListsPath: String? = null,
20
+ val cxxModuleHeaderName: String? = null,
21
+ val dependencyConfiguration: String? = null,
22
+ val isPureCxxDependency: Boolean? = null,
23
+ )
@@ -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
+ )
@@ -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?)
@@ -11,5 +11,6 @@ data class ModelCodegenConfig(
11
11
  val name: String?,
12
12
  val type: String?,
13
13
  val jsSrcsDir: String?,
14
- val android: ModelCodegenConfigAndroid?
14
+ val android: ModelCodegenConfigAndroid?,
15
+ val includesGeneratedCode: Boolean?,
15
16
  )
@@ -7,4 +7,4 @@
7
7
 
8
8
  package com.facebook.react.model
9
9
 
10
- data class ModelPackageJson(val codegenConfig: ModelCodegenConfig?)
10
+ data class ModelPackageJson(val version: String, val codegenConfig: ModelCodegenConfig?)