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

Per variant classpath support #89

Closed

Conversation

arunkumar9t2
Copy link
Contributor

@arunkumar9t2 arunkumar9t2 commented Jun 29, 2023

Proposed Changes

Continuation from

to implement Gradle like multiple classpath support in Bazel. In Gradle, each android variant can have its own classpath, for example debugImplementation extends from implementation and at the same time can use a different version of dependency in debug variant. This is not possible to achieve in current maven_install rules we are generating since artifacts appearing in maven_install go through dependency resolution at once. So even if we have artifact:1.0.0 and artifact:1.0.0-debug, due to dependency resolution only one of them will get picked which is not correct.

To solve the multiple classpath problem, we could generate several maven_install thus forcing each one to resolve differently. While that works they are disjointed and transitives might get duplicated across each one and that is not how Gradle's extendsFrom work. To resolve this problem, we could link several maven_installs by using override_targets feature whereby we generate overrides for transitives if we detect they are being duplicated. This allows us to have multiple classpath as well as not break the One Version Enforcement rule. Which is exactly what is being attempted in this change.

Notable behavior changes

  • Generate multiple maven_installs if we detect we need them, usually when variant specific configuration is used in Gradle like debugImplementation.
  • Include the transitives in generated maven_install to avoid dependency resolution conflicts in Bazel (mostly due to coursier, being addressed by Introduce a new maven dependency resolver bazelbuild/rules_jvm_external#807 ). Explicit transitives + version_conflict_policy set to pinned ensure same classpath from Gradle is being used.
  • Dependency resolution is now cacheable and up-to-date compatible through use of separate variant specific tasks to resolve dependencies and extract metadata. Unlike current implementation, dependency resolution also happens in parallel and thus improving migrateToBazel performance especially on large projects.

Implementation notes

Resolving dependencies

Resolving dependencies now follow best practices by implementing a dedicated task ResolveVariantDependenciesTask with variant specific resolution result as input. Relationship between variants are also carried into this task, for example consider a variant graph like below

graph LR
    debug --> default
    flavor1Debug-->debug
    flavor1Debug-->flavor1

Then the same relationship is established in each ResolveVariantDependenciesTask instance, this is due to unverified assumption and aim to mimic topological sort that happens during dependency resolution.

Computing workspace entries

ComputeWorkspaceDependenciesTask is added as an aggregator and is now the source of truth for all computed dependencies. It collects all jsons from each ResolveVariantDependenciesTask to calculate the versions, exclude rules, repositories, override targets and ultimately the final classpath. This is serialized to disk as json.

Dependency resolution service

Classpath computed by ComputeWorkspaceDependenciesTask needs to be queried in other tasks as well, to speed and to cache the json parsing result, a shared service is used. Implemented such a way that it is compatible with both FROM-CACHE or UP-TO-DATE state of ComputeWorkspaceDependenciesTask

Result serialization

Serializing to disk is essential for using Gradle's task up to date check. Currently we use json and kotlinx.serialization but protobuf can be investigated if serialisation is a bottleneck.

Results

Screenshot 2023-07-10 at 12 29 51 PM

Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Signed-off-by: arunkumar9t2 <arunk.beece@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants