diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/AntTaskLogger.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/AntTaskLogger.groovy index 9c6b92d333ba..6dcc0b1a3091 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/AntTaskLogger.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/AntTaskLogger.groovy @@ -30,6 +30,12 @@ class AntTaskLogger implements BuildListener { BuildMessages defaultHandler private final Map threadHandlers = [:] private final Map taskHandlers = [:] + private final Project antProject + private final ThreadLocal processMessages = ThreadLocal.withInitial { true } + + AntTaskLogger(Project antProject) { + this.antProject = antProject + } void registerThreadHandler(Thread thread, BuildMessages messages) { threadHandlers[thread] = messages @@ -41,7 +47,7 @@ class AntTaskLogger implements BuildListener { @Override void messageLogged(BuildEvent event) { - if (event.priority > Project.MSG_INFO) return + if (!processMessages.get() || event.priority > Project.MSG_INFO) return String message if (event.task != null) { @@ -66,6 +72,16 @@ class AntTaskLogger implements BuildListener { } } + void logMessageToOtherLoggers(String message, int level) { + try { + processMessages.set(false) + antProject.log(message, level) + } + finally { + processMessages.set(true) + } + } + @Override void buildStarted(BuildEvent event) { } diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildMessagesImpl.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildMessagesImpl.groovy index 726b8506e0ab..7b7449b36b50 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildMessagesImpl.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildMessagesImpl.groovy @@ -28,15 +28,14 @@ import org.jetbrains.jps.gant.DefaultBuildInfoPrinter import org.jetbrains.jps.gant.JpsGantProjectBuilder import org.jetbrains.jps.gant.TeamCityBuildInfoPrinter -import java.util.function.Function - +import java.util.function.BiFunction /** * @author nik */ @CompileStatic class BuildMessagesImpl implements BuildMessages { private final BuildMessageLogger logger - private final Function loggerFactory + private final BiFunction loggerFactory private final AntTaskLogger antTaskLogger private final BuildMessagesImpl parentInstance private final List forkedInstances = [] @@ -52,9 +51,9 @@ class BuildMessagesImpl implements BuildMessages { BuildInfoPrinter buildInfoPrinter = underTeamCity ? new TeamCityBuildInfoPrinter() : new DefaultBuildInfoPrinter() builder.buildInfoPrinter = buildInfoPrinter disableAntLogging(antProject) - Function loggerFactory = underTeamCity ? TeamCityBuildMessageLogger.FACTORY : ConsoleBuildMessageLogger.FACTORY - def antTaskLogger = new AntTaskLogger() - def messages = new BuildMessagesImpl(loggerFactory.apply(null), loggerFactory, antTaskLogger, null) + BiFunction loggerFactory = underTeamCity ? TeamCityBuildMessageLogger.FACTORY : ConsoleBuildMessageLogger.FACTORY + def antTaskLogger = new AntTaskLogger(antProject) + def messages = new BuildMessagesImpl(loggerFactory.apply(null, antTaskLogger), loggerFactory, antTaskLogger, null) antTaskLogger.defaultHandler = messages antProject.addBuildListener(antTaskLogger) antProject.addReference(key, messages) @@ -72,7 +71,7 @@ class BuildMessagesImpl implements BuildMessages { } } - private BuildMessagesImpl(BuildMessageLogger logger, Function loggerFactory, AntTaskLogger antTaskLogger, + private BuildMessagesImpl(BuildMessageLogger logger, BiFunction loggerFactory, AntTaskLogger antTaskLogger, BuildMessagesImpl parentInstance) { this.logger = logger this.loggerFactory = loggerFactory @@ -141,7 +140,7 @@ class BuildMessagesImpl implements BuildMessages { @Override BuildMessages forkForParallelTask(String suggestedTaskName) { String taskName = taskNameGenerator.generateUniqueName(suggestedTaskName) - def forked = new BuildMessagesImpl(loggerFactory.apply(taskName), loggerFactory, antTaskLogger, this) + def forked = new BuildMessagesImpl(loggerFactory.apply(taskName, antTaskLogger), loggerFactory, antTaskLogger, this) forkedInstances << forked return forked } diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/ConsoleBuildMessageLogger.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/ConsoleBuildMessageLogger.groovy index bfcce1efa6ea..eb97b83d7917 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/ConsoleBuildMessageLogger.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/ConsoleBuildMessageLogger.groovy @@ -19,14 +19,15 @@ import groovy.transform.CompileStatic import org.jetbrains.intellij.build.BuildMessageLogger import org.jetbrains.intellij.build.LogMessage -import java.util.function.Function - +import java.util.function.BiFunction /** * @author nik */ @CompileStatic class ConsoleBuildMessageLogger extends BuildMessageLogger { - public static final Function FACTORY = { String taskName -> new ConsoleBuildMessageLogger(taskName) } as Function + public static final BiFunction FACTORY = { String taskName, AntTaskLogger logger -> + new ConsoleBuildMessageLogger(taskName) + } as BiFunction private final String parallelTaskId private int indent private static final PrintStream out = BuildUtils.realSystemOut diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/TeamCityBuildMessageLogger.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/TeamCityBuildMessageLogger.groovy index e30a7c9d9c02..b97fd3926d3e 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/TeamCityBuildMessageLogger.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/TeamCityBuildMessageLogger.groovy @@ -16,11 +16,11 @@ package org.jetbrains.intellij.build.impl import groovy.transform.CompileStatic +import org.apache.tools.ant.Project import org.jetbrains.intellij.build.BuildMessageLogger import org.jetbrains.intellij.build.LogMessage -import java.util.function.Function - +import java.util.function.BiFunction /** * todo[nik] this is replacement for BuildInfoPrinter. BuildInfoPrinter should be deleted after we move its remaining methods to this class. * @@ -28,12 +28,16 @@ import java.util.function.Function */ @CompileStatic class TeamCityBuildMessageLogger extends BuildMessageLogger { - public static final Function FACTORY = { String taskName -> new TeamCityBuildMessageLogger(taskName) } as Function + public static final BiFunction FACTORY = { String taskName, AntTaskLogger antLogger -> + new TeamCityBuildMessageLogger(taskName, antLogger) + } as BiFunction private static final PrintStream out = BuildUtils.realSystemOut private final String parallelTaskId + private AntTaskLogger antTaskLogger - TeamCityBuildMessageLogger(String parallelTaskId) { + TeamCityBuildMessageLogger(String parallelTaskId, AntTaskLogger antTaskLogger) { this.parallelTaskId = parallelTaskId + this.antTaskLogger = antTaskLogger } @Override @@ -45,16 +49,16 @@ class TeamCityBuildMessageLogger extends BuildMessageLogger { logPlainMessage(message) break case LogMessage.Kind.PROGRESS: - out.println "##teamcity[progressMessage '${escape(message.text)}']" + printTeamCityMessage("progressMessage", false, "'${escape(message.text)}'") break case LogMessage.Kind.BLOCK_STARTED: - printTeamCityMessage("blockOpened", "name='${escape(message.text)}'") + printTeamCityMessage("blockOpened", true, "name='${escape(message.text)}'") break case LogMessage.Kind.BLOCK_FINISHED: - printTeamCityMessage("blockClosed", "name='${escape(message.text)}'") + printTeamCityMessage("blockClosed", true, "name='${escape(message.text)}'") break case LogMessage.Kind.ARTIFACT_BUILT: - out.println "##teamcity[publishArtifacts '${escape(message.text)}']" + printTeamCityMessage("publishArtifacts", false, "'${escape(message.text)}'") break } } @@ -62,16 +66,20 @@ class TeamCityBuildMessageLogger extends BuildMessageLogger { void logPlainMessage(LogMessage message) { String status = message.kind == LogMessage.Kind.WARNING ? " status='WARNING'" : "" if (parallelTaskId != null || !status.isEmpty()) { - printTeamCityMessage("message", "text='${escape(message.text)}'$status") + printTeamCityMessage("message", true, "text='${escape(message.text)}'$status") } else { + antTaskLogger.logMessageToOtherLoggers(message.text, Project.MSG_INFO) out.println message.text } } - private void printTeamCityMessage(String messageId, String messageArguments) { - String flowArg = parallelTaskId != null ? " flowId='${escape(parallelTaskId)}'" : "" - out.println "##teamcity[$messageId$flowArg $messageArguments]" + private void printTeamCityMessage(String messageId, boolean includeFlowId, String messageArguments) { + String flowArg = includeFlowId && parallelTaskId != null ? " flowId='${escape(parallelTaskId)}'" : "" + String message = "##teamcity[$messageId$flowArg $messageArguments]" + //TeamCity reads messages from Ant-based builds via BuildListener so we need to send it to listeners + antTaskLogger.logMessageToOtherLoggers(message, Project.MSG_INFO) + out.println(message) } private static char escapeChar(char c) {