Skip to content

Incomplete reason explanation on multi capabilities#1170

Merged
autonomousapps merged 1 commit intoautonomousapps:mainfrom
seregamorph:reason-multi-dependencies
May 7, 2024
Merged

Incomplete reason explanation on multi capabilities#1170
autonomousapps merged 1 commit intoautonomousapps:mainfrom
seregamorph:reason-multi-dependencies

Conversation

@seregamorph
Copy link
Copy Markdown
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
Copy Markdown
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
@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