Not all modules are detected at once
I have a project with about 100 modules. When running your plugin on the root app module it doesn't see all modules.
My setup:
app/build.gradle.kts:
plugins {
// ...
id("com.jraska.module.graph.assertion") version "2.4.1"
}
// no custom configuration in moduleGraphAssert
dependencies {
implementation(project(":amount"))
// ...
}
core/build.gradle.kts:
plugins {
// ...
id("com.jraska.module.graph.assertion") version "2.4.1"
}
// no custom configuration in moduleGraphAssert
dependencies {
api(project(":tools"))
// ...
}
Gradle version: 8.1.1
Actual
Output of ./gradlew generateModulesGraphStatistics --rerun-tasks:
...
> Task :app:generateModulesGraphStatistics
GraphStatistics(modulesCount=79, edgesCount=82, height=2, longestPath=':app -> :amount -> :core')
> Task :core:generateModulesGraphStatistics
GraphStatistics(modulesCount=7, edgesCount=6, height=1, longestPath=':core -> :tools')
Expected
From the longestPath, you can notice that app depends on core, and core depends on tools. But then the longest path of app should actually be longestPath=':app -> :amount -> :core -> :tools', no? (In my case, there should be also much longer chains, I just use output of the plugin here as an example.)
Notes
The other tasks seem to have the same problem. For example when I set moduleGraphAssert { maxHeight = 2 } and run assertModuleGraph, it doesn't fail.
It also doesn't change the output of app tasks when I remove the plugin from core module - I've added it there for debugging.
Switching api and implementation in various ways doesn't help either.
I have tested this also with org.gradle.configuration-cache=false in gradle.properties.
Let me know if you have any hint or you want more info. I can't share my project.
Hi! I had a similar problem. The solution for me was to put all the relevant configuration to the root build.gradle file, not into the app module's build.gradle file.
In my root build gradle file I applied the plugin (right after the buildscript closure):
plugins {
id "com.jraska.module.graph.assertion" version "$modules_graph_assert_version"
}
apply from: "${project.rootDir}/buildsystem/moduleConfig.gradle"
allprojects {
moduleGraphAssert {
maxHeight = 10
allowed = [
'app-module -> feature-module',
'app-module -> feature-module-top',
'app-module -> common-module',
'app-module -> legacy-module',
'feature-module -> common-module',
'feature-module -> legacy-module',
'feature-module-top -> common-module',
'feature-module-top -> legacy-module',
'feature-module-middle -> common-module',
'feature-module-middle -> legacy-module',
'feature-module-bottom -> common-module',
'feature-module-bottom -> legacy-module',
'feature-module-top -> feature-module-middle',
'feature-module-middle -> feature-module-bottom',
'common-module -> common-module',
'common-module -> legacy-module',
'legacy-module -> common-module',
'legacy-module -> legacy-module'
]
configurations = ['api', 'implementation']
assertOnAnyBuild = true
}
}
In the moduleConfig.gradle file I have the module aliases defined (and some other stuff that is not related to this plugin). This way for example (omitting the real module names here):
project(":my-awasome-module") {
ext {
moduleNameAssertAlias = 'feature-module'
}
}
It seems for me that the 2 main things that helped are to apply the plugin to the root project (and not to the project that is the root of the dependency graph) and to apply the config to all the modules. Maybe the documentation could be a little bit more obvious on this.
Hey, thanks for reporting those - there might be 2 actions now which would help to understand this:
-
Try using
--no-configure-on-demand- this might be one hypothesis that Gradle simply doesn't configure these projects for some cases -
Debug the Gradle modules extraction and see if the modules are in the
subprojectscollection - see if the modules are actually loaded into Graph - if 1. ☝️ is true - they won't be there. If false then there is another bug.
Thanks for checking and sorry for the late response - summer season :)
--no-configure-on-demand did not fix the issue on our monorepo, and we can see all modules configuring properly with debug logs and gradle scans.
I'll try debugging it, but our project already relies on included-build that need this dependency. Not sure how it will behave.
Adding breakpoints inside the IDE was enough, and here is the result for subprojects
Applying the plugin on the root module as well (without the configuration block) and executing this did the trick for us.
gradlew :generateModulesGraphStatistics -Pmodules.graph.of.module=:MyAppModule --no-configure-on-demand --no-configuration-cache
Applying the plugin on the root module as well (without the configuration block) and executing this did the trick for us.
@SimonMarquis thanks for sharing!
Thanks all for sharing insights! + sorry all for later reply - holidays season 🌴
What we know: Workaround: Apply the plugin to the root project solves the issue
I would still like to fully understand why. The hypothesis is that the plugin tries to iterate over the modules and dependencies in memory too soon, whilst Gradle loads some of these lazily or perhaps not at all. 🤔 Without reproducible sample it is really hard to understand, therefore I have 4 options for proposal on how to get to the bottom of it.
- Sharing your project Gradle configuration - likely not possible or requiring a lot of effort to not expose intellectual property - though if anyone is willing to do that - that would help the most to resolve the issue fast. :)
- Sharing a sample reproducing the issue.
- Connecting with me on Twitter or LinkedIn and arranging a call debugging the issue.
- I can provide a branch with some debugging info and anonymizing the names of the modules - might not be enough, but easiest for anyone to try 🤷
If anyone in this issue is willing to spend some time on this, let me know ;)
Hey, anyone willing to follow up with example or help debugging please? Options here.
I think the problem still exists but without reproducing it is hard to move forward. I intend to close the issue as stale otherwise. 🤷
hey @jraska
I was able to reproduce a similar issue in the github-client repo. Here is the patch to the current master, or fork.
I'm struggling with running commands per individual module, eg:
./gradlew :feature:about:dependencies --configuration debugCompileClasspath
Adding --no-configure-on-demand helps execute the command above, but I wonder if there’s a way to fix this on the plugin side so I don’t have to explicitly tell gradle that.
Hope this helps EDIT: created #260
@haluzpav , @nyekilajos , @SimonMarquis , @max1lyu
Please if you can, give version 2.7.0 a try. There is a possibility it will solve your issue.
In case it does, please let me know. Thanks!
Hi @jraska. I just tried version 2.7.0, it doesn't seem to fix the issue that I had
Thanks a lot @max1lyu. I assume also not even with the --no-configure-on-demand flag. 🤔
no no, it does work when --no-configure-on-demand flag is used, so it's a saver yes