package com.airhacks.wad.boundary; import com.airhacks.wad.control.Builder; import com.airhacks.wad.control.Copier; import com.airhacks.wad.control.FolderWatchService; import com.airhacks.wad.control.TerminalColors; import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import static java.time.temporal.ChronoField.HOUR_OF_DAY; import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; import java.util.ArrayList; import java.util.List; import java.util.LongSummaryStatistics; import java.util.concurrent.atomic.AtomicLong; import org.apache.maven.shared.invoker.InvocationResult; import org.apache.maven.shared.invoker.MavenInvocationException; /** * * @author airhacks.com */ public class WADFlow { private final List<Long> buildTimes; private final AtomicLong successCounter = new AtomicLong(); private final AtomicLong buildErrorCounter = new AtomicLong(); private final Copier copier; private final Builder builder; public WADFlow(Path dir, Path war, List<Path> deploymentTargets) throws IOException { this.builder = new Builder(); this.buildTimes = new ArrayList<>(); this.copier = new Copier(war, deploymentTargets); Runnable changeListener = this::buildAndDeploy; changeListener.run(); registerEnterListener(changeListener); FolderWatchService.listenForChanges(dir, changeListener); } void registerEnterListener(Runnable listener) { InputStream in = System.in; Runnable task = () -> { int c; try { while ((c = in.read()) != -1) { listener.run(); } } catch (IOException ex) { } }; new Thread(task).start(); } void buildAndDeploy() { this.build(); this.deploy(); } void build() { long start = System.currentTimeMillis(); try { System.out.printf("[%s%s%s]", TerminalColors.TIME.value(), currentFormattedTime(), TerminalColors.RESET.value()); InvocationResult result = this.builder.build(); if (result.getExitCode() == 0) { System.out.printf("[%d]", successCounter.incrementAndGet()); System.out.print("\uD83D\uDC4D"); long buildTime = (System.currentTimeMillis() - start); buildTimes.add(buildTime); System.out.println(" built in " + buildTime + " ms"); if (buildTimes.size() % 10 == 0) { this.printStatistics(); } } else { System.out.printf("[%d] ", buildErrorCounter.incrementAndGet()); System.out.println("\uD83D\uDC4E "); } } catch (MavenInvocationException ex) { System.err.println(ex.getClass().getName() + " " + ex.getMessage()); } } void deploy() { long start = System.currentTimeMillis(); this.copier.copy(); System.out.print("\uD83D\uDE80 "); System.out.println(" copied in " + (System.currentTimeMillis() - start) + " ms"); } static String currentFormattedTime() { DateTimeFormatter timeFormatter = new DateTimeFormatterBuilder() .appendValue(HOUR_OF_DAY, 2) .appendLiteral(':') .appendValue(MINUTE_OF_HOUR, 2) .optionalStart() .appendLiteral(':') .appendValue(SECOND_OF_MINUTE, 2) .toFormatter(); return LocalTime.now().format(timeFormatter); } public LongSummaryStatistics buildTimeStatistics() { return this.buildTimes. stream(). mapToLong(t -> t). summaryStatistics(); } String statisticsSummary() { LongSummaryStatistics warSizeStatistics = this.copier.warSizeStatistics(); long maxKb = warSizeStatistics.getMax(); long minKb = warSizeStatistics.getMin(); long totalKb = warSizeStatistics.getSum(); String warStats = String.format("WAR sizes: min %d kB, max %d kB, total %d kB\n", minKb, maxKb, totalKb); LongSummaryStatistics buildTimeStatistics = this.buildTimeStatistics(); long maxTime = buildTimeStatistics.getMax(); long minTime = buildTimeStatistics.getMin(); long totalTime = buildTimeStatistics.getSum(); String buildTimeStats = String.format("Build times: min %d ms, max %d ms, total %d ms\n", minTime, maxTime, totalTime); String failureStats; long failedBuilds = buildErrorCounter.get(); if (failedBuilds == 0) { failureStats = "Great! Every build was a success!"; } else { failureStats = String.format("%d builds failed", buildErrorCounter.get()); } return warStats + buildTimeStats + failureStats; } void printStatistics() { System.out.println(statisticsSummary()); } }