Ant: How to use apply task with identical source and target file - ant

I am trying to run an apply task with the following command:
jpegtran.exe -copy none -optimize -perfect ./images/file.jpg ./images/file.jpg
I would like to apply it recursively for all images. I have tried the following ant code but jpegtran says invalid arguments.
<target name="optimize.images.jpg">
<apply executable="jpegtran.exe" dir="${SRC_DIR}/public/assets/" parallel="false" verbose="true" resolveexecutable="true" force="true" vmlauncher="true">
<arg value="-copy none"/>
<arg value="-optimize"/>
<arg value="-perfect"/>
<srcfile/>
<targetfile/>
<fileset dir="${SRC_DIR}/public/assets/images" casesensitive="yes">
<include name="**/*.jpg"/>
</fileset>
<mapper type="identity"/>
</apply>
</target>
What could be wrong with my ant code?

One item that needs to be changed is the nested <arg> element for -copy none. Since there is a space in the argument, use the line attribute instead of value. See Apache Ant command line arguments.
<target name="optimize.images.jpg">
<apply executable="jpegtran.exe" dir="${SRC_DIR}/public/assets/"
parallel="false" verbose="true" resolveexecutable="true" force="true"
vmlauncher="true">
<arg line="-copy none"/>
<arg value="-optimize"/>
<arg value="-perfect"/>
<srcfile/>
<targetfile/>
<fileset dir="${SRC_DIR}/public/assets/images" casesensitive="yes">
<include name="**/*.jpg"/>
</fileset>
<mapper type="identity"/>
</apply>
</target>

Related

How to apply pack200 using build file?

How to apply pack200 using build file?
Please specify your answer where I am missing.
This is my code:
<target name="pack200">
<apply executable="pack200" parallel="false" dest="${build.dir}">
<arg value="--modification-time=latest"/>
<arg value="--deflate-hint=true"/>
<arg value="--segment-limit=-1"/>
<targetfile/>
<srcfile/>
<fileset dir="${build.dir}" includes="*/.jar" />
<mapper type="glob" from="D:/*" to="D:/*.pack.gz" />
</apply>
</target>

ant compress and override js/css files

Hello i am trying to compress all the .css and .js files from a directory and overwrite the original file with the same name(no concatenation)
I am using this code https://stackoverflow.com/a/3826896/579646 (also tried numerous other tutorials) but it doesn't work.
I tried this
<target name="css.minify">
<apply executable="java" parallel="false" dest="${builddir}/${NAME}/site/assets/css" verbose="true">
<fileset dir="${builddir}/${NAME}/site/assets/css" includes="**/*.css"/>
<arg line="-jar"/>
<arg path="yuicompressor.jar"/>
<arg line="--line-break 0"/>
<srcfile/>
<arg line="-o"/>
<arg line="-v"/>
<mapper type="glob" from="*.css" to="*-min.css"/>
<targetfile/>
</apply>
<move todir="${builddir}/${NAME}/site/assets/css" overwrite="true" >
<fileset dir="${builddir}/${NAME}/site/assets/css" />
<mapper type="glob" from="*-min.css" to="*.css"/>
</move>
</target>
and this
<target name="js.minify">
<apply executable="java" parallel="false">
<fileset dir="${builddir}/${NAME}/site/assets/js" includes="**/*.js" casesensitive="no"/>
<arg line="-jar"/>
<arg path="yuicompressor.jar"/>
<srcfile/>
<arg line="-o"/>
<mapper type="glob" from="*.js" to="*.js"/>
<targetfile/>
</apply>
</target>
They both seem to fail
What am i doing wrong?
I did a test directly using the jar, to see why was not working.
I understood that from command line this is the right command options sequence:
$java -jar WEB-INF/lib/yuicompressor.jar -v -o <destination-file-min.js> <source-file.js>
Note that if the path (parent folders) of the destination file does not exists, the library will not create it (java.io.FileNotFoundException).
So, Ant:
<copy flatten="false" includeemptydirs="true" todir="${js.target.dir}">
<fileset dir="${js.source.dir}" excludes="**/*.*" includes="**/*" />
</copy>
<apply executable="java" dest="${js.target.dir}" parallel="false" verbose="true" ignoremissing="true">
<fileset dir="${js.source.dir}" includes="**/*.js" excludes="**/*-min.js, **/*.min.js"/>
<arg line="-jar"/>
<arg path="docroot/WEB-INF/lib/yuicompressor.jar"/>
<arg line="-o"/>
<mapper type="glob" from="*.js" to="*-min.js"/>
<targetfile/>
<srcfile/>
</apply>
The Copy before Apply is needed to create the relative path of destination minified js.
NOTE that targetfile and srcfile are reversed as expected by the jar.
I pasted only the js part.. for css it's the same.
I use this for both css and js and it works just fine:
<apply executable="java" parallel="false">
<fileset dir="${src.dir}/js" includes="*.js" />
<arg line="-jar" />
<arg path="${lib.path}/yuicompressor-2.4.7.jar" />
<srcfile />
<arg line="-o" />
<mapper type="glob" from="*.js" to="${dest.dir}/js/*.js" />
<targetfile />
</apply>
In the js.minify target u shared seems like u're overwriting the js files (look at the mapper tag), be careful with that.
Also in the css u're moving all the css and renaming them after compressing, this can be done all with the yui compressor target (look at my code).
I hope this helps.

