merge BuildExecutionTimer and MultiModuleLogger
diff --git a/src/main/java/org/apache/easyant/core/ant/listerners/BuildExecutionTimer.java b/src/main/java/org/apache/easyant/core/ant/listerners/BuildExecutionTimer.java
deleted file mode 100644
index fe328ec..0000000
--- a/src/main/java/org/apache/easyant/core/ant/listerners/BuildExecutionTimer.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.apache.easyant.core.ant.listerners;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.easyant.core.EasyAntMagicNames;
-import org.apache.easyant.core.ant.ExecutionStatus;
-import org.apache.ivy.util.StringUtils;
-import org.apache.tools.ant.BuildEvent;
-import org.apache.tools.ant.BuildListener;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.SubBuildListener;
-
-/*
- * This listener is created so that it may be used to provide all statistic
- * collection for easyant builds.
- */
-
-/**
- * Build listener to time execution of builds.
- */
-public class BuildExecutionTimer implements BuildListener, SubBuildListener {
-
- /**
- * Reference key against which build execution results will be stored
- */
- public static final String EXECUTION_TIMER_BUILD_RESULTS = "execution.timer.build.results";
-
- /**
- * Reference key against which sub-build execution times will be stored
- */
- public static final String EXECUTION_TIMER_SUBBUILD_RESULTS = "execution.timer.subbuild.results";
-
- private static final String DEMARKER = "======================================================================";
-
- // build start time
- // to be initialized in buildStarted method
- private long buildStartTime;
-
- /**
- * stops the timer and stores the result as a project reference by the key 'referenceName'
- */
- protected void stopTimer(BuildEvent event, String referenceName, long startTime) {
- List<ExecutionResult> results = event.getProject().getReference(referenceName);
- if (results == null) {
- results = new ArrayList<ExecutionResult>();
- event.getProject().addReference(referenceName, results);
- }
- ExecutionStatus status = ExecutionStatus.SUCCESS;
- if (event.getException() != null) {
- status = ExecutionStatus.FAILED;
- } else if (event.getProject().getProperty(EasyAntMagicNames.PROJECT_EXECUTED_TARGETS) == null) {
- status = ExecutionStatus.SKIPPED;
- }
-
- ExecutionResult execResult = new ExecutionResult(event.getProject().getName(), System.currentTimeMillis()
- - startTime, status);
-
- results.add(execResult);
-
- }
-
- public void buildFinished(BuildEvent event) {
- stopTimer(event, EXECUTION_TIMER_BUILD_RESULTS, buildStartTime);
- printExecutionSubBuildsExecutionTimes(event.getProject());
- }
-
- private void printExecutionSubBuildsExecutionTimes(Project project) {
- String lineSep = org.apache.tools.ant.util.StringUtils.LINE_SEP;
- List<ExecutionResult> allSubBuildResults = project.getReference(EXECUTION_TIMER_SUBBUILD_RESULTS);
- if (allSubBuildResults != null && allSubBuildResults.size() > 0) {
- StringBuilder sb = new StringBuilder();
- sb.append(lineSep).append(DEMARKER).append(lineSep);
- sb.append("Project Sub-modules Summary: ").append(lineSep).append(DEMARKER);
- sb.append(lineSep).append(formatExecutionResults(allSubBuildResults));
- sb.append(lineSep).append(DEMARKER);
- project.log(sb.toString());
- }
- }
-
- public void buildStarted(BuildEvent arg0) {
- buildStartTime = System.currentTimeMillis();
- }
-
- public void messageLogged(BuildEvent arg0) {
- // leaving empty till better use is found
- }
-
- public void targetFinished(BuildEvent arg0) {
- // leaving empty till better use is found
- }
-
- /* following methods may be implemented for more comprehensive stats */
- public void targetStarted(BuildEvent arg0) {
- // leaving empty till better use is found
- }
-
- public void taskFinished(BuildEvent arg0) {
- // leaving empty till better use is found
- }
-
- public void taskStarted(BuildEvent arg0) {
- // leaving empty till better use is found
- }
-
- /**
- * Returns a string containing results of execution timing for display on console in a tabular fashion
- *
- * @param results
- * @return
- */
- public String formatExecutionResults(List<ExecutionResult> results) {
- String formattedResults;
- int constantSpaces = 10;
- int maxUnitNameLength = 0;
- int maxExecTimeLength = 0;
- for (ExecutionResult result : results) {
- maxUnitNameLength = result.getUnitName().length() > maxUnitNameLength ? result.getUnitName().length()
- : maxUnitNameLength;
- maxExecTimeLength = result.getFormattedElapsedTime().length() > maxExecTimeLength ? result
- .getFormattedElapsedTime().length() : maxExecTimeLength;
- }
- StringBuilder sb = new StringBuilder(org.apache.tools.ant.util.StringUtils.LINE_SEP);
- for (ExecutionResult result : results) {
- String moduleName = result.getUnitName();
- int variableSpaces = maxUnitNameLength - moduleName.length() + constantSpaces;
- sb.append(" * ").append(result.getUnitName()).append(StringUtils.repeat(" ", variableSpaces));
- // keeping both success and failed strings of equal length
- String execResult = result.getStatus().toString();
- if (execResult.length() < 7) {
- execResult += StringUtils.repeat(" ", 7 - execResult.length());
- }
- sb.append(execResult).append(" [took ").append(result.getFormattedElapsedTime()).append("]")
- .append(org.apache.tools.ant.util.StringUtils.LINE_SEP);
- }
-
- formattedResults = sb.toString();
- return formattedResults;
- }
-
- public void subBuildFinished(BuildEvent arg0) {
- stopTimer(arg0, EXECUTION_TIMER_SUBBUILD_RESULTS, buildStartTime);
- }
-
- public void subBuildStarted(BuildEvent arg0) {
- buildStartTime = System.currentTimeMillis();
- }
-
-}
diff --git a/src/main/java/org/apache/easyant/core/ant/listerners/MultiModuleLogger.java b/src/main/java/org/apache/easyant/core/ant/listerners/MultiModuleLogger.java
index 2a262f4..a6b9125 100644
--- a/src/main/java/org/apache/easyant/core/ant/listerners/MultiModuleLogger.java
+++ b/src/main/java/org/apache/easyant/core/ant/listerners/MultiModuleLogger.java
@@ -17,31 +17,35 @@
*/
package org.apache.easyant.core.ant.listerners;
-import java.io.File;
-
+import org.apache.easyant.core.EasyAntMagicNames;
+import org.apache.easyant.core.ant.ExecutionStatus;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.Project;
+import org.apache.tools.ant.SubBuildListener;
import org.apache.tools.ant.listener.TimestampedLogger;
import org.apache.tools.ant.util.StringUtils;
-public class MultiModuleLogger extends DefaultEasyAntLogger {
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+public class MultiModuleLogger extends DefaultEasyAntLogger implements SubBuildListener {
+
+
+ /**
+ * Reference key against which build execution results will be stored
+ */
+ public static final String EXECUTION_TIMER_BUILD_RESULTS = "execution.timer.build.results";
+
+ private static final String DEMARKER = "======================================================================";
private volatile boolean subBuildStartedRaised = false;
private final Object subBuildLock = new Object();
-
- /**
- * Header string for the log. * {@value}
- */
- public static final String HEADER = "======================================================================";
- /**
- * Footer string for the log. * {@value}
- */
- public static final String FOOTER = HEADER;
+ private long buildStartTime;
/**
* This is an override point: the message that indicates whether a build failed. Subclasses can change/enhance the
* message.
- *
+ *
* @return The classic "BUILD FAILED" plus a timestamp
*/
protected String getBuildFailedMessage() {
@@ -51,75 +55,58 @@
/**
* This is an override point: the message that indicates that a build succeeded. Subclasses can change/enhance the
* message.
- *
+ *
* @return The classic "BUILD SUCCESSFUL" plus a timestamp
*/
protected String getBuildSuccessfulMessage() {
return super.getBuildSuccessfulMessage() + TimestampedLogger.SPACER + getTimestamp();
}
- /**
- * {@inheritDoc}
- *
- * @param event
- */
public void targetStarted(BuildEvent event) {
maybeRaiseSubBuildStarted(event);
targetName = extractTargetName(event);
}
- /**
- * {@inheritDoc}
- *
- * @param event
- */
public void taskStarted(BuildEvent event) {
maybeRaiseSubBuildStarted(event);
super.taskStarted(event);
}
- /**
- * {@inheritDoc}
- *
- * @param event
- */
public void buildFinished(BuildEvent event) {
+ stopTimer(event);
+ printExecutionSubBuildsExecutionTimes(event.getProject());
maybeRaiseSubBuildStarted(event);
subBuildFinished(event);
super.buildFinished(event);
}
- /**
- * {@inheritDoc}
- *
- * @param event
- */
public void messageLogged(BuildEvent event) {
maybeRaiseSubBuildStarted(event);
super.messageLogged(event);
}
- /**
- * {@inheritDoc}
- *
- * @param event
- * An event with any relevant extra information. Must not be <code>null</code>.
- */
public void subBuildStarted(BuildEvent event) {
+ initTimer(event.getProject());
String name = extractNameOrDefault(event);
Project project = event.getProject();
File base = project == null ? null : project.getBaseDir();
String path = (base == null) ? "With no base directory" : "In " + base.getAbsolutePath();
- printMessage(StringUtils.LINE_SEP + getHeader() + StringUtils.LINE_SEP + "Entering project " + name
- + StringUtils.LINE_SEP + path + StringUtils.LINE_SEP + getFooter(), out, event.getPriority());
+ printMessage(StringUtils.LINE_SEP + DEMARKER + StringUtils.LINE_SEP + "Entering project " + name
+ + StringUtils.LINE_SEP + path + StringUtils.LINE_SEP + DEMARKER, out, event.getPriority());
+ }
+
+
+ @Override
+ public void buildStarted(BuildEvent event) {
+ initTimer(event.getProject());
+ super.buildStarted(event);
}
/**
* Get the name of an event
- *
- * @param event
- * the event name
+ *
+ * @param event the event name
* @return the name or a default string
*/
protected String extractNameOrDefault(BuildEvent event) {
@@ -132,31 +119,14 @@
return name;
}
- /** {@inheritDoc} */
public void subBuildFinished(BuildEvent event) {
+ stopTimer(event);
String name = extractNameOrDefault(event);
String failed = event.getException() != null ? "failing " : "";
- printMessage(StringUtils.LINE_SEP + getHeader() + StringUtils.LINE_SEP + "Exiting " + failed + "project "
- + name + StringUtils.LINE_SEP + getFooter(), out, event.getPriority());
+ printMessage(StringUtils.LINE_SEP + DEMARKER + StringUtils.LINE_SEP + "Exiting " + failed + "project "
+ + name + StringUtils.LINE_SEP + DEMARKER, out, event.getPriority());
}
- /**
- * Override point: return the header string for the entry/exit message
- *
- * @return the header string
- */
- protected String getHeader() {
- return HEADER;
- }
-
- /**
- * Override point: return the footer string for the entry/exit message
- *
- * @return the footer string
- */
- protected String getFooter() {
- return FOOTER;
- }
private void maybeRaiseSubBuildStarted(BuildEvent event) {
// double checked locking should be OK since the flag is write-once
@@ -172,9 +142,8 @@
/**
* Override point, extract the target name
- *
- * @param event
- * the event to work on
+ *
+ * @param event the event to work on
* @return the target name -including the owning project name (if non-null)
*/
protected String extractTargetName(BuildEvent event) {
@@ -187,4 +156,72 @@
}
}
+ private void initTimer(Project project) {
+ buildStartTime = System.currentTimeMillis();
+ project.addReference(EXECUTION_TIMER_BUILD_RESULTS, new ArrayList<ExecutionResult>());
+ }
+
+ /**
+ * stops the timer and stores the result as a project reference by the key 'referenceName'
+ */
+ private void stopTimer(BuildEvent event) {
+ List<ExecutionResult> results = event.getProject().getReference(EXECUTION_TIMER_BUILD_RESULTS);
+ ExecutionStatus status = ExecutionStatus.SUCCESS;
+ if (event.getException() != null) {
+ status = ExecutionStatus.FAILED;
+ } else if (event.getProject().getProperty(EasyAntMagicNames.PROJECT_EXECUTED_TARGETS) == null) {
+ status = ExecutionStatus.SKIPPED;
+ }
+
+ ExecutionResult execResult = new ExecutionResult(event.getProject().getName(), System.currentTimeMillis()
+ - buildStartTime, status);
+
+ results.add(execResult);
+
+ }
+
+ private void printExecutionSubBuildsExecutionTimes(Project project) {
+ String lineSep = org.apache.tools.ant.util.StringUtils.LINE_SEP;
+ List<ExecutionResult> allSubBuildResults = project.getReference(EXECUTION_TIMER_BUILD_RESULTS);
+ if (allSubBuildResults != null && !allSubBuildResults.isEmpty()) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(lineSep).append(DEMARKER).append(lineSep);
+ sb.append("Project Sub-modules Summary: ").append(lineSep).append(DEMARKER);
+ sb.append(lineSep).append(formatExecutionResults(allSubBuildResults));
+ project.log(sb.toString());
+ }
+ }
+
+ private String formatExecutionResults(List<ExecutionResult> results) {
+ String formattedResults;
+ int maxUnitNameLength = 0;
+ int maxExecTimeLength = 0;
+ for (ExecutionResult result : results) {
+ maxUnitNameLength = result.getUnitName().length() > maxUnitNameLength ? result.getUnitName().length()
+ : maxUnitNameLength;
+ maxExecTimeLength = result.getFormattedElapsedTime().length() > maxExecTimeLength ? result
+ .getFormattedElapsedTime().length() : maxExecTimeLength;
+ }
+ StringBuilder sb = new StringBuilder(org.apache.tools.ant.util.StringUtils.LINE_SEP);
+ for (ExecutionResult result : results) {
+ String moduleName = padRight(result.getUnitName(), maxUnitNameLength + 10);
+ sb.append(" * ").append(moduleName);
+ // keeping both success and failed strings of equal length
+ String execResult = padRight(result.getStatus().toString(), 7);
+ sb.append(execResult)//
+ .append(" [ took ")//
+ .append(padRight(result.getFormattedElapsedTime(), maxExecTimeLength + 1))//
+ .append("]")
+ .append(org.apache.tools.ant.util.StringUtils.LINE_SEP);
+ }
+
+ formattedResults = sb.toString();
+ return formattedResults;
+ }
+
+ private String padRight(String string, int nbSpace) {
+ return String.format("%1$-" + nbSpace + "s", string);
+ }
+
+
}
diff --git a/src/main/java/org/apache/easyant/tasks/SubModule.java b/src/main/java/org/apache/easyant/tasks/SubModule.java
index 877f4ba..3144ef6 100644
--- a/src/main/java/org/apache/easyant/tasks/SubModule.java
+++ b/src/main/java/org/apache/easyant/tasks/SubModule.java
@@ -20,8 +20,8 @@
import org.apache.easyant.core.EasyAntConstants;
import org.apache.easyant.core.EasyAntMagicNames;
import org.apache.easyant.core.ant.ProjectUtils;
-import org.apache.easyant.core.ant.listerners.BuildExecutionTimer;
import org.apache.easyant.core.ant.listerners.ExecutionResult;
+import org.apache.easyant.core.ant.listerners.MultiModuleLogger;
import org.apache.easyant.core.ivy.IvyInstanceHelper;
import org.apache.ivy.ant.IvyPublish;
import org.apache.ivy.ant.IvyResolve;
@@ -241,7 +241,7 @@
} finally {
// add execution times for the current submodule to parent
// project references for access from MetaBuildExecutor
- // storeExecutionTimes(getProject(), subModule);
+ storeExecutionTimes(getProject(), subModule);
}
}
@@ -256,10 +256,6 @@
BuildListener buildListener = getProject().getBuildListeners().elementAt(i);
subModule.addBuildListener(buildListener);
}
- // explicitly add the execution timer to time
- // sub builds
- subModule.addBuildListener(new BuildExecutionTimer());
-
// copy all User properties
addAlmostAll(getProject().getUserProperties(), subModule, PropertyType.USER);
// inherit meta.target directory, for shared build repository.
@@ -296,13 +292,13 @@
@SuppressWarnings("unchecked")
private void storeExecutionTimes(Project parent, Project child) {
List<ExecutionResult> allresults = parent
- .getReference(BuildExecutionTimer.EXECUTION_TIMER_SUBBUILD_RESULTS);
+ .getReference(MultiModuleLogger.EXECUTION_TIMER_BUILD_RESULTS);
if (allresults == null) {
allresults = new ArrayList<ExecutionResult>();
- parent.addReference(BuildExecutionTimer.EXECUTION_TIMER_SUBBUILD_RESULTS, allresults);
+ parent.addReference(MultiModuleLogger.EXECUTION_TIMER_BUILD_RESULTS, allresults);
}
List<ExecutionResult> childResults = child
- .getReference(BuildExecutionTimer.EXECUTION_TIMER_SUBBUILD_RESULTS);
+ .getReference(MultiModuleLogger.EXECUTION_TIMER_BUILD_RESULTS);
if (childResults != null) {
allresults.addAll(childResults);
}
diff --git a/src/test/java/org/apache/easyant/tasks/SubModuleTest.java b/src/test/java/org/apache/easyant/tasks/SubModuleTest.java
index a67c083..a0f3c4d 100644
--- a/src/test/java/org/apache/easyant/tasks/SubModuleTest.java
+++ b/src/test/java/org/apache/easyant/tasks/SubModuleTest.java
@@ -18,15 +18,8 @@
package org.apache.easyant.tasks;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertThat;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-
import org.apache.easyant.core.EasyAntMagicNames;
-import org.apache.easyant.core.ant.listerners.BuildExecutionTimer;
+import org.apache.easyant.core.ant.listerners.MultiModuleLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
@@ -36,6 +29,13 @@
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
public class SubModuleTest extends AntTaskBaseTest {
private SubModule submodule;
@@ -156,7 +156,7 @@
assertLogContaining("Executing [modulewithtarget:mytarget] on module1");
assertLogContaining("Executing [modulewithtarget:mytarget] on module2");
- assertThat(submodule.getProject().getReference(BuildExecutionTimer.EXECUTION_TIMER_SUBBUILD_RESULTS),
+ assertThat(submodule.getProject().getReference(MultiModuleLogger.EXECUTION_TIMER_BUILD_RESULTS),
notNullValue());
}
}