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.
--
Steve Appling
Automated Logic Research Team

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email


Reply via email to