Sync task should delete target files if it has no inputs

def test = file('test')
def target = file('target')
def testFile = file('test/foo.txt')

task clean << {
  delete test, target
}

task createFile {
  outputs.files testFile
  doLast {
    test.mkdirs()
    testFile.text = 'Hello World!'
  }
}

task sync1(type:Sync, dependsOn:createFile) {
  from test
  into target
}

task deleteSource(dependsOn: sync1) << {
  delete testFile
}

task sync2(type:Sync, dependsOn:deleteSource) {
  from test
  into target
}

defaultTasks 'clean', 'sync2'

If I run this build, I get the following output:

$ gradle
:clean
:createFile
:sync1
:deleteSource
:sync2 UP-TO-DATE

BUILD SUCCESSFUL

Total time: 0.512 secs

When running with -i, you can see Skipping task ':sync2' as it has no source files. I think, the Sync task should not be skipped if it has no source files, because it may have to clean up stray files in its target directory.

This is a known issue GRADLE-2579 and is on our backlog of items to address.

Still occurs with 3.2-rc-3 though. this time with “Skipping task
’:sync2’ as it has no source files and no previous output files.”

Hi Jochen,

what we did fix is that if a task did run before and we recorded outputs then, when we run the same task again and remove the tasks source files, it will delete the previous known outputs.
In your case, sync1 knows about its outputs while sync2 would run for the first time. If you would run sync1 again excluding createFile, then it would delete the leftover file. Note that we do not rerun sync but delete the output files.
One could argue that a sync task should not skip at all when it has no input files. But this would be a different issue. If you think that this is what we should do, could you please open a Github issue on https://github.com/gradle/gradle?

Cheers,
Stefan