Author: stevel
Date: Fri May 18 07:20:10 2007
New Revision: 539477

URL: http://svn.apache.org/viewvc?view=rev&rev=539477
Log:
Logger work.
The main change is the new BigProjectLogger that makes reading the results of 
very big chained/nested projects  manageable. 

Some pulling up of helper methods into DefaultLogger, and a bit of cleanup 
there; plus the appopriate documentation changes

Added:
    ant/core/trunk/src/main/org/apache/tools/ant/listener/BigProjectLogger.java
Modified:
    ant/core/trunk/WHATSNEW
    ant/core/trunk/docs/manual/listeners.html
    ant/core/trunk/src/main/org/apache/tools/ant/DefaultLogger.java
    ant/core/trunk/src/main/org/apache/tools/ant/NoBannerLogger.java
    ant/core/trunk/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java
    ant/core/trunk/src/main/org/apache/tools/ant/listener/TimestampedLogger.java

Modified: ant/core/trunk/WHATSNEW
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?view=diff&rev=539477&r1=539476&r2=539477
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Fri May 18 07:20:10 2007
@@ -148,6 +148,8 @@
   <comment> nested element as nested text instead of using the 'value'
   attribute.
 
+* A new logger, BigProjectLogger, lists the project name with every target   
+
 
 Changes from Ant 1.6.5 to Ant 1.7.0
 ===================================

Modified: ant/core/trunk/docs/manual/listeners.html
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/listeners.html?view=diff&rev=539477&r1=539476&r2=539477
==============================================================================
--- ant/core/trunk/docs/manual/listeners.html (original)
+++ ant/core/trunk/docs/manual/listeners.html Fri May 18 07:20:10 2007
@@ -44,13 +44,19 @@
   <li>message logged</li>
 </ul>
 
+<p>
+  These are used internally for various recording and housekeeping operations,
+  however new listeners may registered on the command line through the 
<code>-listener</code>
+  argument.
+</p>
+
 <h3><a name="Loggers">Loggers</a></h3>
 
 <p>Loggers extend the capabilities of listeners and add the following 
features:</p>
 
 <ul>
   <li>Receives a handle to the standard output and error print streams and
-  therefore can log information to the console or the -logfile specified 
file.</li>
+  therefore can log information to the console or the <code>-logfile</code> 
specified file.</li>
   <li>Logging level (-quiet, -verbose, -debug) aware</li>
   <li>Emacs-mode aware</li>
 </ul>
@@ -104,7 +110,11 @@
     <td width="33%">Prints the time that a build finished</td>
     <td width="34%">BuildLogger</td>
   </tr>
-
+  <tr>
+    <td width="33%"><code><a 
href="#BigProjectLogger">org.apache.tools.ant.BigProjectLogger</a></code></td>
+    <td width="33%">Prints the project name every target</td>
+    <td width="34%">BuildLogger</td>
+  </tr>
 </table>
 <h3><a name="DefaultLogger">DefaultLogger</a></h3>
 
@@ -235,7 +245,7 @@
 color codes.  It works on XTerm, ETerm, Win9x Console
 (with ANSI.SYS loaded.), etc.</p>
 <p><Strong>NOTE:</Strong>
-It doesn't work on WinNT even when a COMMAND.COM console loaded with
+It doesn't work on WinNT and successors, even when a COMMAND.COM console 
loaded with
 ANSI.SYS is used.</p>
 <p>If the user wishes to override the default colors
 with custom ones, a file containing zero or more of the
@@ -318,7 +328,7 @@
 
 </blockquote>
 
-<p>To use Log4j you will need the Log4j jar file and a 'log4j.properties'
+<p>To use Log4j you will need the Log4j JAR file and a 'log4j.properties'
 configuration file.  Both should be placed somewhere in your Ant
 classpath. If the log4j.properties is in your project root folder you can
 add this with <i>-lib</i> option:</p>
@@ -386,6 +396,7 @@
 <pre>
   BUILD SUCCESSFUL - at 16/08/05 16:24
 </pre>
+<p>To use this listener, use the command:</p>
 
 <blockquote>
 
@@ -393,6 +404,63 @@
 
 </blockquote>
 
