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 } }