Incremental Build Output Corrupted with Rolling Gradle Upgrades

From (at least) 2.11 to 2.13 (but not 2.12 to 2.13) there is a bug in the incremental build detection.

The incremental output from 2.11 will cause some build changes under Gradle 2.13 to go undetected, and therefore not show up in the Gradle build artifacts.

Reproduction details:
Create two empty files in your local dir a.txt and b.txt, along with the build.gradle

apply plugin:'java'

assert hasProperty('gradle_ver')
if (!hasProperty('exclude_b')) ext.exclude_b = false

repositories {
   mavenCentral()
}

sourceSets {
   main {
      resources {
         srcDirs = ['.']
         include 'a.txt'
         project.ext.exclude_b ? exclude('b.txt') : include('b.txt')
      }
   }
}

task wrapper(type: Wrapper) {
    gradleVersion project.ext.gradle_ver
}

The command runs gradle 2.11 and the output is correct:

GRADLE='./gradlew -Pgradle_ver=2.11'
$GRADLE wrapper
$GRADLE -v
$GRADLE clean processResources
ls -l build/resources/main
$GRADLE -v
$GRADLE -Pexclude_b=1 processResources
ls -l build/resources/main

b.txt is removed from build output:

Configuration on demand is an incubating feature.
:wrapper

BUILD SUCCESSFUL

Total time: 0.789 secs

------------------------------------------------------------
Gradle 2.11
------------------------------------------------------------

Build time:   2016-02-08 07:59:16 UTC
Build number: none
Revision:     584db1c7c90bdd1de1d1c4c51271c665bfcba978

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM:          1.7.0_80 (Oracle Corporation 24.80-b11)
OS:           Linux 3.16.0-38-generic amd64

Configuration on demand is an incubating feature.
:clean
:processResources

BUILD SUCCESSFUL

Total time: 0.678 secs
total 0
-rw-r--r-- 1 pcm pcm 0 May  6 11:01 a.txt
-rw-r--r-- 1 pcm pcm 0 May  6 11:01 b.txt

------------------------------------------------------------
Gradle 2.11
------------------------------------------------------------

Build time:   2016-02-08 07:59:16 UTC
Build number: none
Revision:     584db1c7c90bdd1de1d1c4c51271c665bfcba978

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM:          1.7.0_80 (Oracle Corporation 24.80-b11)
OS:           Linux 3.16.0-38-generic amd64

Configuration on demand is an incubating feature.
:processResources

BUILD SUCCESSFUL

Total time: 0.721 secs
total 0
-rw-r--r-- 1 pcm pcm 0 May  6 11:01 a.txt

The following command runs Gradle 2.13 and the output is correct.

GRADLE='./gradlew -Pgradle_ver=2.13'
$GRADLE wrapper
$GRADLE -v
$GRADLE clean processResources
ls -l build/resources/main
$GRADLE -v
$GRADLE -Pexclude_b=1 processResources
ls -l build/resources/main

b.txt is removed from build output:

Configuration on demand is an incubating feature.
:wrapper

BUILD SUCCESSFUL

Total time: 0.917 secs

------------------------------------------------------------
Gradle 2.13
------------------------------------------------------------

Build time:   2016-04-25 04:10:10 UTC
Build number: none
Revision:     3b427b1481e46232107303c90be7b05079b05b1c

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.7.0_80 (Oracle Corporation 24.80-b11)
OS:           Linux 3.16.0-38-generic amd64

Configuration on demand is an incubating feature.
:clean
:processResources

BUILD SUCCESSFUL

Total time: 0.684 secs
total 0
-rw-r--r-- 1 pcm pcm 0 May  6 11:04 a.txt
-rw-r--r-- 1 pcm pcm 0 May  6 11:04 b.txt

------------------------------------------------------------
Gradle 2.13
------------------------------------------------------------

Build time:   2016-04-25 04:10:10 UTC
Build number: none
Revision:     3b427b1481e46232107303c90be7b05079b05b1c

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.7.0_80 (Oracle Corporation 24.80-b11)
OS:           Linux 3.16.0-38-generic amd64

Configuration on demand is an incubating feature.
:processResources

BUILD SUCCESSFUL

Total time: 0.744 secs
total 0
-rw-r--r-- 1 pcm pcm 0 May  6 11:04 a.txt

The following command mixes Gradle 211 and Gradle 2.13 and the output is WRONG.

GRADLE='./gradlew -Pgradle_ver=2.11'
$GRADLE wrapper
$GRADLE -v
$GRADLE clean processResources
ls -l build/resources/main
GRADLE='./gradlew -Pgradle_ver=2.13'
$GRADLE wrapper
$GRADLE -v
$GRADLE -Pexclude_b=1 processResources
ls -l build/resources/main

b.txt remains in the build output:

Configuration on demand is an incubating feature.
:wrapper

BUILD SUCCESSFUL

Total time: 0.736 secs

------------------------------------------------------------
Gradle 2.11
------------------------------------------------------------

Build time:   2016-02-08 07:59:16 UTC
Build number: none
Revision:     584db1c7c90bdd1de1d1c4c51271c665bfcba978

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM:          1.7.0_80 (Oracle Corporation 24.80-b11)
OS:           Linux 3.16.0-38-generic amd64

Configuration on demand is an incubating feature.
:clean
:processResources

BUILD SUCCESSFUL

Total time: 0.709 secs
total 0
-rw-r--r-- 1 pcm pcm 0 May  6 11:06 a.txt
-rw-r--r-- 1 pcm pcm 0 May  6 11:06 b.txt
Configuration on demand is an incubating feature.
:wrapper

BUILD SUCCESSFUL

Total time: 0.75 secs

------------------------------------------------------------
Gradle 2.13
------------------------------------------------------------

Build time:   2016-04-25 04:10:10 UTC
Build number: none
Revision:     3b427b1481e46232107303c90be7b05079b05b1c

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.7.0_80 (Oracle Corporation 24.80-b11)
OS:           Linux 3.16.0-38-generic amd64

Configuration on demand is an incubating feature.
:processResources UP-TO-DATE

BUILD SUCCESSFUL

Total time: 0.698 secs
total 0
-rw-r--r-- 1 pcm pcm 0 May  6 11:06 a.txt
-rw-r--r-- 1 pcm pcm 0 May  6 11:06 b.txt

Thanks for reporting the problem. I think this is not a regression in the latest versions since I can reproduce the problem with all versions 2.11, 2.12, 2.13 if the .gradle directory is removed in the build directory between invocations. I guess the only way to get around the problem is to run clean whenever the Gradle version gets upgraded. There might be a nice way to automate this.

Yes, I had a feeling it wasn’t really a regression but more of an edge case that probably isn’t tested.

IMO this is a pretty serious bug since the actual output of Gradle is not consistent. Will there be an official fix for this eventually? At least for now I would suggest adding a warning to the user if a version change is detected.

Any thoughts on how to work around this bug in 2.X series? I’m trying to develop a method that will inject full project clean when the version changes.

The difficulty when doing this is that either you need to detect the version change during the configuration phase, or find a way to modify the task execution graph after the detection task is executed. Maybe there is a third way to get around this?