Skip to content
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

Incomplete reason explanation on multi capabilities #1170

Merged

Conversation

seregamorph
Copy link
Contributor

@seregamorph seregamorph commented Apr 18, 2024

If there is more than one dependency per sourceSet to the same module, but with different capabilities (like default one vs testFixtures), the reason --id :module explanation is incomplete. It shows only a single explanation of possible routes to dependency instead of all.

Root cause analysis: problem with ComputeAdviceTask toStringCoordinates

The problem is in ComputeAdviceTask:206. The dependencyUsages object is valid before serialization, but the stored object is first wrapped via toStringCoordinates call and there is a problem:

internal fun Map<Coordinates, Set<Usage>>.toStringCoordinates(buildPath: String): Map<String, Set<Usage>> =
  map { (key, value) ->
    toCoordinatesKey(key, buildPath) to value
  }.toMap()

Each calculated via toCoordinatesKey repeated key is simply lost in favor of the last one which just rewrites the map.

Root cause analysis: problem with ReasonTask getUsageFor

The fix of toStringCoordinates is not enough as there is the second place where the reason explanation blocks are squashed as well. There is a sorting method

private fun getUsageFor(id: String): Set<Usage> {
  return dependencyUsages.entries.find(id::equalsKey)?.value?.toSortedSet(Usage.BY_VARIANT)
    ?: annotationProcessorUsages.entries.find(id::equalsKey)?.value?.toSortedSet(Usage.BY_VARIANT)

which calls toSortedSet and it uses TreeSet under the hood. The problem is that even if there are Usage elements which are non-equal via equals, they are squashed if compareTo()==0 from sorting comparator. So it should be addressed too.

Before and after

The sample difference of reason task explanations before the fix:

...
Source: main
------------
(no usages)
...

vs after

...
Source: main
------------
* Uses 17 classes, 5 of which are shown: com.acme.Class1, com.acme.Class2, com.acme.Class3, com.acme.Class4, com.acme.Class5 (implies implementation).
* Provides 1 service loader: com.acme.MetaService (implies runtimeOnly).

Source: main
------------
(no usages)

Further plan

Once we agree on how to approach the issue I'd like to implement a functional test covering it. Existing functional tests seem to be fine.
Also it makes sense to enhance the output reason task explanation in case if Source: x is repeated, e.g. Source: x (via module-dependency-test-fixtures) specifying the according capabilities.

@seregamorph seregamorph changed the title Reason multi dependency capabilities Incomplete reason explanation on multi capabilities Apr 18, 2024
Copy link
Collaborator

@jjohannes jjohannes left a comment

Choose a reason for hiding this comment

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

These changes look very reasonable to me. Good find!

Adding some test for this would be great! (But since there has been no test coverage before and all current tests are still passing, this could be done in a follow up I think.)

@autonomousapps autonomousapps merged commit 71cf517 into autonomousapps:main May 7, 2024
1 check passed
@seregamorph seregamorph deleted the reason-multi-dependencies branch May 8, 2024 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants