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.
Adam
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email