@react-native/gradle-plugin 0.72.2 → 0.72.3

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.
package/build.gradle.kts CHANGED
@@ -33,7 +33,7 @@ group = "com.facebook.react"
33
33
 
34
34
  dependencies {
35
35
  implementation(gradleApi())
36
- implementation("com.android.tools.build:gradle:7.4.0-beta05")
36
+ implementation("com.android.tools.build:gradle:7.4.1")
37
37
  implementation("com.google.code.gson:gson:2.8.9")
38
38
  implementation("com.google.guava:guava:31.0.1-jre")
39
39
  implementation("com.squareup:javapoet:1.13.0")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native/gradle-plugin",
3
- "version": "0.72.2",
3
+ "version": "0.72.3",
4
4
  "description": "⚛️ Gradle Plugin for React Native",
5
5
  "homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-gradle-plugin",
6
6
  "repository": {
@@ -89,7 +89,7 @@ abstract class ReactExtension @Inject constructor(project: Project) {
89
89
  * will:
90
90
  * - Not be bundled (the bundle file will not be created and won't be copied over).
91
91
  * - Have the Hermes Debug flags set. That's useful if you have another variant (say `canary`)
92
- * where you want dev mode to be enabled. Default: ['debug']
92
+ * where you want dev mode to be enabled. Default: ['debug']
93
93
  */
94
94
  val debuggableVariants: ListProperty<String> =
95
95
  objects.listProperty(String::class.java).convention(listOf("debug"))
@@ -129,9 +129,9 @@ abstract class ReactExtension @Inject constructor(project: Project) {
129
129
  /**
130
130
  * The root directory for all JS files for the app.
131
131
  *
132
- * Default: [root] (i.e. ${rootProject.dir}/../)
132
+ * Default: the parent folder of the `/android` folder.
133
133
  */
134
- val jsRootDir: DirectoryProperty = objects.directoryProperty().convention(root.get())
134
+ val jsRootDir: DirectoryProperty = objects.directoryProperty()
135
135
 
136
136
  /**
137
137
  * The library name that will be used for the codegen artifacts.
@@ -9,6 +9,7 @@ package com.facebook.react
9
9
 
10
10
  import com.android.build.api.variant.AndroidComponentsExtension
11
11
  import com.android.build.gradle.internal.tasks.factory.dependsOn
12
+ import com.facebook.react.internal.PrivateReactExtension
12
13
  import com.facebook.react.tasks.BuildCodegenCLITask
13
14
  import com.facebook.react.tasks.GenerateCodegenArtifactsTask
14
15
  import com.facebook.react.tasks.GenerateCodegenSchemaTask
@@ -34,8 +35,22 @@ class ReactPlugin : Plugin<Project> {
34
35
  checkJvmVersion(project)
35
36
  val extension = project.extensions.create("react", ReactExtension::class.java, project)
36
37
 
38
+ // We register a private extension on the rootProject so that project wide configs
39
+ // like codegen config can be propagated from app project to libraries.
40
+ val rootExtension =
41
+ project.rootProject.extensions.findByType(PrivateReactExtension::class.java)
42
+ ?: project.rootProject.extensions.create(
43
+ "privateReact", PrivateReactExtension::class.java, project)
44
+
37
45
  // App Only Configuration
38
46
  project.pluginManager.withPlugin("com.android.application") {
47
+ // We wire the root extension with the values coming from the app (either user populated or
48
+ // defaults).
49
+ rootExtension.root.set(extension.root)
50
+ rootExtension.reactNativeDir.set(extension.reactNativeDir)
51
+ rootExtension.codegenDir.set(extension.codegenDir)
52
+ rootExtension.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs)
53
+
39
54
  project.afterEvaluate {
40
55
  val reactNativeDir = extension.reactNativeDir.get().asFile
41
56
  val propertiesFile = File(reactNativeDir, "ReactAndroid/gradle.properties")
@@ -54,12 +69,12 @@ class ReactPlugin : Plugin<Project> {
54
69
  project.configureReactTasks(variant = variant, config = extension)
55
70
  }
56
71
  }
57
- configureCodegen(project, extension, isLibrary = false)
72
+ configureCodegen(project, extension, rootExtension, isLibrary = false)
58
73
  }
59
74
 
60
75
  // Library Only Configuration
61
76
  project.pluginManager.withPlugin("com.android.library") {
62
- configureCodegen(project, extension, isLibrary = true)
77
+ configureCodegen(project, extension, rootExtension, isLibrary = true)
63
78
  }
64
79
  }
65
80
 
@@ -82,25 +97,36 @@ class ReactPlugin : Plugin<Project> {
82
97
  }
83
98
  }
84
99
 
85
- /**
86
- * A plugin to enable react-native-codegen in Gradle environment. See the Gradle API docs for more
87
- * information: https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html
88
- */
100
+ /** This function sets up `react-native-codegen` in our Gradle plugin. */
89
101
  @Suppress("UnstableApiUsage")
90
- private fun configureCodegen(project: Project, extension: ReactExtension, isLibrary: Boolean) {
102
+ private fun configureCodegen(
103
+ project: Project,
104
+ localExtension: ReactExtension,
105
+ rootExtension: PrivateReactExtension,
106
+ isLibrary: Boolean
107
+ ) {
91
108
  // First, we set up the output dir for the codegen.
92
109
  val generatedSrcDir = File(project.buildDir, "generated/source/codegen")
93
110
 
111
+ // We specify the default value (convention) for jsRootDir.
112
+ // It's the root folder for apps (so ../../ from the Gradle project)
113
+ // and the package folder for library (so ../ from the Gradle project)
114
+ if (isLibrary) {
115
+ localExtension.jsRootDir.convention(project.layout.projectDirectory.dir("../"))
116
+ } else {
117
+ localExtension.jsRootDir.convention(localExtension.root)
118
+ }
119
+
94
120
  val buildCodegenTask =
95
121
  project.tasks.register("buildCodegenCLI", BuildCodegenCLITask::class.java) {
96
- it.codegenDir.set(extension.codegenDir)
122
+ it.codegenDir.set(rootExtension.codegenDir)
97
123
  val bashWindowsHome = project.findProperty("REACT_WINDOWS_BASH") as String?
98
124
  it.bashWindowsHome.set(bashWindowsHome)
99
125
 
100
126
  // Please note that appNeedsCodegen is triggering a read of the package.json at
101
127
  // configuration time as we need to feed the onlyIf condition of this task.
102
128
  // Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
103
- val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension)
129
+ val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(rootExtension.root)
104
130
  it.onlyIf { isLibrary || needsCodegenFromPackageJson }
105
131
  }
106
132
 
@@ -109,23 +135,24 @@ class ReactPlugin : Plugin<Project> {
109
135
  project.tasks.register(
110
136
  "generateCodegenSchemaFromJavaScript", GenerateCodegenSchemaTask::class.java) { it ->
111
137
  it.dependsOn(buildCodegenTask)
112
- it.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs)
113
- it.codegenDir.set(extension.codegenDir)
138
+ it.nodeExecutableAndArgs.set(rootExtension.nodeExecutableAndArgs)
139
+ it.codegenDir.set(rootExtension.codegenDir)
114
140
  it.generatedSrcDir.set(generatedSrcDir)
115
141
 
116
142
  // We're reading the package.json at configuration time to properly feed
117
143
  // the `jsRootDir` @Input property of this task & the onlyIf. Therefore, the
118
144
  // parsePackageJson should be invoked inside this lambda.
119
- val packageJson = findPackageJsonFile(project, extension)
145
+ val packageJson = findPackageJsonFile(project, rootExtension.root)
120
146
  val parsedPackageJson = packageJson?.let { JsonUtils.fromCodegenJson(it) }
121
147
 
122
148
  val jsSrcsDirInPackageJson = parsedPackageJson?.codegenConfig?.jsSrcsDir
123
149
  if (jsSrcsDirInPackageJson != null) {
124
150
  it.jsRootDir.set(File(packageJson.parentFile, jsSrcsDirInPackageJson))
125
151
  } else {
126
- it.jsRootDir.set(extension.jsRootDir)
152
+ it.jsRootDir.set(localExtension.jsRootDir)
127
153
  }
128
- val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension)
154
+ val needsCodegenFromPackageJson =
155
+ project.needsCodegenFromPackageJson(rootExtension.root)
129
156
  it.onlyIf { isLibrary || needsCodegenFromPackageJson }
130
157
  }
131
158
 
@@ -134,17 +161,18 @@ class ReactPlugin : Plugin<Project> {
134
161
  project.tasks.register(
135
162
  "generateCodegenArtifactsFromSchema", GenerateCodegenArtifactsTask::class.java) {
136
163
  it.dependsOn(generateCodegenSchemaTask)
137
- it.reactNativeDir.set(extension.reactNativeDir)
138
- it.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs)
164
+ it.reactNativeDir.set(rootExtension.reactNativeDir)
165
+ it.nodeExecutableAndArgs.set(rootExtension.nodeExecutableAndArgs)
139
166
  it.generatedSrcDir.set(generatedSrcDir)
140
- it.packageJsonFile.set(findPackageJsonFile(project, extension))
141
- it.codegenJavaPackageName.set(extension.codegenJavaPackageName)
142
- it.libraryName.set(extension.libraryName)
167
+ it.packageJsonFile.set(findPackageJsonFile(project, rootExtension.root))
168
+ it.codegenJavaPackageName.set(localExtension.codegenJavaPackageName)
169
+ it.libraryName.set(localExtension.libraryName)
143
170
 
144
171
  // Please note that appNeedsCodegen is triggering a read of the package.json at
145
172
  // configuration time as we need to feed the onlyIf condition of this task.
146
173
  // Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
147
- val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension)
174
+ val needsCodegenFromPackageJson =
175
+ project.needsCodegenFromPackageJson(rootExtension.root)
148
176
  it.onlyIf { isLibrary || needsCodegenFromPackageJson }
149
177
  }
150
178
 
@@ -22,14 +22,16 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
22
22
  val targetName = variant.name.replaceFirstChar { it.uppercase() }
23
23
  val targetPath = variant.name
24
24
 
25
- // React js bundle directories
25
+ // Resources: generated/assets/react/<variant>/index.android.bundle
26
26
  val resourcesDir = File(buildDir, "generated/res/react/$targetPath")
27
- // Bundle: generated/assets/react/path/index.android.bundle
27
+ // Bundle: generated/assets/react/<variant>/index.android.bundle
28
28
  val jsBundleDir = File(buildDir, "generated/assets/react/$targetPath")
29
- // Sourcemap: generated/sourcemaps/react/path/index.android.bundle.map
29
+ // Sourcemap: generated/sourcemaps/react/<variant>/index.android.bundle.map
30
30
  val jsSourceMapsDir = File(buildDir, "generated/sourcemaps/react/$targetPath")
31
- // Intermediate packager: intermediates/sourcemaps/react/path/index.android.bundle.packager.map
32
- // Intermediate compiler: intermediates/sourcemaps/react/path/index.android.bundle.compiler.map
31
+ // Intermediate packager:
32
+ // intermediates/sourcemaps/react/<variant>/index.android.bundle.packager.map
33
+ // Intermediate compiler:
34
+ // intermediates/sourcemaps/react/<variant>/index.android.bundle.compiler.map
33
35
  val jsIntermediateSourceMapsDir = File(buildDir, "intermediates/sourcemaps/react/$targetPath")
34
36
 
35
37
  // The location of the cli.js file for React Native
@@ -0,0 +1,35 @@
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.internal
9
+
10
+ import javax.inject.Inject
11
+ import org.gradle.api.Project
12
+ import org.gradle.api.file.DirectoryProperty
13
+ import org.gradle.api.provider.ListProperty
14
+
15
+ /**
16
+ * A private extension we set on the rootProject to make easier to share values at execution time
17
+ * between app project and library project.
18
+ *
19
+ * Specifically, the [codegenDir], [reactNativeDir] and other properties should be provided by apps
20
+ * (for setups like a monorepo which are app specific) and libraries should honor those values.
21
+ *
22
+ * Users are not supposed to access directly this extension from their build.gradle file.
23
+ */
24
+ abstract class PrivateReactExtension @Inject constructor(project: Project) {
25
+
26
+ private val objects = project.objects
27
+
28
+ val root: DirectoryProperty = objects.directoryProperty()
29
+
30
+ val reactNativeDir: DirectoryProperty = objects.directoryProperty()
31
+
32
+ val nodeExecutableAndArgs: ListProperty<String> = objects.listProperty(String::class.java)
33
+
34
+ val codegenDir: DirectoryProperty = objects.directoryProperty()
35
+ }
@@ -7,6 +7,7 @@
7
7
 
8
8
  package com.facebook.react.tasks
9
9
 
10
+ import com.facebook.react.utils.Os.cliPath
10
11
  import com.facebook.react.utils.detectOSAwareHermesCommand
11
12
  import com.facebook.react.utils.moveTo
12
13
  import com.facebook.react.utils.windowsAwareCommandLine
@@ -135,8 +136,9 @@ abstract class BundleHermesCTask : DefaultTask() {
135
136
  internal fun getBundleCommand(bundleFile: File, sourceMapFile: File): List<Any> =
136
137
  windowsAwareCommandLine(
137
138
  buildList {
139
+ val rootFile = root.get().asFile
138
140
  addAll(nodeExecutableAndArgs.get())
139
- add(cliFile.get().asFile.absolutePath)
141
+ add(cliFile.get().asFile.cliPath(rootFile))
140
142
  add(bundleCommand.get())
141
143
  add("--platform")
142
144
  add("android")
@@ -144,16 +146,16 @@ abstract class BundleHermesCTask : DefaultTask() {
144
146
  add(devEnabled.get().toString())
145
147
  add("--reset-cache")
146
148
  add("--entry-file")
147
- add(entryFile.get().asFile.toString())
149
+ add(entryFile.get().asFile.cliPath(rootFile))
148
150
  add("--bundle-output")
149
- add(bundleFile.toString())
151
+ add(bundleFile.cliPath(rootFile))
150
152
  add("--assets-dest")
151
- add(resourcesDir.get().asFile.toString())
153
+ add(resourcesDir.get().asFile.cliPath(rootFile))
152
154
  add("--sourcemap-output")
153
- add(sourceMapFile.toString())
155
+ add(sourceMapFile.cliPath(rootFile))
154
156
  if (bundleConfig.isPresent) {
155
157
  add("--config")
156
- add(bundleConfig.get().asFile.absolutePath)
158
+ add(bundleConfig.get().asFile.cliPath(rootFile))
157
159
  }
158
160
  add("--minify")
159
161
  add(minifyEnabled.get().toString())
@@ -165,26 +167,30 @@ abstract class BundleHermesCTask : DefaultTask() {
165
167
  hermesCommand: String,
166
168
  bytecodeFile: File,
167
169
  bundleFile: File
168
- ): List<Any> =
169
- windowsAwareCommandLine(
170
- hermesCommand,
171
- "-emit-binary",
172
- "-out",
173
- bytecodeFile.absolutePath,
174
- bundleFile.absolutePath,
175
- *hermesFlags.get().toTypedArray())
170
+ ): List<Any> {
171
+ val rootFile = root.get().asFile
172
+ return windowsAwareCommandLine(
173
+ hermesCommand,
174
+ "-emit-binary",
175
+ "-out",
176
+ bytecodeFile.cliPath(rootFile),
177
+ bundleFile.cliPath(rootFile),
178
+ *hermesFlags.get().toTypedArray())
179
+ }
176
180
 
177
181
  internal fun getComposeSourceMapsCommand(
178
182
  composeScript: File,
179
183
  packagerSourceMap: File,
180
184
  compilerSourceMap: File,
181
185
  outputSourceMap: File
182
- ): List<Any> =
183
- windowsAwareCommandLine(
184
- *nodeExecutableAndArgs.get().toTypedArray(),
185
- composeScript.absolutePath,
186
- packagerSourceMap.toString(),
187
- compilerSourceMap.toString(),
188
- "-o",
189
- outputSourceMap.toString())
186
+ ): List<Any> {
187
+ val rootFile = root.get().asFile
188
+ return windowsAwareCommandLine(
189
+ *nodeExecutableAndArgs.get().toTypedArray(),
190
+ composeScript.cliPath(rootFile),
191
+ packagerSourceMap.cliPath(rootFile),
192
+ compilerSourceMap.cliPath(rootFile),
193
+ "-o",
194
+ outputSourceMap.cliPath(rootFile))
195
+ }
190
196
  }
@@ -8,6 +8,7 @@
8
8
  package com.facebook.react.tasks
9
9
 
10
10
  import com.facebook.react.utils.JsonUtils
11
+ import com.facebook.react.utils.Os.cliPath
11
12
  import com.facebook.react.utils.windowsAwareCommandLine
12
13
  import org.gradle.api.file.Directory
13
14
  import org.gradle.api.file.DirectoryProperty
@@ -63,16 +64,17 @@ abstract class GenerateCodegenArtifactsTask : Exec() {
63
64
  }
64
65
 
65
66
  internal fun setupCommandLine(libraryName: String, codegenJavaPackageName: String) {
67
+ val workingDir = project.projectDir
66
68
  commandLine(
67
69
  windowsAwareCommandLine(
68
70
  *nodeExecutableAndArgs.get().toTypedArray(),
69
- reactNativeDir.file("scripts/generate-specs-cli.js").get().asFile.absolutePath,
71
+ reactNativeDir.file("scripts/generate-specs-cli.js").get().asFile.cliPath(workingDir),
70
72
  "--platform",
71
73
  "android",
72
74
  "--schemaPath",
73
- generatedSchemaFile.get().asFile.absolutePath,
75
+ generatedSchemaFile.get().asFile.cliPath(workingDir),
74
76
  "--outputDir",
75
- generatedSrcDir.get().asFile.absolutePath,
77
+ generatedSrcDir.get().asFile.cliPath(workingDir),
76
78
  "--libraryName",
77
79
  libraryName,
78
80
  "--javaPackageName",
@@ -7,6 +7,7 @@
7
7
 
8
8
  package com.facebook.react.tasks
9
9
 
10
+ import com.facebook.react.utils.Os.cliPath
10
11
  import com.facebook.react.utils.windowsAwareCommandLine
11
12
  import org.gradle.api.file.DirectoryProperty
12
13
  import org.gradle.api.file.RegularFile
@@ -63,6 +64,7 @@ abstract class GenerateCodegenSchemaTask : Exec() {
63
64
  }
64
65
 
65
66
  internal fun setupCommandLine() {
67
+ val workingDir = project.projectDir
66
68
  commandLine(
67
69
  windowsAwareCommandLine(
68
70
  *nodeExecutableAndArgs.get().toTypedArray(),
@@ -70,11 +72,11 @@ abstract class GenerateCodegenSchemaTask : Exec() {
70
72
  .file("lib/cli/combine/combine-js-to-schema-cli.js")
71
73
  .get()
72
74
  .asFile
73
- .absolutePath,
75
+ .cliPath(workingDir),
74
76
  "--platform",
75
77
  "android",
76
- generatedSchemaFile.get().asFile.absolutePath,
77
- jsRootDir.asFile.get().absolutePath,
78
+ generatedSchemaFile.get().asFile.cliPath(workingDir),
79
+ jsRootDir.asFile.get().cliPath(workingDir),
78
80
  ))
79
81
  }
80
82
  }
@@ -11,10 +11,11 @@ import java.io.Serializable
11
11
 
12
12
  /**
13
13
  * This data class represents an entry that can be consumed by the [PreparePrefabHeadersTask].
14
+ *
14
15
  * @param libraryName The name of the library that you're preparing for Prefab
15
16
  * @param pathToPrefixCouples A list of pairs Path to Header prefix. You can use this list to supply
16
- * a list of paths that you want to be considered for prefab. Each path can specify an header prefix
17
- * that will be used by prefab to re-created the header layout.
17
+ * a list of paths that you want to be considered for prefab. Each path can specify an header
18
+ * prefix that will be used by prefab to re-created the header layout.
18
19
  */
19
20
  data class PrefabPreprocessingEntry(
20
21
  val libraryName: String,
@@ -10,6 +10,7 @@ package com.facebook.react.utils
10
10
  import com.android.build.api.variant.AndroidComponentsExtension
11
11
  import com.android.build.api.variant.Variant
12
12
  import com.facebook.react.ReactExtension
13
+ import com.facebook.react.utils.ProjectUtils.getReactNativeArchitectures
13
14
  import com.facebook.react.utils.ProjectUtils.isNewArchEnabled
14
15
  import java.io.File
15
16
  import org.gradle.api.Project
@@ -49,6 +50,13 @@ internal object NdkConfiguratorUtils {
49
50
  if ("-DANDROID_STL" !in cmakeArgs) {
50
51
  cmakeArgs.add("-DANDROID_STL=c++_shared")
51
52
  }
53
+
54
+ val architectures = project.getReactNativeArchitectures()
55
+ // abiFilters are split ABI are not compatible each other, so we set the abiFilters
56
+ // only if the user hasn't enabled the split abi feature.
57
+ if (architectures.isNotEmpty() && !ext.splits.abi.isEnable) {
58
+ ext.defaultConfig.ndk.abiFilters.addAll(architectures)
59
+ }
52
60
  }
53
61
  }
54
62
  }
@@ -7,7 +7,9 @@
7
7
 
8
8
  package com.facebook.react.utils
9
9
 
10
- object Os {
10
+ import java.io.File
11
+
12
+ internal object Os {
11
13
 
12
14
  fun isWindows(): Boolean =
13
15
  System.getProperty("os.name")?.lowercase()?.contains("windows") ?: false
@@ -28,4 +30,15 @@ object Os {
28
30
  it
29
31
  }
30
32
  }
33
+
34
+ /**
35
+ * As Gradle doesn't support well path with spaces on Windows, we need to return relative path on
36
+ * Win. On Linux & Mac we'll default to return absolute path.
37
+ */
38
+ fun File.cliPath(base: File): String =
39
+ if (isWindows()) {
40
+ this.relativeTo(base).path
41
+ } else {
42
+ this.absolutePath
43
+ }
31
44
  }
@@ -11,8 +11,10 @@ package com.facebook.react.utils
11
11
 
12
12
  import com.facebook.react.ReactExtension
13
13
  import com.facebook.react.model.ModelPackageJson
14
+ import com.facebook.react.utils.Os.cliPath
14
15
  import java.io.File
15
16
  import org.gradle.api.Project
17
+ import org.gradle.api.file.DirectoryProperty
16
18
 
17
19
  /**
18
20
  * Computes the entry file for React Native. The Algo follows this order:
@@ -43,10 +45,10 @@ internal fun detectedCliFile(config: ReactExtension): File =
43
45
  * Computes the `hermesc` command location. The Algo follows this order:
44
46
  * 1. The path provided by the `hermesCommand` config in the `react` Gradle extension
45
47
  * 2. The file located in `node_modules/react-native/sdks/hermes/build/bin/hermesc`. This will be
46
- * used if the user is building Hermes from source.
48
+ * used if the user is building Hermes from source.
47
49
  * 3. The file located in `node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc` where `%OS-BIN%`
48
- * is substituted with the correct OS arch. This will be used if the user is using a precompiled
49
- * hermes-engine package.
50
+ * is substituted with the correct OS arch. This will be used if the user is using a precompiled
51
+ * hermes-engine package.
50
52
  * 4. Fails otherwise
51
53
  */
52
54
  internal fun detectedHermesCommand(config: ReactExtension): String =
@@ -106,10 +108,10 @@ private fun detectCliFile(reactNativeRoot: File, preconfiguredCliFile: File?): F
106
108
  * Computes the `hermesc` command location. The Algo follows this order:
107
109
  * 1. The path provided by the `hermesCommand` config in the `react` Gradle extension
108
110
  * 2. The file located in `node_modules/react-native/sdks/hermes/build/bin/hermesc`. This will be
109
- * used if the user is building Hermes from source.
111
+ * used if the user is building Hermes from source.
110
112
  * 3. The file located in `node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc` where `%OS-BIN%`
111
- * is substituted with the correct OS arch. This will be used if the user is using a precompiled
112
- * hermes-engine package.
113
+ * is substituted with the correct OS arch. This will be used if the user is using a precompiled
114
+ * hermes-engine package.
113
115
  * 4. Fails otherwise
114
116
  */
115
117
  internal fun detectOSAwareHermesCommand(projectRoot: File, hermesCommand: String): String {
@@ -130,7 +132,7 @@ internal fun detectOSAwareHermesCommand(projectRoot: File, hermesCommand: String
130
132
  val builtHermesc =
131
133
  getBuiltHermescFile(projectRoot, System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR"))
132
134
  if (builtHermesc.exists()) {
133
- return builtHermesc.absolutePath
135
+ return builtHermesc.cliPath(projectRoot)
134
136
  }
135
137
 
136
138
  // 3. If the react-native contains a pre-built hermesc, use it.
@@ -142,7 +144,7 @@ internal fun detectOSAwareHermesCommand(projectRoot: File, hermesCommand: String
142
144
 
143
145
  val prebuiltHermes = File(projectRoot, prebuiltHermesPath)
144
146
  if (prebuiltHermes.exists()) {
145
- return prebuiltHermes.absolutePath
147
+ return prebuiltHermes.cliPath(projectRoot)
146
148
  }
147
149
 
148
150
  error(
@@ -188,13 +190,13 @@ internal fun projectPathToLibraryName(projectPath: String): String =
188
190
  * Gradle module (generally the case for library projects) or we fallback to looking into the `root`
189
191
  * folder of a React Native project (generally the case for app projects).
190
192
  */
191
- internal fun findPackageJsonFile(project: Project, extension: ReactExtension): File? {
193
+ internal fun findPackageJsonFile(project: Project, rootProperty: DirectoryProperty): File? {
192
194
  val inParent = project.file("../package.json")
193
195
  if (inParent.exists()) {
194
196
  return inParent
195
197
  }
196
198
 
197
- val fromExtension = extension.root.file("package.json").orNull?.asFile
199
+ val fromExtension = rootProperty.file("package.json").orNull?.asFile
198
200
  if (fromExtension?.exists() == true) {
199
201
  return fromExtension
200
202
  }
@@ -206,12 +208,15 @@ internal fun findPackageJsonFile(project: Project, extension: ReactExtension): F
206
208
  * Function to look for the `package.json` and parse it. It returns a [ModelPackageJson] if found or
207
209
  * null others.
208
210
  *
209
- * Please note that this function access the [ReactExtension] field properties and calls .get() on
210
- * them, so calling this during apply() of the ReactPlugin is not recommended. It should be invoked
211
- * inside lazy lambdas or at execution time.
211
+ * Please note that this function access the [DirectoryProperty] parameter and calls .get() on them,
212
+ * so calling this during apply() of the ReactPlugin is not recommended. It should be invoked inside
213
+ * lazy lambdas or at execution time.
212
214
  */
213
- internal fun readPackageJsonFile(project: Project, extension: ReactExtension): ModelPackageJson? {
214
- val packageJson = findPackageJsonFile(project, extension)
215
+ internal fun readPackageJsonFile(
216
+ project: Project,
217
+ rootProperty: DirectoryProperty
218
+ ): ModelPackageJson? {
219
+ val packageJson = findPackageJsonFile(project, rootProperty)
215
220
  return packageJson?.let { JsonUtils.fromCodegenJson(it) }
216
221
  }
217
222
 
@@ -7,9 +7,9 @@
7
7
 
8
8
  package com.facebook.react.utils
9
9
 
10
- import com.facebook.react.ReactExtension
11
10
  import com.facebook.react.model.ModelPackageJson
12
11
  import org.gradle.api.Project
12
+ import org.gradle.api.file.DirectoryProperty
13
13
 
14
14
  internal object ProjectUtils {
15
15
  internal val Project.isNewArchEnabled: Boolean
@@ -35,12 +35,21 @@ internal object ProjectUtils {
35
35
  HERMES_FALLBACK
36
36
  }
37
37
 
38
- internal fun Project.needsCodegenFromPackageJson(extension: ReactExtension): Boolean {
39
- val parsedPackageJson = readPackageJsonFile(this, extension)
38
+ internal fun Project.needsCodegenFromPackageJson(rootProperty: DirectoryProperty): Boolean {
39
+ val parsedPackageJson = readPackageJsonFile(this, rootProperty)
40
40
  return needsCodegenFromPackageJson(parsedPackageJson)
41
41
  }
42
42
 
43
43
  internal fun Project.needsCodegenFromPackageJson(model: ModelPackageJson?): Boolean {
44
44
  return model?.codegenConfig != null
45
45
  }
46
+
47
+ internal fun Project.getReactNativeArchitectures(): List<String> {
48
+ val architectures = mutableListOf<String>()
49
+ if (project.hasProperty("reactNativeArchitectures")) {
50
+ val architecturesString = project.property("reactNativeArchitectures").toString()
51
+ architectures.addAll(architecturesString.split(",").filter { it.isNotBlank() })
52
+ }
53
+ return architectures
54
+ }
46
55
  }