From 54ac1cc8f2de5ef86183e756dbc2165a5ffb07fc Mon Sep 17 00:00:00 2001 From: Hur Ali Date: Sun, 22 Feb 2026 14:04:24 +0500 Subject: [PATCH 1/7] feat: move expo publishing helper to main afterEvaluate block in order --- .../react/brownfield/expo/ExpoPublishingHelper.kt | 8 ++------ .../react/brownfield/plugin/RNBrownfieldPlugin.kt | 11 +++++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt index e9828e15..135f5c52 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt @@ -30,11 +30,8 @@ fun Node.getChildNodeByName(nodeName: String): Node? { } } -open class ExpoPublishingHelper(val brownfieldAppProject: Project, val expoProject: Project) { - fun configure() { - brownfieldAppProject.evaluationDependsOn(EXPO_PROJECT_LOCATOR) - - brownfieldAppProject.afterEvaluate { +open class ExpoPublishingHelper(val brownfieldAppProject: Project) { + fun afterEvaluate() { val discoverableExpoProjects = getDiscoverableExpoProjects() Logging.log( @@ -62,7 +59,6 @@ open class ExpoPublishingHelper(val brownfieldAppProject: Project, val expoProje reconfigurePOM(expoTransitiveDependencies) reconfigureGradleModuleJSON(expoTransitiveDependencies) - } } protected fun shouldExcludeDependency( diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/plugin/RNBrownfieldPlugin.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/plugin/RNBrownfieldPlugin.kt index f698338b..250ee11c 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/plugin/RNBrownfieldPlugin.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/plugin/RNBrownfieldPlugin.kt @@ -42,10 +42,7 @@ class RNBrownfieldPlugin */ if (this.isExpoProject) { Logging.log("Expo project detected.") - ExpoPublishingHelper( - brownfieldAppProject = project, - expoProject = maybeExpoProject!!, - ).configure() + project.evaluationDependsOn(EXPO_PROJECT_LOCATOR) } RNSourceSets.configure(project, extension) @@ -54,6 +51,12 @@ class RNBrownfieldPlugin project.afterEvaluate { afterEvaluate() + + if (this.isExpoProject) { + ExpoPublishingHelper( + brownfieldAppProject = project, + ).afterEvaluate() + } } } From 97bf0ed9d4253e5fb39430a92914ad66bc98baa0 Mon Sep 17 00:00:00 2001 From: Hur Ali Date: Sun, 22 Feb 2026 14:06:03 +0500 Subject: [PATCH 2/7] feat: only add compile scoped dependencies --- .../react/brownfield/expo/ExpoPublishingHelper.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt index 135f5c52..16c83a41 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt @@ -7,7 +7,6 @@ import com.callstack.react.brownfield.expo.utils.DependencyInfo import com.callstack.react.brownfield.expo.utils.ExpoGradleProjectProjection import com.callstack.react.brownfield.expo.utils.VersionMediatingDependencySet import com.callstack.react.brownfield.expo.utils.asExpoGradleProjectProjection -import com.callstack.react.brownfield.plugin.RNBrownfieldPlugin.Companion.EXPO_PROJECT_LOCATOR import com.callstack.react.brownfield.shared.Constants import com.callstack.react.brownfield.shared.Logging import groovy.json.JsonOutput @@ -352,14 +351,18 @@ open class ExpoPublishingHelper(val brownfieldAppProject: Project) { ) { dependenciesNodes.forEach { depNodeList -> depNodeList.childNodes.forEach { depNode -> - // below: some nodes are not dependencies, but pure text, in which case their name is '#text' - if (depNode.nodeName == "dependency") { + /** + * below: some nodes are not dependencies, but pure text, in which case their name is '#text' + * + * only add dependencies with compile scope + */ + val scope = depNode.getChildNodeByName("scope")?.textContent + if (depNode.nodeName == "dependency" && scope == "compile") { val groupId = depNode.getChildNodeByName("groupId")!!.textContent val maybeArtifactId = depNode.getChildNodeByName("artifactId") val artifactId = maybeArtifactId!!.textContent val version = depNode.getChildNodeByName("version")?.textContent - val scope = depNode.getChildNodeByName("scope")?.textContent val optional = depNode.getChildNodeByName("optional")?.textContent val dependencyInfo = @@ -367,7 +370,7 @@ open class ExpoPublishingHelper(val brownfieldAppProject: Project) { groupId = groupId, artifactId = artifactId, version = version, - scope = scope ?: "compile", + scope = scope, optional = optional?.toBoolean() ?: false, ) From 3aa095da78a5b717f735c9a05d607a2dd88798f1 Mon Sep 17 00:00:00 2001 From: Hur Ali Date: Sun, 22 Feb 2026 14:06:51 +0500 Subject: [PATCH 3/7] feat: only add api and implementation configuration dependencies --- .../com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt index 16c83a41..7d5906fc 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt @@ -398,7 +398,7 @@ open class ExpoPublishingHelper(val brownfieldAppProject: Project) { } } .filter { cfg -> - setOf("compile", "implementation", "api", "runtime").any { + setOf("implementation", "api").any { cfg.name.contains(it, ignoreCase = true) } } From 8684bca6c745d83af97a63413badfd64c628a311 Mon Sep 17 00:00:00 2001 From: Hur Ali Date: Sun, 22 Feb 2026 14:07:34 +0500 Subject: [PATCH 4/7] feat: use getByName to reduce array operations --- .../brownfield/expo/ExpoPublishingHelper.kt | 41 +++++-------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt index 7d5906fc..1d101d79 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt @@ -384,38 +384,19 @@ open class ExpoPublishingHelper(val brownfieldAppProject: Project) { pkgProject: Project, dependencies: VersionMediatingDependencySet, ) { - pkgProject.configurations - .filter { cfg -> - setOf( - "test", - "androidTest", - "kapt", - "annotationProcessor", - "lint", - "detached", - ).none { - cfg.name.contains(it, ignoreCase = true) - } - } - .filter { cfg -> - setOf("implementation", "api").any { - cfg.name.contains(it, ignoreCase = true) + listOf("implementation", "api").forEach { + pkgProject.configurations.getByName(it).dependencies.forEach { dep -> + if (dep.group != null) { + dependencies.add( + DependencyInfo.fromGradleDep( + groupId = dep.group!!, + artifactId = dep.name, + version = dep.version, + ), + ) } } - .forEach { cfg -> - cfg.dependencies - .filter { dep -> - dep.group != null - }.forEach { dep -> - dependencies.add( - DependencyInfo.fromGradleDep( - groupId = dep.group!!, - artifactId = dep.name, - version = dep.version, - ), - ) - } - } + } } /** From 6889d4601635cd616a4b2ca428599aef3083d400 Mon Sep 17 00:00:00 2001 From: Hur Ali Date: Mon, 23 Feb 2026 13:47:33 +0500 Subject: [PATCH 5/7] fix: indentation and unused import --- .../brownfield/expo/ExpoPublishingHelper.kt | 42 +++++++++---------- .../react/brownfield/shared/Constants.kt | 1 - 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt index 1d101d79..79912362 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt @@ -31,33 +31,33 @@ fun Node.getChildNodeByName(nodeName: String): Node? { open class ExpoPublishingHelper(val brownfieldAppProject: Project) { fun afterEvaluate() { - val discoverableExpoProjects = getDiscoverableExpoProjects() + val discoverableExpoProjects = getDiscoverableExpoProjects() - Logging.log( - "Discovered ${discoverableExpoProjects.size} discoverable Expo projects: " + - discoverableExpoProjects.joinToString( - ", ", - ) { it.name }, - ) + Logging.log( + "Discovered ${discoverableExpoProjects.size} discoverable Expo projects: " + + discoverableExpoProjects.joinToString( + ", ", + ) { it.name }, + ) - val expoTransitiveDependencies = - discoverAllExpoTransitiveDependencies( - expoProjects = discoverableExpoProjects, - ) + val expoTransitiveDependencies = + discoverAllExpoTransitiveDependencies( + expoProjects = discoverableExpoProjects, + ) + Logging.log( + "Collected a total of ${expoTransitiveDependencies.size} unique Expo transitive " + + "dependencies for brownfield app project publishing", + ) + expoTransitiveDependencies.forEach { Logging.log( - "Collected a total of ${expoTransitiveDependencies.size} unique Expo transitive " + - "dependencies for brownfield app project publishing", + "(*) dependency ${it.groupId}:${it.artifactId}:${it.version} (scope: ${it.scope}, " + + "${if (it.optional) "optional" else "required"})", ) - expoTransitiveDependencies.forEach { - Logging.log( - "(*) dependency ${it.groupId}:${it.artifactId}:${it.version} (scope: ${it.scope}, " + - "${if (it.optional) "optional" else "required"})", - ) - } + } - reconfigurePOM(expoTransitiveDependencies) - reconfigureGradleModuleJSON(expoTransitiveDependencies) + reconfigurePOM(expoTransitiveDependencies) + reconfigureGradleModuleJSON(expoTransitiveDependencies) } protected fun shouldExcludeDependency( diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/shared/Constants.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/shared/Constants.kt index 2cb03925..f04eb43e 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/shared/Constants.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/shared/Constants.kt @@ -2,7 +2,6 @@ package com.callstack.react.brownfield.shared import com.callstack.react.brownfield.expo.utils.DependencyInfo import com.callstack.react.brownfield.utils.StringMatcher -import io.github.g00fy2.versioncompare.Version /** * A condition that checks if a certain Expo version meets specific criteria From a1ab2b5525588defd4bad710a87c57ee0af0c8a8 Mon Sep 17 00:00:00 2001 From: Hur Ali Date: Mon, 23 Feb 2026 13:59:41 +0500 Subject: [PATCH 6/7] fix: pr comments --- .../react/brownfield/expo/ExpoPublishingHelper.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt index 79912362..1087c588 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt @@ -354,10 +354,10 @@ open class ExpoPublishingHelper(val brownfieldAppProject: Project) { /** * below: some nodes are not dependencies, but pure text, in which case their name is '#text' * - * only add dependencies with compile scope + * Only add dependencies with compile scope, if scope is null, default to compile */ val scope = depNode.getChildNodeByName("scope")?.textContent - if (depNode.nodeName == "dependency" && scope == "compile") { + if (depNode.nodeName == "dependency" && (scope == null || scope == "compile")) { val groupId = depNode.getChildNodeByName("groupId")!!.textContent val maybeArtifactId = depNode.getChildNodeByName("artifactId") @@ -370,7 +370,7 @@ open class ExpoPublishingHelper(val brownfieldAppProject: Project) { groupId = groupId, artifactId = artifactId, version = version, - scope = scope, + scope = scope ?: "compile", optional = optional?.toBoolean() ?: false, ) @@ -385,7 +385,8 @@ open class ExpoPublishingHelper(val brownfieldAppProject: Project) { dependencies: VersionMediatingDependencySet, ) { listOf("implementation", "api").forEach { - pkgProject.configurations.getByName(it).dependencies.forEach { dep -> + val configuration = pkgProject.configurations.findByName(it) + configuration?.dependencies?.forEach { dep -> if (dep.group != null) { dependencies.add( DependencyInfo.fromGradleDep( From b3065e2ef1807970b0f542424837f6103630c884 Mon Sep 17 00:00:00 2001 From: Hur Ali Date: Mon, 23 Feb 2026 14:36:26 +0500 Subject: [PATCH 7/7] fix: account for variant specific configurations --- .../react/brownfield/expo/ExpoPublishingHelper.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt index 1087c588..348bddba 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/ExpoPublishingHelper.kt @@ -384,9 +384,11 @@ open class ExpoPublishingHelper(val brownfieldAppProject: Project) { pkgProject: Project, dependencies: VersionMediatingDependencySet, ) { - listOf("implementation", "api").forEach { - val configuration = pkgProject.configurations.findByName(it) - configuration?.dependencies?.forEach { dep -> + val configurations = pkgProject.configurations.matching { + it.name.contains("implementation", ignoreCase = true) || it.name.contains("api", ignoreCase = true) + } + configurations.forEach { + it.dependencies.forEach { dep -> if (dep.group != null) { dependencies.add( DependencyInfo.fromGradleDep(