+<h3><a name="BigProjectLogger">BigProjectLogger</a></h3>
+
+<p>
+  This logger is designed to make examining the logs of a big build easier,
+  especially those run under continuous integration tools. It
+</p>
+<ol>
+  <li>When entering a child project, prints its name and directory</li>
+  <li>When exiting a child project, prints its name</li>
+  <li>Includes the name of the project when printing a target</li>
+  <li>Omits logging the names of all targets that have no direct task 
output</li>
+  <li>Includes the build finished timestamp of the TimeStamp logger</li>
+</ol>
+<p>
+  This is useful when using &lt;subant&gt; to build a large project
+  from many smaller projects -the output shows which particular
+  project is building. Here is an example in which "clean" is being called
+  on all a number of child projects, only some of which perform work:
+</p>
+<pre>
+
+======================================================================
+Entering project "xunit"
+In /home/ant/components/xunit
+======================================================================
+
+xunit.clean:
+   [delete] Deleting directory /home/ant/components/xunit/build
+   [delete] Deleting directory /home/ant/components/xunit/dist
+
+======================================================================
+Exiting project "xunit"
+======================================================================
+
+======================================================================
+Entering project "junit"
+In /home/ant/components/junit
+======================================================================
+
+======================================================================
+Exiting project "junit"
+======================================================================
+</pre>
+
+<p>
+  The entry and exit messages are very verbose in this example, but in
+  a big project compiling or testing many child components, the messages
+  are reduced to becoming clear delimiters of where different projects
+  are in charge -or more importantly, which project is failing.
+</p>
+
+<p>To use this listener, use the command:</p>
+<blockquote>
+
+<code>ant  -logger org.apache.tools.ant.listener.BigProjectLogger</code>
+
+</blockquote>
 
 <h2><a name="dev">Writing your own</a></h2>
 
@@ -402,8 +470,25 @@
 <p>Notes:</p>
 
 <ul>
-  <li>A listener or logger should not write to standard output or error; Ant
-  captures these internally and may cause an infinite loop.</li>
+  <li>
+    A listener or logger should not write to standard output or error in the 
<code>messageLogged() method</code>;
+    Ant captures these internally and it will trigger an infinite loop.
+  </li>
+  <li>
+    Logging is synchronous; all listeners and loggers are called one after the 
other, with the build blocking until
+    the output is processed. Slow logging means a slow build.
+  </li>
+  <li>When a build is started, and <code>BuildListener.buildStarted(BuildEvent 
event)</code> is called,
+    the project is not fully functional. The build has started, yes, and the 
event.getProject() method call
+    returns the Project instance, but that project is initialized with JVM and 
ant properties, nor has it
+    parsed the build file yet. You cannot call 
<code>Project.getProperty()</code> for property lookup, or
+    <code>Project.getName()</code> to get the project name (it will return 
null).
+  </li>
+  <li>
+    Classes that implement <code>org.apache.tools.ant.SubBuildListener</code> 
receive notifications when child projects
+    start and stop.
+  </li>
+
 </ul>
 
 

Modified: ant/core/trunk/src/main/org/apache/tools/ant/DefaultLogger.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/DefaultLogger.java?view=diff&rev=539477&r1=539476&r2=539477
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/DefaultLogger.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/DefaultLogger.java Fri May 18 
07:20:10 2007
@@ -22,9 +22,12 @@
 import java.io.IOException;
 import java.io.PrintStream;
 import java.io.StringReader;
+import java.util.Date;
+import java.text.DateFormat;
 
 import org.apache.tools.ant.util.DateUtils;
 import org.apache.tools.ant.util.StringUtils;
+import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Writes build events to a PrintStream. Currently, it
@@ -251,9 +254,9 @@
                 tmp.append(label);
                 label = tmp.toString();
 
+                BufferedReader r = null;
                 try {
-                    BufferedReader r =
-                        new BufferedReader(
+                    r = new BufferedReader(
                             new StringReader(event.getMessage()));
                     String line = r.readLine();
                     boolean first = true;
@@ -273,8 +276,14 @@
                 } catch (IOException e) {
                     // shouldn't be possible
                     message.append(label).append(event.getMessage());
+                } finally {
+                    if (r != null) {
+                        FileUtils.close(r);
+                    }
                 }
+
             } else {
+                //emacs mode or there is no task
                 message.append(event.getMessage());
             }
             Throwable ex = event.getException();
