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>