Ant Task to create docs directory tree with docco - ant

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>

Related

Specify Multiple Output Files or Target Files for an Ant Apply Task

I'm trying to figure out a way to have Ant run a .jar executable that accepts a file and spits out several generated files from the single input file. Specifically, I'm trying to generate compiled .js files and at the same time generate .map files.
Normally, the command would look something like this:
java -jar compiler-latest --js a.js --js_output_file a.min.js --create_source_map a.js.map
Where:
compiler-latest is the closure-compiler jar
a.js is the JavaScript file to compile
a.min.js is the compiled JavaScript
a.js.map is the source map
My Ant script looks like this:
<project name="BuildTest" default="Build" basedir=".">
<description>
HTML Build Test with Ant
</description>
<property name="src" location="../js"/>
<property name="dst" location="../build"/>
<property name="compiler" location="../compiler.jar"/>
<!--Make Dest Directory-->
<target name="-destination">
<mkdir dir="${dst}"/>
</target>
<!--Compile JS-->
<target name="Build" depends="-destination">
<!--Filesets and Mappers-->
<fileset id="sourceFiles" dir="${src}" includes="*.js"/>
<mapper id="compiledJs" type="glob" from="*.js" to="*.compiled.js"/>
<mapper id="mapJs" type="glob" from="*.js" to="*.js.map"/>
<!--Apply Everything-->
<apply executable="java" parallel="false" dest="${dst}">
<!--Closure Compiler-->
<arg value="-jar"/>
<arg path="${compiler}"/>
<arg value="--compilation_level=SIMPLE_OPTIMIZATIONS"/>
<!--Source Files-->
<arg value="--js"/>
<srcfile/>
<fileset refid="sourceFiles"/>
<!--Output Files-->
<arg value="--js_output_file"/>
<targetfile/>
<mapper refid="compiledJs"/>
<!--Source Maps-->
<arg value="--source_map_format=V3"/>
<arg value="--create_source_map"/>
<arg value="--js_output_file"/>
<targetfile/>
<mapper refid="mapJs"/>
</apply>
</target>
<!--Clean Project-->
<target name="Clean" description="Cleans the project">
<delete dir="${dst}"/>
</target>
</project>
However, I get an error saying I can't have multiple <targetfile/> elements
apply doesn't support multiple targetfile elements.
This is a workaround, not nice, but effective.
You can use an Ant <compositemapper> to construct the command line for your application.
Below is an illustration. You need to set relative="yes" on the task in order that filenames relative to the build directory are used in preference to absolute filenames, otherwise mapping is harder. To build the command line provide a list of mappers inside the <compositemapper>. Use a <mergemapper> for fixed parts (args like --output_file), and use a suitable other mapper, maybe a glob, when you need to generate filenames.
A series of mappers is needed to separate the arguments passed to the java by <apply>, otherwise they will be passed as one long arg with embedded spaces.
<apply executable="java" parallel="false" relative="yes">
<arg line="-jar compiler-latest --js"/>
<srcfile />
<targetfile />
<compositemapper>
<mergemapper to="--js_output_file" />
<globmapper from="*.js" to="*.compiled.js" />
<mergemapper to="--source_map_format=V3" />
<mergemapper to="--create_source_map" />
<globmapper from="*" to="*.map" />
</compositemapper>
<fileset dir="." includes="*.js" />
</apply>
For a simple test that leads to a command line like:
java -jar compiler-latest --js 1.js --js_output_file 1.compiled.js --source_map_format=V3 --create_source_map 1.js.map

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.

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