package com.lassekoskela.maven.buildevents; import static ch.lambdaj.collection.LambdaCollections.with; import static java.lang.String.format; import static org.hamcrest.Matchers.allOf; import java.util.ArrayList; import java.util.List; import org.hamcrest.Matcher; import com.lassekoskela.maven.logging.Log; import com.lassekoskela.time.Duration; class BuildEventLogReport { private final Log log; private final List<BuildStep> steps; public BuildEventLogReport(Log log) { this(log, new ArrayList<BuildStep>()); } public BuildEventLogReport(Log log, List<BuildStep> steps) { this.log = log; this.steps = steps; } public void report() { printHeader(); reportBuildSteps(steps); printFooter(); } private void reportBuildSteps(List<BuildStep> steps) { String currentProject = ""; String currentPhase = ""; long totalDuration = totalDuration(); for (BuildStep buildStep : steps) { reportBuildStep(currentProject, currentPhase, buildStep, totalDuration); currentPhase = buildStep.phase; currentProject = buildStep.project; } } private void reportBuildStep(String currentProject, String currentPhase, BuildStep buildStep, long totalDuration) { String project = buildStep.project; String phase = buildStep.phase; long phaseDuration = totalDurationOfPhase(project, phase); long projectDuration = totalDurationOfProject(project); long percentageOfPhase = (long) buildStep.duration().percentageOf( phaseDuration); if (project != null && !project.equals(currentProject)) { log.info(""); reportProjectStatistics(project, totalDuration, projectDuration); } if (phase != null && !phase.equals(currentPhase)) { reportPhaseStatistics(phase, projectDuration, phaseDuration); } reportGoalStatistics(buildStep, percentageOfPhase); } private void reportGoalStatistics(BuildStep buildStep, long percentage) { String goal = buildStep.artifactId + ":" + buildStep.goal; double seconds = buildStep.duration().inSeconds(); log.info(format(" %-54s %7.1fs %3s%%", goal, seconds, percentage)); } private void reportPhaseStatistics(String phase, long totalDuration, long totalDurationOfPhase) { Duration phaseDuration = new Duration(totalDurationOfPhase); long percentage = (long) phaseDuration.percentageOf(totalDuration); double seconds = phaseDuration.inSeconds(); log.info(format("%-58s %7.1fs %3s%%", " " + phase, seconds, percentage)); } private void reportProjectStatistics(String project, long totalDuration, long totalDurationOfProject) { Duration projectDuration = new Duration(totalDurationOfProject); long percentage = (long) projectDuration.percentageOf(totalDuration); double seconds = projectDuration.inSeconds(); log.info(format("%-58s %7.1fs %3s%%", "*" + project, seconds, percentage)); } public long totalDurationOfPhase(String phase) { long total = 0; for (BuildStep e : filter(steps, phase(phase))) { total += e.duration().inMillis(); } return total; } public long totalDurationOfPhase(final String project, final String phase) { long total = 0; for (BuildStep e : filter(steps, project(project), phase(phase))) { total += e.duration().inMillis(); } return total; } private List<BuildStep> filter(List<BuildStep> steps, Matcher<BuildStep>... matchers) { return with(steps).clone().retain(allOf(matchers)); } private Matcher<BuildStep> project(final String project) { return new FieldMatcher<BuildStep>("project", project); } private Matcher<BuildStep> phase(final String phase) { return new FieldMatcher<BuildStep>("phase", phase); } public long totalDurationOfProject(String project) { long total = 0; for (BuildStep e : filter(steps, project(project))) { total += e.duration().inMillis(); } return total; } public long totalDuration() { long totalDuration = 0; for (BuildStep e : steps) { totalDuration += e.duration().inMillis(); } return totalDuration; } public void add(List<BuildStep> steps) { this.steps.addAll(steps); } private void printFooter() { log.info("------------------------------------------------------------------------"); } private void printHeader() { log.info("------------------------- BUILD STEP DURATIONS -------------------------"); log.info("PROJECT DURATION "); log.info("| PHASE PERCENTAGE"); log.info("| | GOAL | |"); log.info("| | | | |"); } }