- An output level used to filter build events - Access to the ant output print stream - An emacs mode. Update DefaultLogger to the new interface. In its emacs mode, output is unadorned by the [taskname] tags Add -logger option to allow the logger class to be changed Add -emacs option to control the logger's emacsMode setting git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@267836 13f79535-47bb-0310-9956-ffa450edef68master
@@ -0,0 +1,92 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 1999 The Apache Software Foundation. All rights | |||
* reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or without | |||
* modification, are permitted provided that the following conditions | |||
* are met: | |||
* | |||
* 1. Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* 2. Redistributions in binary form must reproduce the above copyright | |||
* notice, this list of conditions and the following disclaimer in | |||
* the documentation and/or other materials provided with the | |||
* distribution. | |||
* | |||
* 3. The end-user documentation included with the redistribution, if | |||
* any, must include the following acknowlegement: | |||
* "This product includes software developed by the | |||
* Apache Software Foundation (http://www.apache.org/)." | |||
* Alternately, this acknowlegement may appear in the software itself, | |||
* if and wherever such third-party acknowlegements normally appear. | |||
* | |||
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software | |||
* Foundation" must not be used to endorse or promote products derived | |||
* from this software without prior written permission. For written | |||
* permission, please contact apache@apache.org. | |||
* | |||
* 5. Products derived from this software may not be called "Apache" | |||
* nor may "Apache" appear in their names without prior written | |||
* permission of the Apache Group. | |||
* | |||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
* SUCH DAMAGE. | |||
* ==================================================================== | |||
* | |||
* This software consists of voluntary contributions made by many | |||
* individuals on behalf of the Apache Software Foundation. For more | |||
* information on the Apache Software Foundation, please see | |||
* <http://www.apache.org/>. | |||
*/ | |||
package org.apache.tools.ant; | |||
import java.io.*; | |||
/** | |||
* Interface used by Ant to log the build output. | |||
* | |||
* A build logger is a build listener which has the 'right' to send output to the | |||
* ant log, which is usually System.out unles redirected by the -logfile option. | |||
* | |||
* @author Conor MacNeill | |||
*/ | |||
public interface BuildLogger extends BuildListener { | |||
/** | |||
* Set the msgOutputLevel this logger is to respond to. | |||
* | |||
* Only messages with a message level lower than or equal to the given level are | |||
* output to the log. | |||
* | |||
* @param level the logging level for the logger. | |||
*/ | |||
public void setMessageOutputLevel(int level); | |||
/** | |||
* Set the output stream to which this logger is to send its output. | |||
* | |||
* @param output the output stream for the logger. | |||
*/ | |||
public void setOutputPrintStream(PrintStream output); | |||
/** | |||
* Set this logger to produce emacs (and other editor) friendly output. | |||
* | |||
* @param emacsMode true if output is to be unadorned so that emacs and other | |||
* editors can parse files names, etc. | |||
*/ | |||
public void setEmacsMode(boolean emacsMode); | |||
} |
@@ -61,24 +61,48 @@ import java.io.*; | |||
* only writes which targets are being executed, and | |||
* any messages that get logged. | |||
*/ | |||
public class DefaultLogger implements BuildListener { | |||
public class DefaultLogger implements BuildLogger { | |||
private static int LEFT_COLUMN_SIZE = 12; | |||
private PrintStream out; | |||
private int msgOutputLevel; | |||
private long startTime = System.currentTimeMillis(); | |||
private boolean emacsMode = false; | |||
/** | |||
* Constructs a new logger which will write to the specified | |||
* PrintStream. Messages with a priority lower (higher?) than | |||
* msgOutputLevel will be ignored. | |||
* Set the msgOutputLevel this logger is to respond to. | |||
* | |||
* Only messages with a message level lower than or equal to the given level are | |||
* output to the log. | |||
* | |||
* @param level the logging level for the logger. | |||
*/ | |||
public DefaultLogger(PrintStream out, int msgOutputLevel) { | |||
this.out = out; | |||
this.msgOutputLevel = msgOutputLevel; | |||
public void setMessageOutputLevel(int level) { | |||
this.msgOutputLevel = level; | |||
} | |||
/** | |||
* Set the output stream to which this logger is to send its output. | |||
* | |||
* @param output the output stream for the logger. | |||
*/ | |||
public void setOutputPrintStream(PrintStream output) { | |||
this.out = output; | |||
} | |||
/** | |||
* Set this logger to produce emacs (and other editor) friendly output. | |||
* | |||
* @param emacsMode true if output is to be unadorned so that emacs and other | |||
* editors can parse files names, etc. | |||
*/ | |||
public void setEmacsMode(boolean emacsMode) { | |||
this.emacsMode = emacsMode; | |||
} | |||
public void buildStarted(BuildEvent event) { | |||
startTime = System.currentTimeMillis(); | |||
} | |||
@@ -133,11 +157,13 @@ public class DefaultLogger implements BuildListener { | |||
if (event.getTask() != null) { | |||
String name = event.getTask().getTaskName(); | |||
String msg = "[" + name + "] "; | |||
for (int i = 0; i < (LEFT_COLUMN_SIZE - msg.length()); i++) { | |||
out.print(" "); | |||
if (!emacsMode) { | |||
String msg = "[" + name + "] "; | |||
for (int i = 0; i < (LEFT_COLUMN_SIZE - msg.length()); i++) { | |||
out.print(" "); | |||
} | |||
out.print(msg); | |||
} | |||
out.print(msg); | |||
} | |||
// Print the message | |||
@@ -90,6 +90,18 @@ public class Main { | |||
/** Names of classes to add as listeners to project */ | |||
private Vector listeners = new Vector(5); | |||
/** | |||
* The Ant logger class. There may be only one logger. It will have the | |||
* right to use the 'out' PrintStream. The class must implements the BuildLogger | |||
* interface | |||
*/ | |||
private String loggerClassname = null; | |||
/** | |||
* Indicates whether output to the log is to be unadorned. | |||
*/ | |||
private boolean emacsMode = false; | |||
/** | |||
* Indicates if this ant should be run. | |||
*/ | |||
@@ -190,6 +202,14 @@ public class Main { | |||
value = args[++i]; | |||
definedProps.put(name, value); | |||
} else if (arg.equals("-logger")) { | |||
if (loggerClassname != null) { | |||
System.out.println("Only one logger class may be specified."); | |||
return; | |||
} | |||
loggerClassname = args[++i]; | |||
} else if (arg.equals("-emacs")) { | |||
emacsMode = true; | |||
} else if (arg.startsWith("-")) { | |||
// we don't have any more args to recognize! | |||
String msg = "Unknown arg: " + arg; | |||
@@ -224,7 +244,6 @@ public class Main { | |||
/** | |||
* Executes the build. | |||
*/ | |||
private void runBuild() throws BuildException { | |||
if (!readyToRun) { | |||
@@ -294,7 +313,7 @@ public class Main { | |||
protected void addBuildListeners(Project project) { | |||
// Add the default listener | |||
project.addBuildListener(createDefaultBuildListener()); | |||
project.addBuildListener(createLogger()); | |||
for (int i = 0; i < listeners.size(); i++) { | |||
String className = (String) listeners.elementAt(i); | |||
@@ -310,10 +329,34 @@ public class Main { | |||
} | |||
/** | |||
* Creates the default build listener for displaying output to the screen. | |||
* Creates the default build logger for sending build events to the ant log. | |||
*/ | |||
private BuildListener createDefaultBuildListener() { | |||
return new DefaultLogger(out, msgOutputLevel); | |||
private BuildLogger createLogger() { | |||
BuildLogger logger = null; | |||
if (loggerClassname != null) { | |||
try { | |||
logger = (BuildLogger)(Class.forName(loggerClassname).newInstance()); | |||
} | |||
catch (ClassCastException e) { | |||
System.err.println("The specified logger class " + loggerClassname + | |||
" does not implement the BuildLogger interface"); | |||
throw new RuntimeException(); | |||
} | |||
catch (Exception e) { | |||
System.err.println("Unable to instantiate specified logger class " + | |||
loggerClassname + " : " + e.getClass().getName()); | |||
throw new RuntimeException(); | |||
} | |||
} | |||
else { | |||
logger = new DefaultLogger(); | |||
} | |||
logger.setMessageOutputLevel(msgOutputLevel); | |||
logger.setOutputPrintStream(out); | |||
logger.setEmacsMode(emacsMode); | |||
return logger; | |||
} | |||
/** | |||
@@ -328,7 +371,9 @@ public class Main { | |||
msg.append(" -version print the version information and exit" + lSep); | |||
msg.append(" -quiet be extra quiet" + lSep); | |||
msg.append(" -verbose be extra verbose" + lSep); | |||
msg.append(" -emacs produce logging information without adornments" + lSep); | |||
msg.append(" -logfile <file> use given file for log" + lSep); | |||
msg.append(" -logger <classname> the class which is to perform logging" + lSep); | |||
msg.append(" -listener <classname> add an instance of class as a project listener" + lSep); | |||
msg.append(" -buildfile <file> use given buildfile" + lSep); | |||
msg.append(" -D<property>=<value> use value for given property" + lSep); | |||
@@ -120,7 +120,10 @@ public class Ant extends Task { | |||
if (output != null) { | |||
try { | |||
PrintStream out = new PrintStream(new FileOutputStream(output)); | |||
p1.addBuildListener(new DefaultLogger(out, Project.MSG_INFO)); | |||
DefaultLogger logger = new DefaultLogger(); | |||
logger.setMessageOutputLevel(Project.MSG_INFO); | |||
logger.setOutputPrintStream(out); | |||
p1.addBuildListener(logger); | |||
} | |||
catch( IOException ex ) { | |||
log( "Ant: Can't set output to " + output ); | |||