Skip to content

Commit

Permalink
Read Maven group from GROUP property (#37204)
Browse files Browse the repository at this point in the history
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: #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
  • Loading branch information
douglowder authored and facebook-github-bot committed May 5, 2023
1 parent ef69c54 commit 615d9ae
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 20 deletions.
Expand Up @@ -18,7 +18,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.JdkConfiguratorUtils.configureJavaToolChains
import com.facebook.react.utils.JsonUtils
import com.facebook.react.utils.NdkConfiguratorUtils.configureReactNativeNdk
Expand Down Expand Up @@ -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)
}

Expand Down
Expand Up @@ -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 {

/**
Expand Down Expand Up @@ -46,7 +48,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 ->
Expand All @@ -56,32 +62,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 =
Expand Down
Expand Up @@ -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
Expand Down Expand Up @@ -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 =
Expand All @@ -238,7 +256,7 @@ class DependencyUtilsTest {
.trimIndent())
}

val versionString = readVersionString(propertiesFile)
val versionString = readVersionAndGroupStrings(propertiesFile).first

assertEquals("1000.0.0", versionString)
}
Expand All @@ -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)
}
Expand All @@ -271,7 +289,7 @@ class DependencyUtilsTest {
.trimIndent())
}

val versionString = readVersionString(propertiesFile)
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertEquals("", versionString)
}

Expand All @@ -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()
Expand Down

1 comment on commit 615d9ae

@Colommassa
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bon vent

Please sign in to comment.