ewan.chalmers
ewan.chalmers

Reputation: 16245

Build a tar and a zip from a shared set of filesets

I have a build file which creates a tar and a zip containing the same resources.

<tar destfile="my.tar.gz" compression="gzip">
  <tarfileset dir="somedir" prefix="some_prefix" filemode="xxx">
    <include name="some_pattern"/>
  </tarfileset>
  <!-- other tarfilesets ... -->
</tar>

<zip destfile="my.zip">
  <zipfileset dir="somedir" prefix="some_prefix" filemode="xxx">
    <include name="some_pattern"/>
  </zipfileset>
  <!-- other zipfilesets ... -->
</tar>

There are a lot of included filesets in the archives.

I would prefer to factor out the duplication - to somehow define the filesets once and reuse them to build both the tar and the zip.

TarFileSet and ZipFileSet are very similar (both extend ArchiveFileSet). I experimented with building a tar and a zip from zipfilesets. This works. At least, so long as you do not need features which are specific to TarFileSet. (I also looked in the source of TarFileSet and see it has code to convert an ArchiveFileset to a TarFileSet, which explains why this works).

What's missing is a way to define a set of archive filesets and reuse it.

You cannot successfully combine archive filesets using a path or a union. In this case, the extra attributes of the ArchiveFileSet (e.g. the prefix) are discarded. (Using PatternSet does not work at all.)

So the best I have come up with so far is this:

<project default="test">

  <target name="test">

    <zipfileset dir="test/1" filemode="755" prefix="test1" id="test1"/>
    <zipfileset dir="test/2" filemode="755" prefix="test2" id="test2"/>

    <do_tar destfile="test.tar.gz">
      <filesets>
        <zipfileset refid="test1"/>
        <zipfileset refid="test2"/>
      </filesets>
    </do_tar>

    <do_zip destfile="test.zip">
      <filesets>
        <zipfileset refid="test1"/>
        <zipfileset refid="test2"/>
      </filesets>
    </do_zip>

  </target>

  <macrodef name="do_tar">
    <attribute name="destfile"/>
    <attribute name="compression" default="gzip"/>
    <element name="filesets"/>
    <sequential>
      <tar destfile="@{destfile}" compression="@{compression}">
        <filesets/>
      </tar>
    </sequential>
  </macrodef>

  <macrodef name="do_zip">
    <attribute name="destfile"/>
    <element name="filesets"/>
    <sequential>
      <zip destfile="@{destfile}">
        <filesets/>
      </zip>
    </sequential>
  </macrodef>

</project>

And really, I don't think it's an improvement at all because it is not really reusing the filesets.

The only other thing I can think of is creating a custom typedef (writing Java code) for "set of archive filesets" which would be referenced by id in the marcos. But if it comes to that, I will probably just live with the duplication in the build file instead.

Is there something much cleaner that I'm missing?

My requirements will be to use Ant alone (not ant-contrib or other third party extensions), but answers which use these might be helpful to others.

Upvotes: 4

Views: 1531

Answers (1)

JB Nizet
JB Nizet

Reputation: 691913

See http://ant.apache.org/manual/using.html#references:

Any project element can be assigned an identifier using its id attribute. In most cases the element can subsequently be referenced by specifying the refid attribute on an element of the same type. This can be useful if you are going to replicate the same snippet of XML over and over again

Upvotes: 1

Related Questions