From e217b7f5134e941c06ddcc94be712a18cf882f15 Mon Sep 17 00:00:00 2001 From: Douglas Lowder Date: Fri, 5 May 2023 03:12:33 -0700 Subject: [PATCH] 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 --- .../kotlin/com/facebook/react/ReactPlugin.kt | 8 ++- .../facebook/react/utils/DependencyUtils.kt | 34 +++++++---- .../react/utils/DependencyUtilsTest.kt | 61 +++++++++++++++++-- 3 files changed, 83 insertions(+), 20 deletions(-) diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt index 4c8a6ff9996020..0aa563c9ae9f25 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt @@ -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.JsonUtils import com.facebook.react.utils.NdkConfiguratorUtils.configureReactNativeNdk import com.facebook.react.utils.ProjectUtils.needsCodegenFromPackageJson @@ -54,8 +54,10 @@ class ReactPlugin : Plugin { 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) } diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt index 6679aba9c216eb..583fc13f377dd5 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt @@ -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 { /** @@ -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 -> @@ -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 { 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 = diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt index 1b7c728cc4b4f6..f77c0bb3026b46 100644 --- a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt +++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt @@ -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()