Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

ant

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.
like image 794
zero298 Avatar asked Mar 07 '14 00:03

zero298


People also ask

How do I call ant target from command line?

To run the ant build file, open up command prompt and navigate to the folder, where the build. xml resides, and then type ant info. You could also type ant instead. Both will work,because info is the default target in the build file.

What is target ant?

A target is a container of tasks and datatypes that cooperate to reach a desired state during the build process. Targets can depend on other targets and Apache Ant ensures that these other targets have been executed before the current target.

What is true about ant task?

Ant tasks are the units of your Ant build script that actually execute the build operations for your project. Ant tasks are usually embedded inside Ant targets. Thus, when you tell Ant to run a specific target it runs all Ant tasks nested inside that target.

What does * stand for in * Test Java in ant?

**\*.sql means "in the given directory and inside all of its subdirectories, all the files that end with .sql"


1 Answers

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
like image 94
martin clayton Avatar answered Oct 29 '22 12:10

martin clayton