2009-09-24 5 views
10

Кто-нибудь знает, как рекурсивно удалять «пустые» каталоги с ANT (пустые включают в себя каталоги, содержащие только «.svn» и т. Д.).ANT Как удалить ТОЛЬКО пустые каталоги рекурсивно

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

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

Перед тем, как скопировать новый строит я могу «ясно» из каталогов, выполнив следующие действия:

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

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

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

+0

Я не понимаю, что вы подразумеваете под «После того, как они скопированы, я не уверен, как я могу очистить оставшиеся пустые каталоги», какие пустые каталоги? –

+0

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

ответ

0

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

+0

Я попытался расширить вопрос, но хочу, чтобы после того, как я очистил содержимое всех каталогов, а затем скопирую новую сборку, он удалит все оставшиеся пустые каталоги (и пустым, что означает, что они могут содержат исключенный файл/папку (например .svn)). Если я запустил delete */** includeEmptyDirs = "true", это удалит ВСЕ, я ТОЛЬКО хочу удалить пустые директории. – Dougnukem

+0

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

0

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

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

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> 
17

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

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

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

<!-- 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> 
+1

Ницца, спасибо –

+0

Это действительно опрятное решение! –

Смежные вопросы