mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Ensure namespace is specified for all the 3rd party libraries (#41085)
Summary: As stated here https://github.com/react-native-community/discussions-and-proposals/issues/671 React Native 0.73 will depend on Android Gradle Plugin (AGP) 8.x which requires all libraries to specify a namespace in their build.gradle file, even though this issue was raised many months ago, lots of libraries have not been updated and don't specify a `namespace` inside their build.gradle files ## Changelog: [ANDROID] [CHANGED] - Ensure namespace is specified for all the 3rd party libraries Pull Request resolved: https://github.com/facebook/react-native/pull/41085 Test Plan: Run RNGP tests and test building rn-tester after doing the following procedure 1. Remove `namespace "com.facebook.react"` from react-native/packages/react-native/ReactAndroid/build.gradle 2. Add `package="com.facebook.react"` to react-native/packages/react-native/ReactAndroid/src/main/AndroidManifest.xml 3. Build rn-tester Also tested this using [BareExpo](https://github.com/expo/expo/tree/main/apps/bare-expo) with AGP 8.1.1 and all libraries that were missing the `namespace` compiled correctly Reviewed By: cipolleschi Differential Revision: D50556667 Pulled By: cortinico fbshipit-source-id: 3d75ec0a8b82427ff0ede89aa7bc58b28b288945
This commit is contained in:
committed by
Facebook GitHub Bot
parent
8809392d87
commit
13ae11152a
@@ -15,6 +15,7 @@ import com.facebook.react.tasks.GenerateCodegenSchemaTask
|
||||
import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildConfigFieldsForApp
|
||||
import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildConfigFieldsForLibraries
|
||||
import com.facebook.react.utils.AgpConfiguratorUtils.configureDevPorts
|
||||
import com.facebook.react.utils.AgpConfiguratorUtils.configureNamespaceForLibraries
|
||||
import com.facebook.react.utils.BackwardCompatUtils.configureBackwardCompatibilityReactMap
|
||||
import com.facebook.react.utils.DependencyUtils.configureDependencies
|
||||
import com.facebook.react.utils.DependencyUtils.configureRepositories
|
||||
@@ -82,6 +83,7 @@ class ReactPlugin : Plugin<Project> {
|
||||
|
||||
// Library Only Configuration
|
||||
configureBuildConfigFieldsForLibraries(project)
|
||||
configureNamespaceForLibraries(project)
|
||||
project.pluginManager.withPlugin("com.android.library") {
|
||||
configureCodegen(project, extension, rootExtension, isLibrary = true)
|
||||
}
|
||||
|
||||
+42
@@ -8,12 +8,17 @@
|
||||
package com.facebook.react.utils
|
||||
|
||||
import com.android.build.api.variant.AndroidComponentsExtension
|
||||
import com.android.build.gradle.LibraryExtension
|
||||
import com.facebook.react.ReactExtension
|
||||
import com.facebook.react.utils.ProjectUtils.isHermesEnabled
|
||||
import com.facebook.react.utils.ProjectUtils.isNewArchEnabled
|
||||
import java.io.File
|
||||
import javax.xml.parsers.DocumentBuilder
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.AppliedPlugin
|
||||
import org.w3c.dom.Element
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
internal object AgpConfiguratorUtils {
|
||||
@@ -63,6 +68,43 @@ internal object AgpConfiguratorUtils {
|
||||
project.pluginManager.withPlugin("com.android.application", action)
|
||||
project.pluginManager.withPlugin("com.android.library", action)
|
||||
}
|
||||
|
||||
fun configureNamespaceForLibraries(appProject: Project) {
|
||||
appProject.rootProject.allprojects { subproject ->
|
||||
subproject.pluginManager.withPlugin("com.android.library") {
|
||||
subproject.extensions.getByType(AndroidComponentsExtension::class.java).finalizeDsl { ext ->
|
||||
if (ext.namespace == null) {
|
||||
val android = subproject.extensions.getByType(LibraryExtension::class.java)
|
||||
val manifestFile = android.sourceSets.getByName("main").manifest.srcFile
|
||||
|
||||
manifestFile
|
||||
.takeIf { it.exists() }
|
||||
?.let { file ->
|
||||
getPackageNameFromManifest(file)?.let { packageName ->
|
||||
ext.namespace = packageName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const val DEFAULT_DEV_SERVER_PORT = "8081"
|
||||
|
||||
fun getPackageNameFromManifest(manifest: File): String? {
|
||||
val factory: DocumentBuilderFactory = DocumentBuilderFactory.newInstance()
|
||||
val builder: DocumentBuilder = factory.newDocumentBuilder()
|
||||
|
||||
try {
|
||||
val xmlDocument = builder.parse(manifest)
|
||||
|
||||
val manifestElement = xmlDocument.getElementsByTagName("manifest").item(0) as? Element
|
||||
val packageName = manifestElement?.getAttribute("package")
|
||||
|
||||
return if (packageName.isNullOrEmpty()) null else packageName
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.utils
|
||||
|
||||
import java.io.File
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
|
||||
class AgpConfiguratorUtilsTest {
|
||||
|
||||
@get:Rule val tempFolder = TemporaryFolder()
|
||||
|
||||
@Test
|
||||
fun getPackageNameFromManifest_withEmptyFile_returnsNull() {
|
||||
val mainFolder = tempFolder.newFolder("awesome-module/src/main/")
|
||||
val manifest = File(mainFolder, "AndroidManifest.xml").apply { writeText("") }
|
||||
|
||||
val actual = getPackageNameFromManifest(manifest)
|
||||
assertNull(actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getPackageNameFromManifest_withMissingPackage_returnsNull() {
|
||||
val mainFolder = tempFolder.newFolder("awesome-module/src/main/")
|
||||
val manifest =
|
||||
File(mainFolder, "AndroidManifest.xml").apply {
|
||||
writeText(
|
||||
// language=xml
|
||||
"""
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
</manifest>
|
||||
"""
|
||||
.trimIndent())
|
||||
}
|
||||
|
||||
val actual = getPackageNameFromManifest(manifest)
|
||||
assertNull(actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getPackageNameFromManifest_withPackage_returnsPackage() {
|
||||
val mainFolder = tempFolder.newFolder("awesome-module/src/main/")
|
||||
val manifest =
|
||||
File(mainFolder, "AndroidManifest.xml").apply {
|
||||
writeText(
|
||||
// language=xml
|
||||
"""
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.facebook.react" >
|
||||
</manifest>
|
||||
"""
|
||||
.trimIndent())
|
||||
}
|
||||
|
||||
val actual = getPackageNameFromManifest(manifest)
|
||||
assertNotNull(actual)
|
||||
assertEquals("com.facebook.react", actual)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user