We are in the process of finalizing the development of a functional port of the continuous integration tool CruiseControl (http://cruisecontrol.sourceforge.net) to the .NET platform. In doing so, we have made a number of enhancements to the XmlLogging capabilities of NAnt that were originally implemented and posted by Bill Caputo. I have confirmed all our modifications with Bill, and hopefully these changes won't affect anyone else.
We have made 3 basic changes: 1) We have changed the output of the XmlLogger from <foobar><exec/></foobar> to <target name="foobar"><task name ="exec"></target>. This helps identify which elements are targets and which are tasks. More importantly, it makes browsing the Xml output using XPath much more explicit. The generated output is also now very similar to what is produced by Ant. 2) We needed to be able to identify the type of messages generated by particular tasks. Specifically, we needed to identify which messages generated by the compile tasks were compiler warnings and errors and which were just informational messages. In Ant, this is solved by using a priority attribute attached to different messages. To accomplish this in NAnt we added a WriteMessage method to Log. Unfortunately we couldn't address the issue by overloading the Write or WriteLine methods, so we had to add a new method. The WriteMessage method adds a type attribute to the outputted message element. Currently it does not modify the output for non-xml loggers. 3) We modified the NUnit task to redirect its Xml output to the console if required. The NUnit task provided a usefile attribute, which was actually not used (if it was activated the output would just disappear -- ie. it would not be logged to file). We modified its implementation so that it would redirect its output via the logger to the console. To this effect, we created a LogWriter class which subclasses StringWriter. It uses a string buffer to cache the output and then redirects it to the Log when the stream is closed. This class enables us to swap implementations that expect a file stream for logging output to file. The nunit2 task, when it is ready, should work similarly. Hopefully these modifications are all acceptable. As a point of reference, I've attached the original email from Bill to the list below. Best regards, Owen. -- www.exortech.com Hi All, I have implemented Xml Logging for use on an upcoming project, and so I wanted to submit a patch and the files in the in the event that the nant maintainers find it goes in the direction they have envisioned for logging. My hope is that it provides a good foundation for that effort. I based the event structure on Ant 1.5's implementation of events, as they fit my needs and allow the use of Log4Net (Ant 1.5 has a listener for LogForJ) as Scott described. The files I have attached represent first pass at Xml (and event-based) logging. Along the way I have kept the code base entirely backward compatible (i.e. the ConsoleLogger works like it always did). My other goals were minimalism, and least-invasive. Here's what I added: An interface IBuildEventConsumer that defines a set of events (defined in Log.cs) A new subtype of LogListener called XmlLogger (in XmlLogger.cs) that also implements the IBuildEventConsumer interface A BuildEventArgs class that represents a build event (defined in Log.cs) A cmd line option for specifying the logger -logger:type name (e.g. SourceForge.NAnt.XmlLogger) a cmd line option for specifying a log file -logfile:fileName A bunch of unit tests A set of delegate based events and OnEvent methods (defined statically in Project.cs) Calling of those events wrapping Build start and finish (in Project.cs) Target start and finish (Target.cs) and Task start and finish (Task.cs) The result is a build report that is informationally the same as the console output, but in an xml format. Here's what I might add at some point to our version (although it meets our needs now) -- and if the code finds its way into the next NAnt release, what others might like to look at: * Add more event args (e.g migrating the BUILD SUCCEEDED and other success metrics for use by the BuildFinished event) * Finish migrating to event-based logging. Right now its sort of a hybrid -- XmlLogger implements the six events, but still uses the Write* methods of LogListener to handle messages. Two additional events: say MessageFragment and Message would complete the migration. * Remove the call in Target that prints the name of the target out and reimplement as the TargetStarted method on ConsoleLogger (after specifying that it implements IBuildEventConsumer) * Refactor the Main function in NAnt.cs (its doing a lot now) so that the property info is more robust, and some of the logging code that is currently inline moved to its own methods * Revisit how the file for logging gets created. * Remove the formatting from the Log.Write* calls and do this formatting in the appropriate events in ConsoleLogger * Change the Loggers into listeners (ala Ant) and also allow a single Logger (ala Ant) * Make it possible to specify multiple listeners on the cmd line (i.e the logfile attribute would go with the logger not the listeners). Currently (in the mod) if you specify a logger on the cmd line it replaces the default Logger. The Log class's round robin implementation is unchanged, but unused for this implementation. * Remove the logging round robin code (which makes a lot of assumptions about formatting and logger needs) and take full advantage of Event multicasting which does more or less the same thing but in a less coupled fashion. * Other miscellaneous refactorings that remove assumptions about what it means to listen and log the build Whew, that got a bit long, hope someone finds this useful. Best, Bill
cc.zip
Description: Zip compressed data