- 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 | * only writes which targets are being executed, and | ||||
* any messages that get logged. | * any messages that get logged. | ||||
*/ | */ | ||||
public class DefaultLogger implements BuildListener { | |||||
public class DefaultLogger implements BuildLogger { | |||||
private static int LEFT_COLUMN_SIZE = 12; | private static int LEFT_COLUMN_SIZE = 12; | ||||
private PrintStream out; | private PrintStream out; | ||||
private int msgOutputLevel; | private int msgOutputLevel; | ||||
private long startTime = System.currentTimeMillis(); | 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) { | public void buildStarted(BuildEvent event) { | ||||
startTime = System.currentTimeMillis(); | startTime = System.currentTimeMillis(); | ||||
} | } | ||||
@@ -133,11 +157,13 @@ public class DefaultLogger implements BuildListener { | |||||
if (event.getTask() != null) { | if (event.getTask() != null) { | ||||
String name = event.getTask().getTaskName(); | 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 | // Print the message | ||||
@@ -90,6 +90,18 @@ public class Main { | |||||
/** Names of classes to add as listeners to project */ | /** Names of classes to add as listeners to project */ | ||||
private Vector listeners = new Vector(5); | 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. | * Indicates if this ant should be run. | ||||
*/ | */ | ||||
@@ -190,6 +202,14 @@ public class Main { | |||||
value = args[++i]; | value = args[++i]; | ||||
definedProps.put(name, value); | 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("-")) { | } else if (arg.startsWith("-")) { | ||||
// we don't have any more args to recognize! | // we don't have any more args to recognize! | ||||
String msg = "Unknown arg: " + arg; | String msg = "Unknown arg: " + arg; | ||||
@@ -224,7 +244,6 @@ public class Main { | |||||
/** | /** | ||||
* Executes the build. | * Executes the build. | ||||
*/ | */ | ||||
private void runBuild() throws BuildException { | private void runBuild() throws BuildException { | ||||
if (!readyToRun) { | if (!readyToRun) { | ||||
@@ -294,7 +313,7 @@ public class Main { | |||||
protected void addBuildListeners(Project project) { | protected void addBuildListeners(Project project) { | ||||
// Add the default listener | // Add the default listener | ||||
project.addBuildListener(createDefaultBuildListener()); | |||||
project.addBuildListener(createLogger()); | |||||
for (int i = 0; i < listeners.size(); i++) { | for (int i = 0; i < listeners.size(); i++) { | ||||
String className = (String) listeners.elementAt(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(" -version print the version information and exit" + lSep); | ||||
msg.append(" -quiet be extra quiet" + lSep); | msg.append(" -quiet be extra quiet" + lSep); | ||||
msg.append(" -verbose be extra verbose" + 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(" -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(" -listener <classname> add an instance of class as a project listener" + lSep); | ||||
msg.append(" -buildfile <file> use given buildfile" + lSep); | msg.append(" -buildfile <file> use given buildfile" + lSep); | ||||
msg.append(" -D<property>=<value> use value for given property" + lSep); | msg.append(" -D<property>=<value> use value for given property" + lSep); | ||||
@@ -120,7 +120,10 @@ public class Ant extends Task { | |||||
if (output != null) { | if (output != null) { | ||||
try { | try { | ||||
PrintStream out = new PrintStream(new FileOutputStream(output)); | 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 ) { | catch( IOException ex ) { | ||||
log( "Ant: Can't set output to " + output ); | log( "Ant: Can't set output to " + output ); | ||||