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

Attachment: cc.zip
Description: Zip compressed data

Reply via email to