@react-native/gradle-plugin 0.72.2
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/README.md +16 -0
- package/build.gradle.kts +68 -0
- package/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/gradlew +234 -0
- package/gradlew.bat +89 -0
- package/package.json +28 -0
- package/settings.gradle.kts +16 -0
- package/src/main/kotlin/com/facebook/react/ReactExtension.kt +151 -0
- package/src/main/kotlin/com/facebook/react/ReactPlugin.kt +163 -0
- package/src/main/kotlin/com/facebook/react/TaskConfiguration.kt +76 -0
- package/src/main/kotlin/com/facebook/react/model/ModelCodegenConfig.kt +15 -0
- package/src/main/kotlin/com/facebook/react/model/ModelCodegenConfigAndroid.kt +10 -0
- package/src/main/kotlin/com/facebook/react/model/ModelPackageJson.kt +10 -0
- package/src/main/kotlin/com/facebook/react/tasks/BuildCodegenCLITask.kt +58 -0
- package/src/main/kotlin/com/facebook/react/tasks/BundleHermesCTask.kt +190 -0
- package/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt +81 -0
- package/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenSchemaTask.kt +80 -0
- package/src/main/kotlin/com/facebook/react/tasks/internal/PrepareBoostTask.kt +46 -0
- package/src/main/kotlin/com/facebook/react/tasks/internal/PrepareGlogTask.kt +79 -0
- package/src/main/kotlin/com/facebook/react/tasks/internal/PrepareJSCTask.kt +50 -0
- package/src/main/kotlin/com/facebook/react/tasks/internal/PrepareLibeventTask.kt +51 -0
- package/src/main/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTask.kt +62 -0
- package/src/main/kotlin/com/facebook/react/tasks/internal/utils/PrefabPreprocessingEntry.kt +27 -0
- package/src/main/kotlin/com/facebook/react/utils/AgpConfiguratorUtils.kt +54 -0
- package/src/main/kotlin/com/facebook/react/utils/BackwardCompatUtils.kt +48 -0
- package/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt +89 -0
- package/src/main/kotlin/com/facebook/react/utils/FileUtils.kt +20 -0
- package/src/main/kotlin/com/facebook/react/utils/JsonUtils.kt +21 -0
- package/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt +139 -0
- package/src/main/kotlin/com/facebook/react/utils/Os.kt +31 -0
- package/src/main/kotlin/com/facebook/react/utils/PathUtils.kt +220 -0
- package/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt +46 -0
- package/src/main/kotlin/com/facebook/react/utils/TaskUtils.kt +28 -0
|
@@ -0,0 +1,139 @@
|
|
|
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.utils
|
|
9
|
+
|
|
10
|
+
import com.android.build.api.variant.AndroidComponentsExtension
|
|
11
|
+
import com.android.build.api.variant.Variant
|
|
12
|
+
import com.facebook.react.ReactExtension
|
|
13
|
+
import com.facebook.react.utils.ProjectUtils.isNewArchEnabled
|
|
14
|
+
import java.io.File
|
|
15
|
+
import org.gradle.api.Project
|
|
16
|
+
|
|
17
|
+
internal object NdkConfiguratorUtils {
|
|
18
|
+
@Suppress("UnstableApiUsage")
|
|
19
|
+
fun configureReactNativeNdk(project: Project, extension: ReactExtension) {
|
|
20
|
+
project.pluginManager.withPlugin("com.android.application") {
|
|
21
|
+
project.extensions.getByType(AndroidComponentsExtension::class.java).finalizeDsl { ext ->
|
|
22
|
+
if (!project.isNewArchEnabled) {
|
|
23
|
+
// For Old Arch, we don't need to setup the NDK
|
|
24
|
+
return@finalizeDsl
|
|
25
|
+
}
|
|
26
|
+
// We enable prefab so users can consume .so/headers from ReactAndroid and hermes-engine
|
|
27
|
+
// .aar
|
|
28
|
+
ext.buildFeatures.prefab = true
|
|
29
|
+
|
|
30
|
+
// If the user has not provided a CmakeLists.txt path, let's provide
|
|
31
|
+
// the default one from the framework
|
|
32
|
+
if (ext.externalNativeBuild.cmake.path == null) {
|
|
33
|
+
ext.externalNativeBuild.cmake.path =
|
|
34
|
+
File(
|
|
35
|
+
extension.reactNativeDir.get().asFile,
|
|
36
|
+
"ReactAndroid/cmake-utils/default-app-setup/CMakeLists.txt")
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Parameters should be provided in an additive manner (do not override what
|
|
40
|
+
// the user provided, but allow for sensible defaults).
|
|
41
|
+
val cmakeArgs = ext.defaultConfig.externalNativeBuild.cmake.arguments
|
|
42
|
+
if ("-DPROJECT_BUILD_DIR" !in cmakeArgs) {
|
|
43
|
+
cmakeArgs.add("-DPROJECT_BUILD_DIR=${project.buildDir}")
|
|
44
|
+
}
|
|
45
|
+
if ("-DREACT_ANDROID_DIR" !in cmakeArgs) {
|
|
46
|
+
cmakeArgs.add(
|
|
47
|
+
"-DREACT_ANDROID_DIR=${extension.reactNativeDir.file("ReactAndroid").get().asFile}")
|
|
48
|
+
}
|
|
49
|
+
if ("-DANDROID_STL" !in cmakeArgs) {
|
|
50
|
+
cmakeArgs.add("-DANDROID_STL=c++_shared")
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* This method is used to configure the .so Packaging Options for the given variant. It will make
|
|
58
|
+
* sure we specify the correct .pickFirsts for all the .so files we are producing or that we're
|
|
59
|
+
* aware of as some of our dependencies are pulling them in.
|
|
60
|
+
*/
|
|
61
|
+
fun configureNewArchPackagingOptions(
|
|
62
|
+
project: Project,
|
|
63
|
+
variant: Variant,
|
|
64
|
+
) {
|
|
65
|
+
if (!project.isNewArchEnabled) {
|
|
66
|
+
// For Old Arch, we set a pickFirst only on libraries that we know are
|
|
67
|
+
// clashing with our direct dependencies (FBJNI, Flipper and Hermes).
|
|
68
|
+
variant.packaging.jniLibs.pickFirsts.addAll(
|
|
69
|
+
listOf(
|
|
70
|
+
"**/libfbjni.so",
|
|
71
|
+
"**/libc++_shared.so",
|
|
72
|
+
))
|
|
73
|
+
} else {
|
|
74
|
+
// We set some packagingOptions { pickFirst ... } for our users for libraries we own.
|
|
75
|
+
variant.packaging.jniLibs.pickFirsts.addAll(
|
|
76
|
+
listOf(
|
|
77
|
+
// This is the .so provided by FBJNI via prefab
|
|
78
|
+
"**/libfbjni.so",
|
|
79
|
+
// Those are prefab libraries we distribute via ReactAndroid
|
|
80
|
+
// Due to a bug in AGP, they fire a warning on console as both the JNI
|
|
81
|
+
// and the prefab .so files gets considered. See more on:
|
|
82
|
+
"**/libfabricjni.so",
|
|
83
|
+
"**/libfolly_runtime.so",
|
|
84
|
+
"**/libglog.so",
|
|
85
|
+
"**/libjsi.so",
|
|
86
|
+
"**/libreact_codegen_rncore.so",
|
|
87
|
+
"**/libreact_debug.so",
|
|
88
|
+
"**/libreact_nativemodule_core.so",
|
|
89
|
+
"**/libreact_newarchdefaults.so",
|
|
90
|
+
"**/libreact_render_componentregistry.so",
|
|
91
|
+
"**/libreact_render_core.so",
|
|
92
|
+
"**/libreact_render_debug.so",
|
|
93
|
+
"**/libreact_render_graphics.so",
|
|
94
|
+
"**/libreact_render_imagemanager.so",
|
|
95
|
+
"**/libreact_render_mapbuffer.so",
|
|
96
|
+
"**/librrc_image.so",
|
|
97
|
+
"**/librrc_view.so",
|
|
98
|
+
"**/libruntimeexecutor.so",
|
|
99
|
+
"**/libturbomodulejsijni.so",
|
|
100
|
+
"**/libyoga.so",
|
|
101
|
+
// AGP will give priority of libc++_shared coming from App modules.
|
|
102
|
+
"**/libc++_shared.so",
|
|
103
|
+
))
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* This method is used to configure the .so Cleanup for the given variant. It takes care of
|
|
109
|
+
* cleaning up the .so files that are not needed for Hermes or JSC, given a specific variant.
|
|
110
|
+
*/
|
|
111
|
+
fun configureJsEnginePackagingOptions(
|
|
112
|
+
config: ReactExtension,
|
|
113
|
+
variant: Variant,
|
|
114
|
+
hermesEnabled: Boolean,
|
|
115
|
+
) {
|
|
116
|
+
if (config.enableSoCleanup.get()) {
|
|
117
|
+
val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled)
|
|
118
|
+
variant.packaging.jniLibs.excludes.addAll(excludes)
|
|
119
|
+
variant.packaging.jniLibs.pickFirsts.addAll(includes)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
fun getPackagingOptionsForVariant(hermesEnabled: Boolean): Pair<List<String>, List<String>> {
|
|
124
|
+
val excludes = mutableListOf<String>()
|
|
125
|
+
val includes = mutableListOf<String>()
|
|
126
|
+
if (hermesEnabled) {
|
|
127
|
+
excludes.add("**/libjsc.so")
|
|
128
|
+
excludes.add("**/libjscexecutor.so")
|
|
129
|
+
includes.add("**/libhermes.so")
|
|
130
|
+
includes.add("**/libhermes_executor.so")
|
|
131
|
+
} else {
|
|
132
|
+
excludes.add("**/libhermes.so")
|
|
133
|
+
excludes.add("**/libhermes_executor.so")
|
|
134
|
+
includes.add("**/libjsc.so")
|
|
135
|
+
includes.add("**/libjscexecutor.so")
|
|
136
|
+
}
|
|
137
|
+
return excludes to includes
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
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.utils
|
|
9
|
+
|
|
10
|
+
object Os {
|
|
11
|
+
|
|
12
|
+
fun isWindows(): Boolean =
|
|
13
|
+
System.getProperty("os.name")?.lowercase()?.contains("windows") ?: false
|
|
14
|
+
|
|
15
|
+
fun isMac(): Boolean = System.getProperty("os.name")?.lowercase()?.contains("mac") ?: false
|
|
16
|
+
|
|
17
|
+
fun isLinuxAmd64(): Boolean {
|
|
18
|
+
val osNameMatch = System.getProperty("os.name")?.lowercase()?.contains("linux") ?: false
|
|
19
|
+
val archMatch = System.getProperty("os.arch")?.lowercase()?.contains("amd64") ?: false
|
|
20
|
+
return osNameMatch && archMatch
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
fun String.unixifyPath() =
|
|
24
|
+
this.replace('\\', '/').replace(":", "").let {
|
|
25
|
+
if (!it.startsWith("/")) {
|
|
26
|
+
"/$it"
|
|
27
|
+
} else {
|
|
28
|
+
it
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
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
|
+
@file:JvmName("PathUtils")
|
|
9
|
+
|
|
10
|
+
package com.facebook.react.utils
|
|
11
|
+
|
|
12
|
+
import com.facebook.react.ReactExtension
|
|
13
|
+
import com.facebook.react.model.ModelPackageJson
|
|
14
|
+
import java.io.File
|
|
15
|
+
import org.gradle.api.Project
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Computes the entry file for React Native. The Algo follows this order:
|
|
19
|
+
* 1. The file pointed by the ENTRY_FILE env variable, if set.
|
|
20
|
+
* 2. The file provided by the `entryFile` config in the `reactApp` Gradle extension
|
|
21
|
+
* 3. The `index.android.js` file, if available.
|
|
22
|
+
* 4. Fallback to the `index.js` file.
|
|
23
|
+
*
|
|
24
|
+
* @param config The [ReactExtension] configured for this project
|
|
25
|
+
*/
|
|
26
|
+
internal fun detectedEntryFile(config: ReactExtension): File =
|
|
27
|
+
detectEntryFile(
|
|
28
|
+
entryFile = config.entryFile.orNull?.asFile, reactRoot = config.root.get().asFile)
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Computes the CLI file for React Native. The Algo follows this order:
|
|
32
|
+
* 1. The path provided by the `cliFile` config in the `react {}` Gradle extension
|
|
33
|
+
* 2. The output of `node --print "require.resolve('react-native/cli');"` if not failing.
|
|
34
|
+
* 3. The `node_modules/react-native/cli.js` file if exists
|
|
35
|
+
* 4. Fails otherwise
|
|
36
|
+
*/
|
|
37
|
+
internal fun detectedCliFile(config: ReactExtension): File =
|
|
38
|
+
detectCliFile(
|
|
39
|
+
reactNativeRoot = config.root.get().asFile,
|
|
40
|
+
preconfiguredCliFile = config.cliFile.asFile.orNull)
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Computes the `hermesc` command location. The Algo follows this order:
|
|
44
|
+
* 1. The path provided by the `hermesCommand` config in the `react` Gradle extension
|
|
45
|
+
* 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.
|
|
47
|
+
* 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
|
+
* 4. Fails otherwise
|
|
51
|
+
*/
|
|
52
|
+
internal fun detectedHermesCommand(config: ReactExtension): String =
|
|
53
|
+
detectOSAwareHermesCommand(config.root.get().asFile, config.hermesCommand.get())
|
|
54
|
+
|
|
55
|
+
private fun detectEntryFile(entryFile: File?, reactRoot: File): File =
|
|
56
|
+
when {
|
|
57
|
+
System.getenv("ENTRY_FILE") != null -> File(System.getenv("ENTRY_FILE"))
|
|
58
|
+
entryFile != null -> entryFile
|
|
59
|
+
File(reactRoot, "index.android.js").exists() -> File(reactRoot, "index.android.js")
|
|
60
|
+
else -> File(reactRoot, "index.js")
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private fun detectCliFile(reactNativeRoot: File, preconfiguredCliFile: File?): File {
|
|
64
|
+
// 1. preconfigured path
|
|
65
|
+
if (preconfiguredCliFile != null) {
|
|
66
|
+
if (preconfiguredCliFile.exists()) {
|
|
67
|
+
return preconfiguredCliFile
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 2. node module path
|
|
72
|
+
val nodeProcess =
|
|
73
|
+
Runtime.getRuntime()
|
|
74
|
+
.exec(
|
|
75
|
+
arrayOf("node", "--print", "require.resolve('react-native/cli');"),
|
|
76
|
+
emptyArray(),
|
|
77
|
+
reactNativeRoot)
|
|
78
|
+
|
|
79
|
+
val nodeProcessOutput = nodeProcess.inputStream.use { it.bufferedReader().readText().trim() }
|
|
80
|
+
|
|
81
|
+
if (nodeProcessOutput.isNotEmpty()) {
|
|
82
|
+
val nodeModuleCliJs = File(nodeProcessOutput)
|
|
83
|
+
if (nodeModuleCliJs.exists()) {
|
|
84
|
+
return nodeModuleCliJs
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 3. cli.js in the root folder
|
|
89
|
+
val rootCliJs = File(reactNativeRoot, "node_modules/react-native/cli.js")
|
|
90
|
+
if (rootCliJs.exists()) {
|
|
91
|
+
return rootCliJs
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
error(
|
|
95
|
+
"""
|
|
96
|
+
Couldn't determine CLI location!
|
|
97
|
+
|
|
98
|
+
Please set `react { cliFile = file(...) }` inside your
|
|
99
|
+
build.gradle to the path of the react-native cli.js file.
|
|
100
|
+
This file typically resides in `node_modules/react-native/cli.js`
|
|
101
|
+
"""
|
|
102
|
+
.trimIndent())
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Computes the `hermesc` command location. The Algo follows this order:
|
|
107
|
+
* 1. The path provided by the `hermesCommand` config in the `react` Gradle extension
|
|
108
|
+
* 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.
|
|
110
|
+
* 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
|
+
* 4. Fails otherwise
|
|
114
|
+
*/
|
|
115
|
+
internal fun detectOSAwareHermesCommand(projectRoot: File, hermesCommand: String): String {
|
|
116
|
+
// 1. If the project specifies a Hermes command, don't second guess it.
|
|
117
|
+
if (hermesCommand.isNotBlank()) {
|
|
118
|
+
val osSpecificHermesCommand =
|
|
119
|
+
if ("%OS-BIN%" in hermesCommand) {
|
|
120
|
+
hermesCommand.replace("%OS-BIN%", getHermesOSBin())
|
|
121
|
+
} else {
|
|
122
|
+
hermesCommand
|
|
123
|
+
}
|
|
124
|
+
return osSpecificHermesCommand
|
|
125
|
+
// Execution on Windows fails with / as separator
|
|
126
|
+
.replace('/', File.separatorChar)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 2. If the project is building hermes-engine from source, use hermesc from there
|
|
130
|
+
val builtHermesc =
|
|
131
|
+
getBuiltHermescFile(projectRoot, System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR"))
|
|
132
|
+
if (builtHermesc.exists()) {
|
|
133
|
+
return builtHermesc.absolutePath
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// 3. If the react-native contains a pre-built hermesc, use it.
|
|
137
|
+
val prebuiltHermesPath =
|
|
138
|
+
HERMESC_IN_REACT_NATIVE_DIR.plus(getHermesCBin())
|
|
139
|
+
.replace("%OS-BIN%", getHermesOSBin())
|
|
140
|
+
// Execution on Windows fails with / as separator
|
|
141
|
+
.replace('/', File.separatorChar)
|
|
142
|
+
|
|
143
|
+
val prebuiltHermes = File(projectRoot, prebuiltHermesPath)
|
|
144
|
+
if (prebuiltHermes.exists()) {
|
|
145
|
+
return prebuiltHermes.absolutePath
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
error(
|
|
149
|
+
"Couldn't determine Hermesc location. " +
|
|
150
|
+
"Please set `react.hermesCommand` to the path of the hermesc binary file. " +
|
|
151
|
+
"node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc")
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Gets the location where Hermesc should be. If nothing is specified, built hermesc is assumed to
|
|
156
|
+
* be inside [HERMESC_BUILT_FROM_SOURCE_DIR]. Otherwise user can specify an override with
|
|
157
|
+
* [pathOverride], which is assumed to be an absolute path where Hermes source code is
|
|
158
|
+
* provided/built.
|
|
159
|
+
*
|
|
160
|
+
* @param projectRoot The root of the Project.
|
|
161
|
+
*/
|
|
162
|
+
internal fun getBuiltHermescFile(projectRoot: File, pathOverride: String?) =
|
|
163
|
+
if (!pathOverride.isNullOrBlank()) {
|
|
164
|
+
File(pathOverride, "build/bin/${getHermesCBin()}")
|
|
165
|
+
} else {
|
|
166
|
+
File(projectRoot, HERMESC_BUILT_FROM_SOURCE_DIR.plus(getHermesCBin()))
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
internal fun getHermesCBin() = if (Os.isWindows()) "hermesc.exe" else "hermesc"
|
|
170
|
+
|
|
171
|
+
internal fun getHermesOSBin(): String {
|
|
172
|
+
if (Os.isWindows()) return "win64-bin"
|
|
173
|
+
if (Os.isMac()) return "osx-bin"
|
|
174
|
+
if (Os.isLinuxAmd64()) return "linux64-bin"
|
|
175
|
+
error(
|
|
176
|
+
"OS not recognized. Please set project.react.hermesCommand " +
|
|
177
|
+
"to the path of a working Hermes compiler.")
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
internal fun projectPathToLibraryName(projectPath: String): String =
|
|
181
|
+
projectPath
|
|
182
|
+
.split(':', '-', '_', '.')
|
|
183
|
+
.joinToString("") { token -> token.replaceFirstChar { it.uppercase() } }
|
|
184
|
+
.plus("Spec")
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Function to look for the relevant `package.json`. We first look in the parent folder of this
|
|
188
|
+
* Gradle module (generally the case for library projects) or we fallback to looking into the `root`
|
|
189
|
+
* folder of a React Native project (generally the case for app projects).
|
|
190
|
+
*/
|
|
191
|
+
internal fun findPackageJsonFile(project: Project, extension: ReactExtension): File? {
|
|
192
|
+
val inParent = project.file("../package.json")
|
|
193
|
+
if (inParent.exists()) {
|
|
194
|
+
return inParent
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
val fromExtension = extension.root.file("package.json").orNull?.asFile
|
|
198
|
+
if (fromExtension?.exists() == true) {
|
|
199
|
+
return fromExtension
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return null
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Function to look for the `package.json` and parse it. It returns a [ModelPackageJson] if found or
|
|
207
|
+
* null others.
|
|
208
|
+
*
|
|
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.
|
|
212
|
+
*/
|
|
213
|
+
internal fun readPackageJsonFile(project: Project, extension: ReactExtension): ModelPackageJson? {
|
|
214
|
+
val packageJson = findPackageJsonFile(project, extension)
|
|
215
|
+
return packageJson?.let { JsonUtils.fromCodegenJson(it) }
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private const val HERMESC_IN_REACT_NATIVE_DIR = "node_modules/react-native/sdks/hermesc/%OS-BIN%/"
|
|
219
|
+
private const val HERMESC_BUILT_FROM_SOURCE_DIR =
|
|
220
|
+
"node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/"
|
|
@@ -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.utils
|
|
9
|
+
|
|
10
|
+
import com.facebook.react.ReactExtension
|
|
11
|
+
import com.facebook.react.model.ModelPackageJson
|
|
12
|
+
import org.gradle.api.Project
|
|
13
|
+
|
|
14
|
+
internal object ProjectUtils {
|
|
15
|
+
internal val Project.isNewArchEnabled: Boolean
|
|
16
|
+
get() =
|
|
17
|
+
project.hasProperty("newArchEnabled") &&
|
|
18
|
+
project.property("newArchEnabled").toString().toBoolean()
|
|
19
|
+
|
|
20
|
+
const val HERMES_FALLBACK = true
|
|
21
|
+
|
|
22
|
+
internal val Project.isHermesEnabled: Boolean
|
|
23
|
+
get() =
|
|
24
|
+
if (project.hasProperty("hermesEnabled")) {
|
|
25
|
+
project.property("hermesEnabled").toString().lowercase().toBooleanStrictOrNull() ?: true
|
|
26
|
+
} else if (project.extensions.extraProperties.has("react")) {
|
|
27
|
+
@Suppress("UNCHECKED_CAST")
|
|
28
|
+
val reactMap = project.extensions.extraProperties.get("react") as? Map<String, Any?>
|
|
29
|
+
when (val enableHermesKey = reactMap?.get("enableHermes")) {
|
|
30
|
+
is Boolean -> enableHermesKey
|
|
31
|
+
is String -> enableHermesKey.lowercase().toBooleanStrictOrNull() ?: true
|
|
32
|
+
else -> HERMES_FALLBACK
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
HERMES_FALLBACK
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
internal fun Project.needsCodegenFromPackageJson(extension: ReactExtension): Boolean {
|
|
39
|
+
val parsedPackageJson = readPackageJsonFile(this, extension)
|
|
40
|
+
return needsCodegenFromPackageJson(parsedPackageJson)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
internal fun Project.needsCodegenFromPackageJson(model: ModelPackageJson?): Boolean {
|
|
44
|
+
return model?.codegenConfig != null
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
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.utils
|
|
9
|
+
|
|
10
|
+
internal fun windowsAwareCommandLine(vararg args: Any): List<Any> =
|
|
11
|
+
windowsAwareCommandLine(args.toList())
|
|
12
|
+
|
|
13
|
+
internal fun windowsAwareCommandLine(args: List<Any>): List<Any> =
|
|
14
|
+
if (Os.isWindows()) {
|
|
15
|
+
listOf("cmd", "/c") + args
|
|
16
|
+
} else {
|
|
17
|
+
args
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
internal fun windowsAwareBashCommandLine(
|
|
21
|
+
vararg args: String,
|
|
22
|
+
bashWindowsHome: String? = null
|
|
23
|
+
): List<String> =
|
|
24
|
+
if (Os.isWindows()) {
|
|
25
|
+
listOf(bashWindowsHome ?: "bash", "-c") + args
|
|
26
|
+
} else {
|
|
27
|
+
args.toList()
|
|
28
|
+
}
|