ANT Как удалить ТОЛЬКО пустые каталоги рекурсивно

Кто-нибудь знает, как рекурсивно удалять "пустые" каталоги с помощью ANT (пустые включают каталоги, содержащие только ".svn" и т.д.).

Я знаю, что ANT позволяет вам включать includeEmptyDirs = true, но я хочу, чтобы он ТОЛЬКО удалял каталог, если он пуст (и на самом деле мне, вероятно, нужно будет перейти к рекурсивной цепочке и удалить каталог, в котором он содержался если он теперь пуст).

В основном, как часть нашего процесса сборки, мы копируем по набору каталогов, которые содержат кучу других вложенных каталогов, содержащих различные XML и данные, и когда мы перемещаем местоположение для этих данных, наш процесс "копирования" и процесса проверки не работает, t действительно работает, и потому что мы проверяем другой источник управления (SVN), уничтожение каталогов и копирование на самом деле не является вариантом (мы будем сбрасывать папки ".svn" ).

Прежде чем копировать новые сборки, я могу "очистить" каталоги, выполнив следующие действия:

<delete>
  <fileset dir="${webplatformBin}" includes="**/*"/>
</delete>

Это оставляет каждый каталог (с ".svn" ) пустым каталогом, а затем я копирую новые файлы. После того, как они будут скопированы, я не знаю, как я могу удалить оставшиеся пустые каталоги (если мы полностью переместились туда, где находится каталог данных верхнего уровня и т.д.).

Например, если у меня был файл /projectA/data/localization/text.xml, и я переместил его в /projectB/data/localization/text.xml, я бы получил пустую папку/projectA/data/localization/(который будет содержать только папку .svn).

Ответ 1

Вот лучший ответ, который я смог придумать:

<delete includeemptydirs="true">
  <fileset dir="${dirToStartFrom}"  >
    <and>
      <size value="0"/>
      <type type="dir"/>
     </and>
  </fileset>
</delete>

Затем я завернул его в макрос, чтобы передать имя dir из любой цели:

<!-- Find and delete empty folders under dir -->
<macrodef name="deleteEmptyFolders">
    <attribute name="dir"/>
    <sequential>
        <delete includeemptydirs="true">
            <fileset dir="@{dir}"  >
                <and>
                    <size value="0"/>
                    <type type="dir"/>
                </and>
            </fileset>
        </delete>
    </sequential>
</macrodef>

Так же:

<target name="clean">
  <deleteEmptyFolders dir="build"/>
  <deleteEmptyFolders dir="common"/>
  <deleteEmptyFolders dir="lib"/>
</target>

Ответ 2

Вот что я приготовил:

<!-- next three targets are connected
     To remove empty folders from XXX folder.  Process is recursed 3 times.  This 
     is necessary because parent directories are not removed until all their children
     are (if they are empty), and parents are processed before children 
      My example will process structures 3 deep, if you need to go deeper
      then add members to the list  like list="1,2,3,x,x,x,x,x,x"  -->

<target name="rmmtdirs">
        <foreach list="1,2,3" target="rmmtdirs_recurse" param="num"/>
</target>

<target name="rmmtdirs_recurse">
        <foreach target="rmmtdir" param="rmdir">
            <path>
                <dirset dir="${XXX}"/>
            </path>
        </foreach>
</target>

<target name="rmmtdir">
        <echo message=" Removing: ${rmdir} "/>
        <delete includeemptydirs="true">
                <fileset dir="${rmdir}" excludes="**/*"/>
        </delete>
</target>

Ответ 3

Если этого недостаточно, чтобы полностью очистить целевое местоположение (используйте defaultExcludes = "false", чтобы удалить папки .svn), вы можете попробовать написав пользовательскую задачу ant, чтобы пересечь файловую систему ниже цели, удалив пустые каталоги при переходе от каждого листа.

Ответ 4

Это, вероятно, проще сделать с пакетным файлом, который вызывается из ant.

Вы можете использовать Raymond Chen script, но он не работает, если в именах есть пробелы.

Ответ 5

Я смог удалить все пустые каталоги, начиная с текущего рабочего каталога:

<delete includeemptydirs="true">
    <fileset dir="." includes="**" excludes="**/*.*" />
</delete>