ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Dominique Devienne" <ddevie...@gmail.com>
Subject Re: BigProjectLogger
Date Fri, 18 May 2007 13:48:07 GMT
On 5/18/07, Steve Loughran <stevel@apache.org> 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 &lt;ant&gt; and &lt;subant&gt; 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 &lt;ant&gt; and &lt;subant&gt;. 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: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Mime
View raw message