Use .gitignore for Gradle task excludes

Recently I stumbled across an issue while working on our internal deployment script. I had to copy the whole but clean project, so without any build files or other mess into the deployment folder. To get a clean project I could have used the git archive task but I didn’t want to add another dependency on the existing script. So I thought about reusing the existing .gitignore file to exclude all the files and folders which are not version controlled so I do always have the same set of files in VCS and in the deployment folder.

Flattening a .gitignore file into a list is straightforward with Groovy: just iterate over all lines and drop empty lines or comments:

def gitignoreToList(File f) {
def ignores = []
  f.eachLine { line ->
//ignore comments and empty lines
if (!line.startsWith('#') && !line.isEmpty()) {
ignores.add(line)
}
}
return ignores
}

This returns a list of exclude patterns (input file from gitignore.io):

[*.apk, *.ap_, *.dex, *.class, bin/, gen/, out/, .gradle/, build/, local.properties, proguard/, *.log, .navigation/, captures/, *.iml, .idea/workspace.xml, .idea/libraries, *.jks, gen-external-apklibs]

These can then be used for excludes on a Gradle task, e.g. Gradle Copy:

task copyProject(type: Copy) {
from('/')
into('build/finalProject')
exclude gitignoreToList(file('.gitignore'))
}

This can also be used for other types of files - you only have to adept which lines to exclude when processing the file.