Using Gradle APIs for caching/keeping track of file modifications?

Hi Everyone! I’m trying to replace a legacy build with a modern Gradle/Kotlin DSL one, that would initially work side-by-side with the old one.

Currently we have Ivy, Ant, and some related properly files. With regards to Ivy dependencies, I load them with the extension function that I created:
fun DependencyHandler.ivyFile(file: String): List<Dependency?>
which in the build.gradle.kts of a given module is used like below:
ivyFile(“ivy.xml”)
and that loads all the dependencies from the ivy.xml file.

One problem is that Ivy XML files (and other files I parse) take a while to load, and they don’t change very frequently, but with my current solution they loaded on every build or project refresh in IDEA.

Is there a way to utilize some Gradle caching API to not parse these files when, say, they haven’t been modified? Ideally a cache of sorts, that would alleviate the need to reparse the files when switching between the branches. Something that would work similarly to Gradle task inputs and outputs, except with creating project dependencies on-the-fly, like I do?

Any caching is going to require reading from a file so I’m not sure that xml will be much slower than any other format. But you could generate a gradle file in one task and import/apply the script in another task.

Its best to use two tasks so that the “generate” task can be up to date/skipped whereas the “apply” task will never be skipped

If you are migrating to Gradle I recommend this approach as you can just copy the generated dependeny script directly into the Gradle build once you are confident with your build and decide to drop ant/ivy support.

task generateScript {
    inputs.file 'path/to/ivy.xml'
    outputs.file "$buildDir/generated/dependencies.gradle"
    doLast {
      // parse xml and write a dependencies {...} block 
    } 
}
task applyScript {
    dependsOn generateScript
    doLast {
        apply from: "$buildDir/generated/dependencies.gradle"
    }
} 

// untested but you could probably wire the task into the DAG via this 
configurations.all {
   dependencies.add(it.name, files(applyScript)) 
}