Use Ant to change the last modified date of a file - ant

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>

Related

ant : apply executable when output file doesn't exist

I try to create a ant target which processes some GLSL shaders from an input directory, output them in another folder. And I'd like to avoid the processing if the output file already exists.
The executable I use can either take an output directory argument, or directly the output file path.
Currently, I have :
<target name="optimize_programs">
<apply executable="TOOLS/glsl_processor" dir="." verbose="true" >
<srcfile/>
<arg value="-output_directory=OUTPUT/PROGRAMS/" />
<fileset dir="INPUT/PROGRAMS/OPENGLES2" includes="**/*.glfx" />
<flattenmapper />
</apply>
</target>
The shaders are correctly processed, but the problem is they are processed each time, even when the output file already exists.
I suspect this is because the flattenmapper is not aware of the glsl_processor output.
I've tried to use to tell the glsl_processor where to output the file :
<target name="optimize_programs">
<apply executable="TOOLS/glsl_processor" dir="." verbose="true" >
<srcfile/>
<targetfile/>
<fileset dir="INPUT/PROGRAMS/OPENGLES2" includes="**/*.glfx" />
<flattenmapper />
</apply>
</target>
But I don't know how to make targetfile point to the output folder.
Any idea?
Thanks!
Well the answer is actually pretty simple:
<target name="optimize_programs">
<apply executable="TOOLS/glsl_processor" dir="INPUT/PROGRAMS/OPENGLES2/" dest="OUTPUT/PROGRAMS" verbose="true" >
<targetfile/>
<srcfile/>
<fileset dir="INPUT/PROGRAMS/OPENGLES2" includes="**/*.glfx" />
<mapper type="glob" from="*.glfx" to="*.glfx"/>
</apply>
</target>
I was just missing to fill the dest attribute of the apply task.

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.

Ant Task to create docs directory tree with docco

I have an ant file to generate coffeescript documentation with docco. It works fine, except that it currently dumps all of the documentation file into the docs folder. I'd like the docs folder to mirror the structure of my scripts directory, rather than just having all files dumped flat into one directory.
<target name="documentation" description="Generate Docco Documentation for coffee files">
<apply executable="docco" verbose="true" force="true" failonerror="true">
<srcfile />
<fileset dir ="${src.script.dir}" >
<include name="**/*.coffee"/>
</fileset>
</apply>
</target>
I know docco has an --output argument, but my I'm not sure how to generate the docs directory path in the docs folder for each file in the fileset without going through them 1 by 1.
Using <srcfile> and <targetfile> parameters for apply task should solve the problem.
Here's an example that moves files with .a extension to .b extension:
<apply executable="mv" dir="./" relative="true">
<mappedresources>
<fileset dir="." includes="**/*.a"/>
</mappedresources>
<mapper type="glob" from="*.a" to="*.b"/>
<srcfile/>
<targetfile/>
</apply>
Take a look at Mapper type, too.
Try something like that for your case:
<target name="documentation" description="Generate Docco Documentation for coffee files">
<apply executable="docco" verbose="true" force="true" failonerror="true">
<srcfile />
<fileset dir ="${src.script.dir}" >
<include name="**/*.coffee"/>
</fileset>
<arg value="--output">
<mapper type="glob" from "*.coffee" to="*.html"/>
<targetfile/>
</apply>
</target>

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

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>

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.

Resources