concat as resource collection in zip not working?
I'm trying to use <concat>
as a resource collection in a <zip>
task and, according to the documentation, this should work. I'd like to do this because some of the files I want to inc开发者_JAVA技巧lude in the zip need to have some properties expanded, so I will also add a <filterchain>
to the <concat>
to do this. I'd prefer to do it directly rather than copying to a temp location (with property substitution) and including the copy in the zip file.
However, I can't seem to get <zip>
to correctly use the <concat>
element.
A simplified example of what I have so far:
<zip destfile="target/dist.zip">
<concat>
<fileset file="CHANGES.txt" />
</concat>
</zip>
This creates a zip file containing several directories all named concat (C:
(obviously this is on a Windows machine).
What am I missing?
A colleague and I came up with the answer by looking through the <zip>
and <concat>
source. There are really two answers:
<concat>
's implementation of theResourceCollection
interface is odd, but we understand why.- There's a way around that.
For #1, while <concat>
is a ResourceCollection
(like FileSet
), under the hood it returns as the name of single Resource
it contains a hard-coded value:
"concat (" + String.valueOf(c) + ")";
Look familiar?
The name of resources is normally ignored--except by <zip>
and its related tasks, which uses the resource name as the ZipEntry
name. Since <concat>
returns the odd-looking name, that's what we get in the zip file.
I haven't quite figured out why I get multiple entries, but it doesn't matter: the observation leads to a convoluted solution.
Since I know the name of the ZipEntry
I want to create, I can use a <mapper>
to give the <concat>
resource a name. Here's what I came up with in all its glory:
<zip destfile="target/distribution.zip">
<fileset dir=".">
<exclude name="target/**" />
<exclude name="CHANGES.txt" />
</fileset>
<mappedresources>
<concat>
<fileset file="CHANGES.txt" />
<filterchain>
<expandproperties />
</filterchain>
</concat>
<mergemapper to="CHANGES.txt" />
</mappedresources>
</zip>
As my colleague says "In Ant every problem can be solved using a mapper."
This only works for Ant 1.8+ because <mappedresources>
was added in that release.
I'm going to post some comments to the Ant mailing list and suggest a couple of enhancements:
- Allow a resource name to be specified as an attribute on
<concat>
when it's being used as aResourceCollection
. - Throw an exception (and don't create a synthetic value) if
getName()
is called without having a value specified. - Finally, though not directly related, I do wish
<expandproperties>
could take a<propertyset>
so I can control which properties get substituted.
Do you want the final zip to contain a single file or multiple files? As far as I can see, using concat (when done successfully, which isn't done above) would produce a single file, the result of concatenation of all files in the resource collection.
If you want multiple files rather than concatenation, I think intermediate copy is what you'll need.
From Ant manual for the concat task:
Since Apache Ant 1.7.1, this task can be used as a Resource Collection that will return exactly one resource.
精彩评论