Allow Build.scala project settings to be ordered via AddSettings.

* Create new AddSettings.ProjectSettings that can be used in the Addsettings order.
* Update Load.scala to correctly abide by AddSettings orderings.
This commit is contained in:
Josh Suereth 2014-03-05 17:59:29 -05:00
parent 7f8d21c2f1
commit ac9391066b
2 changed files with 21 additions and 9 deletions

View File

@ -14,10 +14,21 @@ object AddSettings
private[sbt] final class Plugins(val include: Plugin => Boolean) extends AddSettings
private[sbt] final class DefaultSbtFiles(val include: File => Boolean) extends AddSettings
private[sbt] final class SbtFiles(val files: Seq[File]) extends AddSettings
// Settings created with the Project().settings() commands in build.scala files.
private[sbt] final object ProjectSettings extends AddSettings
/** Adds all settings from a plugin to a project. */
val allPlugins: AddSettings = plugins(const(true))
/** Adds all settings from autoplugins. */
val autoPlugins: AddSettings = plugins(_.isInstanceOf[AutoPlugin])
/** Settings specified in Build.scala `Project` constructors. */
val projectSettings: AddSettings = ProjectSettings
/** All plugins that aren't auto plugins. */
val nonAutoPlugins: AddSettings = plugins(!_.isInstanceOf[AutoPlugin])
/** Allows the plugins whose names match the `names` filter to automatically add settings to a project. */
def plugins(include: Plugin => Boolean): AddSettings = new Plugins(include)
@ -33,7 +44,8 @@ object AddSettings
/** Includes settings automatically*/
def seq(autos: AddSettings*): AddSettings = new Sequence(autos)
val allDefaults: AddSettings = seq(userSettings, allPlugins, defaultSbtFiles)
/** The default inclusion of settings. */
val allDefaults: AddSettings = seq(autoPlugins, projectSettings, userSettings, nonAutoPlugins, defaultSbtFiles)
/** Combines two automatic setting configurations. */
def append(a: AddSettings, b: AddSettings): AddSettings = (a,b) match {

View File

@ -459,20 +459,19 @@ object Load
private[this] def loadTransitive(newProjects: Seq[Project], buildBase: File, plugins: sbt.LoadedPlugins, eval: () => Eval, injectSettings: InjectSettings, acc: Seq[Project], memoSettings: mutable.Map[File, LoadedSbtFile]): Seq[Project] =
{
def loadSbtFiles(auto: AddSettings, base: File, autoPlugins: Seq[AutoPlugin]): LoadedSbtFile =
loadSettings(auto, base, plugins, eval, injectSettings, memoSettings, autoPlugins)
def loadSbtFiles(auto: AddSettings, base: File, autoPlugins: Seq[AutoPlugin], projectSettings: Seq[Setting[_]]): LoadedSbtFile =
loadSettings(auto, base, plugins, eval, injectSettings, memoSettings, autoPlugins, projectSettings)
def loadForProjects = newProjects map { project =>
val autoPlugins =
try plugins.detected.compilePlugins(project.plugins)
catch { case e: AutoPluginException => throw translateAutoPluginException(e, project) }
val autoConfigs = autoPlugins.flatMap(_.projectConfigurations)
val loadedSbtFiles = loadSbtFiles(project.auto, project.base, autoPlugins)
val newSettings = (project.settings: Seq[Setting[_]]) ++ loadedSbtFiles.settings
val loadedSbtFiles = loadSbtFiles(project.auto, project.base, autoPlugins, project.settings)
// add the automatically selected settings, record the selected AutoPlugins, and register the automatically selected configurations
val transformed = project.copy(settings = newSettings).setAutoPlugins(autoPlugins).overrideConfigs(autoConfigs : _*)
val transformed = project.copy(settings = loadedSbtFiles.settings).setAutoPlugins(autoPlugins).overrideConfigs(autoConfigs : _*)
(transformed, loadedSbtFiles.projects)
}
def defaultLoad = loadSbtFiles(AddSettings.defaultSbtFiles, buildBase, Nil).projects
def defaultLoad = loadSbtFiles(AddSettings.defaultSbtFiles, buildBase, Nil, Nil).projects
val (nextProjects, loadedProjects) =
if(newProjects.isEmpty) // load the .sbt files in the root directory to look for Projects
(defaultLoad, acc)
@ -489,7 +488,7 @@ object Load
private[this] def translateAutoPluginException(e: AutoPluginException, project: Project): AutoPluginException =
e.withPrefix(s"Error determining plugins for project '${project.id}' in ${project.base}:\n")
private[this] def loadSettings(auto: AddSettings, projectBase: File, loadedPlugins: sbt.LoadedPlugins, eval: ()=>Eval, injectSettings: InjectSettings, memoSettings: mutable.Map[File, LoadedSbtFile], autoPlugins: Seq[AutoPlugin]): LoadedSbtFile =
private[this] def loadSettings(auto: AddSettings, projectBase: File, loadedPlugins: sbt.LoadedPlugins, eval: ()=>Eval, injectSettings: InjectSettings, memoSettings: mutable.Map[File, LoadedSbtFile], autoPlugins: Seq[AutoPlugin], projectSettings: Seq[Setting[_]]): LoadedSbtFile =
{
lazy val defaultSbtFiles = configurationSources(projectBase)
def settings(ss: Seq[Setting[_]]) = new LoadedSbtFile(ss, Nil, Nil)
@ -506,7 +505,7 @@ object Load
def loadSettingsFile(src: File): LoadedSbtFile =
EvaluateConfigurations.evaluateSbtFile(eval(), src, IO.readLines(src), loadedPlugins.detected.imports, 0)(loader)
import AddSettings.{User,SbtFiles,DefaultSbtFiles,Plugins,Sequence}
import AddSettings.{User,SbtFiles,DefaultSbtFiles,Plugins,Sequence, ProjectSettings}
def pluginSettings(f: Plugins) = {
val included = loadedPlugins.detected.plugins.values.filter(f.include) // don't apply the filter to AutoPlugins, only Plugins
val oldStyle = included.flatMap(p => p.settings.filter(isProjectThis) ++ p.projectSettings)
@ -514,6 +513,7 @@ object Load
oldStyle ++ autoStyle
}
def expand(auto: AddSettings): LoadedSbtFile = auto match {
case ProjectSettings => settings(projectSettings)
case User => settings(injectSettings.projectLoaded(loader))
case sf: SbtFiles => loadSettings( sf.files.map(f => IO.resolve(projectBase, f)))
case sf: DefaultSbtFiles => loadSettings( defaultSbtFiles.filter(sf.include))