@react-native/gradle-plugin 0.74.0 → 0.75.0-main

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
@@ -26,6 +26,10 @@ gradlePlugin {
26
26
  id = "com.facebook.react"
27
27
  implementationClass = "com.facebook.react.ReactPlugin"
28
28
  }
29
+ create("reactrootproject") {
30
+ id = "com.facebook.react.rootproject"
31
+ implementationClass = "com.facebook.react.ReactRootProjectPlugin"
32
+ }
29
33
  }
30
34
  }
31
35
 
@@ -63,7 +67,7 @@ kotlin { jvmToolchain(17) }
63
67
 
64
68
  tasks.withType<KotlinCompile>().configureEach {
65
69
  kotlinOptions {
66
- apiVersion = "1.5"
70
+ apiVersion = "1.6"
67
71
  // See comment above on JDK 11 support
68
72
  jvmTarget = "11"
69
73
  allWarningsAsErrors = true
@@ -1,10 +1,10 @@
1
1
  [versions]
2
- agp = "8.1.1"
2
+ agp = "8.2.1"
3
3
  gson = "2.8.9"
4
4
  guava = "31.0.1-jre"
5
5
  javapoet = "1.13.0"
6
6
  junit = "4.13.2"
7
- kotlin = "1.8.0"
7
+ kotlin = "1.9.22"
8
8
 
9
9
  [libraries]
10
10
  kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
Binary file
@@ -1,6 +1,6 @@
1
1
  distributionBase=GRADLE_USER_HOME
2
2
  distributionPath=wrapper/dists
3
- distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
3
+ distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip
4
4
  networkTimeout=10000
5
5
  validateDistributionUrl=true
6
6
  zipStoreBase=GRADLE_USER_HOME
package/gradlew.bat CHANGED
@@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
43
43
  %JAVA_EXE% -version >NUL 2>&1
44
44
  if %ERRORLEVEL% equ 0 goto execute
45
45
 
46
- echo.
47
- echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48
- echo.
49
- echo Please set the JAVA_HOME variable in your environment to match the
50
- echo location of your Java installation.
46
+ echo. 1>&2
47
+ echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
48
+ echo. 1>&2
49
+ echo Please set the JAVA_HOME variable in your environment to match the 1>&2
50
+ echo location of your Java installation. 1>&2
51
51
 
52
52
  goto fail
53
53
 
@@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57
57
 
58
58
  if exist "%JAVA_EXE%" goto execute
59
59
 
60
- echo.
61
- echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62
- echo.
63
- echo Please set the JAVA_HOME variable in your environment to match the
64
- echo location of your Java installation.
60
+ echo. 1>&2
61
+ echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
62
+ echo. 1>&2
63
+ echo Please set the JAVA_HOME variable in your environment to match the 1>&2
64
+ echo location of your Java installation. 1>&2
65
65
 
66
66
  goto fail
67
67
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native/gradle-plugin",
3
- "version": "0.74.0",
3
+ "version": "0.75.0-main",
4
4
  "description": "Gradle Plugin for React Native",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,7 +31,5 @@
31
31
  "gradlew.bat",
32
32
  "src/main",
33
33
  "README.md"
34
- ],
35
- "dependencies": {},
36
- "devDependencies": {}
34
+ ]
37
35
  }
@@ -12,8 +12,10 @@ import com.android.build.gradle.internal.tasks.factory.dependsOn
12
12
  import com.facebook.react.internal.PrivateReactExtension
13
13
  import com.facebook.react.tasks.GenerateCodegenArtifactsTask
14
14
  import com.facebook.react.tasks.GenerateCodegenSchemaTask
15
- import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildConfigFields
15
+ import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildConfigFieldsForApp
16
+ import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildConfigFieldsForLibraries
16
17
  import com.facebook.react.utils.AgpConfiguratorUtils.configureDevPorts
