Distribution Plugin - installDist overwriting modified files

Hello -

I’ve got a Gradle 6.1 multi-project build with one sub project using the Distribution plugin to generate our full installation. When running a clean build, all of the subproject build tasks, along with installDist, run properly and the output is created in {buildDir}/install/{project.name}. If I immediately run installDist again, without changing any inputs, Gradle correctly reports:

“> Task :myproj-distribution:installDist UP-TO-DATE”

In my case, the installation contains a file that needs to be updated after installation. The “default” file comes from the “src/main/dist/conf/some-config-file.txt”, which gets placed in {buildDir}/install/{project.name}/conf/some-config-file.txt". If I update this config file inside {buildDir}/install/{project.name}, then run installDist again, gradle overwrites my updates with the default version from src/main/dist.

  • Why does installDist run again if none of the input sources are modified?
  • Is there a way this behavior can be changed through configuration?
  • Can gradle only update things in {buildDir}/install/{project.name} that have been modified in the source sets?

-mike

Answering my own question.

  • Why does installDist run again if none of the input sources are modified?

The Sync task takes a hash of both inputs and outputs. If the output is touched, the hash changes. Gradle then considers the output out of date.

  • Is there a way this behavior can be changed through configuration?
  • Can gradle only update things in {buildDir}/install/{project.name} that have been modified in the source sets?

Configure the installDist task with a filesMatching for the files you need to touch in the installation directory. Within the filesMatching closure, test if the file already exists. If it does, exclude it. Then also add a preserve with the file.

installDist {
    filesMatching '/etc/some-config-file', {
       if (file("${buildDir}/install/${project.name}/etc/some-config-file").exists()) {
          println "Preserving config file"
          exclude()
       }
    }
    preserve {
      include '/etc/some-config-file'
    }
}

Running from a ‘clean’ state, the file won’t exist and will be included. Subsequent runs of installDist will exclude the file.

Gradle is cool!