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

API for Ordering artifacts collection #14148

Open
stephanenicolas opened this issue Aug 14, 2020 · 0 comments
Open

API for Ordering artifacts collection #14148

stephanenicolas opened this issue Aug 14, 2020 · 0 comments
Labels
a:feature A new functionality in:dependency-resolution engine metadata

Comments

@stephanenicolas
Copy link

stephanenicolas commented Aug 14, 2020

We are working on a problem on Android: removing duplicate resources (described in an xml file) between modules that provide conflicting resources values. In this case, the Android Gradle Plugin will query Gradle to get a list of artifacts that is obtained by linearizing the dependency tree. It does more or less this:

def runtimeConfiguration = project.configurations["debugRuntimeClasspath"]
  def artifactsForAaptMerging = runtimeConfiguration
          .incoming
          .artifactView { view ->
            view.attributes { attributeContainer ->
                attributeContainer.attribute(ARTIFACT_FORMAT, "android-compiled-dependencies-resources")
            }
          }
          .artifacts
          .artifacts

the list of artifacts, though, is ordered in a complex way that goes beyond the predictability power of a human brain: a simple edge change in the graph can totally change the order of the linearization, even between modules that do not conflict. Here is an example: https://github.com/stephanenicolas/Dependency-Resources-Linearization/.

From the Gradle team perspective, the same problem can be applied to dependencies providing conflicting classes and Gradle has to determine which comes first to produce a classpath. It appears that the order would be quite difficult to control in cases where 2 dependencies with the same classes, an unvoluntary change in the dependency graph could swap classes being used at runtime (no, swapping the 2 dependencies isn't the only way to influence the graph, please read the repo's readme above).

There is already an API to control this in Gradle:


but this API only provides 3 enum values for odering.

Ideally, here we would have an API that lets us specify an ordering freely. In our case, we don't want to provide a complete ordering relation, but a partial ordering. We want to express that dependencyA < dependencyB. It would not be satisfying to provide a comparator.

An efficient implementation of a partial ordering like this could be achieved in O(n) where we would swap unordered dependencies in the linearized DAG. It would give a O(mxn) where m is the number of rules, and n the number of dependencies.

The API could still be provided as a resolution strategy ordering, but maybe as a linear ordering priority pairs list. Ultimately this list could be added to any plugin's DSL when needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:feature A new functionality in:dependency-resolution engine metadata
Projects
None yet
Development

No branches or pull requests

5 participants