-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
feat(java): add support licenses and graph for gradle lock files #6140
feat(java): add support licenses and graph for gradle lock files #6140
Conversation
I see you're trying to parse the
I applaud you for what you're trying to do, but I think it may just not be worth the effort and could easily lead to some confusing behaviour. Edit: That being said, I don't have any better idea how we could retrieve the direct dependencies of a gradle project, at least not without executing the gradle command. This is really a tricky problem. |
Hello @ChristianCiach
I haven't found a better way either. I thought I'd start with this and get some feedback from users. Perhaps together we will find a better way. |
I didn't test your changes yet, but looking at the code, it will probably break on this construct: dependencies {
implementation("com.google.guava:guava:32.1.3-jre") {
exclude(group = "com.google.code.findbugs", module = "jsr305")
}
implementation("com.fasterxml.jackson.core:jackson-databind:2.16.1")
} The Please don't interpret my comments as negative critique. I love what you're doing! Since gradle-support is important to me, I just want to write down my thoughts and ideas. |
Great! Thanks! I will add logic for this case.
Are other words possible here (I mean non UPD: |
That's the issue: Gradle-build-files are just scripts (Groovy or Kotlin) and can contain anything. For example: dependencies {
val maybeDependency = "com.fasterxml.jackson.core:jackson-databind:2.16.1"
if (project.hasProperty("someProperty")) {
implementation(maybeDependency)
}
}
Now it would break again on the closing That's why I am so sceptical of your approach of parsing the
Yeah, I see myself as a bit of a gradle expert. I have been thinking about other approaches to detect direct dependencies of a gradle project and I think I've come up with something nicer: As said in a previous comment, many people are using version catalogs to declare their direct dependencies. By convention (see documentation), the version catalog is a TOML file located at Please keep in mind that a "version-catalog" declares dependencies that a gradle project may (or may not!) use in their Or to put it another way: If we could reliably parse a |
Another approach, but this is also not guaranteed to lead to correct results: When constructing the dependency graph, maybe we should just declare the "roots" (the opposite of the leafs) as "direct dependencies"? As "roots" I mean dependencies that are not dependencies of other dependencies of the graph. Of course, this is a bit wonky, but so is the current approach. It's wonky because a dependency could be both a direct and a transitive dependency of a gradle project. Edit: I think I vastly prefer this approach, even if it results in a few missing direct dependencies. Of all the approaches proposed so far, this is the only one that would mostly work for us, because we use external version-catalogs: https://docs.gradle.org/current/userguide/platforms.html#sec:importing-published-catalog |
Thanks for your opinion!
The more I work on this problem the more I agree with you.
IIUC we already have similar logic : trivy/pkg/report/table/vulnerability.go Lines 317 to 328 in 8221473
We can mark all dependencies as |
Yes, this is exactly what I was saying :) I like it, and I think this is more than "good enough" for now! I am sorry that I cannot contribute any code for this. I am fluent in Java and Python, but I am not yet confident enough in my Go skills, unfortunately. Edit:
Sorry, I do not understand this part. |
Sorry, this is typo. I meant
Thank you for your help. I thought about using this logic, but had my doubts. But now I think we really should have chosen this way. |
// There is no reliable way to determine direct dependencies (even using other files). | ||
// Therefore, we mark all dependencies as Indirect. | ||
// This is necessary to try to guess direct dependencies and build a dependency tree. | ||
Indirect: 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.
I see a second way:
we can mark Gradle dependencies as indirect when before building the dependency tree -
trivy/pkg/report/table/vulnerability.go
Line 210 in 8221473
func (r *vulnerabilityRenderer) renderDependencyTree() { |
It may be worth re-visiting this idea when "declarative gradle" becomes a thing: Parsing a declarative gradle build file surely is a lot more feasible than parsing a gradle script file. This will be very similar to parsing a maven |
@ChristianCiach a more interesting approach would be to use Gradle's own tooling to generate dependency trees and BOMs/license information. For example, you can see how the GitHub Dependency submission action does it for GitHub Security https://github.com/gradle/actions/tree/main/dependency-submission |
Description
We can parse
*.pom
files from gradle cache dir to detect:nuances of dependency parsing:
property
fields.maven
local repository and gradle cache dir use different structs. So we can't just usemaven pom parser
to parse gradle*.pom
files.If we get issues about this, - we will update maven logic (as option - we will add interface to detecting
*.pom
files in local dir)One important change - All gradle dependencies mark as Indirect now.
This is required to use logic to guess direct deps (There is no reliable way to determine direct dependencies (even using other files)) - see comments below.
examples:
Related issues
Checklist