2.14-rc-1 does not remove old artifacts if version changes

I don’t know if this is specific to to 2.14-rc-1 or not, I just came across it when testing it out with a new project.

plugins {
  id 'java-gradle-plugin'
  id 'groovy'
}

group = 'com.mkobit'
version = '0.2.0-SNAPSHOT'

repositories {
  jcenter()
}

task wrapper(type: Wrapper) {
  gradleVersion = '2.14-rc-1'
}

dependencies {
  testCompile(group: 'org.spockframework', name: 'spock-core', version: '1.0-groovy-2.4') {
    exclude module: 'groovy-all'
  }
  testCompile 'junit:junit:4.12'
}

gradlePlugin {
  plugins {
    javaProjectPlugin {
      id = 'mkobit.test.project'
      implementationClass = 'com.mkobit.test.project.TestProjectPlugin'
    }
  }
}

package com.mkobit.test.project

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.model.RuleSource

class TestProjectPlugin implements Plugin<Project> {
  @Override
  void apply(Project project) {
  }

  static class Rules extends RuleSource {

  }
}

If I run a ./gradlew build, a JAR is produced with mkobit-test-project-0.2.0-SNAPSHOT.jar. If I change the version to something else and build again, there are multiple JARs in the build/libs directory

I expect the old JAR to be removed when building as part of an incremental change.

It’s not a specific issue with 2.14, but an issue where the output of a task changes in a way that Gradle doesn’t handle. Gradle doesn’t assume that it can delete outputs it doesn’t know about and Gradle doesn’t correlate old outputs with new outputs in a way that would tell us that it’s safe to remove files.

This talks about a similar issue (although, it’s about upgrading Gradle): Incremental Build Output Corrupted with Rolling Gradle Upgrades

Going forward, we’re working on a way for a task to be able to declare/describe its outputs in a way that would allow Gradle to remove outdated outputs automatically.

Other than cruft building up, it’s usually not an issue to have extra files in build/libs since dependencies between tasks are described in a way that ignores the extra files.