Search code examples
arraysloopsforeachantant-contrib

Iterate through array of hashes in ANT script


I am working on some automation using Jenkins, where I have the schema and DB details stored like

[schema1:db1, schema2:db2] stored in a ANT property ${schemaValue}

<propertycopy name="schemaValue" from="${SchemaVariable}"/>

Now I am trying to loop through this array of hashes to execute the connection, I have tried with

        <for param="theparam" list="${schemaValue}">
            <sequential>
                <echo message="param: @{theparam}"/>
            </sequential>
        </for>

But this considers ${schemaValue} as String and not an array,

Help on this.

EDIT

As suggested by @AR.3, I have tried with

<propertyregex override="yes" property="paramValue" input="@{theparam}" regexp=".+:([^\]]+)]?" replace="\1"/>
<echo message="paramValue: ${paramValue}"/>
<propertyregex override="yes" property="paramKey" input="@{theparam}" regexp="[?([^\[]+):]" replace="\1"/>
<echo message="paramKey: ${paramKey}"/>

${paramValue} gives me db1 and db2 correctly

${paramKey} throws me error


Solution

  • There is no concept of an array in Ant in the strict sense that exists in standard programming languages. The for loop will simply iterate over elements of a string delimited by a delimiter (the default delimiter is ,). In your case, it also looks more like a map or a list of key-value pairs.

    If the expected behavior is to print the values in the map (db1 and db2), an additional step involving a regular expression replacement can be used:

    <for param="theparam" list="${schemaValue}">
        <sequential>
            <propertyregex override="yes"
                  property="paramValue"  input="@{theparam}"
                  regexp=".+:([^\]]+)]?" replace="\1"/>
            <echo message="param: ${paramValue}"/>
        </sequential>
    </for>
    

    So originally, the echoed values contained in theparam will be [schema1:db1 and schema2:db2]. The pattern .+:([^\]]+)]? will match against such values, by matching against:

    1. one or more characters,
    2. followed by a :,
    3. followed by non-] characters,
    4. followed by zero or one ].

    The propertyregex will put the value of the first group, i.e. the one matched by ([^\]]+) in a property paramValue. This will be in fact the value after the colon.

    Running it should print:

    [echo] param: db1
    [echo] param: db2
    

    EDIT:

    To get the key instead, you can use the following regex:

    <propertyregex override="yes" property="paramKey"
                   input="@{theparam}" regexp="\[?([^\[]+):[^\]]+]?" replace="\1"/>