Ant: переименование файлов, чтобы включить их MD5
Вопрос, вероятно, ОЧЕНЬ тривиален для любого, кто знаком с муравьем, из которого я пока использую только основы.
Я знаю, как переименовать файлы, например, я уже использую:
<copy todir="build/css/">
<fileset dir="css/">
<include name="*.css"/>
</fileset>
<globmapper from="*.css" to="*-min.css"/>
</copy>
Я знаю, как рассчитать MD5:
<checksum file="foo.bar" property="foobarMD5"/>
Я не знаю, как включить второе в первое, чтобы переименовать все эти файлы, чтобы включить их MD5 - цель состоит в том, чтобы служить средством защиты кэша веб-браузера. Другой вариант очистки кэша, добавлять "?[Что-то]" не так хорош, как объясняется на некоторых страницах Google для веб-мастеров, лучше использовать MD5 как часть имени.
2 ответа
Вы можете сделать это без необходимости включать ant contrib
, Мне пришлось реализовать это для работы, и мне не разрешили ввести это расширение по соображениям безопасности. Решение, к которому я пришел, заключалось в следующем:
<target name="appendMD5">
<copy todir="teststack">
<fileset dir="css/" includes="**/*.css"/>
<scriptmapper language="javascript"><![CDATA[
var File = Java.type('java.io.File');
var Files = Java.type('java.nio.file.Files');
var MessageDigest = Java.type('java.security.MessageDigest');
var DatatypeConverter = Java.type('javax.xml.bind.DatatypeConverter');
var buildDir = MyProject.getProperty('builddir');
var md5Digest = MessageDigest.getInstance('MD5');
var file = new File(buildDir, source);
var fileContents = FIles.readAllBytes(file.toPath());
var hash = DatatypeConverter.printHexBinary(md5Digest.digest(fileContents));
var baseName = source.substring(0, source.lastIndexOf('.'));
var extension = source.substring(source.lastIndexOf('.'));
self.addMappedName(baseName + '-' + hash + extension);
]]></scriptmapper>
</copy>
</target>
Стоит отметить, что я написал это для Java 8, но с некоторыми незначительными изменениями он может работать на Java 7. К сожалению, это не сработает для более ранних версий Java без дополнительных усилий.
Мне удалось создать несколько странное решение, используя for из ant contrib.
Но сначала вы должны установить ant contrib.
copy
в sequential
похоже не принимает / оценивает mappers
(это не сработает, я попробовал с муравьем 1.7.0), поэтому мне пришлось создать дополнительный move
с фильтром для создания результатов.
Это делает следующее:
- для каждого файла создайте md5sum и сохраните его в свойстве foobarMD5
- свойство должно быть сброшено перед каждой итерацией
- Я создаю новый файл в том же
dir
названныйexample.java_foobarMD5.java
(Обратите внимание, что имя файла содержит расширение файла) - Я перемещаю все файлы с
.java_
в его имя в новую папку и удалите.java_
Я оставляю этот пример с.java.
<for param="file">
<path>
<fileset dir="src/" includes="**/*.java"/>
</path>
<sequential>
<echo>Letter @{file}</echo>
<var name="foobarMD5" unset="true"/>
<checksum file="@{file}" property="foobarMD5"/>
<echo>${foobarMD5}</echo>
<copy file="@{file}" tofile="@{file}_${foobarMD5}.java"/>
</sequential>
</for>
<move todir="teststack" verbose="true">
<fileset dir="src/">
<include name="**/*java_*"/>
</fileset>
<filtermapper>
<replacestring from=".java_" to="-"/>
</filtermapper>
</move>