Read Maven group from GROUP property (#37204)

Summary:
The [React Native TV repo](https://github.com/react-native-tvos/react-native-tvos) shares most of the same Android code as the core repo. Beginning in 0.71, it needs to also publish Android Maven artifacts for the `react-android` and `hermes-android` libraries.

In order to avoid conflicts, it needs to publish the artifacts to a different group name. However, `react-native-gradle-plugin` uses a hardcoded group name (`com.facebook.react`).

Solution: read the group name from the existing `GROUP` property in `ReactAndroid/gradle.properties`.

## Changelog:

[Android] [Fixed] - read GROUP name in gradle-plugin dependency code

Pull Request resolved: https://github.com/facebook/react-native/pull/37204

Test Plan:
- Android unit tests have been added for the new code and new method in `DependencyUtils.kt`.
- Existing tests should pass
- The new code defaults to the correct group (`com.facebook.react`) so no functional change is expected in the core repo.

Reviewed By: luluwu2032

Differential Revision: D45576700

Pulled By: cortinico

fbshipit-source-id: 6297ab515b4bdbb17024989c7d3035b0a2ded0ae

# Conflicts:
#	packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt
This commit is contained in:
Douglas Lowder
2023-05-10 10:35:01 +01:00
committed by Lorenzo Sciandra
parent 1fbfd8c7bb
commit 0dda452eb7
3 changed files with 83 additions and 20 deletions
@@ -19,7 +19,7 @@ import com.facebook.react.utils.AgpConfiguratorUtils.configureDevPorts
import com.facebook.react.utils.BackwardCompatUtils.configureBackwardCompatibilityReactMap
import com.facebook.react.utils.DependencyUtils.configureDependencies
import com.facebook.react.utils.DependencyUtils.configureRepositories
import com.facebook.react.utils.DependencyUtils.readVersionString
import com.facebook.react.utils.DependencyUtils.readVersionAndGroupStrings
import com.facebook.react.utils.JsonUtils
import com.facebook.react.utils.NdkConfiguratorUtils.configureReactNativeNdk
import com.facebook.react.utils.ProjectUtils.needsCodegenFromPackageJson
@@ -55,8 +55,10 @@ class ReactPlugin : Plugin<Project> {
project.afterEvaluate {
val reactNativeDir = extension.reactNativeDir.get().asFile
val propertiesFile = File(reactNativeDir, "ReactAndroid/gradle.properties")
val versionString = readVersionString(propertiesFile)
configureDependencies(project, versionString)
val versionAndGroupStrings = readVersionAndGroupStrings(propertiesFile)
val versionString = versionAndGroupStrings.first
val groupString = versionAndGroupStrings.second
configureDependencies(project, versionString, groupString)
configureRepositories(project, reactNativeDir)
}
@@ -13,6 +13,8 @@ import java.util.*
import org.gradle.api.Project
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
internal const val DEFAULT_GROUP_STRING = "com.facebook.react"
internal object DependencyUtils {
/**
@@ -43,7 +45,11 @@ internal object DependencyUtils {
* - Forcing the react-android/hermes-android version to the one specified in the package.json
* - Substituting `react-native` with `react-android` and `hermes-engine` with `hermes-android`.
*/
fun configureDependencies(project: Project, versionString: String) {
fun configureDependencies(
project: Project,
versionString: String,
groupString: String = DEFAULT_GROUP_STRING
) {
if (versionString.isBlank()) return
project.rootProject.allprojects { eachProject ->
eachProject.configurations.all { configuration ->
@@ -53,32 +59,36 @@ internal object DependencyUtils {
// implementation("com.facebook.react:react-native:+") and resolve the right dependency.
configuration.resolutionStrategy.dependencySubstitution {
it.substitute(it.module("com.facebook.react:react-native"))
.using(it.module("com.facebook.react:react-android:${versionString}"))
.using(it.module("${groupString}:react-android:${versionString}"))
.because(
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.")
it.substitute(it.module("com.facebook.react:hermes-engine"))
.using(it.module("com.facebook.react:hermes-android:${versionString}"))
.using(it.module("${groupString}:hermes-android:${versionString}"))
.because(
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.")
}
configuration.resolutionStrategy.force(
"com.facebook.react:react-android:${versionString}",
"com.facebook.react:hermes-android:${versionString}",
"${groupString}:react-android:${versionString}",
"${groupString}:hermes-android:${versionString}",
)
}
}
}
fun readVersionString(propertiesFile: File): String {
fun readVersionAndGroupStrings(propertiesFile: File): Pair<String, String> {
val reactAndroidProperties = Properties()
propertiesFile.inputStream().use { reactAndroidProperties.load(it) }
val versionString = reactAndroidProperties["VERSION_NAME"] as? String ?: ""
val versionStringFromFile = reactAndroidProperties["VERSION_NAME"] as? String ?: ""
// If on a nightly, we need to fetch the -SNAPSHOT artifact from Sonatype.
return if (versionString.startsWith("0.0.0")) {
"$versionString-SNAPSHOT"
} else {
versionString
}
val versionString =
if (versionStringFromFile.startsWith("0.0.0")) {
"$versionStringFromFile-SNAPSHOT"
} else {
versionStringFromFile
}
// Returns Maven group for repos using different group for Maven artifacts
val groupString = reactAndroidProperties["GROUP"] as? String ?: DEFAULT_GROUP_STRING
return Pair(versionString, groupString)
}
fun Project.mavenRepoFromUrl(url: String): MavenArtifactRepository =
@@ -12,7 +12,7 @@ import com.facebook.react.utils.DependencyUtils.configureDependencies
import com.facebook.react.utils.DependencyUtils.configureRepositories
import com.facebook.react.utils.DependencyUtils.mavenRepoFromURI
import com.facebook.react.utils.DependencyUtils.mavenRepoFromUrl
import com.facebook.react.utils.DependencyUtils.readVersionString
import com.facebook.react.utils.DependencyUtils.readVersionAndGroupStrings
import java.net.URI
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
import org.gradle.testfixtures.ProjectBuilder
@@ -226,6 +226,24 @@ class DependencyUtilsTest {
assertTrue(libForcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
}
@Test
fun configureDependencies_withVersionStringAndGroupString_appliesOnAllProjects() {
val rootProject = ProjectBuilder.builder().build()
val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
appProject.plugins.apply("com.android.application")
libProject.plugins.apply("com.android.library")
configureDependencies(appProject, "1.2.3", "io.github.test")
val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules
val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules
assertTrue(appForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" })
assertTrue(appForcedModules.any { it.toString() == "io.github.test:hermes-android:1.2.3" })
assertTrue(libForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" })
assertTrue(libForcedModules.any { it.toString() == "io.github.test:hermes-android:1.2.3" })
}
@Test
fun readVersionString_withCorrectVersionString_returnsIt() {
val propertiesFile =
@@ -238,7 +256,7 @@ class DependencyUtilsTest {
.trimIndent())
}
val versionString = readVersionString(propertiesFile)
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertEquals("1000.0.0", versionString)
}
@@ -255,7 +273,7 @@ class DependencyUtilsTest {
.trimIndent())
}
val versionString = readVersionString(propertiesFile)
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertEquals("0.0.0-20221101-2019-cfe811ab1-SNAPSHOT", versionString)
}
@@ -271,7 +289,7 @@ class DependencyUtilsTest {
.trimIndent())
}
val versionString = readVersionString(propertiesFile)
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertEquals("", versionString)
}
@@ -287,10 +305,43 @@ class DependencyUtilsTest {
.trimIndent())
}
val versionString = readVersionString(propertiesFile)
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertEquals("", versionString)
}
@Test
fun readGroupString_withCorrectGroupString_returnsIt() {
val propertiesFile =
tempFolder.newFile("gradle.properties").apply {
writeText(
"""
GROUP=io.github.test
ANOTHER_PROPERTY=true
"""
.trimIndent())
}
val groupString = readVersionAndGroupStrings(propertiesFile).second
assertEquals("io.github.test", groupString)
}
@Test
fun readGroupString_withEmptyGroupString_returnsDefault() {
val propertiesFile =
tempFolder.newFile("gradle.properties").apply {
writeText(
"""
ANOTHER_PROPERTY=true
"""
.trimIndent())
}
val groupString = readVersionAndGroupStrings(propertiesFile).second
assertEquals("com.facebook.react", groupString)
}
@Test
fun mavenRepoFromUrl_worksCorrectly() {
val process = createProject()