Fixes to the internal API hooks for the sbt server.

* Alter the TaskProgress listener key to be `State => TaskProgress` so it
  can be instantiated from the current server/sbt state.
* Expose the xsbti.Reporter interface for compilation through to sbt builds.
This commit is contained in:
Josh Suereth 2014-01-14 08:09:55 -05:00
parent cef1d28f22
commit 2abe7574df
5 changed files with 42 additions and 20 deletions

View File

@ -58,16 +58,21 @@ object Compiler
val provider = ComponentCompiler.interfaceProvider(componentManager) val provider = ComponentCompiler.interfaceProvider(componentManager)
new AnalyzingCompiler(instance, provider, cpOptions, log) 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.compilers._
import in.config._ import in.config._
import in.incSetup._ 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) val agg = new AggressiveCompile(cacheFile)
agg(scalac, javac, sources, classpath, CompileOutput(classesDirectory), cache, None, options, javacOptions, 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]]) = private[sbt] def foldMappers[A](mappers: Seq[A => Option[A]]) =

View File

@ -59,7 +59,7 @@ final object Aggregation
import extracted.structure import extracted.structure
val toRun = ts map { case KeyValue(k,t) => t.map(v => KeyValue(k,v)) } join; val toRun = ts map { case KeyValue(k,t) => t.map(v => KeyValue(k,v)) } join;
val roots = ts map { case KeyValue(k,_) => k } val roots = ts map { case KeyValue(k,_) => k }
val config = extractedConfig(extracted, structure) val config = extractedConfig(extracted, structure, s)
val start = System.currentTimeMillis val start = System.currentTimeMillis
val (newS, result) = withStreams(structure, s){ str => val (newS, result) = withStreams(structure, s){ str =>

View File

@ -732,13 +732,16 @@ object Defaults extends BuildCommon
@deprecated("Use inTask(compile)(compileInputsSettings)", "0.13.0") @deprecated("Use inTask(compile)(compileInputsSettings)", "0.13.0")
def compileTaskSettings: Seq[Setting[_]] = inTask(compile)(compileInputsSettings) def compileTaskSettings: Seq[Setting[_]] = inTask(compile)(compileInputsSettings)
def compileTask: Initialize[Task[inc.Analysis]] = Def.task { compileTaskImpl(streams.value, (compileInputs in compile).value) } 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): inc.Analysis = private[this] def compileTaskImpl(s: TaskStreams, ci: Compiler.Inputs, reporter: Option[xsbti.Reporter]): inc.Analysis =
{ {
lazy val x = s.text(ExportStream) 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"))) 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)) 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 finally x.close() // workaround for #937
} }
def compileIncSetupTask = def compileIncSetupTask =
@ -749,7 +752,8 @@ object Defaults extends BuildCommon
Seq(compileInputs := { Seq(compileInputs := {
val cp = classDirectory.value +: data(dependencyClasspath.value) 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) 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]] = def printWarningsTask: Initialize[Task[Unit]] =
(streams, compile, maxErrors, sourcePositionMappers) map { (s, analysis, max, spms) => (streams, compile, maxErrors, sourcePositionMappers) map { (s, analysis, max, spms) =>

View File

@ -44,18 +44,25 @@ object EvaluateTask
def defaultConfig(state: State): EvaluateConfig = def defaultConfig(state: State): EvaluateConfig =
{ {
val extracted = Project.extract(state) val extracted = Project.extract(state)
defaultConfig(extracted, extracted.structure) extractedConfig(extracted, extracted.structure, state)
} }
@deprecated("Use extractedConfig.", "0.13.0") @deprecated("Use extractedConfig.", "0.13.0")
def defaultConfig(extracted: Extracted, structure: BuildStructure) = 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 = def extractedConfig(extracted: Extracted, structure: BuildStructure): EvaluateConfig =
{ {
val workers = restrictions(extracted, structure) val workers = restrictions(extracted, structure)
val canCancel = cancelable(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) EvaluateConfig(cancelable = canCancel, restrictions = workers, progress = progress)
} }
@ -78,8 +85,11 @@ object EvaluateTask
def cancelable(extracted: Extracted, structure: BuildStructure): Boolean = def cancelable(extracted: Extracted, structure: BuildStructure): Boolean =
getSetting(Keys.cancelable, false, extracted, structure) getSetting(Keys.cancelable, false, extracted, structure)
private[sbt] def executeProgress(extracted: Extracted, structure: BuildStructure): ExecuteProgress[Task] = private[sbt] def executeProgress(extracted: Extracted, structure: BuildStructure, state: State): ExecuteProgress[Task] = {
getSetting(Keys.executeProgress, new Keys.TaskProgress(defaultProgress), extracted, structure).progress 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 = def getSetting[T](key: SettingKey[T], default: T, extracted: Extracted, structure: BuildStructure): T =
key in extracted.currentRef get structure.data getOrElse default 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 root = ProjectRef(pluginDef.root, Load.getRootProject(pluginDef.units)(pluginDef.root))
val pluginKey = pluginData 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 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) val (newS, result) = evaluated getOrElse sys.error("Plugin data does not exist for plugin definition at " + pluginDef.root)
Project.runUnloadHooks(newS) // discard states Project.runUnloadHooks(newS) // discard states

View File

@ -344,7 +344,10 @@ object Keys
// wrapper to work around SI-2915 // wrapper to work around SI-2915
private[sbt] final class TaskProgress(val progress: ExecuteProgress[Task]) 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 triggeredBy = Def.triggeredBy
val runBefore = Def.runBefore val runBefore = Def.runBefore