Endo
Endo

Reputation: 363

ANT: Load file names and extract data from the file names

Hello I wasn't quite sure how to title this question, but I'll explain why I'm trying to do.

First of all, I have a folder that contains SQL scripts in a specific format, which is updateXtoY.sql, where X and Y are integers. What I need is to know which Y is the highest number. (basically, to know which is the latest script)

So if I have in my folder "scripts/" 3 files:

update3to5.sql
update2to5.sql
update1to6.sql

the result I need is to have assign a property 'latest.version' the value of 6.

From that point I can easily run the script. So the problem I have is 3-fold:

1- How to load the file names into a data structure.

2- How to iterate over the data structure.

3- How to evaluate each file name so that I can extract the "Y" part of the file and get the highest value. (I'm reading on regex right now)

I'm new to ANT and I'm not sure if this is possible and/or feasible.

Thanks for any suggestions.

Upvotes: 4

Views: 1182

Answers (1)

martin clayton
martin clayton

Reputation: 78105

The first part of the task - getting the filenames into a 'structure' is best done using a FileSet - say for SQL scripts in a directory called scripts:

<fileset dir="scripts" includes="*.sql" id="versions" />

That creates an Ant resource collection that can be referred to using the id versions. The collection knows about your SQL script files.

Using (as you suggest) a regexp mapper, we can convert the set of files into a collection of strings, holding just the version parts from the filenames:

<mappedresources id="versions">
    <fileset dir="scripts" includes="*.sql" />
    <regexpmapper from="update.*to(.*).sql" to="\1" />
</mappedresources>

In this example versions now holds a 'list', which would be "5,5,6" for your example files.

It gets trickier now, because you probably need to carry out a numeric sort on what is a list of strings - to avoid 10 sorting as 'less' than 9. Ant ships with an embbeded Javascript interpreter, so you could use that to find the maximum. Another option would be to make use of the numeric sorting capability that ant-contrib has to offer.

Here's a Javascript 'max finder':

<scriptdef name="numeric_max" language="javascript">
    <attribute name="property" />
    <attribute name="resources_id" />
    <![CDATA[
    var iter = project.getReference(
       attributes.get( "resources_id" )
   ).iterator( );

    var max_n = 0.0;
    while ( iter.hasNext() )
    {
        var n = parseFloat( iter.next() );
        if ( n > max_n ) max_n = n;
    }
    project.setProperty( attributes.get( "property" ), max_n );
    ]]>
</scriptdef>

That defines a new Ant XML entity - numeric_max - that looks like a task, and can be used to find the numeric maximum of a collection of strings. It's not perfect - there's no validation of the strings, and I've used floats rather than ints.

Combining that with the mappedresources above:

<mappedresources id="versions">
    <fileset dir="scripts" includes="*.sql" />
    <regexpmapper from="update.*to(.*).sql" to="\1" />
</mappedresources>
<numeric_max property="latest.version" resources_id="versions" />

<echo message="Latest SQL script version: ${latest.version}." />

When I run that with your three files I get:

[echo] Latest SQL script version: 6.

Upvotes: 5

Related Questions