Build-Cache issue - How to Exclude empty directories from compile


(Louis-Rémi Paquet) #1

Hi,

I’m trying to exclude empty directories from a compile sourceset. (Also empty dirs containing only empty dirs)
First of all, I question the fact of empty directories to be included in a JavaCompile task since it prevents cache hits. If someone can tell me if there’s a reason or if it’s an error, the answer is welcomed :slight_smile:

The reason I need to do that is that remnant empty directories on dev machines prevents the hash for source to be the consistent across dev machines, highly impacting the hit rate of the remote cache. In other words, it creates a different hash for every combination of empty directories. Here’s the debug output: [org.gradle.caching.internal.tasks.DefaultTaskOutputCachingBuildCacheKeyBuilder] Appending inputPropertyHash for ‘source’ to build cache key: 64e7b2ee84f93e3a603859560e570f52

Each developer eventually ends up having an empty directory somewhere on the sourceset because of removed files via the source control or any other reason.

It could probably be done with a FileTreeSpec like this but I suspect it’ll hurt the performance because of the iterator on the files and the recursion:

sourceSets.all {
    tasks.withType(JavaCompile) {
        it.exclude(
                new Spec<FileTreeElement>() {
                    @Override
                    boolean isSatisfiedBy(FileTreeElement element) {
                        //Do recursion here to find if directory only contains empty directories.
                        return element.isDirectory() && !Files.newDirectoryStream(element.file.toPath()).iterator().hasNext()
                    }
                }
        )
    }
}

What I found but doesn’t seem to apply to this situation

  • Works for Copy and would’ve been great but JavaCompile task isn’t a Copy task: Excluding empty directories from SourceSets
  • Using exclude(pattern) won’t work, unless empty directories can be referenced with patterns…