@@ -328,5 +337,28 @@
      * @param message Message being logged. Should not be <code>null</code>.
      */
     protected void log(String message) {
+    }
+
+    /**
+     * Get the current time.
+     * @return the current time as a formatted string.
+     * @since Ant1.7.1
+     */
+    protected String getTimestamp() {
+        Date date = new Date(System.currentTimeMillis());
+        DateFormat formatter = 
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
+        String finishTime = formatter.format(date);
+        return finishTime;
+    }
+
+    /**
+     * Get the project name or null
+     * @param event the event
+     * @return the project that raised this event
+     * @since Ant1.7.1
+     */
+    protected String extractProjectName(BuildEvent event) {
+        Project project = event.getProject();
+        return project!=null?project.getName():null;
     }
 }

Modified: ant/core/trunk/src/main/org/apache/tools/ant/NoBannerLogger.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/NoBannerLogger.java?view=diff&rev=539477&r1=539476&r2=539477
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/NoBannerLogger.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/NoBannerLogger.java Fri May 18 
07:20:10 2007
@@ -49,7 +49,17 @@
      *              Must not be <code>null</code>.
      */
     public void targetStarted(BuildEvent event) {
-        targetName = event.getTarget().getName();
+        targetName = extractTargetName(event);
+    }
+
+    /**
+     * Override point, extract the target name
+     * @param event the event to work on
+     * @return the target name to print
+     * @since Ant1.7.1
+     */
+    protected String extractTargetName(BuildEvent event) {
+        return event.getTarget().getName();
     }
 
     /**

Modified: 
ant/core/trunk/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java?view=diff&rev=539477&r1=539476&r2=539477
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java 
(original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java 
Fri May 18 07:20:10 2007
@@ -96,7 +96,7 @@
  *  47 -> White
  *
  */
