-
Notifications
You must be signed in to change notification settings - Fork 329
fix: skip deep dependency comparison for Gradle projects #9817
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix: skip deep dependency comparison for Gradle projects #9817
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #9817 +/- ##
============================================
- Coverage 56.47% 56.46% -0.02%
Complexity 1572 1572
============================================
Files 328 328
Lines 12381 12385 +4
Branches 1162 1163 +1
============================================
+ Hits 6992 6993 +1
- Misses 4926 4928 +2
- Partials 463 464 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
a3c19f7
to
86d09b3
Compare
There are some test differences to inspect. |
For whatever reason, the change causes a lot of the following differences in the dependency tree: It basically seems that cycles are now cut too early or so. |
Or actually, it seems that runtime dependencies are omitted now. Take a look at e.g. lifecycle-livedata-core:2.5.0:
|
86d09b3
to
05b57b9
Compare
val dependencies2 = dependencies.associateBy { dependencyHandler.identifierFor(it) } | ||
if (!dependencies2.keys.containsAll(dependencies1)) return false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, @oheger-bosch do you recall why the original code uses an "uni-directional" containsAll()
here? In other words, why did we continue here if dependencies2
was a superset of dependencies1
, instead of also returning false
early?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is because the two sets only contain identifier IDs, but it has to be checked whether the structure of the dependency sub trees is identical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, ok, but that does not really answer my question why we can't / shouldn't do
if (dependencies1 != dependencies2.keys) return false
because if those sets of IDs are not equal, also their sub-trees cannot be equal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's anyway extract this a bit unrelated change: #9940
Head branch was pushed to by a user without write access
05b57b9
to
bbd5289
Compare
@sschuberth in order to make this solution workable, the selected variants need to be tracked. The same component may have a different set of dependencies, depending on which variant was selected. In most cases, it is only one, but Gradle also supports to select multiple in one scope under certain conditions. I added |
ae58a8c
to
7229394
Compare
Wit the change in this PR, the problem described in the description of #9763 no longer occurs. |
Changing the However, I wonder if even you even use the new property anywhere in this change? I couldn't find it. |
Yes I was afraid that it may not be a simple thing to do. Although, the change only adds a new field (
I is implicitly used by |
Yes, I would prefer not change that class. But if the information is only required during dependency resolution and not in the output, it should be possible to store it separately. @sschuberth I only commented on the identifier change because I haven't really looked into the issue itself, do you have comments on the remaining implementation? |
I haven't looked into any details here, but noticed the discussion. A smaller performance optimization alternative idea could be, to start from the original code and just introduce a |
@heliocastro, please try this PR (rebased to |
This comment was marked as outdated.
This comment was marked as outdated.
efbc14a
to
30b1b05
Compare
This comment was marked as outdated.
This comment was marked as outdated.
This makes the diff, if any, to expected results more readable. Signed-off-by: Sebastian Schuberth <sebastian@doubleopen.org>
This can be avoided as it leads to a long runtime (and possible an infinite loop / recursion) for large dependency graphs. In order to be able to skip the deep comparison, the selected variants need to be tracked in the Identifier. In the DependencyGraphBuilder all 'scopes' (runtimeClasspath, compileClasspath, ...) are thrown together. Gradle may have selected different variants of the components in different 'scopes'. Signed-off-by: Jendrik Johannes <jendrik.johannes@gmail.com>
30b1b05
to
8b36075
Compare
Local test results improved a lot with the current patch, for analyzer case. We we're able to finalize in 1/5 of the time now with less memory and no fault. |
This is unnecessary and leads to a long runtime (and possible an infinite loop/recursion) for large dependency graphs as observed in #9763.