ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Steve Loughran <ste...@apache.org>
Subject Re: BigProjectLogger
Date Fri, 18 May 2007 15:27:36 GMT
Dominique Devienne wrote:
> 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.


OK. You've done what I've done, except with some stacking. Now, if 
projects had an optional parent project, we could work it out dynamically.

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


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Mime
View raw message