dependency-analysis-gradle-plugin icon indicating copy to clipboard operation
dependency-analysis-gradle-plugin copied to clipboard

artifactsReport granular cache inputs

Open seregamorph opened this issue 1 year ago • 1 comments

Problem statement

artifactsReportX tasks (ArtifactsReportTask) declare too "sensitive" file task inputs (absolute file path + full file contents). But the task output does not depend on file content itself, only on resolved dependency tree. As a result, the caching hit rate for these tasks is quite low.

Proposed solution

The problematic task input:

/**
 * This is the "official" input for wiring task dependencies correctly, but is otherwise
 * unused. This needs to use [InputFiles] and [PathSensitivity.ABSOLUTE] because the path to the
 * jars really does matter here. Using [Classpath] is an error, as it looks only at content and
 * not name or path, and we really do need to know the actual path to the artifact, even if its
 * contents haven't changed.
 */
@PathSensitive(PathSensitivity.ABSOLUTE)
@InputFiles
fun getClasspathArtifactFiles(): FileCollection = artifacts.artifactFiles

should be replaced with absolute file paths only:

@Input
fun getClasspathArtifactFilePaths(): Set<String> = artifacts.artifactFiles.mapToSet { it.path }

From the debugger, sample file inputs (Set of String values):

0 = "/Users/morph/Projects/demo-gradle-included-issue/module-contracts/build/libs/module-contracts.jar"
1 = "/Users/morph/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.14.0/1ed471194b02f2c6cb734a0cd6f6f107c673afae/commons-lang3-3.14.0.jar"

FYI: sample artifactsReportMain task output looks like:

[
  {
    "coordinates": {
      "type": "included_build",
      "identifier": "isolated-build-1:module-contracts",
      "resolvedProject": {
        "identifier": ":module-contracts",
        "gradleVariantIdentification": {
          "capabilities": [
            "isolated-build-1:module-contracts"
          ],
          "attributes": {}
        },
        "buildPath": ":"
      },
      "gradleVariantIdentification": {
        "capabilities": [
          "isolated-build-1:module-contracts"
        ],
        "attributes": {}
      }
    },
    "file": "/Users/morph/Projects/demo-gradle-included-issue/module-contracts/build/libs/module-contracts.jar"
  },

as you can see - does not depend on jar content, only on dependency resolution.

Testing

The functional test is not attached. Let me know WDYT about this change and if there is a green light, I can try to provide a test. The problem here is that the test should assert the caching result. It is possible, but requires extended test setup.

seregamorph avatar Jul 08 '24 10:07 seregamorph

The builds fails on functionalTests, but only for android. It seems that file iteration has side effect. I need some time to investigate it, but still curious about the idea in general.

seregamorph avatar Jul 08 '24 21:07 seregamorph