Emulate make's file based targets

I’m currently trying to convert a Makefile based build to gradle. One thing I’m uncertain of is how to emulate make’s file based targets properly in gradle, so that the build system can figure out the dependencies automatically, for example:

foo.txt:
    	echo foo > $@

bar.txt: foo.txt
    	cp $< $@

The gradle version could look like this:

task foo {
    ext.destFile = file('foo.txt')
    outputs.file destFile
    doLast { destFile.text = 'foo' }
}

task bar {
    ext.sourceFile = foo.destFile
    ext.destFile = file('bar.txt')
    inputs.file sourceFile
    outputs.file destFile
    doLast { destFile.text = sourceFile.text }
}

The way input and outputs are connected the up-to-date checks work as expected but I still need to manually declare a dependency from bar to foo. Is there a way for gradle to figure out automatically that it needs to run foo first based on declared inputs/outputs?

Yes, you can do something like:

task bar {
    ext.destFile = file('bar.txt')
    inputs.files foo
    outputs.file destFile
    doLast { 
        destFile.text = inputs.files.singleFile.text 
    }
}

Passing the task foo makes bar's inputs have a collection of files built by foo.

Thanks, that works. Did not realise you can just pass a task as input to files. It’s also a bit confusing that there is no inputs.file, analogous to outputs.file, so you could just write:

task bar {
    ext.destFile = file('bar.txt')
    inputs.file foo
    outputs.file destFile
    doLast { destFile.text = inputs.file.text }
}

There is, but input.file expects to be able to resolve its argument into a single File (which doesn’t carry any extra information with it, like which task builds it). input.files accepts a FileCollection which can be a single file + dependency information.

Ah ok I see, so you need to pass a Buildable object as input. Make sense, although I guess gradle could somehow figure out the dependency information by looking at which tasks have declared the file as output. The current solution works fine though. Thanks again!