Skip to content

feat(gradle): use project configurations to determine project dependencies#32704

Merged
FrozenPandaz merged 5 commits intomasterfrom
gradle-use-configuration-dependencies
Sep 15, 2025
Merged

feat(gradle): use project configurations to determine project dependencies#32704
FrozenPandaz merged 5 commits intomasterfrom
gradle-use-configuration-dependencies

Conversation

@MaxKless
Copy link
Copy Markdown
Contributor

@MaxKless MaxKless commented Sep 11, 2025

Current Behavior

gradle dependencies are hardcoded to included builds & subprojects

Expected Behavior

we use project configurations to determine dependencies like the tooling api does

Related Issue(s)

Fixes #

@MaxKless MaxKless requested review from a team, Coly010, FrozenPandaz and lourw as code owners September 11, 2025 16:23
@vercel
Copy link
Copy Markdown

vercel Bot commented Sep 11, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
nx-dev Ready Ready Preview Sep 12, 2025 8:39pm

@nx-cloud
Copy link
Copy Markdown
Contributor

nx-cloud Bot commented Sep 11, 2025

View your CI Pipeline Execution ↗ for commit 44c99d3

Command Status Duration Result
nx run-many -t check-imports check-commit check... ✅ Succeeded 1m 56s View ↗
nx affected --targets=lint,test,build,e2e,e2e-c... ✅ Succeeded 53s View ↗
nx-cloud record -- nx-cloud conformance:check ✅ Succeeded 2s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded 5s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 5s View ↗
nx documentation ✅ Succeeded 2m 39s View ↗

☁️ Nx Cloud last updated this comment at 2025-09-12 20:36:46 UTC

Comment on lines +5 to +6
import org.gradle.api.internal.artifacts.result.DefaultResolvedDependencyResult
import org.gradle.internal.component.local.model.DefaultProjectComponentSelector
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Dependency on internal Gradle APIs creates brittleness

The code imports and uses internal Gradle implementation classes (DefaultResolvedDependencyResult and DefaultProjectComponentSelector) that aren't part of Gradle's public API contract. These internal classes can change without notice between Gradle versions.

Consider using the public API interfaces instead:

import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.gradle.api.artifacts.component.ProjectComponentSelector

This would make the implementation more robust against Gradle upgrades and follow Gradle's recommended practices for plugin development.

Suggested change
import org.gradle.api.internal.artifacts.result.DefaultResolvedDependencyResult
import org.gradle.internal.component.local.model.DefaultProjectComponentSelector
import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.gradle.api.artifacts.component.ProjectComponentSelector

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