18
+ import com.facebook.react.utils.AgpConfiguratorUtils.configureNamespaceForLibraries
17
19
  import com.facebook.react.utils.BackwardCompatUtils.configureBackwardCompatibilityReactMap
18
20
  import com.facebook.react.utils.DependencyUtils.configureDependencies
19
21
  import com.facebook.react.utils.DependencyUtils.configureRepositories
@@ -66,9 +68,10 @@ class ReactPlugin : Plugin<Project> {
66
68
  }
67
69
 
68
70
  configureReactNativeNdk(project, extension)
69
- configureBuildConfigFields(project, extension)
71
+ configureBuildConfigFieldsForApp(project, extension)
70
72
  configureDevPorts(project)
71
73
  configureBackwardCompatibilityReactMap(project)
74
+ configureJavaToolChains(project)
72
75
 
73
76
  project.extensions.getByType(AndroidComponentsExtension::class.java).apply {
74
77
  onVariants(selector().all()) { variant ->
@@ -79,12 +82,11 @@ class ReactPlugin : Plugin<Project> {
79
82
  }
80
83
 
81
84
  // Library Only Configuration
85
+ configureBuildConfigFieldsForLibraries(project)
86
+ configureNamespaceForLibraries(project)
82
87
  project.pluginManager.withPlugin("com.android.library") {
83
88
  configureCodegen(project, extension, rootExtension, isLibrary = true)
84
89
  }
85
-
86
- // Library and App Configurations
87
- configureJavaToolChains(project)
88
90
  }
89
91
 
90
92
  private fun checkJvmVersion(project: Project) {
@@ -159,6 +161,8 @@ class ReactPlugin : Plugin<Project> {
159
161
  val parsedPackageJson = packageJson?.let { JsonUtils.fromPackageJson(it) }
160
162
 
161
163
  val jsSrcsDirInPackageJson = parsedPackageJson?.codegenConfig?.jsSrcsDir
164
+ val includesGeneratedCode =
165
+ parsedPackageJson?.codegenConfig?.includesGeneratedCode ?: false
162
166
  if (jsSrcsDirInPackageJson != null) {
163
167
  it.jsRootDir.set(File(packageJson.parentFile, jsSrcsDirInPackageJson))
164
168
  } else {
@@ -166,7 +170,7 @@ class ReactPlugin : Plugin<Project> {
166
170
  }
167
171
  val needsCodegenFromPackageJson =
168
172
  project.needsCodegenFromPackageJson(rootExtension.root)
169
- it.onlyIf { isLibrary || needsCodegenFromPackageJson }
173
+ it.onlyIf { (isLibrary || needsCodegenFromPackageJson) && !includesGeneratedCode }
170
174
  }
171
175
 
172
176
  // We create the task to generate Java code from schema.
@@ -186,7 +190,11 @@ class ReactPlugin : Plugin<Project> {
186
190
  // Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
187
191
  val needsCodegenFromPackageJson =
188
192
  project.needsCodegenFromPackageJson(rootExtension.root)
189
- it.onlyIf { isLibrary || needsCodegenFromPackageJson }
193
+ val packageJson = findPackageJsonFile(project, rootExtension.root)
194
+ val parsedPackageJson = packageJson?.let { JsonUtils.fromPackageJson(it) }
195
+ val includesGeneratedCode =
196
+ parsedPackageJson?.codegenConfig?.includesGeneratedCode ?: false
197
+ it.onlyIf { (isLibrary || needsCodegenFromPackageJson) && !includesGeneratedCode }
190
198
  }
191
199
 
192
200
  // We update the android configuration to include the generated sources.
@@ -0,0 +1,30 @@
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 org.gradle.api.Plugin
11
+ import org.gradle.api.Project
12
+
13
+ /**
14
+ * Gradle plugin applied to the `android/build.gradle` file.
15
+ *
16
+ * This plugin allows to specify project wide configurations that can be applied to both apps and
17
+ * libraries before they're evaluated.
18
+ */
19
+ class ReactRootProjectPlugin : Plugin<Project> {
20
+ override fun apply(project: Project) {
21
+ project.subprojects {
22
+ // As the :app project (i.e. ReactPlugin) configures both namespaces and JVM toolchains
23
+ // for libraries, its evaluation must happen before the libraries' evaluation.
24
+ // Eventually the configuration of namespace/JVM toolchain can be moved inside this plugin.
25
+ if (it.path != ":app") {
26
+ it.evaluationDependsOn(":app")
27
+ }
28
+ }
29
+ }
30
+ }
@@ -23,7 +23,7 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
23
23
  val targetName = variant.name.capitalizeCompat()
24
24
  val targetPath = variant.name
25
25
 
26
- val buildDir = this.layout.buildDirectory.get().asFile
26
+ val buildDir = layout.buildDirectory.get().asFile
27
27
  // Resources: generated/assets/react/<variant>/index.android.bundle
28
28
  val resourcesDir = File(buildDir, "generated/res/react/$targetPath")
29
29
  // Bundle: generated/assets/react/<variant>/index.android.bundle
@@ -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
  )
@@ -67,6 +67,8 @@ abstract class GenerateCodegenSchemaTask : Exec() {
67
67
  .cliPath(workingDir),
68
68
  "--platform",
69
69
  "android",
70
+ "--exclude",
71
+ "NativeSampleTurboModule",
70
72
  generatedSchemaFile.get().asFile.cliPath(workingDir),
71
73
  jsRootDir.asFile.get().cliPath(workingDir),
72
74
  ))
@@ -40,7 +40,7 @@ abstract class PrepareBoostTask : DefaultTask() {
40
40
  it.into(outputDir)
41
41
  }
42
42
  File(outputDir.asFile.get(), "boost").apply {
43
- renameTo(File(this.parentFile, "boost_${boostVersion.get()}"))
43
+ renameTo(File(parentFile, "boost_${boostVersion.get()}"))
44
44
  }
45
45
  }
