On 09/04/2013, at 8:55 PM, Luke Daley <[email protected]> wrote:

> 
> On 27/03/2013, at 3:43 PM, Daz DeBoer <[email protected]> wrote:
> 
>> G'day
>> 
>> Now in master is a pretty cool new feature: you can now implement an
>> 'incremental' task that is informed about exactly which input files
>> have changed when the task is out of date.
>> This is very useful for something like a C++ compile task, as it means
>> that only the changed files need to be recompiled, rather than the
>> entire set of inputs.
>> 
>> I've got a 'draft' DSL functioning, and would appreciate any feedback
>> you guys have. Here's a sample:
>> 
>>       class IncrementalSync extends DefaultTask {
>>           @InputFiles
>>           def FileCollection src
>> 
>>           @OutputDirectory
>>           def File destination
>> 
>>           @TaskAction
>>           void execute(TaskInputChanges inputs) {
>>               if (inputs.allOutOfDate) {
>>                   FileUtils.forceDelete(destination)
>>               }
>> 
>>               inputs.outOfDate({
>>                   FileUtils.copyFile(change.file, targetFile(change.file))
>>               } as Action)
>>               .removed({
>>                   FileUtils.forceDelete(targetFile(change.file))
>>               } as Action)
>>               .process()
>>           }
>> 
>>           def targetFile(def inputFile) {
>>               new File(destination, change.file.name)
>>           }
>>       }
> 
> Thinking more about this, I don't think what we have is right. I think we can 
> come up with a simpler API.
> 
> interface TaskExecutionContext {
> 
>  boolean isCleanRun(); // there's no history of this task, so requires full 
> execution
> 
>  void eachInputFileChange(Action<InputFileChange> action);
> 
>       interface InputFileChange { 
>         boolean isAdded();
>         boolean isModified();
>         boolean isRemoved();
>         File getFile(); 
>       }
> 
> }
> 
> @TaskAction
> void execute(TaskExecutionContext executionContext) {
>       if (!executionContext.cleanRun) {
>               executionContext.eachInputFileChange {
>                       
>               }
>       }
> }
> 
> Some issues I have with the existing design:
> 
> * I'm not sure "outOfDate" is the right term here. It doesn't quite capture 
> it and can imply more than what we actually mean. You could say that an 
> output is out of date, but it doesn't quite work for inputs.
> * why do we need the outOfDate() and removed() methods? After reading the 
> Javadoc I'm not sure how I would use this API. What's the difference between 
> out-of-date and removed? I could guess, but it's not clear.

The question that we want the task to ask is 'what work do I need to do?' 
rather than 'what has changed?'. Right now, we're only interested in two 
answers to this question: 
- you need to do work on this set of input files.
- you need to clean-up whatever work you previously did for this set of input 
files.

The answers are intentionally vague because:
- The task implementations don't actually care about any more detail.
- We want to be able to add and remove reasons why work might be required on a 
given input file or might need to be cleaned up for a given input file.
- We want to be able to apply performance optimisations.

I think all we need to do is come up with some better names for the existing 
methods.


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com

Join us at the Gradle Summit 2013, June 13th and 14th in Santa Clara, CA: 
http://www.gradlesummit.com

Reply via email to