-public final class AnsiColorLogger extends DefaultLogger {
+public class AnsiColorLogger extends DefaultLogger {
     // private static final int ATTR_NORMAL = 0;
     // private static final int ATTR_BRIGHT = 1;
     private static final int ATTR_DIM = 2;

Added: 
ant/core/trunk/src/main/org/apache/tools/ant/listener/BigProjectLogger.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/listener/BigProjectLogger.java?view=auto&rev=539477
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/listener/BigProjectLogger.java 
(added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/listener/BigProjectLogger.java 
Fri May 18 07:20:10 2007
@@ -0,0 +1,171 @@
+/*
+ * Copyright  2007 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.listener;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.NoBannerLogger;
+import org.apache.tools.ant.SubBuildListener;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.StringUtils;
+
+import java.io.File;
+
+/**
+ * This is a special logger that is designed to make it easier to work with 
big projects, those that use imports and
+ * subant to build complex systems.
+ *
+ * @since Ant1.7.1
+ */
+
+public class BigProjectLogger extends NoBannerLogger implements 
SubBuildListener {
+
+    /**
+     * Header string for the log.
+     * [EMAIL PROTECTED]
+     */
+    public static final String 
HEADER="======================================================================";
+    /**
+     * Footer string for the log.
+     * [EMAIL PROTECTED]
+     */
+    public static final String FOOTER=HEADER;
+
+    /**
+    * This is an override point: the message that indicates whether a build 
failed. Subclasses can change/enhance the
+    * message.
+    *
+    * @return The classic "BUILD FAILED" plus a timestamp
+    */
+    protected String getBuildFailedMessage() {
+        return super.getBuildFailedMessage() + TimestampedLogger.SPACER + 
getTimestamp();
+    }
+
+    /**
+     * This is an override point: the message that indicates that a build 
succeeded. Subclasses can change/enhance the
+     * message.
+     *
+     * @return The classic "BUILD SUCCESSFUL" plus a timestamp
+     */
+    protected String getBuildSuccessfulMessage() {
+        return super.getBuildSuccessfulMessage() + TimestampedLogger.SPACER + 
getTimestamp();
+    }
+
+
+    /**
+     * [EMAIL PROTECTED]
+     *
+     * @param event
+     */
+    public void buildStarted(BuildEvent event) {
+        super.buildStarted(event);
+        subBuildStarted(event);
+    }
+
+    /**
+     * [EMAIL PROTECTED]
+     *
+     * @param event
+     */
+    public void buildFinished(BuildEvent event) {
+        subBuildFinished(event);
+        super.buildFinished(event);
+    }
+
+    /**
+     * Override point, extract the target name
+     *
+     * @param event the event to work on
+     * @return the target name -including the owning project name (if non-null)
+     */
+    protected String extractTargetName(BuildEvent event) {
+        String targetName = event.getTarget().getName();
+        String projectName = extractProjectName(event);
+        if (projectName != null && targetName != null) {
+            return projectName + '.' + targetName;
+        } else {
+            return targetName;
+        }
+    }
+
+
+    /**
+     * [EMAIL PROTECTED]
+     *
+     * @param event An event with any relevant extra information. Must not be 
<code>null</code>.
+     */
+    public void subBuildStarted(BuildEvent event) {
+        String name = extractNameOrDefault(event);
+        Project project = event.getProject();
+
+        File base = project == null ? null : project.getBaseDir();
+        String path = base == null ?
+                "With no base directory"
+                : "In " + base.getAbsolutePath();
+        printMessage(StringUtils.LINE_SEP + getHeader()
+                + StringUtils.LINE_SEP +"Entering project " + name
+                        + StringUtils.LINE_SEP + path
+                        +StringUtils.LINE_SEP + getFooter(),
+                out,
+                event.getPriority());
+    }
+
+    /**
+     * Get the name of an event
+     *
+     * @param event the event name
+     * @return the name or a default string
+     */
+    protected String extractNameOrDefault(BuildEvent event) {
+        String name = extractProjectName(event);
+        if (name == null) {
+            name = "";
+        } else {
+            name = '"'+name+'"';
+        }
+        return name;
+    }
+
+    /** [EMAIL PROTECTED] */
+    public void subBuildFinished(BuildEvent event) {
+        String name = extractNameOrDefault(event);
+        String failed = event.getException() != null ? "failing " : "";
+        printMessage(StringUtils.LINE_SEP + getHeader()
+                + StringUtils.LINE_SEP + "Exiting " + failed + "project "
+                + name
+                + StringUtils.LINE_SEP + getFooter(),
+                out,
+                event.getPriority());
+    }
+
+    /**
+     * Override point: return the header string for the entry/exit message
+     * @return the header string
+     */
+    protected String getHeader() {
+        return HEADER;
+    }
+
+    /**
+     * Override point: return the footer string for the entry/exit message
+     * @return the footer string 
+     */
+    protected String getFooter() {
+        return FOOTER;
+    }
+
+}

Modified: 
ant/core/trunk/src/main/org/apache/tools/ant/listener/TimestampedLogger.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/listener/TimestampedLogger.java?view=diff&rev=539477&r1=539476&r2=539477
==============================================================================
--- 
ant/core/trunk/src/main/org/apache/tools/ant/listener/TimestampedLogger.java 
(original)
+++ 
ant/core/trunk/src/main/org/apache/tools/ant/listener/TimestampedLogger.java 
Fri May 18 07:20:10 2007
@@ -31,14 +31,14 @@
     /**
      * what appears between the old message and the new
      */
-    private static final String SPACER = " - at ";
+    public static final String SPACER = " - at ";
 
 
     /**
      * This is an override point: the message that indicates whether a build 
failed.
      * Subclasses can change/enhance the message.
      *
-     * @return The classic "BUILD FAILED"
+     * @return The classic "BUILD FAILED" plus a timestamp
      */
     protected String getBuildFailedMessage() {
         return super.getBuildFailedMessage() + SPACER + getTimestamp();
@@ -48,20 +48,10 @@
      * This is an override point: the message that indicates that a build 
succeeded.
      * Subclasses can change/enhance the message.
      *
-     * @return The classic "BUILD SUCCESSFUL"
+     * @return The classic "BUILD SUCCESSFUL" plus a timestamp
      */
     protected String getBuildSuccessfulMessage() {
         return super.getBuildSuccessfulMessage() + SPACER + getTimestamp();
     }
 
-    /**
-     * Get the current time.
-     * @return the current time as a formatted string.
-     */
-    protected String getTimestamp() {
-        Date date = new Date(System.currentTimeMillis());
-        DateFormat formatter = 
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
-        String finishTime = formatter.format(date);
-        return finishTime;
-    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to