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 <subant> 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]