Search code examples
javascriptantmacrosbackslash

javascript + ANT issue


working on an ANT build file, where I have two macros defined and need to call one Macro from other.

Here is what I need to do (I have simplified the whole scenario for easy understanding). My main target calls FirstMacro with two params. The First Macro needs to do "something" with two params received and make an embedded call to SecondMacro.

One of the params passed to FirstMacro is a file path with "backslash" () in it. When I print it in the macro using echo it prints fine. But when I pass the same parameter to SecondMacro via JavaScript, the backslashes are gone (instead of C:\Test I see C:Test). What is the solution to preserve the backslash or replace them with forward slash.

Note that I am using ANT 1.7 and I have already tried string.replace(/\/g,"/") etc.

Also note that, you can copy paste the entire code below, save it as build.xml and try running the main task to see the issue in running.

<?xml version="1.0"?>
<project name="build" basedir="." default="main">
    <description>
    ==========================
    Macro: Second Macro
    ==========================
    </description>
    <macrodef name="secondMacro">
        <attribute name="param"/>

        <sequential>
            <echo>secondMacro param: @{param}</echo>
        </sequential>
    </macrodef>

    <description>
    ==========================
    Macro: FirstMacro
    ==========================
    </description>
    <macrodef name="firstMacro">
        <attribute name="param1"/>
        <attribute name="param2"/>

        <sequential>
            <echo>firstMacro first param: @{param1}</echo>
            <echo>firstMacro second param: @{param2}</echo>
            <script language="javascript">
                <![CDATA[
                    var ext = "@{param2}";
                    if ("".equals(ext)) {
                        ext = "out";
                    }

                    macrotask = project.createTask("secondMacro");
                    macrotask.setDynamicAttribute("param", "@{param1}" + "."+ext );
                    macrotask.perform();
                ]]>
            </script>
        </sequential>
    </macrodef>

    <description>
    ==========================
    Target: main target
    ==========================
    </description>
    <target name="main">

        <firstMacro param1="C:\TestFolder/TestFile" param2=""/>
    </target>
</project>

Solution

  • <firstMacro param1="C:\\TestFolder/TestFile" param2=""/>
    

    prints

    main:

    [echo] firstMacro first param: C:\TestFolder/TestFile
    [echo] firstMacro second param:
    [echo] secondMacro param: C:\TestFolder/TestFile.out

    It should be your JS code's problem. I know little about JS, but backslash means "this is an escape character" in most languages. So when JS see a single backslash, it may regard it as an escape character and do some convertion... Even if you use beanshell or something else, similar thing may happen.

    To solve the problem, you can try to modify your JS code (which I can't help, sorry) or try to use slash (/) instead of backslash.

    Update: you can use the if task from ant-contrib.
    Here is the example of the if-task version "firstMacro".

    <macrodef name="firstMacro">
        <attribute name="param1"/>
        <attribute name="param2"/>
        <sequential>
            <echo>firstMacro first param: @{param1}</echo>
            <echo>firstMacro second param: @{param2}</echo>
            <if>
                <equals arg1="@{param2}" arg2="" />
                <then>
                    <property name="param" value="@{param1}.out" />
                </then>
                <else>
                    <property name="param" value="@{param1}.@{param2}" />
                </else>
            </if>
            <secondMacro param="${param}" />
        </sequential>
    </macrodef>