John Murph wrote:
I'm not sure that separating include/exclude rules from the remapping is a good idea. On the surface it sure sounds reasonable, but I think it would make our use case much uglier. Our remap code is sorta like:

remapTarget { File inputFile ->
  if (not a special file)
     return inputFile

  perform phase one renaming // fairly complicated
  perform phase two renaming // also complicated

if (resultName is not valid) // did phase one and phase two result in the desired format?
     return null
  else
     return resultName
}

The point is that phase one and phase two renaming are not simple replaceAll kinds of functions. This means that if we were to split up these concepts we would has an include/exclude closure that performed the logic and then checks if the resultName is valid. Then we need a mapTo closure that performed the logic and returned the result (with an assert failure if the result name is not valid?). Now, we could pull this common stuff into a method, but it just seems an overly complicated way of getting the desired behavior. It also seems like it would affect performance when processing over 30,000 files.


This is a reasonable use case. I'm not sold on the solution, however. My concern is this:

There are currently 3 primitive operations you can apply to a CopySpec:
- selecting: decide whether a given file should be excluded from the result
- mapping: determine the destination path for a given file
- filtering: filter the content of a given file when copying it

Each of these operations is logically independent. But sometimes, as in your case, a given piece of build logic means that more than 1 of these operations need to be applied to a given file.

The problem with combining selecting and mapping in the mapTo() method is that it only solves the problem for the particular combination of operations that you happen to need. It doesn't solve it for builds that need to map and filter or select and filter. This becomes more of a problem as we add more operations, such as
- signing: determine the signature for a given file
- permissions: determine the owner, group and permissions for a given file

So, merging the primitive operations into discrete combinations is not a general solution, nor a particularly backwards compatible one.

I think instead, we want a single 'do everything' method which you can pass a closure (or Action) which can apply any of the primitive operations to the given file, however it wants. The existing selecting, mapping and filtering method would remain simply as convenience methods.

This method might look something like:

eachFile { FileCopyDetails details ->
   if (not a special file) {
       return
   }

   perform phase one renaming
   perform phase two renaming

   if (resultName is not valid) {
       details.exclude()
   }
   else {
       details.setPath(resultName)
   }
}

FileCopyDetails would extend FileVisitDetails and add methods to allow you to:
- exclude the file from the result
- set the destination name or the path for the file
- set the filter to use when reading or writing to the file


--
Adam Murdoch
Gradle Developer
http://www.gradle.org


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

   http://xircles.codehaus.org/manage_email


Reply via email to