nx-cloud[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud Bot left a comment

Choose a reason for hiding this comment

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

Nx Cloud is proposing a fix for your failed CI:

We have automatically formatted the ProjectDependencyUtils.kt file using ktfmt to fix the linting errors. This includes proper indentation, import organization, and code style consistency to match the project's Kotlin formatting standards.

We verified this fix by re-running gradle-project-graph:lint.

Suggested Fix changes
diff --git a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/ProjectDependencyUtils.kt b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/ProjectDependencyUtils.kt
index 8b2b35f..f001de4 100644
--- a/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/ProjectDependencyUtils.kt
+++ b/packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/ProjectDependencyUtils.kt
@@ -2,60 +2,54 @@ package dev.nx.gradle.utils
 
 import dev.nx.gradle.data.Dependency
 import org.gradle.api.Project
-
-import org.gradle.api.artifacts.result.ResolvedDependencyResult
 import org.gradle.api.artifacts.component.ProjectComponentSelector
-
+import org.gradle.api.artifacts.result.ResolvedDependencyResult
 
 private val dependencyCache = mutableMapOf<Project, Set<Dependency>>()
 
 fun getDependenciesForProject(project: Project): MutableSet<Dependency> {
-    return dependencyCache
-        .getOrPut(project) { buildDependenciesForProject(project) }
-        .toMutableSet() // Return a new mutable copy to prevent modifying the cached set
+  return dependencyCache
+      .getOrPut(project) { buildDependenciesForProject(project) }
+      .toMutableSet() // Return a new mutable copy to prevent modifying the cached set
 }
 
 private fun buildDependenciesForProject(project: Project): Set<Dependency> {
-    val dependencies = mutableSetOf<Dependency>()
-
-    val sourcePath = project.projectDir.absolutePath
-    val sourceFilePath = project.buildFile.takeIf { it.exists() }?.absolutePath ?: ""
-
-    project.configurations
-        .matching { it.isCanBeResolved }
-        .forEach { conf ->
-            try {
-                conf.incoming.resolutionResult.allDependencies.forEach { dependency ->
-                    if (dependency is ResolvedDependencyResult) {
-                        val requested = dependency.requested
-                        if (requested is ProjectComponentSelector) {
-                            val dependentProject =
-                                project.findProject(requested.projectPath)
-
-                            if (
-                                dependentProject != null &&
-                                    dependentProject.projectDir.exists() &&
-                                    dependentProject.buildFile.exists()
-                            ) {
-
-                                val targetPath = dependentProject.projectDir.absolutePath
-
-                                dependencies.add(
-                                    Dependency(
-                                        source = sourcePath,
-                                        target = targetPath,
-                                        sourceFile = sourceFilePath,
-                                    )
-                                )
-                            }
-                        }
-                    }
+  val dependencies = mutableSetOf<Dependency>()
+
+  val sourcePath = project.projectDir.absolutePath
+  val sourceFilePath = project.buildFile.takeIf { it.exists() }?.absolutePath ?: ""
+
+  project.configurations
+      .matching { it.isCanBeResolved }
+      .forEach { conf ->
+        try {
+          conf.incoming.resolutionResult.allDependencies.forEach { dependency ->
+            if (dependency is ResolvedDependencyResult) {
+              val requested = dependency.requested
+              if (requested is ProjectComponentSelector) {
+                val dependentProject = project.findProject(requested.projectPath)
+
+                if (dependentProject != null &&
+                    dependentProject.projectDir.exists() &&
+                    dependentProject.buildFile.exists()) {
+
+                  val targetPath = dependentProject.projectDir.absolutePath
+
+                  dependencies.add(
+                      Dependency(
+                          source = sourcePath,
+                          target = targetPath,
+                          sourceFile = sourceFilePath,
+                      ))
                 }
-            } catch (e: Exception) {
-                // Log the error but don't fail the build
-                project.logger.debug("Error processing configuration ${conf.name}: ${e.message}")
+              }
+            }
+          }
+        } catch (e: Exception) {
+          // Log the error but don't fail the build
+          project.logger.debug("Error processing configuration ${conf.name}: ${e.message}")
         }
+      }
 
-    return dependencies
+  return dependencies
 }

Apply fix via Nx Cloud  Reject fix via Nx Cloud  Nx CloudView interactive diff and more actions ↗


⚙️ An Nx Cloud workspace admin can disable these reviews in workspace settings.

@lourw lourw force-pushed the gradle-use-configuration-dependencies branch from 815f5aa to 44c99d3 Compare September 12, 2025 20:28
@FrozenPandaz FrozenPandaz merged commit 537bb42 into master Sep 15, 2025
15 checks passed
@FrozenPandaz FrozenPandaz deleted the gradle-use-configuration-dependencies branch September 15, 2025 14:42
FrozenPandaz pushed a commit that referenced this pull request Sep 18, 2025
…cies (#32704)

## Current Behavior
gradle dependencies are hardcoded to included builds & subprojects

## Expected Behavior
we use project configurations to determine dependencies like the tooling
api does

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

---------

Co-authored-by: lourw <56288712+lourw@users.noreply.github.com>
(cherry picked from commit 537bb42)
jaysoo pushed a commit that referenced this pull request Sep 19, 2025
…cies (#32704)

## Current Behavior
gradle dependencies are hardcoded to included builds & subprojects

## Expected Behavior
we use project configurations to determine dependencies like the tooling
api does

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

---------

Co-authored-by: lourw <56288712+lourw@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Sep 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants