jfrog / build-info

Artifactory's open integration layer for CI build servers
https://www.buildinfo.org
Apache License 2.0
145 stars 154 forks source link

build-info-extractor-gradle build-info.json inconsistent when direct and transitive dependencies exist #746

Open georgenicoll opened 1 year ago

georgenicoll commented 1 year ago

Describe the bug extractor gradle: requestedBy in modules.dependencies.requestedBy for dependencies that are both direct and transitive is populated with only the first requester according to the ordering of the dependencies in build.gradle. This means that if the transitive dependency is defined first, we miss the direct dependency (and vice-versa, if the direct is defined first then the transitive is missed).

There is specific code in org/jfrog/gradle/plugin/artifactory/extractor/listener/ArtifactoryDependencyResolutionListener.groovy that ignores a resolved dependency if that dependency has been seen before which is the cause of this.

Without the curDependents check, The code is able to handle multiple requestedBy paths so I see 2 possible solutions to this:

  1. remove the check on curDependents == null
  2. if there is already a dependency and the new resolved dependency is for the project/module then replace the existing (so always take the direct dependency, if it is found)

I don't mind attempting to fix this, but wanted your thoughts on the solution. Without any other info, I would go for the first: it records the true state of the dependencies as requestedBy can accept multiple dependency paths. However, the check looks to be quite deliberate so there may be constraints that I am unaware of that mean requestedBy should be limited to a single path only (a single path would satisfy my use-case if requestedBy always contained the direct dependency when found).

To Reproduce Compare the generated build-info.json when running against:

apply plugin: 'java'
group 'cut.down.gradle'

sourceCompatibility = 17
targetCompatibility = 17

repositories {
    mavenLocal()
    mavenCentral()
}

dependencies {
    implementation "org.slf4j:slf4j-api:$slf4j_version"
    implementation "org.slf4j:slf4j-simple:$slf4j_version"
}

which gives:

{
      "id" : "org.slf4j:slf4j-api:1.7.36",
      "requestedBy" : [ [ "cut.down.gradle:gradle-jvm-cutdown:unspecified" ] ]
}

vs

apply plugin: 'java'
group 'cut.down.gradle'

sourceCompatibility = 17
targetCompatibility = 17

repositories {
    mavenLocal()
    mavenCentral()
}

dependencies {
    implementation "org.slf4j:slf4j-simple:$slf4j_version"
    implementation "org.slf4j:slf4j-api:$slf4j_version"
}

which gives:

{
      "id" : "org.slf4j:slf4j-api:1.7.36",
      "requestedBy" : [ [ "org.slf4j:slf4j-simple:1.7.36", "cut.down.gradle:gradle-jvm-cutdown:unspecified" ] ]
} 

Expected behavior One of the following:

  1. Both paths to the dependency are represented in the requestedBy lists, OR
  2. The direct dependency path is always shown in requestedBy

Screenshots N/A

Versions

Additional context