46
46
  }
@@ -8,17 +8,22 @@
8
8
  package com.facebook.react.utils
9
9
 
10
10
  import com.android.build.api.variant.AndroidComponentsExtension
11
+ import com.android.build.gradle.LibraryExtension
11
12
  import com.facebook.react.ReactExtension
12
13
  import com.facebook.react.utils.ProjectUtils.isHermesEnabled
13
14
  import com.facebook.react.utils.ProjectUtils.isNewArchEnabled
15
+ import java.io.File
16
+ import javax.xml.parsers.DocumentBuilder
17
+ import javax.xml.parsers.DocumentBuilderFactory
14
18
  import org.gradle.api.Action
15
19
  import org.gradle.api.Project
16
20
  import org.gradle.api.plugins.AppliedPlugin
21
+ import org.w3c.dom.Element
17
22
 
18
23
  @Suppress("UnstableApiUsage")
19
24
  internal object AgpConfiguratorUtils {
20
25
 
21
- fun configureBuildConfigFields(project: Project, extension: ReactExtension) {
26
+ fun configureBuildConfigFieldsForApp(project: Project, extension: ReactExtension) {
22
27
  val action =
23
28
  Action<AppliedPlugin> {
24
29
  project.extensions.getByType(AndroidComponentsExtension::class.java).finalizeDsl { ext ->
@@ -35,24 +40,67 @@ internal object AgpConfiguratorUtils {
35
40
  project.pluginManager.withPlugin("com.android.library", action)
36
41
  }
37
42
 
43
+ fun configureBuildConfigFieldsForLibraries(appProject: Project) {
44
+ appProject.rootProject.allprojects { subproject ->
45
+ subproject.pluginManager.withPlugin("com.android.library") {
46
+ subproject.extensions.getByType(AndroidComponentsExtension::class.java).finalizeDsl { ext ->
47
+ ext.buildFeatures.buildConfig = true
48
+ }
49
+ }
50
+ }
51
+ }
52
+
38
53
  fun configureDevPorts(project: Project) {
39
54
  val devServerPort =
40
55
  project.properties["reactNativeDevServerPort"]?.toString() ?: DEFAULT_DEV_SERVER_PORT
41
- val inspectorProxyPort =
42
- project.properties["reactNativeInspectorProxyPort"]?.toString() ?: devServerPort
43
56
 
44
57
  val action =
45
58
  Action<AppliedPlugin> {
46
59
  project.extensions.getByType(AndroidComponentsExtension::class.java).finalizeDsl { ext ->
47
60
  ext.defaultConfig.resValue("integer", "react_native_dev_server_port", devServerPort)
48
- ext.defaultConfig.resValue(
49
- "integer", "react_native_inspector_proxy_port", inspectorProxyPort)
50
61
  }
51
62
  }
52
63
 
53
64
  project.pluginManager.withPlugin("com.android.application", action)
54
65
  project.pluginManager.withPlugin("com.android.library", action)
55
66
  }
67
+
68
+ fun configureNamespaceForLibraries(appProject: Project) {
69
+ appProject.rootProject.allprojects { subproject ->
70
+ subproject.pluginManager.withPlugin("com.android.library") {
71
+ subproject.extensions.getByType(AndroidComponentsExtension::class.java).finalizeDsl { ext ->
72
+ if (ext.namespace == null) {
73
+ val android = subproject.extensions.getByType(LibraryExtension::class.java)
74
+ val manifestFile = android.sourceSets.getByName("main").manifest.srcFile
75
+
76
+ manifestFile
77
+ .takeIf { it.exists() }
78
+ ?.let { file ->
79
+ getPackageNameFromManifest(file)?.let { packageName ->
80
+ ext.namespace = packageName
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
56
88
  }
57
89
 
58
90
  const val DEFAULT_DEV_SERVER_PORT = "8081"
91
+
92
+ fun getPackageNameFromManifest(manifest: File): String? {
93
+ val factory: DocumentBuilderFactory = DocumentBuilderFactory.newInstance()
94
+ val builder: DocumentBuilder = factory.newDocumentBuilder()
95
+
96
+ try {
97
+ val xmlDocument = builder.parse(manifest)
98
+
99
+ val manifestElement = xmlDocument.getElementsByTagName("manifest").item(0) as? Element
100
+ val packageName = manifestElement?.getAttribute("package")
101
+
102
+ return if (packageName.isNullOrEmpty()) null else packageName
103
+ } catch (e: Exception) {
104
+ return null
105
+ }
106
+ }
@@ -36,6 +36,12 @@ internal object DependencyUtils {
36
36
  repositories.mavenCentral { repo ->
37
37
  // We don't want to fetch JSC from Maven Central as there are older versions there.
38
38
  repo.content { it.excludeModule("org.webkit", "android-jsc") }
39
+
40
+ // If the user provided a react.internal.mavenLocalRepo, do not attempt to load
41
+ // anything from Maven Central that is react related.
42
+ if (hasProperty(INTERNAL_REACT_NATIVE_MAVEN_LOCAL_REPO)) {
43
+ repo.content { it.excludeGroup("com.facebook.react") }
44
+ }
39
45
  }
40
46
  // Android JSC is installed from npm
41
47
  mavenRepoFromURI(File(reactNativeDir, "../jsc-android/dist").toURI())
@@ -48,8 +54,7 @@ internal object DependencyUtils {
48
54
  /**
49
55
  * This method takes care of configuring the resolution strategy for both the app and all the 3rd
50
56
  * party libraries which are auto-linked. Specifically it takes care of:
51
- * - Forcing the react-android/hermes-android/flipper-integration version to the one specified in
52
- * the package.json
57
+ * - Forcing the react-android/hermes-android version to the one specified in the package.json
53
58
  * - Substituting `react-native` with `react-android` and `hermes-engine` with `hermes-android`.
54
59
  */
55
60
  fun configureDependencies(
@@ -71,7 +76,6 @@ internal object DependencyUtils {
71
76
  }
72
77
  configuration.resolutionStrategy.force(
73
78
  "${groupString}:react-android:${versionString}",
74
- "${groupString}:flipper-integration:${versionString}",
75
79
  )
76
80
  if (!(eachProject.findProperty(INTERNAL_USE_HERMES_NIGHTLY) as? String).toBoolean()) {
77
81
  // Contributors only: The hermes-engine version is forced only if the user has
@@ -115,7 +119,7 @@ internal object DependencyUtils {
115
119
  fun readVersionAndGroupStrings(propertiesFile: File): Pair<String, String> {
116
120
  val reactAndroidProperties = Properties()
117
121
  propertiesFile.inputStream().use { reactAndroidProperties.load(it) }
118
- val versionStringFromFile = reactAndroidProperties[INTERNAL_VERSION_NAME] as? String ?: ""
122
+ val versionStringFromFile = (reactAndroidProperties[INTERNAL_VERSION_NAME] as? String).orEmpty()
119
123
  // If on a nightly, we need to fetch the -SNAPSHOT artifact from Sonatype.
120
124
  val versionString =
121
125
  if (versionStringFromFile.startsWith("0.0.0") || "-nightly-" in versionStringFromFile) {
@@ -102,6 +102,7 @@ internal object NdkConfiguratorUtils {
102
102
  "**/libreact_debug.so",
103
103
  "**/libreact_nativemodule_core.so",
104
104
  "**/libreact_newarchdefaults.so",
105
+ "**/libreact_cxxreactpackage.so",
105
106
  "**/libreact_render_componentregistry.so",
106
107
  "**/libreact_render_core.so",
107
108
  "**/libreact_render_debug.so",
@@ -40,6 +40,6 @@ internal object Os {
40
40
  if (isWindows()) {
41
41
  this.relativeTo(base).path
42
42
  } else {
43
- this.absolutePath
43
+ absolutePath
44
44
  }
45
45
  }
@@ -1,51 +0,0 @@
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.tasks.internal
9
-
10
- import java.io.File
11
- import org.gradle.api.DefaultTask
12
- import org.gradle.api.file.ConfigurableFileCollection
13
- import org.gradle.api.file.DirectoryProperty
14
- import org.gradle.api.provider.Property
15
- import org.gradle.api.tasks.*
16
-
17
- /**
18
- * A task that takes care of extracting Libevent from a source folder/zip and preparing it to be
19
- * consumed by the NDK.
20
- */
21
- abstract class PrepareLibeventTask : DefaultTask() {
22
-
23
- @get:InputFiles abstract val libeventPath: ConfigurableFileCollection
24
-
25
- @get:Input abstract val libeventVersion: Property<String>
26
-
27
- @get:OutputDirectory abstract val outputDir: DirectoryProperty
28
-
29
- @TaskAction
30
- fun taskAction() {
31
- project.copy { it ->
32
- it.from(libeventPath)
33
- it.from(project.file("src/main/jni/third-party/libevent/"))
34
- it.include(
35
- "libevent-${libeventVersion.get()}-stable/*.c",
36
- "libevent-${libeventVersion.get()}-stable/*.h",
37
- "libevent-${libeventVersion.get()}-stable/include/**/*",
38
- "evconfig-private.h",
39
- "event-config.h",
40
- "CMakeLists.txt")
41
- it.eachFile { it.path = it.path.removePrefix("libevent-${libeventVersion.get()}-stable/") }
42
- it.includeEmptyDirs = false
43
- it.into(outputDir)
44
- }
45
- File(outputDir.asFile.get(), "event-config.h").apply {
46
- val destination =
47
- File(this.parentFile, "include/event2/event-config.h").apply { parentFile.mkdirs() }
48
- renameTo(destination)
49
- }
50
- }
51
- }