2009/4/27 Steve Appling <[email protected]>

> Adam Murdoch wrote:
>
>>
>>
>> Steve Appling wrote:
>>
>>> I have a 'Sync' task we use in our projects that I would like to submit
>>> as a possible replacement for the current Copy (previously named Resources)
>>> task.  I don't use ant to actually do the copy (although I am currently
>>> using the groovy ant.FileScanner to iterate over the source files).  This is
>>> a little faster than ant (especially when there is nothing out of date) and
>>> I can check the status afterwards to see if anything was done.  I would like
>>> some feedback on the current DSL syntax used to configure it.
>>>
>>> BTW, this is called a Sync task instead of copy because it will
>>> optionally delete target files if the source is no longer present.
>>>
>>> Please bear with me in this email - it is a contrived example where there
>>> is really no need to have a global exclude since the specific includes are
>>> so specific.  There are real reasons to have both global types of
>>> configuration values and some that are restricted to a particular source
>>> directory (as is supported in the existing Copy task).
>>>
>>> For review, the current Copy task has a configuration syntax like:
>>>
>>> copyTask {
>>>   from(file('javasource'), file('scriptsource'), file('resources'))
>>>   into(file('build/copiedstuff')
>>>   excludes('**/*.bak')
>>>   includes(file('javasource'), '**/*.java')
>>>   includes(file('scriptsource'), '**/*.script')
>>>   includes(file('resources'), '**/*.properties')
>>>   includes(file('resources'), '**/*.png')
>>> }
>>>
>>> When I added support for regular expression based name mapping to my
>>> original task, I decided that I didn't like having the source file specified
>>> again to differentiate global and specific conditions, so I tried something
>>> else.  You might find this more awkward so please let me know.  Currently I
>>> use nested 'SyncSpecs' which works like this:
>>>
>>> syncTask {
>>>   into('build/copiedstuff')
>>>   excludes('**/*.bak')
>>>   add {
>>>      from('javasource')
>>>      includes('**/*.java')
>>>   }
>>>   add {
>>>      from('scriptsource')
>>>      includes('**/*.script')
>>>   }
>>>   add {
>>>      from('resources')
>>>      includes('**/*.properties', '**/*.png')
>>>   }
>>> }
>>>
>>>
>> Generally, I like the approach you've proposed. I think whatever DSL we
>> come up with for the Sync task, we should also use for the archive tasks, as
>> they are both describing the same thing.
>>
>> I think this might be a better layout:
>>
>> syncTask {
>>   into('destDir')
>>   exclude 'someGlobalExclude'
>>   from('build/generated') {
>>       include '**/*.txt'
>>       exclude 'someDir/**'
>>   }
>>   from('resources') {
>>       include '**/*.txt', '**/*.xml'
>>   }
>> }
>>
>> I notice that some of our tasks use 'include' and 'exclude', and Copy uses
>> 'includes' and 'excludes'. We should use the same term for all tasks. I
>> prefer 'include' and 'exclude'.
>>
>> The above layout fits well with Tom's proposal for the archive tasks,
>> where you can use closures to describe the layout of the destination:
>>
>> syncTask {
>>   into('destDir')
>>   someDir {
>>       from('build/generated') { include '**/*.xml' }
>>   }
>>   someOtherDir {
>>       subDir {
>>           from('resources')
>>       }
>>   }
>> }
>>
>
>>
>>
>>  The 'add' method is used to create and configure a child SyncSpec.
>>>  SyncSpecs inherit values from their parent.  A root SyncSpec is created as
>>> a part of the Sync task and SyncTask delegates to it, so normal single
>>> source copies are configured directly on the task:
>>>
>>> syncTask {
>>>   from 'mysource'
>>>   into 'build/mydest'
>>>   includes "**/OEM_${oemname}*"
>>>   mapname "OEM_${oemname}_(.*)", '\\1'
>>> }
>>>
>>>
>> I think mapname() should take a closure, instead:
>>
>> mapname { it.name.replaceAll("OEM_${oemname}_(.*)", '\\1') }
>>
>>  I found myself almost always using files relative to the project
>>> directory, so I added forms of into and from that take plain strings as
>>> relative paths from there instead of requiring use of Project.file().
>>>
>>>
>> This is a good idea.
>>
>>
> Thanks, I like all those suggestions.


Same here, except for one small detail: I would put the someDir closure in a
closure that is related to the into('destDir') this makes it just a little
bit more clear what is going on. The extra nesting not really needed but
still.

syncTask {
   into('destDir') {
       someDir {
           from('build/generated') { include '**/*.xml' }
       }
       someOtherDir {
           subDir {
               from('resources')
           }
       }
   }
}


>
> --
> Steve Appling
> Automated Logic Research Team
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>   http://xircles.codehaus.org/manage_email
>
>
>

Reply via email to