-
-
Notifications
You must be signed in to change notification settings - Fork 274
Add support for gradle resolver #1357
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
Add support for gradle resolver #1357
Conversation
|
This is great to see! Thank you! @smocherla-brex, I've had a stalled branch to do this exact same thing for months. Would you like to work together on this? I've put up my WIP as #1360, but I'm more than happy to drop it in favour of your work. Please feel free to lift anything you think is useful from my WIP PR! |
|
@shs96c Thanks for sharing your in-progress changes. I'm happy to help get this over the line. I'll take a look at your PR and see if I can leverage some of it in here later this week when I have cycles and hopefully get it in a place where it can be open for review. |
|
Update:
I'm hoping to get the above unblocked and the tests passing in the next few days and will open it up for review. |
|
@smocherla-brex, I really appreciate all the work you're doing on this. Thank you! When you're ready for review, just let us know. If you need a hand with anything, just ask :) |
| name = "regression_testing_gradle", | ||
| artifacts = [ | ||
| # https://github.com/bazel-contrib/rules_jvm_external/issues/909 | ||
| "androidx.compose.foundation:foundation-layout:1.5.0-beta01", |
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.
Added a couple of regression tests for the issues linked above/below.
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.
That's great. Thank you
|
|
||
| java_test( | ||
| name = "GradleResolverTest", | ||
| timeout = "eternal", |
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.
Increased the timeout here since the target takes about 5-6 minutes on my machine (seems to be longer about 8-9 minutes in CI) to complete as using an isolated instance of gradle per test and running things serially adds up quite a bit. We could look into test sharding if this is unacceptably slow.
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.
Thanks for the explanation. I think it's fine to leave as-is
|
This should be ready for review now @shs96c. It's possible my gradle implementation may not be optimal (as I'm not a gradle expert) but all tests are passing and I also added some regression tests and added comments where relevant for context. There's one job failure in |
|
This is fantastic. Thank you! I'll make sure to review this next week. |
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.
This is great stuff. Thank you so much for working on it. The only real blocker is the comment about the exclusions being included in the handlebars context as a Stream rather than a collection.
| name = "regression_testing_gradle", | ||
| artifacts = [ | ||
| # https://github.com/bazel-contrib/rules_jvm_external/issues/909 | ||
| "androidx.compose.foundation:foundation-layout:1.5.0-beta01", |
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.
That's great. Thank you
MODULE.bazel
Outdated
| fail_if_repin_required = True, | ||
| generate_compat_repositories = True, | ||
| lock_file = "//tests/custom_maven_install:regression_testing_gradle_install.json", | ||
| repin_instructions = "Please run `REPIN=1 bazel run @regression_testing_gradle//:pin` to refresh the lock file.", |
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.
We shouldn't need this line.
MODULE.bazel
Outdated
| "regression_testing_gradle", | ||
| "regression_testing_maven", | ||
| "unpinned_regression_testing_coursier", | ||
| "unpinned_regression_testing_gradle", |
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.
Nit: we shouldn't need to expose the unpinned_ version either. We used to need it for the :pin target, but that's no longer the case.
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.
Removed
|
|
||
| # How do we do artifact resolution? | ||
| "resolver": attr.string(doc = "The resolver to use. Only honoured for the root module.", values = ["coursier", "maven"], default = _DEFAULT_RESOLVER), | ||
| "resolver": attr.string(doc = "The resolver to use. Only honoured for the root module.", values = ["coursier", "maven", "gradle"], default = _DEFAULT_RESOLVER), |
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.
🎉
| import java.io.IOException; | ||
| import java.nio.file.Files; | ||
| import java.nio.file.Path; | ||
| import java.util.*; |
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.
If you bazel run scripts:format this wild card import should be expanded properly.
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.
Updated.
| List<GradleResolvedDependency> resolvedRoots, | ||
| Map<Coordinates, GradleResolvedDependency> coordinatesGradleResolvedDependencyMap, | ||
| List<GradleDependency> declaredDeps) { | ||
| ArtifactView sourcesView = |
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 had no idea about this mechanism for getting artifacts. Great stuff
| } | ||
|
|
||
| private boolean isVerbose() { | ||
| return System.getenv("RJE_VERBOSE") != null && System.getenv("RJE_VERBOSE").equals("true"); |
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.
Quite often people set RJE_VERBOSE to 1. It's enough that the env var isn't null
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.
updated
| public class PomUtil { | ||
| public static String extractPackagingFromPom(File pomFile) { | ||
| try { | ||
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
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 fine for now, but experience suggests that we'll need to use the Maven classes for parsing poms. We can definitely leave that change for later.
|
|
||
| java_test( | ||
| name = "GradleResolverTest", | ||
| timeout = "eternal", |
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.
Thanks for the explanation. I think it's fine to leave as-is
| import com.github.bazelbuild.rules_jvm_external.resolver.netrc.Netrc; | ||
|
|
||
|
|
||
| public class GradleResolverTest extends ResolverTestBase { |
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 am genuinely impressed that you managed to get all the tests passing. Very cool.
Thanks, updated the PR and addressed the feedback you shared. Also added a small update to the README about the new resolver. |
|
I've been looking at improving performance of the resolver as it's extremely slow right now (on our monorepo, it takes 15 mins+ which isn't great). My hunch for one of the reasons (not everything) based on testing so far is that it's really slow right now due to the serial nature of artifact resolution in the plugin for various artifact views (javadocs, source jars) and additionally serially downloading POMs for every artifact rather than batching. I'm going to try make some of those resolutions async and see if it helps the performance. |
|
After looking further into the slowness, I've made a few optimizations to improve the resolver:
To illustrate the improvement, I tested the gradle resolver on the Before: It took nearly 9 minutes to build the lockfile even for the small repo here. After (cold cache/no unsafe cache with removal of Javadoc/source jar resolution) It takes around 2.5 minutes, which is pretty significant. With warm/unsafe/gradle cache support, it is even faster It takes about 30 seconds in total. Overall, I think that's a pretty healthy improvement and could be considered something close to usable for an experimental implementation. There's likely room for more improvement though, especially for larger repos.. |
|
@smocherla-brex, I plan on merging this on Monday since it LGTM, but I'd like the other committers to also have a final chance to review. Thank you for working on this! |
…into smocherla/gradle-resolver
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.
It's great to see this working. We've had enough time to review, and I think the right thing to do now is to land this, and then iterate on top of it as we find things that we need to tinker with. The other committers have had time to review this, so I think it's reasonable to land this now.
Thank you for putting this together, and thank you for focusing on improving the speed!
* master: Update maven-metadata.xml when publishing locally (bazel-contrib#1369) Add support for gradle resolver (bazel-contrib#1357) Prepare for 6.8 release (bazel-contrib#1380)
* master: (39 commits) Fix resolution of Android/AAR artifacts with Gradle resolver (bazel-contrib#1395) fail_if_repin_required is now True by default and minor improvement to failure message (bazel-contrib#1397) Housekeeping before we release 6.8 (bazel-contrib#1384) Add dll, dylib and so types to maven package mappings (bazel-contrib#1392) [bzlmod] Allow suppressing warning about multiple contributing modules. (bazel-contrib#1393) Use the artifact default values when adding them to a struct and add tests for coursier artifacts that have empty versions provided by BOMs and don't inlcude them in outdated (bazel-contrib#1390) Allow package exclusions and inclusions in javadocs (bazel-contrib#1293) Document well-known issues with `bzlmod` (bazel-contrib#1388) Begin documenting the gradle resolver (bazel-contrib#1389) Run gradle regression tests in CI (bazel-contrib#1385) Modify maven_export to allow exporting zip archives (bazel-contrib#1368) Allow root module's override tags to take precedence over the overridees from transitive deps. (bazel-contrib#1381) Ensure root module artifacts and boms take precedence with warnings (bazel-contrib#1373) Update maven-metadata.xml when publishing locally (bazel-contrib#1369) Add support for gradle resolver (bazel-contrib#1357) Prepare for 6.8 release (bazel-contrib#1380) Remove the Windows `kt_jvm_export` example (bazel-contrib#1383) Avoid spurious warnings about poorly formatted artifact coordinates (bazel-contrib#1374) Flip `fail_if_repin_required` to `True` by default (bazel-contrib#1371) Allow the same coordinate to be overridden in different repos (bazel-contrib#1378) ...
This attempts to add support for a gradle resolver to support usecases like #864 and #909 (downloading the relevant JVM artifact without having to specify the JVM specific one, aka rely on Gradle metadata to do its magic).
I borrowed some of the work from @shs96c's PR in #1360. It works as follows:
runtimeClasspathconfiguration, collects the dependency graph, collects all the resolved artifacts (and requests additional things like javadoc, sources, poms). In this process, conflicts are also collected, and failures are reported.ToolingModelBuilderrequires serialization with interfaces, so there's a bit of boilerplate I had to add.Forgive me if my code is not idiomatic Java (it's been a while since I've worked with Java).
Checklist:
Follow-up work: