Я могу отправить вывод задачи 'замены' Муравья в новый файл?

Муравей replace задача делает оперативную замену, не создавая новый файл.

Ниже отрывка заменяет маркеры в любом из '*.xml' файлы с соответствующими значениями из файла 'my.propertie.

<replace dir="${projects.prj.dir}/config"
         replacefilterfile="${projects.prj.dir}/my.properties"
         includes="*.xml" summary="true" />

Я хочу те файлы, которым заменили их маркеры, чтобы быть созданными названные в честь шаблона (например). '*.xml.filtered', и сохраняют исходные файлы.

Действительно ли это возможно у Муравья с некоторой умной комбинацией задач?

6
задан martin clayton 11 September 2011 в 22:01
поделиться

1 ответ

Задача заменить не учитывает зависимости, вместо этого она выполняет замену, записывая временный файл для каждого входного файла. Если временный файл совпадает с входным файлом, он отбрасывается. Временный файл, который отличается от входного файла, переименовывается, чтобы заменить этот входной файл. Это означает, что обрабатываются все файлы, даже если ни один из них не нужен - следовательно, это может быть неэффективным.

Первоначальным решением этого вопроса было выполнение копии-замены-копии. Однако вторая копия не нужна, поскольку в первой можно использовать картограф. В копии зависимости могут использоваться для ограничения обработки только измененными файлами - с помощью селектора зависимых в явном наборе файлов:

<copy todir="${projects.prj.dir}">
  <fileset dir="${projects.prj.dir}">
    <include name="*.xml" />
    <depend targetdir="${projects.prj.dir}">
      <mapper type="glob" from="*.xml" to="*.xml.filtered" />
    </depend>
  </fileset>
  <mapper type="glob" from="*.xml" to="*.xml.filtered" />
</copy>

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

<globmapper from="*.xml" to="*.xml.filtered" />

Простейшая замена будет выглядеть так:

<replace dir="${projects.prj.dir}"
         replacefilterfile="my.properties"
         includes="*.xml.filtered" />

Это все равно обработает все файлы, даже если ни один из них не нуждается в замене. Задача replace имеет неявный набор файлов и может работать с явным набором файлов, но в отличие от аналогичных задач неявный набор файлов не является необязательным, поэтому, чтобы воспользоваться преимуществами селекторов в явном наборе файлов, вы должны сделать неявный набор файлов 'do ничего »- отсюда файл .dummy здесь:

<replace dir="${projects.prj.dir}"
         replacefilterfile="my.properties">
         includes=".dummy" />
  <fileset dir="${projects.prj.dir}" includes="*.xml.filtered">
    <not>
      <different targetdir="${projects.prj.dir}">
        <globmapper from="*.xml.filtered" to="*.xml" />
      </different>
    </not>
  </fileset>
</replace>

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

Кроме того, я не уверен, что есть способ "закодировать гольф" эту проблему, чтобы сократить количество шагов до одного. Не существует фильтра замены нескольких строк, который можно было бы использовать в задача копировать для достижения того же эффекта, что и заменить , что очень жаль, потому что кажется, что это было бы правильным решением.

Еще один подход - сгенерировать xml для серии фильтров replace string и затем заставить Ant выполнить это. Но это будет более сложным, чем существующее решение, и подвержено проблемам с заменой строк, которые при вставке во фрагмент xml приведут к чему-то, что не может быть проанализировано.

Еще один подход - написать специальную задачу или сценарий для выполнения этой работы. Если файлов много и решение «копировать-заменить» считается слишком медленным, то это может быть подходящим вариантом. Но опять же, этот подход менее прост, чем существующее решение.

Если требуется минимизировать объем работы, выполняемой при обработке, а не предлагать кратчайшее решение Ant, то этот подход может подойти.

  • Создайте набор файлов, содержащий список измененных входных данных.
  • Из этого набора файлов создайте список соответствующих отфильтрованных файлов, разделенных запятыми.
  • Выполнить копирование в наборе файлов.
  • Выполните замену в списке, разделенном запятыми.

Проблемой здесь является то, что неявный набор файлов в задаче замены вернется к обработке всего, если ни один файл не изменился. Чтобы преодолеть это, мы вставляем фиктивное имя файла.

<fileset id="changed" dir="${projects.prj.dir}" includes="*.xml">
  <depend targetdir="${projects.prj.dir}">
    <globmapper from="*.xml" to="*.xml.filtered" />
  </depend>
</fileset>

<pathconvert property="replace.includes" refid="changed">
  <map from=".xml" to=".xml.filtered" />
</pathconvert>

<copy todir="${projects.prj.dir}" preservelastmodified="true">
  <fileset refid="changed" />
 <globmapper from="*.xml" to="*.xml.filtered" />
</copy>

<replace dir="${projects.prj.dir}"
         replacefilterfile="my.properties"
         includes=".dummy,${replace.includes}" summary="true" />
1
ответ дан 16 December 2019 в 21:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: