auto-compiler plugins

This commit is contained in:
Mark Harrah 2011-04-11 22:12:03 -04:00
parent 00722de739
commit 4b70fe0921
5 changed files with 46 additions and 16 deletions

View File

@ -7,7 +7,7 @@ package sbt
import Scope.{GlobalScope, ThisScope} import Scope.{GlobalScope, ThisScope}
import compiler.Discovery import compiler.Discovery
import Project.{inConfig, Initialize, inScope, inTask, ScopedKey, Setting} import Project.{inConfig, Initialize, inScope, inTask, ScopedKey, Setting}
import Configurations.{Compile => CompileConf, Test => TestConf} import Configurations.{Compile => CompileConf, CompilerPlugin, Test => TestConf}
import complete._ import complete._
import std.TaskExtra._ import std.TaskExtra._
@ -61,6 +61,7 @@ object Defaults
)) ))
def globalCore: Seq[Setting[_]] = inScope(GlobalScope)(Seq( def globalCore: Seq[Setting[_]] = inScope(GlobalScope)(Seq(
pollInterval :== 500, pollInterval :== 500,
autoCompilerPlugins :== true,
initialize :== (), initialize :== (),
credentials :== Nil, credentials :== Nil,
scalaHome :== None, scalaHome :== None,
@ -166,7 +167,7 @@ object Defaults
} }
def watchTransitiveSourcesTask: Initialize[Task[Seq[File]]] = def watchTransitiveSourcesTask: Initialize[Task[Seq[File]]] =
(state, thisProjectRef) flatMap { (s, base) => (state, thisProjectRef) flatMap { (s, base) =>
inAllDependencies(base, watchSources.setting, Project structure s).join.map(_.flatten) inAllDependencies(base, watchSources.task, Project structure s).join.map(_.flatten)
} }
def watchSourcesTask: Initialize[Task[Seq[File]]] = Seq(sources, resources).map(inAllConfigurations).join { _.join.map(_.flatten.flatten) } def watchSourcesTask: Initialize[Task[Seq[File]]] = Seq(sources, resources).map(inAllConfigurations).join { _.join.map(_.flatten.flatten) }
@ -410,7 +411,6 @@ object Defaults
val CompletionsID = "completions" val CompletionsID = "completions"
def noAggregation = Seq(run, console, consoleQuick, consoleProject) def noAggregation = Seq(run, console, consoleQuick, consoleProject)
lazy val disableAggregation = noAggregation map disableAggregate lazy val disableAggregation = noAggregation map disableAggregate
def disableAggregate(k: Scoped) = def disableAggregate(k: Scoped) =
@ -419,7 +419,7 @@ object Defaults
lazy val baseTasks: Seq[Setting[_]] = projectTasks ++ packageBase lazy val baseTasks: Seq[Setting[_]] = projectTasks ++ packageBase
lazy val baseClasspaths = Classpaths.publishSettings ++ Classpaths.baseSettings lazy val baseClasspaths = Classpaths.publishSettings ++ Classpaths.baseSettings
lazy val configSettings = Classpaths.configSettings ++ configTasks ++ configPaths ++ packageConfig lazy val configSettings = Classpaths.configSettings ++ configTasks ++ configPaths ++ packageConfig ++ Classpaths.compilerPluginConfig
lazy val compileSettings = configSettings ++ (mainRunMainTask +: mainRunTask +: addBaseSources) lazy val compileSettings = configSettings ++ (mainRunMainTask +: mainRunTask +: addBaseSources)
lazy val testSettings = configSettings ++ testTasks lazy val testSettings = configSettings ++ testTasks
@ -460,7 +460,7 @@ object Classpaths
val publishSettings: Seq[Setting[_]] = Seq( val publishSettings: Seq[Setting[_]] = Seq(
publishMavenStyle in GlobalScope :== true, publishMavenStyle in GlobalScope :== true,
packageToPublish <<= defaultPackageTasks.dependOn, packageToPublish <<= defaultPackageTasks.dependOn,
deliverDepends <<= (publishMavenStyle, makePom.setting, packageToPublish.setting) { (mavenStyle, mkpom, ptp) => deliverDepends <<= (publishMavenStyle, makePom.task, packageToPublish.task) { (mavenStyle, mkpom, ptp) =>
if(mavenStyle) mkpom.map(_ => ()) else ptp if(mavenStyle) mkpom.map(_ => ()) else ptp
}, },
makePom <<= (ivyModule, makePomConfiguration, packageToPublish, streams) map { (module, config, _, s) => IvyActions.makePom(module, config, s.log); config.file }, makePom <<= (ivyModule, makePomConfiguration, packageToPublish, streams) map { (module, config, _, s) => IvyActions.makePom(module, config, s.log); config.file },
@ -513,8 +513,11 @@ object Classpaths
val lock = app.provider.scalaProvider.launcher.globalLock val lock = app.provider.scalaProvider.launcher.globalLock
new InlineIvyConfiguration(paths, rs, other, moduleConfs, off, Some(lock), s.log) new InlineIvyConfiguration(paths, rs, other, moduleConfs, off, Some(lock), s.log)
}, },
moduleSettings <<= (projectID, allDependencies, ivyXML, thisProject, defaultConfiguration, ivyScala, ivyValidate) map { ivyConfigurations <<= (autoCompilerPlugins, thisProject) { (auto, project) =>
(pid, deps, ivyXML, project, defaultConf, ivyS, validate) => new InlineConfiguration(pid, deps, ivyXML, project.configurations, defaultConf, ivyS, validate) project.configurations ++ (if(auto) CompilerPlugin :: Nil else Nil)
},
moduleSettings <<= (projectID, allDependencies, ivyXML, ivyConfigurations, defaultConfiguration, ivyScala, ivyValidate) map {
(pid, deps, ivyXML, confs, defaultConf, ivyS, validate) => new InlineConfiguration(pid, deps, ivyXML, confs, defaultConf, ivyS, validate)
}, },
makePomConfiguration <<= pomFile(file => makePomConfigurationTask(file)), makePomConfiguration <<= pomFile(file => makePomConfigurationTask(file)),
publishConfiguration <<= (target, publishTo, ivyLoggingLevel, publishMavenStyle) map { (outputDirectory, publishTo, level, mavenStyle) => publishConfiguration <<= (target, publishTo, ivyLoggingLevel, publishMavenStyle) map { (outputDirectory, publishTo, level, mavenStyle) =>
@ -730,4 +733,28 @@ object Classpaths
import DependencyFilter._ import DependencyFilter._
def managedJars(config: Configuration, jarTypes: Set[String], up: UpdateReport): Classpath = up.select( configuration = configurationFilter(config.name), artifact = artifactFilter(`type` = jarTypes) ) def managedJars(config: Configuration, jarTypes: Set[String], up: UpdateReport): Classpath = up.select( configuration = configurationFilter(config.name), artifact = artifactFilter(`type` = jarTypes) )
def autoPlugins(inputs: Compiler.Inputs, report: UpdateReport): Compiler.Inputs =
inputs.copy(config = inputs.config.copy(options = autoPlugins(report) ++ inputs.config.options))
def autoPlugins(report: UpdateReport): Seq[String] =
{
val pluginClasspath = report matching configurationFilter(CompilerPlugin.name)
classpath.ClasspathUtilities.compilerPlugins(pluginClasspath).map("-Xplugin:" + _.getAbsolutePath).toSeq
}
lazy val compilerPluginConfig = Seq(
compileInputs <<= (compileInputs, autoCompilerPlugins, update) map { (inputs, auto, report) =>
if(auto) autoPlugins(inputs, report) else inputs
}
)
}
trait CompilerPluginExtra
{
def compilerPlugin(dependency: ModuleID): ModuleID =
dependency.copy(configurations = Some("plugin->default(compile)"))
def addCompilerPlugin(dependency: ModuleID): Setting[Seq[ModuleID]] =
libraryDependencies += compilerPlugin(dependency)
} }

View File

@ -66,6 +66,7 @@ object Keys
val crossPaths = SettingKey[Boolean]("cross-paths") val crossPaths = SettingKey[Boolean]("cross-paths")
// compile/doc keys // compile/doc keys
val autoCompilerPlugins = SettingKey[Boolean]("auto-compiler-plugins")
val maxErrors = SettingKey[Int]("max-errors") val maxErrors = SettingKey[Int]("max-errors")
val scaladocOptions = SettingKey[Seq[String]]("scaladoc-options") val scaladocOptions = SettingKey[Seq[String]]("scaladoc-options")
val scalacOptions = SettingKey[Seq[String]]("scalac-options") val scalacOptions = SettingKey[Seq[String]]("scalac-options")
@ -149,6 +150,7 @@ object Keys
val fullClasspath = TaskKey[Classpath]("full-classpath") val fullClasspath = TaskKey[Classpath]("full-classpath")
val ivyConfiguration = TaskKey[IvyConfiguration]("ivy-configuration") val ivyConfiguration = TaskKey[IvyConfiguration]("ivy-configuration")
val ivyConfigurations = SettingKey[Seq[Configuration]]("ivy-configurations")
val moduleSettings = TaskKey[ModuleSettings]("module-settings") val moduleSettings = TaskKey[ModuleSettings]("module-settings")
val unmanagedBase = SettingKey[File]("unmanaged-base") val unmanagedBase = SettingKey[File]("unmanaged-base")
val updateConfiguration = SettingKey[UpdateConfiguration]("update-configuration") val updateConfiguration = SettingKey[UpdateConfiguration]("update-configuration")

View File

@ -6,7 +6,7 @@ package sbt
/** An abstraction on top of Settings for build configuration and task definition. */ /** An abstraction on top of Settings for build configuration and task definition. */
import Types._ import Types._
import std.TaskExtra._ import std.TaskExtra.{task => mktask, _}
import Task._ import Task._
import Project.{Initialize, ScopedKey, Setting, setting} import Project.{Initialize, ScopedKey, Setting, setting}
import complete.Parser import complete.Parser
@ -151,7 +151,7 @@ object Scoped
final class RichInputScoped[T](val scope: Scope, val key: AttributeKey[InputTask[T]]) extends RichBaseScoped[InputTask[T]] final class RichInputScoped[T](val scope: Scope, val key: AttributeKey[InputTask[T]]) extends RichBaseScoped[InputTask[T]]
final class RichSettingScoped[S](val scope: Scope, val key: AttributeKey[S]) extends RichBaseScoped[S] final class RichSettingScoped[S](val scope: Scope, val key: AttributeKey[S]) extends RichBaseScoped[S]
{ {
def map[T](f: S => T): Initialize[Task[T]] = flatMap(s => task(f(s)) ) def map[T](f: S => T): Initialize[Task[T]] = flatMap(s => mktask(f(s)) )
def flatMap[T](f: S => Task[T]): Initialize[Task[T]] = Apply.single(scoped)(f) def flatMap[T](f: S => Task[T]): Initialize[Task[T]] = Apply.single(scoped)(f)
} }
final class RichTaskScoped[S](scope: Scope, key: AttributeKey[Task[S]]) final class RichTaskScoped[S](scope: Scope, key: AttributeKey[Task[S]])
@ -159,14 +159,14 @@ object Scoped
type ScS = Setting[Task[S]] type ScS = Setting[Task[S]]
def :==(value: S): ScS = :=(value) def :==(value: S): ScS = :=(value)
def ::=(value: Task[S]): ScS = Project.setting(scoped, Project.value( value )) def ::=(value: Task[S]): ScS = Project.setting(scoped, Project.value( value ))
def := (value: => S): ScS = ::=(task(value)) def := (value: => S): ScS = ::=(mktask(value))
def :== (v: ScopedTask[S]): ScS = Project.setting(scoped, Project.app(ScopedKey(v.scope, v.key) :^: KNil)(_.head) ) def :== (v: ScopedTask[S]): ScS = Project.setting(scoped, Project.app(ScopedKey(v.scope, v.key) :^: KNil)(_.head) )
def :== (v: ScopedSetting[S]): ScS = <<=( v(const)) def :== (v: ScopedSetting[S]): ScS = <<=( v(const))
def ~= (f: S => S): ScS = Project.update(scoped)( _ map f ) def ~= (f: S => S): ScS = Project.update(scoped)( _ map f )
def <<= (app: App[S]): ScS = Project.setting(scoped, app) def <<= (app: App[S]): ScS = Project.setting(scoped, app)
def setting: ScopedSetting[Task[S]] = scopedSetting(scope, key) def task: ScopedSetting[Task[S]] = scopedSetting(scope, key)
def get(settings: Settings[Scope]): Option[Task[S]] = settings.get(scope, key) def get(settings: Settings[Scope]): Option[Task[S]] = settings.get(scope, key)
type App[T] = Initialize[Task[T]] type App[T] = Initialize[Task[T]]

View File

@ -22,10 +22,10 @@ object Compiler
case _ => Nil case _ => Nil
} }
final class Inputs(val compilers: Compilers, val config: Options, val incSetup: IncSetup) final case class Inputs(compilers: Compilers, config: Options, incSetup: IncSetup)
final class Options(val classpath: Seq[File], val sources: Seq[File], val classesDirectory: File, val options: Seq[String], val javacOptions: Seq[String], val maxErrors: Int, val order: CompileOrder.Value) final case class Options(classpath: Seq[File], sources: Seq[File], classesDirectory: File, options: Seq[String], javacOptions: Seq[String], maxErrors: Int, order: CompileOrder.Value)
final class IncSetup(val analysisMap: Map[File, Analysis], val cacheDirectory: File) final case class IncSetup(analysisMap: Map[File, Analysis], cacheDirectory: File)
final class Compilers(val scalac: AnalyzingCompiler, val javac: JavaCompiler) final case class Compilers(scalac: AnalyzingCompiler, javac: JavaCompiler)
def inputs(classpath: Seq[File], sources: Seq[File], outputDirectory: File, options: Seq[String], javacOptions: Seq[String], maxErrors: Int, order: CompileOrder.Value)(implicit compilers: Compilers, log: Logger): Inputs = def inputs(classpath: Seq[File], sources: Seq[File], outputDirectory: File, options: Seq[String], javacOptions: Seq[String], maxErrors: Int, order: CompileOrder.Value)(implicit compilers: Compilers, log: Logger): Inputs =
{ {

View File

@ -1,7 +1,8 @@
/* sbt -- Simple Build Tool /* sbt -- Simple Build Tool
* Copyright 2010, 2011 Mark Harrah * Copyright 2010, 2011 Mark Harrah
*/ */
package object sbt extends sbt.std.TaskExtra with sbt.Types with sbt.ProcessExtra with sbt.impl.DependencyBuilders with sbt.PathExtra with sbt.ProjectExtra with sbt.DependencyFilterExtra package object sbt extends sbt.std.TaskExtra with sbt.Types with sbt.ProcessExtra with sbt.impl.DependencyBuilders
with sbt.PathExtra with sbt.ProjectExtra with sbt.DependencyFilterExtra with sbt.CompilerPluginExtra
{ {
type Setting[T] = Project.Setting[T] type Setting[T] = Project.Setting[T]
type ScopedKey[T] = Project.ScopedKey[T] type ScopedKey[T] = Project.ScopedKey[T]