mirror of https://github.com/sbt/sbt.git
scalacOptions, javacOptions in Compile in project/plugins/ affect build definitions. fixes #166
This commit is contained in:
parent
f515a0e8b6
commit
d145fcc457
|
|
@ -12,8 +12,8 @@ package sbt
|
||||||
|
|
||||||
object EvaluateTask
|
object EvaluateTask
|
||||||
{
|
{
|
||||||
import Load.BuildStructure
|
import Load.{BuildStructure, PluginData}
|
||||||
import Project.display
|
import Project.{display, Initialize}
|
||||||
import std.{TaskExtra,Transform}
|
import std.{TaskExtra,Transform}
|
||||||
import TaskExtra._
|
import TaskExtra._
|
||||||
import Keys.state
|
import Keys.state
|
||||||
|
|
@ -25,13 +25,24 @@ object EvaluateTask
|
||||||
(streamsManager in GlobalScope) ::= dummyStreamsManager
|
(streamsManager in GlobalScope) ::= dummyStreamsManager
|
||||||
)
|
)
|
||||||
|
|
||||||
def evalPluginDef(log: Logger)(pluginDef: BuildStructure, state: State): Seq[Attributed[File]] =
|
def evalPluginDef(log: Logger)(pluginDef: BuildStructure, state: State): PluginData =
|
||||||
{
|
{
|
||||||
|
import Keys.{fullClasspath, javacOptions, scalacOptions}
|
||||||
|
import Configurations.{Compile, Runtime}
|
||||||
|
import Scoped._
|
||||||
|
|
||||||
val root = ProjectRef(pluginDef.root, Load.getRootProject(pluginDef.units)(pluginDef.root))
|
val root = ProjectRef(pluginDef.root, Load.getRootProject(pluginDef.units)(pluginDef.root))
|
||||||
val pluginKey = Keys.fullClasspath in Configurations.Runtime
|
val init = (fullClasspath in Runtime, scalacOptions in Compile, javacOptions in Compile) map { (cp, so, jo) => new PluginData(cp, so, jo) }
|
||||||
val evaluated = evaluateTask(pluginDef, ScopedKey(pluginKey.scope, pluginKey.key), state, root)
|
processResult(evaluateInitTask(pluginDef, init, state, root), log)
|
||||||
val result = evaluated getOrElse error("Plugin classpath does not exist for plugin definition at " + pluginDef.root)
|
}
|
||||||
processResult(result, log)
|
def evaluateInitTask[T](structure: BuildStructure, init: Initialize[Task[T]], state: State, ref: ProjectRef, checkCycles: Boolean = false, maxWorkers: Int = SystemProcessors): Result[T] =
|
||||||
|
{
|
||||||
|
val resolveThis = Project.mapScope( Scope.replaceThis(Load.projectScope(ref)) )
|
||||||
|
val task = init mapReferenced resolveThis evaluate structure.data
|
||||||
|
withStreams(structure) { str =>
|
||||||
|
val toNode = nodeView(state, str)
|
||||||
|
runTask(task, str, structure.index.triggers, checkCycles, maxWorkers)(toNode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
def evaluateTask[T](structure: BuildStructure, taskKey: ScopedKey[Task[T]], state: State, ref: ProjectRef, checkCycles: Boolean = false, maxWorkers: Int = SystemProcessors): Option[Result[T]] =
|
def evaluateTask[T](structure: BuildStructure, taskKey: ScopedKey[Task[T]], state: State, ref: ProjectRef, checkCycles: Boolean = false, maxWorkers: Int = SystemProcessors): Option[Result[T]] =
|
||||||
withStreams(structure) { str =>
|
withStreams(structure) { str =>
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ object Keys
|
||||||
val maxErrors = SettingKey[Int]("max-errors", "The maximum number of errors, such as compile errors, to list.")
|
val maxErrors = SettingKey[Int]("max-errors", "The maximum number of errors, such as compile errors, to list.")
|
||||||
val scaladocOptions = TaskKey[Seq[String]]("scaladoc-options", "Options for Scaladoc.")
|
val scaladocOptions = TaskKey[Seq[String]]("scaladoc-options", "Options for Scaladoc.")
|
||||||
val scalacOptions = TaskKey[Seq[String]]("scalac-options", "Options for the Scala compiler.")
|
val scalacOptions = TaskKey[Seq[String]]("scalac-options", "Options for the Scala compiler.")
|
||||||
val javacOptions = SettingKey[Seq[String]]("javac-options", "Options for the Java compiler.")
|
val javacOptions = TaskKey[Seq[String]]("javac-options", "Options for the Java compiler.")
|
||||||
val compileOrder = SettingKey[CompileOrder.Value]("compile-order", "Configures the order in which Java and sources within a single compilation are compiled. Valid values are: JavaThenScala, ScalaThenJava, or Mixed.")
|
val compileOrder = SettingKey[CompileOrder.Value]("compile-order", "Configures the order in which Java and sources within a single compilation are compiled. Valid values are: JavaThenScala, ScalaThenJava, or Mixed.")
|
||||||
val initialCommands = SettingKey[String]("initial-commands", "Initial commands to execute when starting up the Scala interpreter.")
|
val initialCommands = SettingKey[String]("initial-commands", "Initial commands to execute when starting up the Scala interpreter.")
|
||||||
val compileInputs = TaskKey[Compiler.Inputs]("compile-inputs", "Collects all inputs needed for compilation.")
|
val compileInputs = TaskKey[Compiler.Inputs]("compile-inputs", "Collects all inputs needed for compilation.")
|
||||||
|
|
|
||||||
|
|
@ -406,14 +406,14 @@ object Load
|
||||||
else
|
else
|
||||||
noPlugins(dir, config)
|
noPlugins(dir, config)
|
||||||
|
|
||||||
def noPlugins(dir: File, config: LoadBuildConfiguration): LoadedPlugins = loadPluginDefinition(dir, config, config.globalPluginClasspath)
|
def noPlugins(dir: File, config: LoadBuildConfiguration): LoadedPlugins = loadPluginDefinition(dir, config, new PluginData(config.globalPluginClasspath, Nil, Nil))
|
||||||
def buildPlugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins =
|
def buildPlugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins =
|
||||||
loadPluginDefinition(dir, config, buildPluginDefinition(dir, s, config))
|
loadPluginDefinition(dir, config, buildPluginDefinition(dir, s, config))
|
||||||
|
|
||||||
def loadPluginDefinition(dir: File, config: LoadBuildConfiguration, pluginClasspath: Seq[Attributed[File]]): LoadedPlugins =
|
def loadPluginDefinition(dir: File, config: LoadBuildConfiguration, data: PluginData): LoadedPlugins =
|
||||||
{
|
{
|
||||||
val (definitionClasspath, pluginLoader) = pluginDefinitionLoader(config, pluginClasspath)
|
val (definitionClasspath, pluginLoader) = pluginDefinitionLoader(config, data.classpath)
|
||||||
loadPlugins(dir, definitionClasspath, pluginLoader)
|
loadPlugins(dir, data.copy(classpath = definitionClasspath), pluginLoader)
|
||||||
}
|
}
|
||||||
def pluginDefinitionLoader(config: LoadBuildConfiguration, pluginClasspath: Seq[Attributed[File]]): (Seq[Attributed[File]], ClassLoader) =
|
def pluginDefinitionLoader(config: LoadBuildConfiguration, pluginClasspath: Seq[Attributed[File]]): (Seq[Attributed[File]], ClassLoader) =
|
||||||
{
|
{
|
||||||
|
|
@ -421,7 +421,7 @@ object Load
|
||||||
val pluginLoader = if(pluginClasspath.isEmpty) config.loader else ClasspathUtilities.toLoader(data(pluginClasspath), config.loader)
|
val pluginLoader = if(pluginClasspath.isEmpty) config.loader else ClasspathUtilities.toLoader(data(pluginClasspath), config.loader)
|
||||||
(definitionClasspath, pluginLoader)
|
(definitionClasspath, pluginLoader)
|
||||||
}
|
}
|
||||||
def buildPluginDefinition(dir: File, s: State, config: LoadBuildConfiguration): Seq[Attributed[File]] =
|
def buildPluginDefinition(dir: File, s: State, config: LoadBuildConfiguration): PluginData =
|
||||||
{
|
{
|
||||||
val (eval,pluginDef) = apply(dir, s, config)
|
val (eval,pluginDef) = apply(dir, s, config)
|
||||||
val pluginState = Project.setProject(Load.initialSession(pluginDef, eval), pluginDef, s)
|
val pluginState = Project.setProject(Load.initialSession(pluginDef, eval), pluginDef, s)
|
||||||
|
|
@ -430,7 +430,7 @@ object Load
|
||||||
|
|
||||||
def definitions(base: File, targetBase: File, srcs: Seq[File], plugins: LoadedPlugins, definesClass: DefinesClass, compilers: Compilers, log: Logger, buildBase: File): LoadedDefinitions =
|
def definitions(base: File, targetBase: File, srcs: Seq[File], plugins: LoadedPlugins, definesClass: DefinesClass, compilers: Compilers, log: Logger, buildBase: File): LoadedDefinitions =
|
||||||
{
|
{
|
||||||
val (inputs, defAnalysis) = build(plugins.fullClasspath, srcs, targetBase, compilers, definesClass, log)
|
val (inputs, defAnalysis) = build(plugins.pluginData, srcs, targetBase, compilers, definesClass, log)
|
||||||
val target = inputs.config.classesDirectory
|
val target = inputs.config.classesDirectory
|
||||||
val definitionLoader = ClasspathUtilities.toLoader(target :: Nil, plugins.loader)
|
val definitionLoader = ClasspathUtilities.toLoader(target :: Nil, plugins.loader)
|
||||||
val defNames = findDefinitions(defAnalysis)
|
val defNames = findDefinitions(defAnalysis)
|
||||||
|
|
@ -443,23 +443,23 @@ object Load
|
||||||
def loadDefinition(loader: ClassLoader, definition: String): Build =
|
def loadDefinition(loader: ClassLoader, definition: String): Build =
|
||||||
ModuleUtilities.getObject(definition, loader).asInstanceOf[Build]
|
ModuleUtilities.getObject(definition, loader).asInstanceOf[Build]
|
||||||
|
|
||||||
def build(classpath: Seq[Attributed[File]], sources: Seq[File], target: File, compilers: Compilers, definesClass: DefinesClass, log: Logger): (Inputs, inc.Analysis) =
|
def build(pd: PluginData, sources: Seq[File], target: File, compilers: Compilers, definesClass: DefinesClass, log: Logger): (Inputs, inc.Analysis) =
|
||||||
{
|
{
|
||||||
// TODO: make used of classpath metadata for recompilation
|
// TODO: make used of classpath metadata for recompilation
|
||||||
val inputs = Compiler.inputs(data(classpath), sources, target, Nil, Nil, definesClass, Compiler.DefaultMaxErrors, CompileOrder.Mixed)(compilers, log)
|
val inputs = Compiler.inputs(data(pd.classpath), sources, target, pd.scalacOptions, pd.javacOptions, definesClass, Compiler.DefaultMaxErrors, CompileOrder.Mixed)(compilers, log)
|
||||||
val analysis =
|
val analysis =
|
||||||
try { Compiler(inputs, log) }
|
try { Compiler(inputs, log) }
|
||||||
catch { case _: xsbti.CompileFailed => throw new NoMessageException } // compiler already logged errors
|
catch { case _: xsbti.CompileFailed => throw new NoMessageException } // compiler already logged errors
|
||||||
(inputs, analysis)
|
(inputs, analysis)
|
||||||
}
|
}
|
||||||
|
|
||||||
def loadPlugins(dir: File, classpath: Seq[Attributed[File]], loader: ClassLoader): LoadedPlugins =
|
def loadPlugins(dir: File, data: PluginData, loader: ClassLoader): LoadedPlugins =
|
||||||
{
|
{
|
||||||
val (pluginNames, plugins) = if(classpath.isEmpty) (Nil, Nil) else {
|
val (pluginNames, plugins) = if(data.classpath.isEmpty) (Nil, Nil) else {
|
||||||
val names = getPluginNames(classpath, loader)
|
val names = getPluginNames(data.classpath, loader)
|
||||||
(names, loadPlugins(loader, names) )
|
(names, loadPlugins(loader, names) )
|
||||||
}
|
}
|
||||||
new LoadedPlugins(dir, classpath, loader, plugins, pluginNames)
|
new LoadedPlugins(dir, data, loader, plugins, pluginNames)
|
||||||
}
|
}
|
||||||
def getPluginNames(classpath: Seq[Attributed[File]], loader: ClassLoader): Seq[String] =
|
def getPluginNames(classpath: Seq[Attributed[File]], loader: ClassLoader): Seq[String] =
|
||||||
( binaryPlugins(loader) ++ (analyzed(classpath) flatMap findPlugins) ).distinct
|
( binaryPlugins(loader) ++ (analyzed(classpath) flatMap findPlugins) ).distinct
|
||||||
|
|
@ -505,8 +505,9 @@ object Load
|
||||||
|
|
||||||
final class EvaluatedConfigurations(val eval: Eval, val settings: Seq[Setting[_]])
|
final class EvaluatedConfigurations(val eval: Eval, val settings: Seq[Setting[_]])
|
||||||
final class LoadedDefinitions(val base: File, val target: File, val loader: ClassLoader, val builds: Seq[Build], val buildNames: Seq[String])
|
final class LoadedDefinitions(val base: File, val target: File, val loader: ClassLoader, val builds: Seq[Build], val buildNames: Seq[String])
|
||||||
final class LoadedPlugins(val base: File, val fullClasspath: Seq[Attributed[File]], val loader: ClassLoader, val plugins: Seq[Setting[_]], val pluginNames: Seq[String])
|
final class LoadedPlugins(val base: File, val pluginData: PluginData, val loader: ClassLoader, val plugins: Seq[Setting[_]], val pluginNames: Seq[String])
|
||||||
{
|
{
|
||||||
|
def fullClasspath: Seq[Attributed[File]] = pluginData.classpath
|
||||||
def classpath = data(fullClasspath)
|
def classpath = data(fullClasspath)
|
||||||
}
|
}
|
||||||
final class BuildUnit(val uri: URI, val localBase: File, val definitions: LoadedDefinitions, val plugins: LoadedPlugins)
|
final class BuildUnit(val uri: URI, val localBase: File, val definitions: LoadedDefinitions, val plugins: LoadedPlugins)
|
||||||
|
|
@ -559,12 +560,13 @@ object Load
|
||||||
def allProjectRefs(build: URI): Seq[ProjectRef] = refs(build, allProjects(build))
|
def allProjectRefs(build: URI): Seq[ProjectRef] = refs(build, allProjects(build))
|
||||||
private[this] def refs(build: URI, projects: Seq[ResolvedProject]): Seq[ProjectRef] = projects.map { p => ProjectRef(build, p.id) }
|
private[this] def refs(build: URI, projects: Seq[ResolvedProject]): Seq[ProjectRef] = projects.map { p => ProjectRef(build, p.id) }
|
||||||
}
|
}
|
||||||
final case class LoadBuildConfiguration(stagingDirectory: File, classpath: Seq[Attributed[File]], loader: ClassLoader, compilers: Compilers, evalPluginDef: (BuildStructure, State) => Seq[Attributed[File]], definesClass: DefinesClass, delegates: LoadedBuild => Scope => Seq[Scope], scopeLocal: ScopeLocal, injectSettings: InjectSettings, globalPlugin: Option[GlobalPlugin], log: Logger)
|
final case class LoadBuildConfiguration(stagingDirectory: File, classpath: Seq[Attributed[File]], loader: ClassLoader, compilers: Compilers, evalPluginDef: (BuildStructure, State) => PluginData, definesClass: DefinesClass, delegates: LoadedBuild => Scope => Seq[Scope], scopeLocal: ScopeLocal, injectSettings: InjectSettings, globalPlugin: Option[GlobalPlugin], log: Logger)
|
||||||
{
|
{
|
||||||
lazy val (globalPluginClasspath, globalPluginLoader) = pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin))
|
lazy val (globalPluginClasspath, globalPluginLoader) = pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin))
|
||||||
lazy val globalPluginNames = if(globalPluginClasspath.isEmpty) Nil else getPluginNames(globalPluginClasspath, globalPluginLoader)
|
lazy val globalPluginNames = if(globalPluginClasspath.isEmpty) Nil else getPluginNames(globalPluginClasspath, globalPluginLoader)
|
||||||
}
|
}
|
||||||
final case class InjectSettings(global: Seq[Setting[_]], project: Seq[Setting[_]], projectLoaded: ClassLoader => Seq[Setting[_]])
|
final case class InjectSettings(global: Seq[Setting[_]], project: Seq[Setting[_]], projectLoaded: ClassLoader => Seq[Setting[_]])
|
||||||
|
final case class PluginData(classpath: Seq[Attributed[File]], scalacOptions: Seq[String], javacOptions: Seq[String])
|
||||||
|
|
||||||
// information that is not original, but can be reconstructed from the rest of BuildStructure
|
// information that is not original, but can be reconstructed from the rest of BuildStructure
|
||||||
final class StructureIndex(val keyMap: Map[String, AttributeKey[_]], val taskToKey: Map[Task[_], ScopedKey[Task[_]]], val triggers: Triggers[Task], val keyIndex: KeyIndex)
|
final class StructureIndex(val keyMap: Map[String, AttributeKey[_]], val taskToKey: Map[Task[_], ScopedKey[Task[_]]], val triggers: Triggers[Task], val keyIndex: KeyIndex)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue