diff --git a/main/actions/src/main/scala/sbt/Compiler.scala b/main/actions/src/main/scala/sbt/Compiler.scala index 0d0a33c49..459636f8e 100644 --- a/main/actions/src/main/scala/sbt/Compiler.scala +++ b/main/actions/src/main/scala/sbt/Compiler.scala @@ -58,16 +58,21 @@ object Compiler val provider = ComponentCompiler.interfaceProvider(componentManager) new AnalyzingCompiler(instance, provider, cpOptions, log) } - - def apply(in: Inputs, log: Logger): Analysis = + def apply(in: Inputs, log: Logger): Analysis = { - import in.compilers._ - import in.config._ - import in.incSetup._ - + import in.compilers._ + import in.config._ + import in.incSetup._ + apply(in, log, new LoggerReporter(maxErrors, log, sourcePositionMapper)) + } + def apply(in: Inputs, log: Logger, reporter: xsbti.Reporter): Analysis = + { + import in.compilers._ + import in.config._ + import in.incSetup._ val agg = new AggressiveCompile(cacheFile) agg(scalac, javac, sources, classpath, CompileOutput(classesDirectory), cache, None, options, javacOptions, - analysisMap, definesClass, new LoggerReporter(maxErrors, log, sourcePositionMapper), order, skip, incOptions)(log) + analysisMap, definesClass, reporter, order, skip, incOptions)(log) } private[sbt] def foldMappers[A](mappers: Seq[A => Option[A]]) = diff --git a/main/src/main/scala/sbt/Aggregation.scala b/main/src/main/scala/sbt/Aggregation.scala index 81a9d5494..57b7c8c4f 100644 --- a/main/src/main/scala/sbt/Aggregation.scala +++ b/main/src/main/scala/sbt/Aggregation.scala @@ -59,7 +59,7 @@ final object Aggregation import extracted.structure val toRun = ts map { case KeyValue(k,t) => t.map(v => KeyValue(k,v)) } join; val roots = ts map { case KeyValue(k,_) => k } - val config = extractedConfig(extracted, structure) + val config = extractedConfig(extracted, structure, s) val start = System.currentTimeMillis val (newS, result) = withStreams(structure, s){ str => @@ -211,4 +211,4 @@ final object Aggregation @deprecated("Use BuildUtil.aggregationRelation", "0.13.0") def relation(units: Map[URI, LoadedBuildUnit]): Relation[ProjectRef, ProjectRef] = BuildUtil.aggregationRelation(units) -} \ No newline at end of file +} diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 8283b5b54..9310c44f7 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -732,13 +732,16 @@ object Defaults extends BuildCommon @deprecated("Use inTask(compile)(compileInputsSettings)", "0.13.0") def compileTaskSettings: Seq[Setting[_]] = inTask(compile)(compileInputsSettings) - def compileTask: Initialize[Task[inc.Analysis]] = Def.task { compileTaskImpl(streams.value, (compileInputs in compile).value) } - private[this] def compileTaskImpl(s: TaskStreams, ci: Compiler.Inputs): inc.Analysis = + def compileTask: Initialize[Task[inc.Analysis]] = Def.task { compileTaskImpl(streams.value, (compileInputs in compile).value, (compilerReporter in compile).value) } + private[this] def compileTaskImpl(s: TaskStreams, ci: Compiler.Inputs, reporter: Option[xsbti.Reporter]): inc.Analysis = { lazy val x = s.text(ExportStream) def onArgs(cs: Compiler.Compilers) = cs.copy(scalac = cs.scalac.onArgs(exported(x, "scalac")), javac = cs.javac.onArgs(exported(x, "javac"))) val i = ci.copy(compilers = onArgs(ci.compilers)) - try Compiler(i,s.log) + try reporter match { + case Some(reporter) => Compiler(i, s.log, reporter) + case None => Compiler(i, s.log) + } finally x.close() // workaround for #937 } def compileIncSetupTask = @@ -749,7 +752,8 @@ object Defaults extends BuildCommon Seq(compileInputs := { val cp = classDirectory.value +: data(dependencyClasspath.value) Compiler.inputs(cp, sources.value, classDirectory.value, scalacOptions.value, javacOptions.value, maxErrors.value, sourcePositionMappers.value, compileOrder.value)(compilers.value, compileIncSetup.value, streams.value.log) - }) + }, + compilerReporter := None) def printWarningsTask: Initialize[Task[Unit]] = (streams, compile, maxErrors, sourcePositionMappers) map { (s, analysis, max, spms) => diff --git a/main/src/main/scala/sbt/EvaluateTask.scala b/main/src/main/scala/sbt/EvaluateTask.scala index 66192feb2..4c8fe8756 100644 --- a/main/src/main/scala/sbt/EvaluateTask.scala +++ b/main/src/main/scala/sbt/EvaluateTask.scala @@ -44,18 +44,25 @@ object EvaluateTask def defaultConfig(state: State): EvaluateConfig = { val extracted = Project.extract(state) - defaultConfig(extracted, extracted.structure) + extractedConfig(extracted, extracted.structure, state) } @deprecated("Use extractedConfig.", "0.13.0") def defaultConfig(extracted: Extracted, structure: BuildStructure) = - EvaluateConfig(false, restrictions(extracted, structure), progress = executeProgress(extracted, structure)) + EvaluateConfig(false, restrictions(extracted, structure), progress = defaultProgress) + @deprecated("Use other extractedConfig", "0.13.2") def extractedConfig(extracted: Extracted, structure: BuildStructure): EvaluateConfig = { val workers = restrictions(extracted, structure) val canCancel = cancelable(extracted, structure) - val progress = executeProgress(extracted, structure) + EvaluateConfig(cancelable = canCancel, restrictions = workers, progress = defaultProgress) + } + def extractedConfig(extracted: Extracted, structure: BuildStructure, state: State): EvaluateConfig = + { + val workers = restrictions(extracted, structure) + val canCancel = cancelable(extracted, structure) + val progress = executeProgress(extracted, structure, state) EvaluateConfig(cancelable = canCancel, restrictions = workers, progress = progress) } @@ -78,8 +85,11 @@ object EvaluateTask def cancelable(extracted: Extracted, structure: BuildStructure): Boolean = getSetting(Keys.cancelable, false, extracted, structure) - private[sbt] def executeProgress(extracted: Extracted, structure: BuildStructure): ExecuteProgress[Task] = - getSetting(Keys.executeProgress, new Keys.TaskProgress(defaultProgress), extracted, structure).progress + private[sbt] def executeProgress(extracted: Extracted, structure: BuildStructure, state: State): ExecuteProgress[Task] = { + import Types.const + val maker: State => Keys.TaskProgress = getSetting(Keys.executeProgress, const(new Keys.TaskProgress(defaultProgress)), extracted, structure) + maker(state).progress + } def getSetting[T](key: SettingKey[T], default: T, extracted: Extracted, structure: BuildStructure): T = key in extracted.currentRef get structure.data getOrElse default @@ -94,7 +104,7 @@ object EvaluateTask { val root = ProjectRef(pluginDef.root, Load.getRootProject(pluginDef.units)(pluginDef.root)) val pluginKey = pluginData - val config = extractedConfig(Project.extract(state), pluginDef) + val config = extractedConfig(Project.extract(state), pluginDef, state) val evaluated = apply(pluginDef, ScopedKey(pluginKey.scope, pluginKey.key), state, root, config) val (newS, result) = evaluated getOrElse sys.error("Plugin data does not exist for plugin definition at " + pluginDef.root) Project.runUnloadHooks(newS) // discard states diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index c0ffdbd6d..17f64e0b3 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -344,8 +344,11 @@ object Keys // wrapper to work around SI-2915 private[sbt] final class TaskProgress(val progress: ExecuteProgress[Task]) - private[sbt] val executeProgress = SettingKey[TaskProgress]("executeProgress", "Experimental task execution listener.", DTask) + private[sbt] val executeProgress = SettingKey[State => TaskProgress]("executeProgress", "Experimental task execution listener.", DTask) + // Experimental in sbt 0.13.2 to enable grabing semantic compile failures. + private[sbt] val compilerReporter = TaskKey[Option[xsbti.Reporter]]("compilerReporter", "Experimental hook to listen (or send) compilation failure messages.", DTask) + val triggeredBy = Def.triggeredBy val runBefore = Def.runBefore