<!--
   Ant build template for Javascript projects.

   To use it, projects must import this file into their own build.xml and define all variables.
-->
<!-- TODO define all base targets as extension-point and make javascript.* targets -->
<project name="javascript" default="package" xmlns:ivy="antlib:org.apache.ivy.ant">

    <!--
        Loads default properties : simple convenience (not specific to Javascript)
    -->

    <!-- example of use : local properties for the main project only -->
    <property file="local.properties"/>
    <!-- example of use : default properties for the main project only -->
    <property file="build.properties"/>
    <!-- example of use : default generic properties -->
    <property file="default.properties"/>

    <!-- shorthand properties -->
    <property name="target.lib.dir" value="${target.dir}/lib" />

    <!--
        Loads dependent tasks
    -->

    <path id="ivy.lib.path">
        <fileset file="${ant.ivytask.path}" />
    </path>
    <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>


    <!--
        Main phases : they are greatly inspired from the Maven build lifecycle
        See http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference
    -->

    <extension-point name="validate" description="Validates the project is correct and all necessary information is available." />

    <extension-point name="compile" depends="validate" description="Compiles the source code of the project." />

    <extension-point name="test" depends="compile" description="Tests the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed." />

    <extension-point name="package" depends="test" description="Takes the compiled code and package it in its distributable format, such as a JAR." />

    <extension-point name="integration-test" depends="package" description="Processes and deploys the package if necessary into an environment where integration tests can be run." />

    <extension-point name="verify" depends="integration-test" description="Runs any checks to verify the package is valid and meets quality criteria." />

    <extension-point name="install" description="Installs the package into the local repository, for use as a dependency in other projects locally." />

    <extension-point name="deploy" depends="verify" description="Done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects." />

    <extension-point name="clean" description="Restores the initial state of the project, deleting any generated file." />

    <extension-point name="site" description="Generates site documentation for this project." />


    <!--
        Some more specific targets
    -->

    <target name="make-validate" extensionOf="validate" description="Validates the project is correct and all necessary information is available.">
        <!-- Retrieves dependencies with ivy : required to initialize the cache and to get informations about the module being built -->
        <!-- We use the default pattern, but put the resolved artifacts in a directory of ours so we can delete it afterwards -->
    	<ivy:retrieve pattern="${build.dir}/ivy/[conf]/[artifact].[ext]" sync="true" />
        <!-- Creates required directories -->
        <mkdir dir="${target.dir}" />
    </target>

    <target name="ivy-install" extensionOf="install" depends="validate" description="Builds and installs the artifacts into the local Ivy repository.">
        <!-- 'local' resolver is a default one bundled with Ivy ; it resides in the user's home directory -->
        <!-- 'artifactspattern' must match the name of the files this script builds -->
        <!-- Note : We use all options to force overwriting of existing (and possibly deprecated, during development) files -->
        <ivy:publish resolver="local" artifactspattern="${target.lib.dir}/[artifact].[ext]" overwrite="true" forcedeliver="true" publishivy="true" />
    </target>

    <target name="make-clean" extensionOf="clean" description="Deletes build and target directories">
        <!-- NOTE 'dir' attribute is more efficient at deleting dirs than nested <fileset dir='...' /> -->
        <delete dir="${build.dir}" deleteonexit="true" failonerror="false" />
        <delete dir="${target.dir}" deleteonexit="true" failonerror="false" />
    </target>

    <target name="doc" depends="validate" extensionOf="site" description="Generates API documentation for this project.">

        <!-- Generates a report of dependencies -->
        <ivy:report todir="${target.dir}/doc/ivy"/>

        <!-- Generates the API doc -->
        <java jar="${jsdoc.dir}/jsrun.jar" fork="true" failonerror="true">
            <arg file="${jsdoc.dir}/app/run.js" />
            <arg file="${src.dir}"/>
            <arg prefix="--template=" file="${jsdoc.dir}/templates/jsdoc" />
            <arg value="--allfunctions" />
            <arg value="--private" />
            <arg prefix="--directory=" file="${target.dir}/doc/api/js"/>
            <arg value="--recurse"/>
            <arg value="--verbose" />
        </java>

        <echo message="Done generating site." />

    </target>

    <!--
        Takes all *.js files inside ${src.dir} as input.
        Creates a file name after the new property 'build.bigsource.js'.
    -->
    <target name="build-bigsource" depends="validate" description="Copies all source scripts into one big file for further work on it." >
        <tempfile property="build.bigsource.js" destDir="${build.dir}" prefix="${ant.project.name}" suffix=".js" />
        <!-- TODO handle encoding (and eol?) -->
        <concat destfile="${build.bigsource.js}">
            <fileset dir="${src.dir}">
                <include name="**/*.js" />
            </fileset>
        </concat>
        <echo message="Created : ${build.bigsource.js}" level="verbose" />
    </target>

    <macrodef name="make-default" description="Builds the default .js.">
        <attribute name="bigsource" />
        <attribute name="dir" default="${target.lib.dir}" />
        <attribute name="module" default="${ivy.module}" />
        <attribute name="revision" default="${ivy.revision}" />
        <sequential>
            <copy file="@{bigsource}" tofile="@{dir}/@{module}.js" />
            <echo message="Copied : @{dir}/@{module}.js" />
        </sequential>
    </macrodef>

    <macrodef name="make-min" description="Builds a minified version of the .js.">
        <attribute name="bigsource" />
        <attribute name="dir" default="${target.lib.dir}" />
        <attribute name="module" default="${ivy.module}" />
        <attribute name="revision" default="${ivy.revision}" />
        <sequential>
        <java jar="${yuicompressor.jar}" fork="true" output="@{dir}/@{module}-min.js" failonerror="true">
            <arg line="--type js" />
            <arg file="@{bigsource}"/>
        </java>
        <echo message="Minified : @{dir}/@{module}-min.js" />
        </sequential>
    </macrodef>

    <target name="build-default" extensionOf="package" depends="build-bigsource" description="Builds the default .js.">
        <make-default bigsource="${build.bigsource.js}" />
    </target>

    <target name="build-minified" extensionOf="package" depends="build-bigsource" description="Builds a minified version of the .js.">
        <make-min bigsource="${build.bigsource.js}" />
    </target>

    <!-- TODO Works but misses minified artifact amongst other things ; see http://ant.1045680.n5.nabble.com/Review-Needed-for-quot-Publishing-Maven-Artifacts-with-Ivy-quot-Doc-td3204659.html -->
    <target name="build-pom" extensionOf="package" depends="validate" description="Builds a Maven POM.">
        <ivy:makepom ivyfile="${basedir}/ivy.xml" pomfile="${target.dir}/${ivy.module}.pom">
            <mapping conf="default" scope="test"/>
            <mapping conf="minified" scope="compile"/>
        </ivy:makepom>
    </target>

    <target name="build-site" extensionOf="deploy" depends="site" description="Builds a local directory that will reflect the structure of the final site with Ivy and Maven repositories as well as online API docs" >
        <!-- First, creates an Ivy repo -->
        <ivy:settings id="ivy.repo.site" file="${ivy.settings.path}" />
        <!-- Note : transitive=false so we need to 'deploy' each project -->
        <!-- Note : overwrite=true because it's easier during development -->
        <ivy:install organisation="${ivy.organisation}" module="${ivy.module}" revision="${ivy.revision}" settingsRef="ivy.repo.site" from="target" to="site" overwrite="true" />
        <!-- Then add supplementary files -->
        <copy todir="${pub.dir}/${ivy.organisation}/${ivy.module}/${ivy.revision}">
            <fileset dir="${basedir}">
                <include name="*.txt" />
            </fileset>
            <!-- TODO copy pom
            <fileset dir="${target.dir}">
                <include name="*.pom" />
            </fileset>
            -->
        </copy>
        <copy todir="${pub.dir}/${ivy.organisation}/${ivy.module}/${ivy.revision}/doc/api/js">
            <fileset dir="${target.dir}/doc/api/js" />
        </copy>
    </target>

    <target name="clean-site" description="Deletes the local site built with 'buils-site'">
        <delete dir="${pub.dir}" includeemptydirs="true" deleteonexit="true" failonerror="false" />
    </target>

    <!--
        TODO fix and integrate the following targets
    -->

    <target name="pre-test" extensionOf="test" description="Runs unit tests">
       <!-- We use this target to copy all required files for the tests together in a consistent hierarchy -->
        <!--
        <copy file="${jsunit.coreJs}" todir="${jsunit.tmp}"/>
        <copy todir="${jsunit.tmp}" overwrite="true">
            <resources refid="jsunit.in.files"/>
        </copy>
        -->
        <!-- nothing more to do -->
    </target>

    <target name="test-integration" extensionOf="integration-test" description="Runs integration tests" >
        <!-- Testing the compressed version of the library -->

        <!-- Replaces the tested library with the compressed version -->
        <!-- FIXME : it's not clean : it should not override a file already in build.dir -->
        <!--
        <copy file="${target.dir}/${ant.project.name}-compressed-${ivy.revision}.js" tofile="${build.dir}/sha1.js"/>
        -->

        <!--
        <resources id="jsunit.in.files">
            <file file="${build.dir}/sha1.js"/>
            <fileset dir="${tests.dir}"/>
        </resources>
        -->

        <!--
        <antcall target="jsunit">
            <reference refid="jsunit.in.files"/>
            <param name="jsunit.in.testsuite" value="AllTests.html"/>
            <param name="jsunit.out.logs" value="${tests.logs}"/>
        </antcall>
        -->
        <!-- nothing more to do -->
    </target>

    <!--
        Runs JsUnit tests. This target saves a lot of verbosity in the projects' build scripts.
        
        Firefox 3 users : change the security.fileuri.strict_origin_policy parameter to 'false' for the following target to work
        
        // static configuration
        @in jsunit.dir          the directory where JsUnit resides
        @in jsunit.coreJs       the jsUnitCore.js file
        @in jsunit.testRunner   the test runner's HTML page
        -->
    <!--<taskdef name="jsunit" classname="net.jsunit.ant.StandaloneTestTask" classpath="/home/cbonar/src/jsunit/java/bin" />-->

    <!-- NOTE : These tests should not require the code be packaged or deployed. -->
    <target name="test-fixme" depends="compile" description="Tests the compiled source code using a suitable unit testing framework.">

        <jsunit showoutput="true"
                printsummary="true"
                filtertrace="false"
                jsUnitRoot="${jsunit.dir}"
                haltonfailure="true"
                haltonerror="true"
                >
            <sysproperty key="browserFileNames" value="${jsunit.browsers}"/>
            <sysproperty key="port" value="45678"/>
            <sysproperty key="logsDirectory" value="${tests.logs}"/>
            <test todir="${tests.logs}">
                <fileset dir="${src.dir}" includes="**/*.js"/>
                <fileset dir="${tests.dir}" includes="**/*.js"/>
            </test>
            <!--
            <scripts dir="${src.dir}" includes="**/*.js"/>
            <scripts dir="${tests.dir}" includes="**/*.js"/>
            -->
            <classpath>
                <fileset dir="${jsunit.dir}/java/lib">
                    <include name="*.jar"/>
                </fileset>
                <!--
                    <fileset dir="${jsunit.dir}/java/bin">
                        <include name="jsunit.jar"/>
                    </fileset>
                -->
                <dirset dir="/home/cbonar/src/jsunit/java/bin"/>
                <dirset dir="${jsunit.dir}/java/config"/>
            </classpath>
            <formatter type="xml"/>
        </jsunit>

    </target>

    <!-- Generates developer documentation using (old) jsdoc. -->
    <target name="jsdoc" depends="validate">

        <!-- Generates a report of dependencies -->
        <ivy:report todir="${target.dir}/doc/ivy"/>

        <!-- Generates the API doc -->
        <exec command="${jsdoc}" failonerror="true">
            <arg value="-d"/>
                <arg value="${{target.dir}/doc/js"/>
            <arg value="--no-lexical-privates"/>
            <arg value="--package-naming"/>
            <arg value="--nested-file-naming"/>
            <arg line="--logo pix/ciform-flat-48x48.png" />
            <arg line="--project-name Crypto.SHA1"/>
            <arg value="${src.dir}"/>
        </exec>

    </target>

</project>
