Как переименовать файлы при включении в банку с помощью задачи ant jar?

Я хочу поместить в файл набор файлов, похожих на него:

yay/my.jar
boo/my.jar
foo/my.jar
bar/my.jar

В этом процессе я хочу, чтобы все они были переименованы следующим образом:

yay_my.jar
boo_my.jar
foo_my.jar
bar_my.jar

Я надеялся использовать mapper для выполнения этого, но элементы набора файлов, которые я использую, и задача jar, похоже, нигде не поддерживают.

Как применить картограф при создании флага, или как я могу выполнить такое преобразование? Я хочу, чтобы не копировать все файлы в структуру каталогов, которые я хочу, и делать дубликаты повсюду, как сейчас работает наша система сборки.

Ответы

Ответ 1

Вы можете использовать zipfileset с атрибутом fullpath, чтобы переименовать имя файла в банке:

<jar destfile="newjar.jar">
    <zipfileset dir="yay" includes="my.jar" fullpath="yay_my.jar"/>
    <zipfileset dir="boo" includes="my.jar" fullpath="boo_my.jar"/>
    <!-- etc. -->
</jar>

Вы не можете использовать компаньон с этой техникой, но вам придется перечислять каждый файл jar явно. Если вы можете предположить, что каждый файл имеет имя my.jar, и все они находятся в непосредственном дочернем каталоге, вы можете использовать цель subant, чтобы объединить их все:

<target name="glom">
    <subant genericantfile="${ant.file}" target="update-jar">
        <dirset dir="." includes="*"/>
    </subant>
</target>

<target name="update-jar">
    <basename file="${basedir}" property="dirname"/>
    <property name="path" value="${dirname}_my.jar"/>
    <jar destfile="../newjar.jar" update="yes">
        <zipfileset dir="." includes="my.jar" fullpath="${path}"/>
    </jar>
</target> 

Ответ 2

Обновление: вы, вероятно, на самом деле хотите скопировать задачу, а не перемещать, но regexp mapper работает одинаково для копирования и перемещения.

Следующий regexp будет копировать все банки в каталоге jars в jars_out, сопоставляя [folder]/[file].jar с [папкой] _ [файл].jar.

<copy todir="./jars_out">
  <fileset dir="jars"/>
  <mapper type="regexp" from="([^/\\]*)[/\\](.*)\.jar$$" to="\1_\2.jar"/>
</copy>

Для преобразования в regexp mapper требуется соответствующая реализация jgegegegegege в пути classpath. Доступны различные реализации:

Ответ 3

Если вы не хотите (или не можете легко) перечислить каждый файл отдельно, одним из решений является использование задачи Zip, которая позволяет вложенные <mappedresources> (Ant 1.8.0+). После завершения задачи Zip вы можете использовать задачу Jar для добавления/обновления манифеста и/или добавления индекса.

Предположим, например, что в дополнение к желанию

yay_my.jar
boo_my.jar
foo_my.jar
bar_my.jar

в выводе JAR, у вас также есть каталог stuff/, содержащий некоторые файлы и подкаталоги. Если вы хотите, чтобы содержимое stuff/ включено в JAR, но вы хотите добавить stuff/subdir/* как other_subdir/*, рассмотрите следующее:

<zip destfile="newjar.jar">
    <zipfileset dir="yay" includes="my.jar" fullpath="yay_my.jar"/>
    <zipfileset dir="boo" includes="my.jar" fullpath="boo_my.jar"/>
    <!-- etc. -->

    <mappedresources>
        <fileset dir="stuff"/>
        <compositemapper>
            <globmapper from="subdir/*" to="other_subdir/*"/>
            <identitymapper/>
        </compositemapper>
    </mappedresources>
</zip>
<!-- Update the newly-created ZIP in-place to add a basic manifest -->
<jar destfile="newjar.jar" update="true"/>

Я тестировал этот файл сборки и работает с Ant 1.8.2. Однако, если после его изменения Ant начинает бросать NullPointerException, см. Ошибка 54026.