-
Notifications
You must be signed in to change notification settings - Fork 10
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
Run ARQ during task serialization #72
Conversation
alright one final rebase I guess 🎉 thanks for splitting everything up |
- Solves the issue with configuration variants and mismatched attributes - Reflects the current best approach that Gradle suggests - They're hopefully going to provide better APIs in the future
d4c8f84
to
2163fa1
Compare
Done! |
t.getRootComponents().add(rootComponent); | ||
} | ||
|
||
Provider<List<ResolvedArtifactResult>> resolvedArtifactsProvider = | ||
t.getRootComponents() |
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 accessing the getRootComponents()
here feels a bit weird to me. Can we create an intermediate that can be shared so we can still set t.getRootComponents()...
and then reuse here?
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
Collection<ResolvedArtifactResult> resolvedArtifactResults) { | ||
return resolvedArtifactResults.stream() | ||
// ignore gradle API components as they cannot be serialized | ||
.filter(x -> !(x.getId().getComponentIdentifier() instanceof OpaqueComponentIdentifier)) |
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.
is there a reason we don't need this filter anymore?
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, must've lost it in the refactor
src/main/java/org/spdx/sbom/gradle/maven/DependencyResolver.java
Outdated
Show resolved
Hide resolved
src/main/java/org/spdx/sbom/gradle/maven/DependencyResolver.java
Outdated
Show resolved
Hide resolved
src/main/java/org/spdx/sbom/gradle/maven/DependencyResolver.java
Outdated
Show resolved
Hide resolved
LGTM, except some very minor things. Sorry it took me a little to read and understand what was going on. |
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 believe a separation of the arq result of poms and archives needs to happen.
src/main/java/org/spdx/sbom/gradle/maven/DependencyResolver.java
Outdated
Show resolved
Hide resolved
Hey yeah sorry I'm doing some of my own experiments to understand this. |
for (var configurationName : configurationNames) { | ||
Provider<Set<ResolvedArtifactResult>> artifacts = |
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.
Instead of inferring the artifact from the pom resolution, why not just keep this section in?
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 believe that's what causing the attribute mismatch errors
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.
Correct me if I'm wrong, but I thought that was the pom resolver stuff, while the artifact resolver was actually fine? I'm suggesting we still keep the code in here for dealing with POMs, and for the actual artifacts themselves keep the other section?
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'll try again and see what happens
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.
Although I'd think that it would be simpler to derive it from the POM vs resolving the artifact.
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.
Okay just for posterity, conversation continued here: https://gradle-community.slack.com/archives/CAHSN3LDN/p1699854619838439
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.
Based on that conversation I'll investigate some alternatives.
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.
Instead of inferring the artifact from the pom resolution, why not just keep this section in?
I tested this and it has issues resolving variants.
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.
Can you provide an example where this issue arises? It'd be nice to have a test to prevent regression and provide a sort of documentation via code on this specific 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.
I think it comes up with Kotlin Multiplatform dependencies. I'll try to get a failing test on main
a963c25
to
629b042
Compare
.artifactView( | ||
viewConfiguration -> | ||
viewConfiguration.attributes( | ||
attributes -> | ||
attributes.attribute( | ||
Attribute.of("artifactType", String.class), | ||
"android-aar-or-jar"))) |
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 turned out to be the solution for resolving normal artifacts. I was inspired by gradle/gradle#20779.
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.
629b042
to
7a9627f
Compare
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.
Sorry it took a while, I was on vacation.
* @see org.gradle.api.artifacts.dsl.DependencyHandler | ||
* @see org.gradle.api.artifacts.result.ResolvedArtifactResult | ||
*/ | ||
public class DependencyResolver { |
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 DependencyResolver is now only used for POMs, so can we rename it a bit? DependecyPomMapper? or something along those lines?
It might even make sense to just move this whole thing into PomResolver
.filter(ResolvedArtifactResult.class::isInstance) | ||
.map(ResolvedArtifactResult.class::cast) | ||
// ignore gradle API components as they cannot be serialized | ||
.filter(x -> !(x.getId().getComponentIdentifier() instanceof OpaqueComponentIdentifier)) |
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'm not actually sure this filter is useful here? Since we apply it above on the artifact transformer?
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.
True I'll remove it
.artifactView( | ||
viewConfiguration -> | ||
viewConfiguration.attributes( | ||
attributes -> | ||
attributes.attribute( | ||
Attribute.of("artifactType", String.class), | ||
artifactType))) |
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.
Would this now provide an incomplete sbom on a project with a war
dependency or something (in the weird war overlay case)? or if someone was importing any other non jar/aar type from a repository (a zip
or rar
for instance) that pulls in resources and stuff?
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.
Yes, technically. We can try covering as many cases as possible, and add support for plugins that provide artifact types (like Android), but I don't know if there's a way to get everything. Maybe there's an attribute other than artifactType to use. I'll look into it.
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.
Maybe it's possible to map the POM info into this and get a unique set of the packaging
from the POM and use that to set up the attributes. Not sure if that'll work, but it's an idea 😅
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 we can wait on that. This PR has had a lot of work done on it, I'd like to get it in soonish
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.
Can we just apply this filter in the android usecase? It appears this only happens when referencing a subproject from within an android project -- because android subprojects output all these crazy variants?
if android project {
apply artifactView
}
else {
just do what we were doing before
}
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'm just not super fond of applying the filter and potentially missing some cases (war, zip, rar, etc)
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 just applying the filter in the Android use case would work for now until there's another type of plugin that causes the same issue.
I'm experimenting with making filters based on the packaging in the poms.
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 was able to get it working by using a separate artifactView for each packaging found in the POMs, but it required some provider magic redirections (i.e. declare a property for the set of packagings at the top, flatMapping it to the artifactViews, and populating the packagings property later on in the file mapping from the pomInfo property).
It seems to be working pretty well. I tested on a regular Kotlin JVM project, a Kotlin JVM project that depends on a KMP project, and a KMP project, and it all worked fine. For the KMP project, using the jvm configuration resulted in an sbom referencing jar files, and using the js configuration resulted in an sbom referencing klib files (which was pretty cool).
Android was a trouble maker again, but that was because there are conflicts where requesting jar artifacts returns the classes.jar from the aar file. The workaround was to detect if there was an Android plugin and replace aar and jar with android-aar-or-jar in the list of packagings.
It seems to be working with the configuration cache, and from what I can tell the resolution is happening during the configuration phase, so it should be fine. Let me know what you want to do with that.
for (var configurationName : configurationNames) { | ||
Provider<Set<ResolvedArtifactResult>> artifacts = |
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.
Can you provide an example where this issue arises? It'd be nice to have a test to prevent regression and provide a sort of documentation via code on this specific case?
Addressed the PR comments. Working on getting a failing test case to demonstrate the attribute/variant issue |
Pushed a test case that fails on main but not on this branch. It is technically failing on this branch because there's no Android SDK defined. Options are:
Downside to 1 is that it will require that anyone running tests has the Android SDK at that specific location. Downside to 2 is that it is brittle. |
The test case was super helpful for me to understand the problem. We can apply a conditional run on the testcase using |
63b88bd
to
2222683
Compare
Adding the setup-android action requires using at least JDK 17 to build. Bumping that in the setup-java action should be fine (and updating Gradle to 8.5 should allow using JDK 21), as it's just used for building, and the target compat is set to 11. |
I think the problem with depending on the pom is that it's not an accurate representation of a variant. A variant can have any packaging, but the pom only shows what the "main" variant's packaging is. |
True, so then I guess the best approach would be to special case Android, and deal with any other variant issues similarly when they come up. |
This reverts commit 5ce33b4.
2222683
to
2810048
Compare
OK I made those changes, and surprise! there's another issue 😅 A Kotlin multiplatform (KMP) build that includes an android target would cause issues because the Android plugin is present, so we use the artifactView for aar-or-jar, but if you generate an sbom for the js target (for example, would apply to any non JVM target) then the klib dependencies aren't found (since the attribute filter is only looking for aar and jar). So we can change the condition to only use the artifactView if the android plugin is present, and the KMP plugin is not present, but that will cause the variant errors when generating an sbom for the android target. This might not be an issue in practice, since the user would probably be generating the sbom for a leaf module (e.g. an app), and with KMP those tend to only target one platform. What are your thoughts on that? |
So I'm not familiar enough with kotlin multiplatform to know user behavior with it. I think we get a version of this PR in now with what we kind of landed on earlier. And then we can deal with KMP in a followup. |
@eygraber so this is ready to merge? |
Yes, it should be! |
No description provided.