How to tell ant apply task the destination

Here is my ant apply task:
<apply executable="${7z.exec}" failonerror="true">
<arg value="x"/>
<fileset dir="${distdir}">
<include name="**/*.zip"/>
</fileset>
</apply>
7z.exec is an absolute path to the 7z.exe executable. How can I tell 7zip to deposit the unzipped files into the same folder as the .zip?
You need to use the 7z -o switch for the eXtract command and an Ant mapper to get just the path to the zip. The Ant apply task has a targetfile element that allows you extra flexibility in composing the command line for the task. Leads to something like:
<apply executable="${7z.exec}" failonerror="true">
<arg value="x"/>
<srcfile />
<targetfile prefix="-o" />
<mapper type="regexp" from="^(.*)/(.*\.zip)" to="\1" />
<fileset dir="${distdir}">
<include name="**/*.zip"/>
</fileset>
</apply>

Creating the new Directories in the ANT Apply Operation

I am trying to minify the css files in a directory and place the minified items into another directory. I already have:
<target name="css.minify">
<apply executable="java" parallel="false" force="true" dest="FDN/css/min">
<fileset dir="FDN/css" includes="**/*.css"/>
<arg value="-jar"/>
<arg path="lib/yuicompressor-2.4.7.jar"/>
<srcfile/>
<arg value="-o"/>
<mapper type="glob" from="*.css" to="*-min.css"/>
<targetfile/>
</apply>
</target>
This works fine when the directory structure in FDN/css/min is the same as FDN/css. However, if a new directory is added a FileNotFound occurs because it does not exist in the destination.
How can I force the directory to be created if it does not already exist?
You could create the dirs before you execute the apply task.
Here's an example of how you could do it:
<touch mkdirs="true">
<fileset dir="src">
<include name="**/*.css"/>
</fileset>
<regexpmapper from="^(.*)/[^/]*$$" to="dest/\1/.tmp" handledirsep="true"/>
</touch>
<delete>
<fileset dir="dest" includes="**/.tmp"/>
</delete>
It's based on an answer I gave to a different question.

Use Ant to change the last modified date of a file

I am currently using YUI to compress JavaScript files via Ant:
<apply executable="java" parallel="false">
<fileset dir="." includes="${build.web.dir}/js/*.js"/>
<arg line="-jar"/>
<arg path="yuicompressor-2.4.7.jar"/>
<srcfile/>
<arg line="-o"/>
<mapper type="glob" from="*.js" to="*-min.js"/>
<targetfile/>
</apply>
However the newly created *-min.js files now have newer "Last Modified" dates. This becomes a problem when I rollout the files using RSYNC which compares the last modified date to determine whether or not the file should be updated.
Ideally I would like to preserve the last modified date so the rollout doesn't update all the files unnecessarily and also overwriting newer files on the server (It has happened before).
Suggest you look into Ant selectors, most likely the depend selector. They will let you restrict the compression to only those files where the uncompressed javascript is newer than the previous compressed version, if you see what I mean.
For example, something like:
<apply executable="java" parallel="false">
<fileset dir="." includes="${build.web.dir}/js/*.js"
excludes="${build.web.dir}/js/*-min.js">
<depend targetdir=".">
<globmapper from="*.js" to="*-min.js"/>
</depend>
</fileset>
<arg line="-jar"/>
<arg path="yuicompressor-2.4.7.jar"/>
<srcfile/>
<arg line="-o"/>
<mapper type="glob" from="*.js" to="*-min.js"/>
<targetfile/>
</apply>
Thanks to #martin-clayton I was able to use the Touch Task to restore the newly created minified files to their original Last Modified dates.
The following is a parameterised ant call allowing both CSS and JS files to be easily minified:
<target name="minify-filetype" >
<echo>Minimise all ${filetype} files</echo>
<apply executable="java" parallel="false">
<fileset dir="." includes="${build.web.dir}/${filetype}/*.${filetype}"/>
<arg line="-jar"/>
<arg path="../../../etc/ant/trunk/lib/yuicompressor-2.4.7.jar"/>
<srcfile/>
<arg line="-o"/>
<mapper type="glob" from="*.${filetype}" to="*-min.${filetype}"/>
<targetfile/>
</apply>
<echo>Convert minified files back to original Last Modified dates</echo>
<touch>
<fileset dir="." includes="${build.web.dir}/${filetype}/*.${filetype}"
excludes="${build.web.dir}/${filetype}/*-min.${filetype}"/>
<mapper type="glob" from="*.${filetype}" to="*-min.${filetype}"/>
</touch>
<!-- moving *-min.js and creating *.js files (overwriting orginal and deleting *-min) -->
<move todir="${build.web.dir}/${filetype}/" overwrite="true" preservelastmodified="true">
<fileset dir="${build.web.dir}/${filetype}/" />
<mapper type="glob" from="*-min.${filetype}" to="*.${filetype}"/>
</move>
</target>

Resources