On 5/18/07, Steve Loughran <[EMAIL PROTECTED]> wrote:
One question I have here, is : how should I present teh project name.
(a) with a . for example: kernel.init and kernel.common.init
-good for simple things, but imports can confuse it
(b) a / for example: kernel/init and kernel/common.init
-may cause confusion as project names != dir names
(c) colon for example: kernel:init and kernel:common.init
(d) brackets [kernel]:init and [kernel]:common.init
-makes targets look like task output
(e) XML Qualified names :) {kernel}#init and {somewith with
spaces}#common.init
-awful
For NoBannerSubBuildLogger, for reference, I used
target-name: [main-project-name/level1-subbuild/level2-subsubbuild]
at a fixed offset unless the target name was too long.
import java.util.Stack;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.util.StringUtils;
/**
* Build logger that allows to make sense of the nesting structure
* generated by the use of <ant> and <subant> in Ant build files.
* <p>
* The target banner (the target name followed by a colon, all in its own line)
* will not be printed until that target's tasks output any kind of message.
* This greatly simplifies the build output for all those targets that do not
* execute, either because they are prevented to from their 'if' or 'unless'
* attributes, or because all their input files are up-to-date versus their
* output files.
* <p>
* In addition, the target banner (when output) will be postfixed with the
* project path that lead to its execution, i.e. the list of project names
* that were started using either <ant> and <subant>. Assuming
* one calls the build target of 3 different sub-builds called A, B, and C
* all called from a master build, one could get an output as follows:
* <pre>
* Buildfile: master.xml
*
* build: [master/A]
* Compiling 19 source file to /acme/A/classes
*
* build: [master/B]
* Compiling 15 source file to /acme/B/classes
*
* build: [master/C]
* Compiling 12 source file to /acme/C/classes
*
* BUILD SUCCESSFUL
* Total time: 8 seconds
* </pre>
* <p>
* Inspired from NoBannerLogger by Peter Donald.
*/
public class NoBannerSubBuildLogger
extends DefaultLogger {
/** The cached current target name, awaiting to be possibly printed. */
private String _targetName;
/** The stack of nesting Ant projects. */
private Stack _projects = new Stack();
/** The private buffer of this logger. */
protected StringBuffer _buffer = new StringBuffer(128);
/**
* Gets the target banner for a given target name.
*
* @param targetName the target name to get the banner for.
* @return the full target banner name.
*/
protected String getTargetBanner(String targetName) {
_buffer.setLength(0);
// Target banner as usual
_buffer.append(StringUtils.LINE_SEP);
_buffer.append(targetName);
_buffer.append(':');
// Postfix the project path
fillToIndex(_buffer, 16, ' ', 1);
_buffer.append('[');
appendProjectPath(_buffer, '/');
_buffer.append(']');
// Return the full target banner (toString() in bugged in JDK 1.4.1)
return _buffer.substring(0);
}
/**
* Appends the current project path to a given buffer.
*
* @param buffer the string buffer to append to.
* @param separator the project path separator to use.
*/
protected void appendProjectPath(StringBuffer buffer, char separator) {
final int count = _projects.size();
for (int i = 0; i < count; ++i) {
Project project = (Project)_projects.get(i);
buffer.append(project.getName());
buffer.append(separator);
}
if (count > 0) {
buffer.setLength(_buffer.length()-1);
}
}
/**
* Fills a string buffer with a given character to reach a known length.
*
* @param buffer the string buffer to fill (Cannot be <code>null</code>).
* @param column the column index to fill up to.
* @param c the char to fill up with.
* @param minLength the mininum number of character to add in case the
* string buffer is already longer than <code>column</code>
* @return the number of characters actually added.
*/
protected static int fillToIndex(StringBuffer buffer, int column,
char c, int minLength) {
final int fillCount = Math.max(column - buffer.length(), minLength);
for (int i = 0; i < fillCount; ++i) {
buffer.append(c);
}
return fillCount;
}
/**
* Records/caches the target name and its project just started.
*
* @param event the build event to extract the target from.
*/
public void targetStarted(BuildEvent event) {
Target target = event.getTarget();
_targetName = target.getName();
_projects.push(target.getProject());
}
/**
* Cleans up the record/cache of the target name and its project.
*
* @param event the (ignored here) build event.
*/
public void targetFinished(BuildEvent event) {
_targetName = null;
_projects.pop();
}
/**
* Logs a task message, possibly displaying the target and project path
* that led to its execution, if they were not displayed earlier.
*
* @param event the build event containing message information.
* Must not be <code>null</code>.
*/
public void messageLogged(BuildEvent event) {
if (event.getPriority() > msgOutputLevel
|| null == event.getMessage()
|| (_targetName != null && "".equals(event.getMessage().trim()))) {
return;
}
if (_targetName != null) {
out.println(getTargetBanner(_targetName));
_targetName = null;
}
super.messageLogged(event);
}
} // END class NoBannerSubBuildLogger
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]