I'd like to propose a new function set that would help solve the issue of
generating a classpath from a list of files. The functions deal with named
filesets like this:

<project>
    <fileset id="zzz">
        <includes name="*.cs" />
    </fileset>
    <fileset id="rrr">
        <includes name="*.csu7987987" />
    </fileset>
    <echo message="flatten: ${fileset::flatten('zzz',';')}" />
    <echo message="exists: ${fileset::exists('zzz')}" />
    <echo message="exists: ${fileset::exists('zzz2')}" />
    <echo message="is-empty: ${fileset::is-empty('zzz')}" />
    <echo message="is-empty: ${fileset::is-empty('rrr')}" />
    <echo message="file-count: ${fileset::get-file-count('zzz')}" />
    <echo message="file-name[0]: ${fileset::get-file-name('zzz',0)}" />
</project>

Proposed implementation is attached (no help yet, but if we decide this
should go in, I'll write some help text).

With this you'd be able to do:

<fileset id="jarfiles">
    <includes name="${ant.home}/lib/*.jar" />
</fileset>

<exec commandline "...-classpath ${fileset::flatten('jarfiles',';')}...  "
/>

I believe that this technique would be useful in many more places.
Should I commit?

Jarek

----- Original Message ----- 
From: <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Friday, March 19, 2004 2:57 PM
Subject: [nant-dev] New to the list


>
>
>
>
> Hi everyone!  I joined this list because there are some differences
between
> Nant and Ant which have been causing me trouble.  I wanted to post my
> solutions in the hopes that they may be useful.  If it's stuff that's
> already been thought of, just tell me to shut up :)
>
> The first problem I ran up against was running Ant from Nant.  On the
> Windows platform, Ant is run through a batch file which does not
> communicate the program exit code.  So the Nant build always believes that
> the Ant build succeeded.  To get around this, I actually call the Java
> class file like so:
>
>         <exec
>             program="${java.home}/bin/java.exe"
>             workingdir="${mbpa.home}"
>             commandline="-classpath ${ant.cp}
> org.apache.tools.ant.launch.Launcher build"
>             failonerror="true"
>             />
>
> This is obviously not a problem, however getting the classpath correct is
a
> pain because you have to add all the jars in the ant/lib directory since
> Nant doesn't have any clue what a Java classpath is.  To achieve this, I
> wrote a little script:
>
>         <script language="C#">
>             <code><![CDATA[
>                 public static void ScriptMain( Project project ) {
>                     string ald = project.Properties["ant.home"] + "/lib";
>                     string jh = project.Properties["java.home"];
>                     string cp = jh + "/lib/tools.jar";
>                     DirectoryInfo di = new DirectoryInfo(ald);
>                     FileInfo[] files = di.GetFiles("*.jar");
>                     foreach (FileInfo fi in files)
>                         cp += ";" + ald + "/" + fi.Name;
>                     project.Properties["ant.cp"] = cp;
>                 }
>             ]]></code>
>         </script>
>
> It's a simple script and it has been working very well for me.  Is there a
> better way to do this?  I guess what I want to achieve eventually is an
Ant
> task for Nant.  I imagine it would require that a Java task also be
> created.  Is anybody else working on this kind of thing?  I'd appreciate
> some suggestions on what it would take to start working on an Ant task.
> And if you don't think this is desirable, please speak up so that I don't
> waste my time.
>
> Alright, the second thing I ran into is a big annoyance to me.  Ant has
the
> ability to load a properties file using the following:
>
>     <property file="build.properties" />
>
> I could not find anything similar to this in Nant, so please tell me if I
> just missed something.  I want to share a properties file between Nant and
> Ant, so I needed something that would load the properties from that file.
> To do this, I wrote the following script outside of a target:
>
>     <script language="C#">
>         <code><![CDATA[
>             public static void ScriptMain( Project project ) {
>                 try {
>                     string prop_file = project.Properties["prop.file"];
>                     using (StreamReader sr = new StreamReader(prop_file))
{
>                         string line;
>                         while ((line = sr.ReadLine()) != null) {
>                             Regex re = new
> Regex("^\\s*([\\w_\\-\\.]+)\\s*=\\s*(.*?)\\s*$");
>                             if (re.IsMatch(line)) {
>                                 Match m = re.Match(line);
>                                 string prop_name = m.Groups[1].ToString();
>                                 string prop_val = m.Groups[2].ToString();
>                                 // The following line does semantic
> processing on the property before
>                                 // adding it to the list of properties.
>                                 prop_val =
> project.Properties.ExpandProperties(prop_val, Location.UnknownLocation);
>                                 project.Properties[prop_name] = prop_val;
>                             }
>                         }
>                     }
>                 }
>                 catch (Exception exc) {
>                     throw new BuildException("Exception caught while
> loading properties file:\n" + exc.Message);
>                 }
>             }
>         ]]></code>
>     </script>
>
> This is also a bit of functionality that I'd like to add to Nant.  This
> code doesn't verify the property file at all, it just finds lines that
look
> like properties and ignores the rest.  Also, there's this line:
>
>     prop_val = project.Properties.ExpandProperties(prop_val,
> Location.UnknownLocation);
>
> This line seems troublesome to me because if something later changes one
of
> those properties, the dependent properties will not change.  I did try to
> mark the properties as dynamic through the PropertyDictionary, but Nant
> comes back with an error explaining that MarkDynamic is not defined.  Any
> suggestions on how to fix this?  And how much validation would be required
> for a properties file in order to add the same properties file
capabilities
> that Ant has to Nant?
>
> Thanks for your time,
>
> Dustin
>
>
>
> -------------------------------------------------------
> This SF.Net email is sponsored by: IBM Linux Tutorials
> Free Linux tutorial presented by Daniel Robbins, President and CEO of
> GenToo technologies. Learn everything from fundamentals to system
> administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
> _______________________________________________
> nant-developers mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/nant-developers
>
// NAnt - A .NET build tool
// Copyright (C) 2001-2003 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Ian Maclean ([EMAIL PROTECTED])
// Jaroslaw Kowalski ([EMAIL PROTECTED])

using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Reflection;
using System.Globalization;

using NAnt.Core;
using NAnt.Core.Types;
using NAnt.Core.Attributes;

namespace NAnt.Core.Functions {
    [FunctionSet("fileset", "Fileset")]
    public class FilesetFunctions : FunctionSetBase {
        #region Public Instance Constructors

        public FilesetFunctions(Project project, PropertyDictionary propDict) : 
base(project, propDict) {
        }

        #endregion Public Instance Constructors

        #region Public Instance Methods

        [Function("exists")]
        public bool Exists(string filesetId) {
            DataTypeBase dtb = Project.DataTypeReferences[filesetId];
            if (dtb == null)
                return false;
            if (dtb is FileSet)
                return true;
            else
                return false;
        }

        [Function("get-file-count")]
        public int GetFileCount(string filesetId) {
            FileSet fs = GetFileSetByID(filesetId);
            return fs.FileNames.Count;
        }

        [Function("get-file-name")]
        public string GetFileCount(string filesetId, int pos) {
            FileSet fs = GetFileSetByID(filesetId);
            return fs.FileNames[pos];
        }

        [Function("is-empty")]
        public bool IsEmpty(string filesetId) {
            FileSet fs = GetFileSetByID(filesetId);
            return fs.FileNames.Count == 0;
        }

        [Function("flatten")]
        public string Flatten(string filesetId, string separator) {
            FileSet fs = GetFileSetByID(filesetId);
            StringBuilder result = new StringBuilder();

            foreach (string s in fs.FileNames) {
                if (result.Length != 0)
                    result.Append(separator);

                result.Append(s);
            }

            return result.ToString();
        }

        private FileSet GetFileSetByID(string id)
        {
            DataTypeBase dtb = Project.DataTypeReferences[id];
            if (dtb == null)
                throw new 
ArgumentException(String.Format(CultureInfo.InvariantCulture, "Fileset: '{0}' not 
found", id));
            if (!(dtb is FileSet))
                throw new 
ArgumentException(String.Format(CultureInfo.InvariantCulture, "Fileset: '{0}' not 
found", id));
            return (FileSet)dtb;
        }

        #endregion Public Instance Methods
    }
}

Reply via email to