It took me some time to get this exactly right (if such a thing can be said): How to get ant to copy over a set of files when one is out of date, but do nothing otherwise. Pretty simple, I know, but still I discovered several gotchas. Here is what I wound up with:
(Yes, this does not resemble a production ant script. The real task was signing jars for JNLP deployment from a CVS repository into a staging directory if they were not already there.)
<project default="boom"> <property name="bob" location="bob"/> <property name="nancy" location="nancy"/> <fileset id="bobs" dir="${bob}"/> <target name="check-up"> <uptodate property="dental"> <srcfiles refid="bobs"/> <mapper type="glob" from="*" to="${nancy}/*"/> </uptodate> </target> <target name="boom" depends="check-up" unless="dental"> <echo message="Ka-BOOM!"/> <copy todir="${nancy}"> <fileset refid="bobs"/> </copy> </target> </project>
Some of the mistakes I made along the way:
- The unless attribute of target is just a plain token; do not try to surround it with dollar-curly braces>.
- If you do not give srcfiles an includes or refid attribute, it silently does nothing rather than complaining.
- The from attribute to mapper takes a plain asterisk and is relative to the srcfiles: it was easy to get this wrong in several ways and only experimentation saved me.
In short this is a nice setup to avoid extra build work, but it is somewhat fragile and Ant needs more documentation and examples in this area.
2 comments:
Yes, "uptodate" is very handy.
But I don't understand why you need it here. The "copy" task has similar checking built-in, and will avoid overwriting files that are already up-to-date (unless, of course, you set overwrite="true").
I tend to use "uptodate" in conjunction with "checkpoint files", to work around the shortcomings of tasks that don't have built-in up-to-date checking. For instance, the "junit" can't tell when a test needs to be re-run. So, if all my unit-tests pass, I'll create a checkpoint file called "unit-tests-done" in the build-area. Subsequent builds will skip unit-tests unless there is code newer than the checkpoint file.
You make a good point. Yes, "copy" already has this built in. I picked "copy" only for illustrative purposes. My actual build uses "signjar" and had to work around that "signjar" does not check the timestamps for anything.
Post a Comment