Merge pull request #2844 from dwijnand/reunite

Add props to define source dependencies on io/util/lm/zinc
This commit is contained in:
eugene yokota 2016-12-11 21:59:57 -05:00 committed by GitHub
commit d9cc0c2f0b
60 changed files with 602 additions and 453 deletions

View File

@ -105,8 +105,9 @@ lazy val testingProj = (project in file("testing")).
settings( settings(
baseSettings, baseSettings,
name := "Testing", name := "Testing",
libraryDependencies ++= Seq(sbtIO, testInterface,launcherInterface, compilerClasspath, utilLogging) libraryDependencies ++= Seq(testInterface,launcherInterface)
) ).
configure(addSbtIO, addSbtCompilerClasspath, addSbtUtilLogging)
// Testing agent for running tests in a separate process. // Testing agent for running tests in a separate process.
lazy val testAgentProj = (project in file("testing") / "agent"). lazy val testAgentProj = (project in file("testing") / "agent").
@ -123,9 +124,9 @@ lazy val testAgentProj = (project in file("testing") / "agent").
lazy val taskProj = (project in file("tasks")). lazy val taskProj = (project in file("tasks")).
settings( settings(
testedBaseSettings, testedBaseSettings,
name := "Tasks", name := "Tasks"
libraryDependencies ++= Seq(utilControl, utilCollection) ).
) configure(addSbtUtilControl, addSbtUtilCollection)
// Standard task system. This provides map, flatMap, join, and more on top of the basic task model. // Standard task system. This provides map, flatMap, join, and more on top of the basic task model.
lazy val stdTaskProj = (project in file("tasks-standard")). lazy val stdTaskProj = (project in file("tasks-standard")).
@ -133,46 +134,45 @@ lazy val stdTaskProj = (project in file("tasks-standard")).
settings( settings(
testedBaseSettings, testedBaseSettings,
name := "Task System", name := "Task System",
testExclusive, testExclusive
libraryDependencies ++= Seq(utilCollection, utilLogging, sbtIO) ).
) configure(addSbtUtilCollection, addSbtUtilLogging, addSbtIO)
// Embedded Scala code runner // Embedded Scala code runner
lazy val runProj = (project in file("run")). lazy val runProj = (project in file("run")).
settings( settings(
testedBaseSettings, testedBaseSettings,
name := "Run", name := "Run"
libraryDependencies ++= Seq(sbtIO, ).
utilLogging, compilerClasspath) configure(addSbtIO, addSbtUtilLogging, addSbtCompilerClasspath)
)
lazy val scriptedSbtProj = (project in scriptedPath / "sbt"). lazy val scriptedSbtProj = (project in scriptedPath / "sbt").
dependsOn(commandProj). dependsOn(commandProj).
settings( settings(
baseSettings, baseSettings,
name := "Scripted sbt", name := "Scripted sbt",
libraryDependencies ++= Seq(launcherInterface % "provided", libraryDependencies ++= Seq(launcherInterface % "provided")
sbtIO, utilLogging, compilerInterface, utilScripted) ).
) configure(addSbtIO, addSbtUtilLogging, addSbtCompilerInterface, addSbtUtilScripted)
lazy val scriptedPluginProj = (project in scriptedPath / "plugin"). lazy val scriptedPluginProj = (project in scriptedPath / "plugin").
dependsOn(sbtProj). dependsOn(sbtProj).
settings( settings(
baseSettings, baseSettings,
name := "Scripted Plugin", name := "Scripted Plugin"
libraryDependencies ++= Seq(compilerClasspath) ).
) configure(addSbtCompilerClasspath)
// Implementation and support code for defining actions. // Implementation and support code for defining actions.
lazy val actionsProj = (project in file("main-actions")). lazy val actionsProj = (project in file("main-actions")).
dependsOn(runProj, stdTaskProj, taskProj, testingProj). dependsOn(runProj, stdTaskProj, taskProj, testingProj).
settings( settings(
testedBaseSettings, testedBaseSettings,
name := "Actions", name := "Actions"
libraryDependencies ++= Seq(compilerClasspath, utilCompletion, compilerApiInfo, ).
zinc, compilerIvyIntegration, compilerInterface, configure(addSbtCompilerClasspath, addSbtUtilCompletion, addSbtCompilerApiInfo,
sbtIO, utilLogging, utilRelation, libraryManagement, utilTracking) addSbtZinc, addSbtCompilerIvyIntegration, addSbtCompilerInterface,
) addSbtIO, addSbtUtilLogging, addSbtUtilRelation, addSbtLm, addSbtUtilTracking)
// General command support and core commands not specific to a build system // General command support and core commands not specific to a build system
lazy val commandProj = (project in file("main-command")). lazy val commandProj = (project in file("main-command")).
@ -180,30 +180,31 @@ lazy val commandProj = (project in file("main-command")).
settings( settings(
testedBaseSettings, testedBaseSettings,
name := "Command", name := "Command",
libraryDependencies ++= Seq(launcherInterface, compilerInterface, libraryDependencies ++= Seq(launcherInterface, sjsonNewScalaJson),
sbtIO, utilLogging, utilCompletion, compilerClasspath, sjsonNewScalaJson),
sourceManaged in (Compile, generateDatatypes) := baseDirectory.value / "src" / "main" / "datatype-scala" sourceManaged in (Compile, generateDatatypes) := baseDirectory.value / "src" / "main" / "datatype-scala"
) ).
configure(addSbtCompilerInterface, addSbtIO, addSbtUtilLogging, addSbtUtilCompletion, addSbtCompilerClasspath)
// Fixes scope=Scope for Setting (core defined in collectionProj) to define the settings system used in build definitions // Fixes scope=Scope for Setting (core defined in collectionProj) to define the settings system used in build definitions
lazy val mainSettingsProj = (project in file("main-settings")). lazy val mainSettingsProj = (project in file("main-settings")).
dependsOn(commandProj, stdTaskProj). dependsOn(commandProj, stdTaskProj).
settings( settings(
testedBaseSettings, testedBaseSettings,
name := "Main Settings", name := "Main Settings"
libraryDependencies ++= Seq(utilCache, utilApplyMacro, compilerInterface, utilRelation, ).
utilLogging, sbtIO, utilCompletion, compilerClasspath, libraryManagement) configure(addSbtUtilCache, addSbtUtilApplyMacro, addSbtCompilerInterface, addSbtUtilRelation,
) addSbtUtilLogging, addSbtIO, addSbtUtilCompletion, addSbtCompilerClasspath, addSbtLm)
// The main integration project for sbt. It brings all of the Projsystems together, configures them, and provides for overriding conventions. // The main integration project for sbt. It brings all of the projects together, configures them, and provides for overriding conventions.
lazy val mainProj = (project in file("main")). lazy val mainProj = (project in file("main")).
dependsOn(actionsProj, mainSettingsProj, runProj, commandProj). dependsOn(actionsProj, mainSettingsProj, runProj, commandProj).
settings( settings(
testedBaseSettings, testedBaseSettings,
name := "Main", name := "Main",
libraryDependencies ++= scalaXml.value ++ Seq(launcherInterface, compilerInterface, libraryDependencies ++= scalaXml.value ++ Seq(launcherInterface)
sbtIO, utilLogging, utilLogic, libraryManagement, zincCompile) ).
) configure(addSbtCompilerInterface,
addSbtIO, addSbtUtilLogging, addSbtUtilLogic, addSbtLm, addSbtZincCompile)
// Strictly for bringing implicits and aliases from subsystems into the top-level sbt namespace through a single package object // Strictly for bringing implicits and aliases from subsystems into the top-level sbt namespace through a single package object
// technically, we need a dependency on all of mainProj's dependencies, but we don't do that since this is strictly an integration project // technically, we need a dependency on all of mainProj's dependencies, but we don't do that since this is strictly an integration project
@ -215,9 +216,9 @@ lazy val sbtProj = (project in file("sbt")).
name := "sbt", name := "sbt",
normalizedName := "sbt", normalizedName := "sbt",
crossScalaVersions := Seq(scala211), crossScalaVersions := Seq(scala211),
crossPaths := false, crossPaths := false
libraryDependencies ++= Seq(compilerBrdige) ).
) configure(addSbtCompilerBridge)
def scriptedTask: Def.Initialize[InputTask[Unit]] = Def.inputTask { def scriptedTask: Def.Initialize[InputTask[Unit]] = Def.inputTask {
val result = scriptedSource(dir => (s: State) => Scripted.scriptedParser(dir)).parsed val result = scriptedSource(dir => (s: State) => Scripted.scriptedParser(dir)).parsed

View File

@ -74,7 +74,8 @@ object CacheIvy {
implicit def moduleReportFormat(implicit cf: Format[Seq[Caller]], ff: Format[File]): Format[ModuleReport] = { implicit def moduleReportFormat(implicit cf: Format[Seq[Caller]], ff: Format[File]): Format[ModuleReport] = {
wrap[ModuleReport, (ModuleID, Seq[(Artifact, File)], Seq[Artifact], Option[String], Option[Long], Option[String], Option[String], Boolean, Option[String], Option[String], Option[String], Option[String], Map[String, String], Option[Boolean], Option[String], Seq[String], Seq[(String, Option[String])], Seq[Caller])]( wrap[ModuleReport, (ModuleID, Seq[(Artifact, File)], Seq[Artifact], Option[String], Option[Long], Option[String], Option[String], Boolean, Option[String], Option[String], Option[String], Option[String], Map[String, String], Option[Boolean], Option[String], Seq[String], Seq[(String, Option[String])], Seq[Caller])](
m => (m.module, m.artifacts, m.missingArtifacts, m.status, m.publicationDate map { _.getTime }, m.resolver, m.artifactResolver, m.evicted, m.evictedData, m.evictedReason, m.problem, m.homepage, m.extraAttributes, m.isDefault, m.branch, m.configurations, m.licenses, m.callers), m => (m.module, m.artifacts, m.missingArtifacts, m.status, m.publicationDate map { _.getTime }, m.resolver, m.artifactResolver, m.evicted, m.evictedData, m.evictedReason, m.problem, m.homepage, m.extraAttributes, m.isDefault, m.branch, m.configurations, m.licenses, m.callers),
{ case (m, as, ms, s, pd, r, a, e, ed, er, p, h, ea, d, b, cs, ls, ks) => new ModuleReport(m, as, ms, s, pd map { new ju.Date(_) }, r, a, e, ed, er, p, h, ea, d, b, cs, ls, ks) }) { case (m, as, ms, s, pd, r, a, e, ed, er, p, h, ea, d, b, cs, ls, ks) => new ModuleReport(m, as, ms, s, pd map { new ju.Date(_) }, r, a, e, ed, er, p, h, ea, d, b, cs, ls, ks) }
)
} }
implicit def artifactFormat(implicit sf: Format[String], uf: Format[Option[URL]]): Format[Artifact] = { implicit def artifactFormat(implicit sf: Format[String], uf: Format[Option[URL]]): Format[Artifact] = {
wrap[Artifact, (String, String, String, Option[String], Seq[Configuration], Option[URL], Map[String, String])]( wrap[Artifact, (String, String, String, Option[String], Seq[Configuration], Option[URL], Map[String, String])](
@ -85,8 +86,10 @@ object CacheIvy {
implicit def organizationArtifactReportFormat(implicit sf: Format[String], bf: Format[Boolean], df: Format[Seq[ModuleReport]]): Format[OrganizationArtifactReport] = implicit def organizationArtifactReportFormat(implicit sf: Format[String], bf: Format[Boolean], df: Format[Seq[ModuleReport]]): Format[OrganizationArtifactReport] =
wrap[OrganizationArtifactReport, (String, String, Seq[ModuleReport])](m => (m.organization, m.name, m.modules), { case (o, n, r) => OrganizationArtifactReport(o, n, r) }) wrap[OrganizationArtifactReport, (String, String, Seq[ModuleReport])](m => (m.organization, m.name, m.modules), { case (o, n, r) => OrganizationArtifactReport(o, n, r) })
implicit def callerFormat: Format[Caller] = implicit def callerFormat: Format[Caller] =
wrap[Caller, (ModuleID, Seq[String], Map[String, String], Boolean, Boolean, Boolean, Boolean)](c => (c.caller, c.callerConfigurations, c.callerExtraAttributes, c.isForceDependency, c.isChangingDependency, c.isTransitiveDependency, c.isDirectlyForceDependency), wrap[Caller, (ModuleID, Seq[String], Map[String, String], Boolean, Boolean, Boolean, Boolean)](
{ case (c, cc, ea, fd, cd, td, df) => new Caller(c, cc, ea, fd, cd, td, df) }) c => (c.caller, c.callerConfigurations, c.callerExtraAttributes, c.isForceDependency, c.isChangingDependency, c.isTransitiveDependency, c.isDirectlyForceDependency),
{ case (c, cc, ea, fd, cd, td, df) => new Caller(c, cc, ea, fd, cd, td, df) }
)
implicit def exclusionRuleFormat(implicit sf: Format[String]): Format[InclExclRule] = implicit def exclusionRuleFormat(implicit sf: Format[String]): Format[InclExclRule] =
wrap[InclExclRule, (String, String, String, Seq[String])](e => (e.organization, e.name, e.artifact, e.configurations), { case (o, n, a, cs) => InclExclRule(o, n, a, cs) }) wrap[InclExclRule, (String, String, String, Seq[String])](e => (e.organization, e.name, e.artifact, e.configurations), { case (o, n, a, cs) => InclExclRule(o, n, a, cs) })
implicit def crossVersionFormat: Format[CrossVersion] = wrap(crossToInt, crossFromInt) implicit def crossVersionFormat: Format[CrossVersion] = wrap(crossToInt, crossFromInt)

View File

@ -18,7 +18,7 @@ object Compiler {
private[sbt] def defaultCompilerBridgeSource(sv: String): ModuleID = private[sbt] def defaultCompilerBridgeSource(sv: String): ModuleID =
VersionNumber(sv) match { VersionNumber(sv) match {
case VersionNumber(ns, _, _) if (ns.size == 3) && (ns(0) == 2) && (ns(1) <= 10) => scalaCompilerBridgeSource2_10 case VersionNumber(ns, _, _) if (ns.size == 3) && (ns(0) == 2) && (ns(1) <= 10) => scalaCompilerBridgeSource2_10
case _ => scalaCompilerBridgeSource2_11 case _ => scalaCompilerBridgeSource2_11
} }
private[sbt] def scalaCompilerBridgeSource2_10: ModuleID = private[sbt] def scalaCompilerBridgeSource2_10: ModuleID =
ModuleID(xsbti.ArtifactInfo.SbtOrganization, "compiler-bridge_2.10", ModuleID(xsbti.ArtifactInfo.SbtOrganization, "compiler-bridge_2.10",

View File

@ -24,11 +24,13 @@ object Doc {
def javadoc(label: String, cache: File, doc: JavaTools, log: Logger, reporter: Reporter): Gen = def javadoc(label: String, cache: File, doc: JavaTools, log: Logger, reporter: Reporter): Gen =
javadoc(label, cache, doc, log, reporter, Seq()) javadoc(label, cache, doc, log, reporter, Seq())
def javadoc(label: String, cache: File, doc: JavaTools, log: Logger, reporter: Reporter, fileInputOptions: Seq[String]): Gen = def javadoc(label: String, cache: File, doc: JavaTools, log: Logger, reporter: Reporter, fileInputOptions: Seq[String]): Gen =
cached(cache, fileInputOptions, prepare(label + " Java API documentation", filterSources(javaSourcesOnly, cached(cache, fileInputOptions, prepare(label + " Java API documentation", filterSources(
javaSourcesOnly,
(sources: Seq[File], classpath: Seq[File], outputDirectory: File, options: Seq[String], maxErrors: Int, log: Logger) => { (sources: Seq[File], classpath: Seq[File], outputDirectory: File, options: Seq[String], maxErrors: Int, log: Logger) => {
// doc.doc // doc.doc
??? ???
}))) }
)))
val javaSourcesOnly: File => Boolean = _.getName.endsWith(".java") val javaSourcesOnly: File => Boolean = _.getName.endsWith(".java")

View File

@ -77,7 +77,8 @@ object TestResultLogger {
printSummary: TestResultLogger = Defaults.printSummary, printSummary: TestResultLogger = Defaults.printSummary,
printStandard: TestResultLogger = Defaults.printStandard, printStandard: TestResultLogger = Defaults.printStandard,
printFailures: TestResultLogger = Defaults.printFailures, printFailures: TestResultLogger = Defaults.printFailures,
printNoTests: TestResultLogger = Defaults.printNoTests) extends TestResultLogger { printNoTests: TestResultLogger = Defaults.printNoTests
) extends TestResultLogger {
override def run(log: Logger, results: Output, taskName: String): Unit = { override def run(log: Logger, results: Output, taskName: String): Unit = {
def run(r: TestResultLogger): Unit = r.run(log, results, taskName) def run(r: TestResultLogger): Unit = r.run(log, results, taskName)
@ -154,7 +155,6 @@ object TestResultLogger {
}) })
val printNoTests = TestResultLogger((log, results, taskName) => val printNoTests = TestResultLogger((log, results, taskName) =>
log.info("No tests to run for " + taskName) log.info("No tests to run for " + taskName))
)
} }
} }

View File

@ -120,7 +120,8 @@ object Tests {
val tests: Seq[TestDefinition], val tests: Seq[TestDefinition],
val setup: Seq[ClassLoader => Unit], val setup: Seq[ClassLoader => Unit],
val cleanup: Seq[ClassLoader => Unit], val cleanup: Seq[ClassLoader => Unit],
val testListeners: Seq[TestReportListener]) val testListeners: Seq[TestReportListener]
)
private[sbt] def processOptions(config: Execution, discovered: Seq[TestDefinition], log: Logger): ProcessedOptions = private[sbt] def processOptions(config: Execution, discovered: Seq[TestDefinition], log: Logger): ProcessedOptions =
{ {
import collection.mutable.{ HashSet, ListBuffer } import collection.mutable.{ HashSet, ListBuffer }

View File

@ -229,7 +229,7 @@ final class Eval(optionsNoncp: Seq[String], classpath: Seq[File], mkReporter: Se
def getType(t: Tree) = { result = ""; traverse(t); result } def getType(t: Tree) = { result = ""; traverse(t); result }
override def traverse(tree: Tree): Unit = tree match { override def traverse(tree: Tree): Unit = tree match {
case d: DefDef if d.symbol.nameString == WrapValName => result = d.symbol.tpe.finalResultType.toString case d: DefDef if d.symbol.nameString == WrapValName => result = d.symbol.tpe.finalResultType.toString
case _ => super.traverse(tree) case _ => super.traverse(tree)
} }
} }
/** Tree traverser that obtains the names of vals in a top-level module whose type is a subtype of one of `types`.*/ /** Tree traverser that obtains the names of vals in a top-level module whose type is a subtype of one of `types`.*/

View File

@ -55,7 +55,8 @@ class CacheIvyTest extends Properties("CacheIvy") {
} yield ModuleID( } yield ModuleID(
organization = o, name = n, revision = r, configurations = cs, isChanging = isChanging, isTransitive = isTransitive, organization = o, name = n, revision = r, configurations = cs, isChanging = isChanging, isTransitive = isTransitive,
isForce = isForce, explicitArtifacts = explicitArtifacts, inclusions = inclusions, exclusions = exclusions, isForce = isForce, explicitArtifacts = explicitArtifacts, inclusions = inclusions, exclusions = exclusions,
extraAttributes = extraAttributes, crossVersion = crossVersion, branchName = branch) extraAttributes = extraAttributes, crossVersion = crossVersion, branchName = branch
)
} }
property("moduleIDFormat") = forAll { (m: ModuleID) => property("moduleIDFormat") = forAll { (m: ModuleID) =>

View File

@ -78,7 +78,7 @@ object MainLoop {
Logger.transferLevels(old.backed, logging.backed) Logger.transferLevels(old.backed, logging.backed)
(old.full, logging.full) match { // well, this is a hack (old.full, logging.full) match { // well, this is a hack
case (oldLog: AbstractLogger, newLog: AbstractLogger) => Logger.transferLevels(oldLog, newLog) case (oldLog: AbstractLogger, newLog: AbstractLogger) => Logger.transferLevels(oldLog, newLog)
case _ => () case _ => ()
} }
} }

View File

@ -32,7 +32,8 @@ final case class State(
history: State.History, history: State.History,
attributes: AttributeMap, attributes: AttributeMap,
globalLogging: GlobalLogging, globalLogging: GlobalLogging,
next: State.Next) extends Identity { next: State.Next
) extends Identity {
lazy val combinedParser = Command.combine(definedCommands)(this) lazy val combinedParser = Command.combine(definedCommands)(this)
} }

View File

@ -38,7 +38,6 @@ private[sbt] final class NetworkChannel extends CommandChannel {
server.publish( server.publish(
if (cmdStatus.canEnter) StatusEvent(Ready) if (cmdStatus.canEnter) StatusEvent(Ready)
else StatusEvent(Processing("TODO current command", cmdStatus.state.remainingCommands)) else StatusEvent(Processing("TODO current command", cmdStatus.state.remainingCommands))
) ))
)
} }
} }

View File

@ -24,21 +24,29 @@ object Serialization {
def toMessage(event: Event): EventMessage = def toMessage(event: Event): EventMessage =
event match { event match {
case LogEvent(level, message) => case LogEvent(level, message) =>
EventMessage(`type` = "logEvent", EventMessage(
`type` = "logEvent",
status = None, commandQueue = Vector(), status = None, commandQueue = Vector(),
level = Some(level), message = Some(message), success = None, commandLine = None) level = Some(level), message = Some(message), success = None, commandLine = None
)
case StatusEvent(Ready) => case StatusEvent(Ready) =>
EventMessage(`type` = "statusEvent", EventMessage(
`type` = "statusEvent",
status = Some("ready"), commandQueue = Vector(), status = Some("ready"), commandQueue = Vector(),
level = None, message = None, success = None, commandLine = None) level = None, message = None, success = None, commandLine = None
)
case StatusEvent(Processing(command, commandQueue)) => case StatusEvent(Processing(command, commandQueue)) =>
EventMessage(`type` = "statusEvent", EventMessage(
`type` = "statusEvent",
status = Some("processing"), commandQueue = commandQueue.toVector, status = Some("processing"), commandQueue = commandQueue.toVector,
level = None, message = None, success = None, commandLine = None) level = None, message = None, success = None, commandLine = None
)
case ExecutionEvent(command, status) => case ExecutionEvent(command, status) =>
EventMessage(`type` = "executionEvent", EventMessage(
`type` = "executionEvent",
status = None, commandQueue = Vector(), status = None, commandQueue = Vector(),
level = None, message = None, success = Some(status), commandLine = Some(command)) level = None, message = None, success = Some(status), commandLine = Some(command)
)
} }
/** /**

View File

@ -20,8 +20,7 @@ final class InputTask[T] private (val parser: State => Parser[Task[T]]) {
case Left(msg) => case Left(msg) =>
val indented = msg.lines.map(" " + _).mkString("\n") val indented = msg.lines.map(" " + _).mkString("\n")
Parser.failure(s"Invalid programmatic input:\n$indented") Parser.failure(s"Invalid programmatic input:\n$indented")
} })
)
} }
object InputTask { object InputTask {
@ -38,9 +37,7 @@ object InputTask {
case Left(msg) => case Left(msg) =>
val indented = msg.lines.map(" " + _).mkString("\n") val indented = msg.lines.map(" " + _).mkString("\n")
sys.error(s"Invalid programmatic input:\n$indented") sys.error(s"Invalid programmatic input:\n$indented")
} }))
)
)
) )
} }

View File

@ -142,7 +142,8 @@ object Scope {
projectInherit: ProjectRef => Seq[ProjectRef], projectInherit: ProjectRef => Seq[ProjectRef],
configInherit: (ResolvedReference, ConfigKey) => Seq[ConfigKey], configInherit: (ResolvedReference, ConfigKey) => Seq[ConfigKey],
taskInherit: AttributeKey[_] => Seq[AttributeKey[_]], taskInherit: AttributeKey[_] => Seq[AttributeKey[_]],
extraInherit: (ResolvedReference, AttributeMap) => Seq[AttributeMap]): Scope => Seq[Scope] = extraInherit: (ResolvedReference, AttributeMap) => Seq[AttributeMap]
): Scope => Seq[Scope] =
{ {
val index = delegates(refs, configurations, projectInherit, configInherit) val index = delegates(refs, configurations, projectInherit, configInherit)
scope => indexedDelegates(resolve, index, rootProject, taskInherit, extraInherit)(scope) scope => indexedDelegates(resolve, index, rootProject, taskInherit, extraInherit)(scope)
@ -153,7 +154,8 @@ object Scope {
index: DelegateIndex, index: DelegateIndex,
rootProject: URI => String, rootProject: URI => String,
taskInherit: AttributeKey[_] => Seq[AttributeKey[_]], taskInherit: AttributeKey[_] => Seq[AttributeKey[_]],
extraInherit: (ResolvedReference, AttributeMap) => Seq[AttributeMap])(rawScope: Scope): Seq[Scope] = extraInherit: (ResolvedReference, AttributeMap) => Seq[AttributeMap]
)(rawScope: Scope): Seq[Scope] =
{ {
val scope = Scope.replaceThis(GlobalScope)(rawScope) val scope = Scope.replaceThis(GlobalScope)(rawScope)
@ -190,7 +192,8 @@ object Scope {
refs: Seq[(ProjectRef, Proj)], refs: Seq[(ProjectRef, Proj)],
configurations: Proj => Seq[ConfigKey], configurations: Proj => Seq[ConfigKey],
projectInherit: ProjectRef => Seq[ProjectRef], projectInherit: ProjectRef => Seq[ProjectRef],
configInherit: (ResolvedReference, ConfigKey) => Seq[ConfigKey]): DelegateIndex = configInherit: (ResolvedReference, ConfigKey) => Seq[ConfigKey]
): DelegateIndex =
{ {
val pDelegates = refs map { val pDelegates = refs map {
case (ref, project) => case (ref, project) =>

View File

@ -199,7 +199,7 @@ object ParserInput {
private def wrapInitInputTask[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree, pos: c.Position) = { private def wrapInitInputTask[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree, pos: c.Position) = {
val e = c.Expr[Initialize[InputTask[T]]](tree) val e = c.Expr[Initialize[InputTask[T]]](tree)
wrapInit[Task[T]](c)(c.universe.reify {Def.toIParser(e.splice)}, pos) wrapInit[Task[T]](c)(c.universe.reify { Def.toIParser(e.splice) }, pos)
} }
/** Implements `Parser[T].parsed` by wrapping the Parser with the ParserInput wrapper.*/ /** Implements `Parser[T].parsed` by wrapping the Parser with the ParserInput wrapper.*/
@ -216,12 +216,12 @@ object ParserInput {
private def wrapParser[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree, pos: c.Position) = { private def wrapParser[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree, pos: c.Position) = {
val e = c.Expr[Parser[T]](tree) val e = c.Expr[Parser[T]](tree)
wrap[T](c)(c.universe.reify {Def.toSParser(e.splice)}, pos) wrap[T](c)(c.universe.reify { Def.toSParser(e.splice) }, pos)
} }
private def wrapInitParser[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree, pos: c.Position) = { private def wrapInitParser[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree, pos: c.Position) = {
val e = c.Expr[Initialize[Parser[T]]](tree) val e = c.Expr[Initialize[Parser[T]]](tree)
val es = c.universe.reify {Def.toISParser(e.splice)} val es = c.universe.reify { Def.toISParser(e.splice) }
wrapInit[T](c)(es, pos) wrapInit[T](c)(es, pos)
} }

View File

@ -33,8 +33,8 @@ private[sbt] object KeyMacro {
def enclosingVal(trees: List[c.Tree]): String = def enclosingVal(trees: List[c.Tree]): String =
{ {
trees match { trees match {
case vd @ ValDef(_, name, _, _) :: ts => processName(name) case vd @ ValDef(_, name, _, _) :: ts => processName(name)
case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs) case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs)
// lazy val x: X = <methodName> has this form for some reason (only when the explicit type is present, though) // lazy val x: X = <methodName> has this form for some reason (only when the explicit type is present, though)
case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: xs if mods.hasFlag(Flag.LAZY) => processName(name) case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: xs if mods.hasFlag(Flag.LAZY) => processName(name)
case _ => case _ =>

View File

@ -54,11 +54,9 @@ object FullInstance extends Instance.Composed[Initialize, Task](InitializeInstan
def flattenFun[S, T](in: Initialize[Task[S => Initialize[Task[T]]]]): Initialize[S => Task[T]] = def flattenFun[S, T](in: Initialize[Task[S => Initialize[Task[T]]]]): Initialize[S => Task[T]] =
{ {
import Scoped._ import Scoped._
(in, settingsData, Def.capturedTransformations) apply { (in, settingsData, Def.capturedTransformations) apply { (a: Task[S => Initialize[Task[T]]], data: Task[SS], f) => (s: S) =>
(a: Task[S => Initialize[Task[T]]], data: Task[SS], f) => import TaskExtra.multT2Task
(s: S) => (a, data) flatMap { case (af, d) => f(af(s)) evaluate d }
import TaskExtra.multT2Task
(a, data) flatMap { case (af, d) => f(af(s)) evaluate d }
} }
} }
} }

View File

@ -265,7 +265,8 @@ object Defaults extends BuildCommon {
def compileBase = inTask(console)(compilersSetting :: Nil) ++ compileBaseGlobal ++ Seq( def compileBase = inTask(console)(compilersSetting :: Nil) ++ compileBaseGlobal ++ Seq(
incOptions := incOptions.value.withClassfileManagerType( incOptions := incOptions.value.withClassfileManagerType(
Maybe.just(new TransactionalManagerType(crossTarget.value / "classes.bak", sbt.util.Logger.Null))), Maybe.just(new TransactionalManagerType(crossTarget.value / "classes.bak", sbt.util.Logger.Null))
),
scalaInstance := scalaInstanceTask.value, scalaInstance := scalaInstanceTask.value,
crossVersion := (if (crossPaths.value) CrossVersion.binary else CrossVersion.Disabled), crossVersion := (if (crossPaths.value) CrossVersion.binary else CrossVersion.Disabled),
crossTarget := makeCrossTarget(target.value, scalaBinaryVersion.value, sbtBinaryVersion.value, sbtPlugin.value, crossPaths.value), crossTarget := makeCrossTarget(target.value, scalaBinaryVersion.value, sbtBinaryVersion.value, sbtPlugin.value, crossPaths.value),
@ -678,7 +679,8 @@ object Defaults extends BuildCommon {
} }
)) ++ )) ++
inTask(packageSrc)(Seq( inTask(packageSrc)(Seq(
packageOptions := Package.addSpecManifestAttributes(name.value, version.value, organizationName.value) +: packageOptions.value)) ++ packageOptions := Package.addSpecManifestAttributes(name.value, version.value, organizationName.value) +: packageOptions.value
)) ++
packageTaskSettings(packageBin, packageBinMappings) ++ packageTaskSettings(packageBin, packageBinMappings) ++
packageTaskSettings(packageSrc, packageSrcMappings) ++ packageTaskSettings(packageSrc, packageSrcMappings) ++
packageTaskSettings(packageDoc, packageDocMappings) ++ packageTaskSettings(packageDoc, packageDocMappings) ++
@ -947,7 +949,8 @@ object Defaults extends BuildCommon {
(compilerReporter in compile).value, (compilerReporter in compile).value,
o2m(None), o2m(None),
// TODO - task / setting for extra, // TODO - task / setting for extra,
Array.empty) Array.empty
)
} }
def compileInputsSettings: Seq[Setting[_]] = { def compileInputsSettings: Seq[Setting[_]] = {
Seq( Seq(
@ -959,13 +962,15 @@ object Defaults extends BuildCommon {
javacOptions.value.toArray, javacOptions.value.toArray,
maxErrors.value, maxErrors.value,
f1(Compiler.foldMappers(sourcePositionMappers.value)), f1(Compiler.foldMappers(sourcePositionMappers.value)),
compileOrder.value), compileOrder.value
),
compilerReporter := new LoggerReporter(maxErrors.value, streams.value.log, Compiler.foldMappers(sourcePositionMappers.value)), compilerReporter := new LoggerReporter(maxErrors.value, streams.value.log, Compiler.foldMappers(sourcePositionMappers.value)),
compileInputs := new Inputs( compileInputs := new Inputs(
compilers.value, compilers.value,
compileOptions.value, compileOptions.value,
compileIncSetup.value, compileIncSetup.value,
previousCompile.value) previousCompile.value
)
) )
} }
def compileAnalysisSettings: Seq[Setting[_]] = Seq( def compileAnalysisSettings: Seq[Setting[_]] = Seq(
@ -1484,8 +1489,8 @@ object Classpaths {
import UpdateLogging.{ Full, DownloadOnly, Default } import UpdateLogging.{ Full, DownloadOnly, Default }
val uc = (logLevel in update).?.value orElse st.get(logLevel.key) match { val uc = (logLevel in update).?.value orElse st.get(logLevel.key) match {
case Some(Level.Debug) if uc0.logging == Default => uc0.copy(logging = Full) case Some(Level.Debug) if uc0.logging == Default => uc0.copy(logging = Full)
case Some(x) if uc0.logging == Default => uc0.copy(logging = DownloadOnly) case Some(x) if uc0.logging == Default => uc0.copy(logging = DownloadOnly)
case _ => uc0 case _ => uc0
} }
val ewo = val ewo =
if (executionRoots.value exists { _.key == evicted.key }) EvictionWarningOptions.empty if (executionRoots.value exists { _.key == evicted.key }) EvictionWarningOptions.empty
@ -1543,7 +1548,7 @@ object Classpaths {
Tracked.inputChanged(cacheFile / "inputs") { (inChanged: Boolean, in: In) => Tracked.inputChanged(cacheFile / "inputs") { (inChanged: Boolean, in: In) =>
val outCache = Tracked.lastOutput[In, UpdateReport](outCacheFile) { val outCache = Tracked.lastOutput[In, UpdateReport](outCacheFile) {
case (_, Some(out)) if uptodate(inChanged, out) => out case (_, Some(out)) if uptodate(inChanged, out) => out
case _ => work(in) case _ => work(in)
} }
try { try {
outCache(in) outCache(in)

View File

@ -11,8 +11,16 @@ import sbt.librarymanagement.{ Resolver, UpdateReport }
import scala.concurrent.duration.Duration import scala.concurrent.duration.Duration
import java.io.File import java.io.File
import Def.{ dummyState, ScopedKey, Setting } import Def.{ dummyState, ScopedKey, Setting }
import Keys.{ Streams, TaskStreams, dummyRoots, executionRoots, pluginData, streams, import Keys.{
streamsManager, transformState } Streams,
TaskStreams,
dummyRoots,
executionRoots,
pluginData,
streams,
streamsManager,
transformState
}
import Project.richInitializeTask import Project.richInitializeTask
import Scope.GlobalScope import Scope.GlobalScope
import scala.Console.RED import scala.Console.RED
@ -97,21 +105,25 @@ sealed trait EvaluateTaskConfig {
} }
object EvaluateTaskConfig { object EvaluateTaskConfig {
@deprecated("Use the alternative that specifies minForcegcInterval", "0.13.9") @deprecated("Use the alternative that specifies minForcegcInterval", "0.13.9")
def apply(restrictions: Seq[Tags.Rule], def apply(
restrictions: Seq[Tags.Rule],
checkCycles: Boolean, checkCycles: Boolean,
progressReporter: ExecuteProgress[Task], progressReporter: ExecuteProgress[Task],
cancelStrategy: TaskCancellationStrategy, cancelStrategy: TaskCancellationStrategy,
forceGarbageCollection: Boolean): EvaluateTaskConfig = forceGarbageCollection: Boolean
): EvaluateTaskConfig =
apply(restrictions, checkCycles, progressReporter, cancelStrategy, forceGarbageCollection, apply(restrictions, checkCycles, progressReporter, cancelStrategy, forceGarbageCollection,
GCUtil.defaultMinForcegcInterval) GCUtil.defaultMinForcegcInterval)
/** Raw constructor for EvaluateTaskConfig. */ /** Raw constructor for EvaluateTaskConfig. */
def apply(restrictions: Seq[Tags.Rule], def apply(
restrictions: Seq[Tags.Rule],
checkCycles: Boolean, checkCycles: Boolean,
progressReporter: ExecuteProgress[Task], progressReporter: ExecuteProgress[Task],
cancelStrategy: TaskCancellationStrategy, cancelStrategy: TaskCancellationStrategy,
forceGarbageCollection: Boolean, forceGarbageCollection: Boolean,
minForcegcInterval: Duration): EvaluateTaskConfig = { minForcegcInterval: Duration
): EvaluateTaskConfig = {
val r = restrictions val r = restrictions
val check = checkCycles val check = checkCycles
val cs = cancelStrategy val cs = cancelStrategy
@ -362,7 +374,7 @@ object EvaluateTask {
result.toEither.left.map { i => Incomplete.transformBU(i)(convertCyclicInc andThen taskToKey andThen liftAnonymous) } result.toEither.left.map { i => Incomplete.transformBU(i)(convertCyclicInc andThen taskToKey andThen liftAnonymous) }
def taskToKey: Incomplete => Incomplete = { def taskToKey: Incomplete => Incomplete = {
case in @ Incomplete(Some(node: Task[_]), _, _, _, _) => in.copy(node = transformNode(node)) case in @ Incomplete(Some(node: Task[_]), _, _, _, _) => in.copy(node = transformNode(node))
case i => i case i => i
} }
type AnyCyclic = Execute[({ type A[_] <: AnyRef })#A]#CyclicException[_] type AnyCyclic = Execute[({ type A[_] <: AnyRef })#A]#CyclicException[_]
def convertCyclicInc: Incomplete => Incomplete = { def convertCyclicInc: Incomplete => Incomplete = {

View File

@ -63,7 +63,8 @@ final case class Extracted(structure: BuildStructure, session: SessionSettings,
import EvaluateTask._ import EvaluateTask._
val scopedKey = Scoped.scopedSetting( val scopedKey = Scoped.scopedSetting(
Scope.resolveScope(Load.projectScope(currentRef), currentRef.build, structure.rootProject)(key.scope), key.key) Scope.resolveScope(Load.projectScope(currentRef), currentRef.build, structure.rootProject)(key.scope), key.key
)
val rkey = resolve(scopedKey.scopedKey) val rkey = resolve(scopedKey.scopedKey)
val inputTask = get(Scoped.scopedSetting(rkey.scope, rkey.key)) val inputTask = get(Scoped.scopedSetting(rkey.scope, rkey.key))
val task = Parser.parse(input, inputTask.parser(state)) match { val task = Parser.parse(input, inputTask.parser(state)) match {

View File

@ -31,9 +31,11 @@ object LogManager {
def withScreenLogger(mk: (ScopedKey[_], State) => AbstractLogger): LogManager = withLoggers(screen = mk) def withScreenLogger(mk: (ScopedKey[_], State) => AbstractLogger): LogManager = withLoggers(screen = mk)
def withLoggers(screen: (ScopedKey[_], State) => AbstractLogger = (sk, s) => defaultScreen(s.globalLogging.console), def withLoggers(
screen: (ScopedKey[_], State) => AbstractLogger = (sk, s) => defaultScreen(s.globalLogging.console),
backed: PrintWriter => AbstractLogger = defaultBacked(), backed: PrintWriter => AbstractLogger = defaultBacked(),
extra: ScopedKey[_] => Seq[AbstractLogger] = _ => Nil): LogManager = new LogManager { extra: ScopedKey[_] => Seq[AbstractLogger] = _ => Nil
): LogManager = new LogManager {
def apply(data: Settings[Scope], state: State, task: ScopedKey[_], to: PrintWriter): Logger = def apply(data: Settings[Scope], state: State, task: ScopedKey[_], to: PrintWriter): Logger =
defaultLogger(data, state, task, screen(task, state), backed(to), extra(task).toList) defaultLogger(data, state, task, screen(task, state), backed(to), extra(task).toList)
} }

View File

@ -49,28 +49,31 @@ final class xMain extends xsbti.AppMain {
import BasicCommandStrings.runEarly import BasicCommandStrings.runEarly
import BuiltinCommands.defaults import BuiltinCommands.defaults
import sbt.internal.CommandStrings.{ BootCommand, DefaultsCommand, InitCommand } import sbt.internal.CommandStrings.{ BootCommand, DefaultsCommand, InitCommand }
runManaged(initialState(configuration, runManaged(initialState(
configuration,
Seq(defaults, early), Seq(defaults, early),
runEarly(DefaultsCommand) :: runEarly(InitCommand) :: BootCommand :: Nil) runEarly(DefaultsCommand) :: runEarly(InitCommand) :: BootCommand :: Nil
) ))
} }
} }
final class ScriptMain extends xsbti.AppMain { final class ScriptMain extends xsbti.AppMain {
def run(configuration: xsbti.AppConfiguration): xsbti.MainResult = def run(configuration: xsbti.AppConfiguration): xsbti.MainResult =
{ {
import BasicCommandStrings.runEarly import BasicCommandStrings.runEarly
runManaged(initialState(configuration, runManaged(initialState(
configuration,
BuiltinCommands.ScriptCommands, BuiltinCommands.ScriptCommands,
runEarly(Level.Error.toString) :: Script.Name :: Nil) runEarly(Level.Error.toString) :: Script.Name :: Nil
) ))
} }
} }
final class ConsoleMain extends xsbti.AppMain { final class ConsoleMain extends xsbti.AppMain {
def run(configuration: xsbti.AppConfiguration): xsbti.MainResult = def run(configuration: xsbti.AppConfiguration): xsbti.MainResult =
runManaged(initialState(configuration, runManaged(initialState(
configuration,
BuiltinCommands.ConsoleCommands, BuiltinCommands.ConsoleCommands,
IvyConsole.Name :: Nil) IvyConsole.Name :: Nil
) ))
} }
object StandardMain { object StandardMain {

View File

@ -7,8 +7,8 @@ TODO:
import sbt.librarymanagement.Configuration import sbt.librarymanagement.Configuration
import sbt.internal.util.logic.{Atom, Clause, Clauses, Formula, Literal, Logic, Negated} import sbt.internal.util.logic.{ Atom, Clause, Clauses, Formula, Literal, Logic, Negated }
import Logic.{CyclicNegation, InitialContradictions, InitialOverlap, LogicException} import Logic.{ CyclicNegation, InitialContradictions, InitialOverlap, LogicException }
import Def.Setting import Def.Setting
import Plugins._ import Plugins._
import annotation.tailrec import annotation.tailrec
@ -60,16 +60,19 @@ import sbt.util.Logger
* then the `MyPlugin` settings (and anything that activates only when `MyPlugin` is activated) will not be added. * then the `MyPlugin` settings (and anything that activates only when `MyPlugin` is activated) will not be added.
*/ */
abstract class AutoPlugin extends Plugins.Basic with PluginsFunctions { abstract class AutoPlugin extends Plugins.Basic with PluginsFunctions {
/** Determines whether this AutoPlugin will be activated for this project when the `requires` clause is satisfied. /**
* Determines whether this AutoPlugin will be activated for this project when the `requires` clause is satisfied.
* *
* When this method returns `allRequirements`, and `requires` method returns `Web && Javascript`, this plugin * When this method returns `allRequirements`, and `requires` method returns `Web && Javascript`, this plugin
* instance will be added automatically if the `Web` and `Javascript` plugins are enabled. * instance will be added automatically if the `Web` and `Javascript` plugins are enabled.
* *
* When this method returns `noTrigger`, and `requires` method returns `Web && Javascript`, this plugin * When this method returns `noTrigger`, and `requires` method returns `Web && Javascript`, this plugin
* instance will be added only if the build user enables it, but it will automatically add both `Web` and `Javascript`. */ * instance will be added only if the build user enables it, but it will automatically add both `Web` and `Javascript`.
*/
def trigger: PluginTrigger = noTrigger def trigger: PluginTrigger = noTrigger
/** This AutoPlugin requires the plugins the [[Plugins]] matcher returned by this method. See [[trigger]]. /**
* This AutoPlugin requires the plugins the [[Plugins]] matcher returned by this method. See [[trigger]].
*/ */
def requires: Plugins = plugins.JvmPlugin def requires: Plugins = plugins.JvmPlugin
@ -83,9 +86,11 @@ abstract class AutoPlugin extends Plugins.Basic with PluginsFunctions {
/** The [[Setting]]s to add in the scope of each project that activates this AutoPlugin. */ /** The [[Setting]]s to add in the scope of each project that activates this AutoPlugin. */
def projectSettings: Seq[Setting[_]] = Nil def projectSettings: Seq[Setting[_]] = Nil
/** The [[Setting]]s to add to the build scope for each project that activates this AutoPlugin. /**
* The settings returned here are guaranteed to be added to a given build scope only once * The [[Setting]]s to add to the build scope for each project that activates this AutoPlugin.
* regardless of how many projects for that build activate this AutoPlugin. */ * The settings returned here are guaranteed to be added to a given build scope only once
* regardless of how many projects for that build activate this AutoPlugin.
*/
def buildSettings: Seq[Setting[_]] = Nil def buildSettings: Seq[Setting[_]] = Nil
/** The [[Setting]]s to add to the global scope exactly once if any project activates this AutoPlugin. */ /** The [[Setting]]s to add to the global scope exactly once if any project activates this AutoPlugin. */
@ -101,12 +106,11 @@ abstract class AutoPlugin extends Plugins.Basic with PluginsFunctions {
private[sbt] def unary_! : Exclude = Exclude(this) private[sbt] def unary_! : Exclude = Exclude(this)
/** If this plugin does not have any requirements, it means it is actually a root plugin. */ /** If this plugin does not have any requirements, it means it is actually a root plugin. */
private[sbt] final def isRoot: Boolean = private[sbt] final def isRoot: Boolean =
requires match { requires match {
case Empty => true case Empty => true
case _ => false case _ => false
} }
/** If this plugin does not have any requirements, it means it is actually a root plugin. */ /** If this plugin does not have any requirements, it means it is actually a root plugin. */
@ -114,9 +118,11 @@ abstract class AutoPlugin extends Plugins.Basic with PluginsFunctions {
isRoot && (trigger == AllRequirements) isRoot && (trigger == AllRequirements)
} }
/** An error that occurs when auto-plugins aren't configured properly. /**
* It translates the error from the underlying logic system to be targeted at end users. */ * An error that occurs when auto-plugins aren't configured properly.
final class AutoPluginException private(val message: String, val origin: Option[LogicException]) extends RuntimeException(message) { * It translates the error from the underlying logic system to be targeted at end users.
*/
final class AutoPluginException private (val message: String, val origin: Option[LogicException]) extends RuntimeException(message) {
/** Prepends `p` to the error message derived from `origin`. */ /** Prepends `p` to the error message derived from `origin`. */
def withPrefix(p: String) = new AutoPluginException(p + message, origin) def withPrefix(p: String) = new AutoPluginException(p + message, origin)
} }
@ -131,10 +137,9 @@ case object NoTrigger extends PluginTrigger
/** An expression that matches `AutoPlugin`s. */ /** An expression that matches `AutoPlugin`s. */
sealed trait Plugins { sealed trait Plugins {
def && (o: Basic): Plugins def &&(o: Basic): Plugins
} }
sealed trait PluginsFunctions { sealed trait PluginsFunctions {
/** [[Plugins]] instance that doesn't require any [[Plugins]]s. */ /** [[Plugins]] instance that doesn't require any [[Plugins]]s. */
def empty: Plugins = Plugins.Empty def empty: Plugins = Plugins.Empty
@ -146,20 +151,22 @@ sealed trait PluginsFunctions {
} }
object Plugins extends PluginsFunctions { object Plugins extends PluginsFunctions {
/** Given the available auto plugins `defined`, returns a function that selects [[AutoPlugin]]s for the provided [[AutoPlugin]]s. /**
* The [[AutoPlugin]]s are topologically sorted so that a required [[AutoPlugin]] comes before its requiring [[AutoPlugin]].*/ * Given the available auto plugins `defined`, returns a function that selects [[AutoPlugin]]s for the provided [[AutoPlugin]]s.
* The [[AutoPlugin]]s are topologically sorted so that a required [[AutoPlugin]] comes before its requiring [[AutoPlugin]].
*/
def deducer(defined0: List[AutoPlugin]): (Plugins, Logger) => Seq[AutoPlugin] = def deducer(defined0: List[AutoPlugin]): (Plugins, Logger) => Seq[AutoPlugin] =
if(defined0.isEmpty) (_, _) => Nil if (defined0.isEmpty) (_, _) => Nil
else { else {
// TODO: defined should return all the plugins // TODO: defined should return all the plugins
val allReqs = (defined0 flatMap { asRequirements }).toSet val allReqs = (defined0 flatMap { asRequirements }).toSet
val diff = allReqs diff defined0.toSet val diff = allReqs diff defined0.toSet
val defined = if (diff.nonEmpty) diff.toList ::: defined0 val defined = if (diff.nonEmpty) diff.toList ::: defined0
else defined0 else defined0
val byAtom = defined map { x => (Atom(x.label), x) } val byAtom = defined map { x => (Atom(x.label), x) }
val byAtomMap = byAtom.toMap val byAtomMap = byAtom.toMap
if(byAtom.size != byAtomMap.size) duplicateProvidesError(byAtom) if (byAtom.size != byAtomMap.size) duplicateProvidesError(byAtom)
// Ignore clauses for plugins that does not require anything else. // Ignore clauses for plugins that does not require anything else.
// Avoids the requirement for pure Nature strings *and* possible // Avoids the requirement for pure Nature strings *and* possible
// circular dependencies in the logic. // circular dependencies in the logic.
@ -186,7 +193,7 @@ object Plugins extends PluginsFunctions {
val forbidden: Set[AutoPlugin] = (selectedPlugins flatMap { Plugins.asExclusions }).toSet val forbidden: Set[AutoPlugin] = (selectedPlugins flatMap { Plugins.asExclusions }).toSet
val c = selectedPlugins.toSet & forbidden val c = selectedPlugins.toSet & forbidden
if (c.nonEmpty) { if (c.nonEmpty) {
exlusionConflictError(requestedPlugins, selectedPlugins, c.toSeq sortBy {_.label}) exlusionConflictError(requestedPlugins, selectedPlugins, c.toSeq sortBy { _.label })
} }
val retval = topologicalSort(selectedPlugins, log) val retval = topologicalSort(selectedPlugins, log)
log.debug(s" :: sorted deduced result: ${retval.toString}") log.debug(s" :: sorted deduced result: ${retval.toString}")
@ -210,26 +217,25 @@ object Plugins extends PluginsFunctions {
} }
private[sbt] def translateMessage(e: LogicException) = e match { private[sbt] def translateMessage(e: LogicException) = e match {
case ic: InitialContradictions => s"Contradiction in selected plugins. These plugins were both included and excluded: ${literalsString(ic.literals.toSeq)}" case ic: InitialContradictions => s"Contradiction in selected plugins. These plugins were both included and excluded: ${literalsString(ic.literals.toSeq)}"
case io: InitialOverlap => s"Cannot directly enable plugins. Plugins are enabled when their required plugins are satisifed. The directly selected plugins were: ${literalsString(io.literals.toSeq)}" case io: InitialOverlap => s"Cannot directly enable plugins. Plugins are enabled when their required plugins are satisifed. The directly selected plugins were: ${literalsString(io.literals.toSeq)}"
case cn: CyclicNegation => s"Cycles in plugin requirements cannot involve excludes. The problematic cycle is: ${literalsString(cn.cycle)}" case cn: CyclicNegation => s"Cycles in plugin requirements cannot involve excludes. The problematic cycle is: ${literalsString(cn.cycle)}"
} }
private[this] def literalsString(lits: Seq[Literal]): String = private[this] def literalsString(lits: Seq[Literal]): String =
lits map { case Atom(l) => l; case Negated(Atom(l)) => l } mkString(", ") lits map { case Atom(l) => l; case Negated(Atom(l)) => l } mkString (", ")
private[this] def duplicateProvidesError(byAtom: Seq[(Atom, AutoPlugin)]): Unit = { private[this] def duplicateProvidesError(byAtom: Seq[(Atom, AutoPlugin)]): Unit = {
val dupsByAtom = byAtom.groupBy(_._1).mapValues(_.map(_._2)) val dupsByAtom = byAtom.groupBy(_._1).mapValues(_.map(_._2))
val dupStrings = for( (atom, dups) <- dupsByAtom if dups.size > 1 ) yield val dupStrings = for ((atom, dups) <- dupsByAtom if dups.size > 1) yield s"${atom.label} by ${dups.mkString(", ")}"
s"${atom.label} by ${dups.mkString(", ")}" val (ns, nl) = if (dupStrings.size > 1) ("s", "\n\t") else ("", " ")
val (ns, nl) = if(dupStrings.size > 1) ("s", "\n\t") else ("", " ")
val message = s"Plugin$ns provided by multiple AutoPlugins:$nl${dupStrings.mkString(nl)}" val message = s"Plugin$ns provided by multiple AutoPlugins:$nl${dupStrings.mkString(nl)}"
throw AutoPluginException(message) throw AutoPluginException(message)
} }
private[this] def exlusionConflictError(requested: Plugins, selected: Seq[AutoPlugin], conflicting: Seq[AutoPlugin]): Unit = { private[this] def exlusionConflictError(requested: Plugins, selected: Seq[AutoPlugin], conflicting: Seq[AutoPlugin]): Unit = {
def listConflicts(ns: Seq[AutoPlugin]) = (ns map { c => def listConflicts(ns: Seq[AutoPlugin]) = (ns map { c =>
val reasons = (if (flatten(requested) contains c) List("requested") val reasons = (if (flatten(requested) contains c) List("requested")
else Nil) ++ else Nil) ++
(if (c.requires != empty && c.trigger == allRequirements) List(s"enabled by ${c.requires.toString}") (if (c.requires != empty && c.trigger == allRequirements) List(s"enabled by ${c.requires.toString}")
else Nil) ++ else Nil) ++
{ {
val reqs = selected filter { x => asRequirements(x) contains c } val reqs = selected filter { x => asRequirements(x) contains c }
if (reqs.nonEmpty) List(s"""required by ${reqs.mkString(", ")}""") if (reqs.nonEmpty) List(s"""required by ${reqs.mkString(", ")}""")
@ -258,7 +264,7 @@ ${listConflicts(conflicting)}""")
sealed abstract class Basic extends Plugins { sealed abstract class Basic extends Plugins {
def &&(o: Basic): Plugins = And(this :: o :: Nil) def &&(o: Basic): Plugins = And(this :: o :: Nil)
} }
private[sbt] final case class Exclude(n: AutoPlugin) extends Basic { private[sbt] final case class Exclude(n: AutoPlugin) extends Basic {
override def toString = s"!$n" override def toString = s"!$n"
} }
private[sbt] final case class And(plugins: List[Basic]) extends Plugins { private[sbt] final case class And(plugins: List[Basic]) extends Plugins {
@ -266,27 +272,27 @@ ${listConflicts(conflicting)}""")
override def toString = plugins.mkString(" && ") override def toString = plugins.mkString(" && ")
} }
private[sbt] def and(a: Plugins, b: Plugins) = b match { private[sbt] def and(a: Plugins, b: Plugins) = b match {
case Empty => a case Empty => a
case And(ns) => (a /: ns)(_ && _) case And(ns) => (a /: ns)(_ && _)
case b: Basic => a && b case b: Basic => a && b
} }
private[sbt] def remove(a: Plugins, del: Set[Basic]): Plugins = a match { private[sbt] def remove(a: Plugins, del: Set[Basic]): Plugins = a match {
case b: Basic => if(del(b)) Empty else b case b: Basic => if (del(b)) Empty else b
case Empty => Empty case Empty => Empty
case And(ns) => case And(ns) =>
val removed = ns.filterNot(del) val removed = ns.filterNot(del)
if(removed.isEmpty) Empty else And(removed) if (removed.isEmpty) Empty else And(removed)
} }
/** Defines enabled-by clauses for `ap`. */ /** Defines enabled-by clauses for `ap`. */
private[sbt] def asEnabledByClauses(ap: AutoPlugin): List[Clause] = private[sbt] def asEnabledByClauses(ap: AutoPlugin): List[Clause] =
// `ap` is the head and the required plugins for `ap` is the body. // `ap` is the head and the required plugins for `ap` is the body.
if (ap.trigger == AllRequirements) Clause( convert(ap.requires), Set(Atom(ap.label)) ) :: Nil if (ap.trigger == AllRequirements) Clause(convert(ap.requires), Set(Atom(ap.label))) :: Nil
else Nil else Nil
/** Defines requirements clauses for `ap`. */ /** Defines requirements clauses for `ap`. */
private[sbt] def asRequirementsClauses(ap: AutoPlugin): List[Clause] = private[sbt] def asRequirementsClauses(ap: AutoPlugin): List[Clause] =
// required plugin is the head and `ap` is the body. // required plugin is the head and `ap` is the body.
asRequirements(ap) map { x => Clause( convert(ap), Set(Atom(x.label)) ) } asRequirements(ap) map { x => Clause(convert(ap), Set(Atom(x.label))) }
private[sbt] def asRequirements(ap: AutoPlugin): List[AutoPlugin] = flatten(ap.requires).toList collect { private[sbt] def asRequirements(ap: AutoPlugin): List[AutoPlugin] = flatten(ap.requires).toList collect {
case x: AutoPlugin => x case x: AutoPlugin => x
} }
@ -295,41 +301,41 @@ ${listConflicts(conflicting)}""")
} }
// TODO - This doesn't handle nested AND boolean logic... // TODO - This doesn't handle nested AND boolean logic...
private[sbt] def hasExclude(n: Plugins, p: AutoPlugin): Boolean = n match { private[sbt] def hasExclude(n: Plugins, p: AutoPlugin): Boolean = n match {
case `p` => false case `p` => false
case Exclude(`p`) => true case Exclude(`p`) => true
// TODO - This is stupidly advanced. We do a nested check through possible and-ed // TODO - This is stupidly advanced. We do a nested check through possible and-ed
// lists of plugins exclusions to see if the plugin ever winds up in an excluded=true case. // lists of plugins exclusions to see if the plugin ever winds up in an excluded=true case.
// This would handle things like !!p or !(p && z) // This would handle things like !!p or !(p && z)
case Exclude(n) => hasInclude(n, p) case Exclude(n) => hasInclude(n, p)
case And(ns) => ns.forall(n => hasExclude(n, p)) case And(ns) => ns.forall(n => hasExclude(n, p))
case b: Basic => false case b: Basic => false
case Empty => false case Empty => false
} }
private[sbt] def hasInclude(n: Plugins, p: AutoPlugin): Boolean = n match { private[sbt] def hasInclude(n: Plugins, p: AutoPlugin): Boolean = n match {
case `p` => true case `p` => true
case Exclude(n) => hasExclude(n, p) case Exclude(n) => hasExclude(n, p)
case And(ns) => ns.forall(n => hasInclude(n, p)) case And(ns) => ns.forall(n => hasInclude(n, p))
case b: Basic => false case b: Basic => false
case Empty => false case Empty => false
} }
private[this] def flattenConvert(n: Plugins): Seq[Literal] = n match { private[this] def flattenConvert(n: Plugins): Seq[Literal] = n match {
case And(ns) => convertAll(ns) case And(ns) => convertAll(ns)
case b: Basic => convertBasic(b) :: Nil case b: Basic => convertBasic(b) :: Nil
case Empty => Nil case Empty => Nil
} }
private[sbt] def flatten(n: Plugins): Seq[Basic] = n match { private[sbt] def flatten(n: Plugins): Seq[Basic] = n match {
case And(ns) => ns case And(ns) => ns
case b: Basic => b :: Nil case b: Basic => b :: Nil
case Empty => Nil case Empty => Nil
} }
private[this] def convert(n: Plugins): Formula = n match { private[this] def convert(n: Plugins): Formula = n match {
case And(ns) => convertAll(ns).reduce[Formula](_ && _) case And(ns) => convertAll(ns).reduce[Formula](_ && _)
case b: Basic => convertBasic(b) case b: Basic => convertBasic(b)
case Empty => Formula.True case Empty => Formula.True
} }
private[this] def convertBasic(b: Basic): Literal = b match { private[this] def convertBasic(b: Basic): Literal = b match {
case Exclude(n) => !convertBasic(n) case Exclude(n) => !convertBasic(n)
case a: AutoPlugin => Atom(a.label) case a: AutoPlugin => Atom(a.label)
} }
private[this] def convertAll(ns: Seq[Basic]): Seq[Literal] = ns map convertBasic private[this] def convertAll(ns: Seq[Basic]): Seq[Literal] = ns map convertBasic
@ -337,19 +343,19 @@ ${listConflicts(conflicting)}""")
/** True if the trigger clause `n` is satisifed by `model`. */ /** True if the trigger clause `n` is satisifed by `model`. */
def satisfied(n: Plugins, model: Set[AutoPlugin]): Boolean = def satisfied(n: Plugins, model: Set[AutoPlugin]): Boolean =
flatten(n) forall { flatten(n) forall {
case Exclude(a) => !model(a) case Exclude(a) => !model(a)
case ap: AutoPlugin => model(ap) case ap: AutoPlugin => model(ap)
} }
private[sbt] def hasAutoImportGetter(ap: AutoPlugin, loader: ClassLoader): Boolean = { private[sbt] def hasAutoImportGetter(ap: AutoPlugin, loader: ClassLoader): Boolean = {
import reflect.runtime.{universe => ru} import reflect.runtime.{ universe => ru }
import scala.util.control.Exception.catching import scala.util.control.Exception.catching
val m = ru.runtimeMirror(loader) val m = ru.runtimeMirror(loader)
val im = m.reflect(ap) val im = m.reflect(ap)
val hasGetterOpt = catching(classOf[ScalaReflectionException]) opt { val hasGetterOpt = catching(classOf[ScalaReflectionException]) opt {
im.symbol.asType.toType.decl(ru.TermName("autoImport")) match { im.symbol.asType.toType.decl(ru.TermName("autoImport")) match {
case ru.NoSymbol => false case ru.NoSymbol => false
case sym => sym.asTerm.isGetter || sym.asTerm.isModule case sym => sym.asTerm.isGetter || sym.asTerm.isModule
} }
} }
hasGetterOpt getOrElse false hasGetterOpt getOrElse false

View File

@ -94,16 +94,17 @@ sealed trait Project extends ProjectDefinition[ProjectReference] {
private[sbt] def delegatesEval: Eval[Seq[ProjectReference]] private[sbt] def delegatesEval: Eval[Seq[ProjectReference]]
private[sbt] def dependenciesEval: Eval[Seq[ClasspathDep[ProjectReference]]] private[sbt] def dependenciesEval: Eval[Seq[ClasspathDep[ProjectReference]]]
// TODO: add parameters for plugins in 0.14.0 (not reasonable to do in a binary compatible way in 0.13) // TODO: add parameters for plugins in 0.14.0 (not reasonable to do in a binary compatible way in 0.13)
private[sbt] def copy(id: String = id, private[sbt] def copy(
id: String = id,
base: File = base, base: File = base,
aggregateEval: Eval[Seq[ProjectReference]] = aggregateEval, aggregateEval: Eval[Seq[ProjectReference]] = aggregateEval,
dependenciesEval: Eval[Seq[ClasspathDep[ProjectReference]]] = dependenciesEval, dependenciesEval: Eval[Seq[ClasspathDep[ProjectReference]]] = dependenciesEval,
delegatesEval: Eval[Seq[ProjectReference]] = delegatesEval, delegatesEval: Eval[Seq[ProjectReference]] = delegatesEval,
settingsEval: Eval[Seq[Setting[_]]] = settingsEval, settingsEval: Eval[Seq[Setting[_]]] = settingsEval,
configurations: Seq[Configuration] = configurations, configurations: Seq[Configuration] = configurations,
auto: AddSettings = auto): Project = auto: AddSettings = auto
): Project =
unresolved(id, base, unresolved(id, base,
aggregateEval = aggregateEval, aggregateEval = aggregateEval,
dependenciesEval = dependenciesEval, dependenciesEval = dependenciesEval,
@ -261,10 +262,10 @@ final case class ClasspathDependency(project: ProjectReference, configuration: O
*/ */
sealed trait ProjectOrigin sealed trait ProjectOrigin
object ProjectOrigin { object ProjectOrigin {
case object Organic extends ProjectOrigin case object Organic extends ProjectOrigin
case object ExtraProject extends ProjectOrigin case object ExtraProject extends ProjectOrigin
case object DerivedProject extends ProjectOrigin case object DerivedProject extends ProjectOrigin
case object GenericRoot extends ProjectOrigin case object GenericRoot extends ProjectOrigin
} }
object Project extends ProjectExtra { object Project extends ProjectExtra {
@ -280,7 +281,8 @@ object Project extends ProjectExtra {
val auto: AddSettings, val auto: AddSettings,
val plugins: Plugins, val plugins: Plugins,
val autoPlugins: Seq[AutoPlugin], val autoPlugins: Seq[AutoPlugin],
val projectOrigin: ProjectOrigin) extends ProjectDefinition[PR] { val projectOrigin: ProjectOrigin
) extends ProjectDefinition[PR] {
def aggregate: Seq[PR] = aggregateEval.get def aggregate: Seq[PR] = aggregateEval.get
def dependencies: Seq[ClasspathDep[PR]] = dependenciesEval.get def dependencies: Seq[ClasspathDep[PR]] = dependenciesEval.get
def delegates: Seq[PR] = delegatesEval.get def delegates: Seq[PR] = delegatesEval.get
@ -649,7 +651,7 @@ object Project extends ProjectExtra {
private[sbt] trait GeneratedRootProject private[sbt] trait GeneratedRootProject
trait ProjectExtra0 { trait ProjectExtra0 {
implicit def wrapProjectReferenceSeqEval[T](rs: => Seq[T])(implicit ev: T => ProjectReference): Seq[Eval[ProjectReference]] = implicit def wrapProjectReferenceSeqEval[T](rs: => Seq[T])(implicit ev: T => ProjectReference): Seq[Eval[ProjectReference]] =
rs map { r => Eval.later(r: ProjectReference) } rs map { r => Eval.later(r: ProjectReference) }
} }
@ -665,7 +667,6 @@ trait ProjectExtra extends ProjectExtra0 {
implicit def configDependencyConstructor[T](p: T)(implicit ev: T => ProjectReference): Constructor = new Constructor(p) implicit def configDependencyConstructor[T](p: T)(implicit ev: T => ProjectReference): Constructor = new Constructor(p)
implicit def classpathDependency[T](p: T)(implicit ev: T => ProjectReference): ClasspathDep[ProjectReference] = new ClasspathDependency(p, None) implicit def classpathDependency[T](p: T)(implicit ev: T => ProjectReference): ClasspathDep[ProjectReference] = new ClasspathDependency(p, None)
// These used to be in Project so that they didn't need to get imported (due to Initialize being nested in Project). // These used to be in Project so that they didn't need to get imported (due to Initialize being nested in Project).
// Moving Initialize and other settings types to Def and decoupling Project, Def, and Structure means these go here for now // Moving Initialize and other settings types to Def and decoupling Project, Def, and Structure means these go here for now
implicit def richInitializeTask[T](init: Initialize[Task[T]]): Scoped.RichInitializeTask[T] = new Scoped.RichInitializeTask(init) implicit def richInitializeTask[T](init: Initialize[Task[T]]): Scoped.RichInitializeTask[T] = new Scoped.RichInitializeTask(init)

View File

@ -28,8 +28,7 @@ object SessionVar {
def persist[T](key: ScopedKey[Task[T]], state: State, value: T)(implicit f: sbinary.Format[T]): Unit = def persist[T](key: ScopedKey[Task[T]], state: State, value: T)(implicit f: sbinary.Format[T]): Unit =
Project.structure(state).streams(state).use(key)(s => Project.structure(state).streams(state).use(key)(s =>
Operations.write(s.binary(DefaultDataID), value)(f) Operations.write(s.binary(DefaultDataID), value)(f))
)
def clear(s: State): State = s.put(sessionVars, SessionVar.emptyMap) def clear(s: State): State = s.put(sessionVars, SessionVar.emptyMap)

View File

@ -253,12 +253,11 @@ object Act {
def evaluate(kvs: Seq[ScopedKey[_]]): Parser[() => State] = { def evaluate(kvs: Seq[ScopedKey[_]]): Parser[() => State] = {
val preparedPairs = anyKeyValues(structure, kvs) val preparedPairs = anyKeyValues(structure, kvs)
val showConfig = Aggregation.defaultShow(state, showTasks = action == ShowAction) val showConfig = Aggregation.defaultShow(state, showTasks = action == ShowAction)
evaluatingParser(state, structure, showConfig)(preparedPairs) map { evaluate => evaluatingParser(state, structure, showConfig)(preparedPairs) map { evaluate => () => {
() => { val keyStrings = preparedPairs.map(pp => showKey(pp.key)).mkString(", ")
val keyStrings = preparedPairs.map(pp => showKey(pp.key)).mkString(", ") state.log.debug("Evaluating tasks: " + keyStrings)
state.log.debug("Evaluating tasks: " + keyStrings) evaluate()
evaluate() }
}
} }
} }
action match { action match {

View File

@ -150,11 +150,10 @@ object Aggregation {
} else { } else {
val base = if (tasks.isEmpty) success(() => s) else val base = if (tasks.isEmpty) success(() => s) else
applyTasks(s, structure, maps(tasks)(x => success(castToAny(x))), show) applyTasks(s, structure, maps(tasks)(x => success(castToAny(x))), show)
base.map { res => base.map { res => () =>
() => val newState = res()
val newState = res() if (show.settingValues && settings.nonEmpty) printSettings(settings, show.print)
if (show.settingValues && settings.nonEmpty) printSettings(settings, show.print) newState
newState
} }
} }
} }
@ -169,8 +168,7 @@ object Aggregation {
{ {
val resRef = proj.map(p => extra.projectRefFor(extra.resolveRef(p))) val resRef = proj.map(p => extra.projectRefFor(extra.resolveRef(p)))
resRef.toList.flatMap(ref => resRef.toList.flatMap(ref =>
if (reverse) extra.aggregates.reverse(ref) else extra.aggregates.forward(ref) if (reverse) extra.aggregates.reverse(ref) else extra.aggregates.forward(ref))
)
} }
def aggregate[T, Proj](key: ScopedKey[T], rawMask: ScopeMask, extra: BuildUtil[Proj], reverse: Boolean = false): Seq[ScopedKey[T]] = def aggregate[T, Proj](key: ScopedKey[T], rawMask: ScopeMask, extra: BuildUtil[Proj], reverse: Boolean = false): Seq[ScopedKey[T]] =

View File

@ -105,23 +105,22 @@ final class BuildLoader(
val builders: MultiHandler[BuildInfo, () => BuildUnit], val builders: MultiHandler[BuildInfo, () => BuildUnit],
val transformer: Transformer, val transformer: Transformer,
val full: MultiHandler[LoadInfo, () => BuildUnit], val full: MultiHandler[LoadInfo, () => BuildUnit],
val transformAll: TransformAll) { val transformAll: TransformAll
) {
def addNonRoot(uri: URI, loaders: Components): BuildLoader = def addNonRoot(uri: URI, loaders: Components): BuildLoader =
new BuildLoader(fail, state, config, new BuildLoader(fail, state, config,
resolvers.addNonRoot(uri, loaders.resolver), resolvers.addNonRoot(uri, loaders.resolver),
builders.addNonRoot(uri, loaders.builder), builders.addNonRoot(uri, loaders.builder),
seq(transformer, loaders.transformer), seq(transformer, loaders.transformer),
full.addNonRoot(uri, loaders.full), full.addNonRoot(uri, loaders.full),
transformAll andThen loaders.transformAll transformAll andThen loaders.transformAll)
)
def setRoot(loaders: Components): BuildLoader = def setRoot(loaders: Components): BuildLoader =
new BuildLoader(fail, state, config, new BuildLoader(fail, state, config,
resolvers.setRoot(loaders.resolver), resolvers.setRoot(loaders.resolver),
builders.setRoot(loaders.builder), builders.setRoot(loaders.builder),
seq(loaders.transformer, transformer), seq(loaders.transformer, transformer),
full.setRoot(loaders.full), full.setRoot(loaders.full),
loaders.transformAll andThen transformAll loaders.transformAll andThen transformAll)
)
def resetPluginDepth: BuildLoader = copyWithNewPM(config.pluginManagement.resetDepth) def resetPluginDepth: BuildLoader = copyWithNewPM(config.pluginManagement.resetDepth)
def updatePluginManagement(overrides: Set[ModuleID]): BuildLoader = def updatePluginManagement(overrides: Set[ModuleID]): BuildLoader =

View File

@ -30,7 +30,8 @@ final class StructureIndex(
val taskToKey: Map[Task[_], ScopedKey[Task[_]]], val taskToKey: Map[Task[_], ScopedKey[Task[_]]],
val triggers: Triggers[Task], val triggers: Triggers[Task],
val keyIndex: KeyIndex, val keyIndex: KeyIndex,
val aggregateKeyIndex: KeyIndex) val aggregateKeyIndex: KeyIndex
)
/** /**
* A resolved build unit. (`ResolvedBuildUnit` would be a better name to distinguish it from the loaded, but unresolved `BuildUnit`.) * A resolved build unit. (`ResolvedBuildUnit` would be a better name to distinguish it from the loaded, but unresolved `BuildUnit`.)
@ -92,13 +93,16 @@ final class LoadedDefinitions(
val builds: Seq[BuildDef], val builds: Seq[BuildDef],
val projects: Seq[Project], val projects: Seq[Project],
val buildNames: Seq[String], val buildNames: Seq[String],
val dslDefinitions: DefinedSbtValues) { val dslDefinitions: DefinedSbtValues
def this(base: File, ) {
def this(
base: File,
target: Seq[File], target: Seq[File],
loader: ClassLoader, loader: ClassLoader,
builds: Seq[BuildDef], builds: Seq[BuildDef],
projects: Seq[Project], projects: Seq[Project],
buildNames: Seq[String]) = this(base, target, loader, builds, projects, buildNames, DefinedSbtValues.empty) buildNames: Seq[String]
) = this(base, target, loader, builds, projects, buildNames, DefinedSbtValues.empty)
} }
/** Auto-detected top-level modules (as in `object X`) of type `T` paired with their source names. */ /** Auto-detected top-level modules (as in `object X`) of type `T` paired with their source names. */

View File

@ -12,7 +12,8 @@ final class BuildUtil[Proj](
val rootProjectID: URI => String, val rootProjectID: URI => String,
val project: (URI, String) => Proj, val project: (URI, String) => Proj,
val configurations: Proj => Seq[ConfigKey], val configurations: Proj => Seq[ConfigKey],
val aggregates: Relation[ProjectRef, ProjectRef]) { val aggregates: Relation[ProjectRef, ProjectRef]
) {
def rootProject(uri: URI): Proj = def rootProject(uri: URI): Proj =
project(uri, rootProjectID(uri)) project(uri, rootProjectID(uri))

View File

@ -181,11 +181,13 @@ private[sbt] object EvaluateConfigurations {
case e: sbt.compiler.EvalException => throw new MessageOnlyException(e.getMessage) case e: sbt.compiler.EvalException => throw new MessageOnlyException(e.getMessage)
} }
// TODO - keep track of configuration classes defined. // TODO - keep track of configuration classes defined.
TrackedEvalResult(result.generated, TrackedEvalResult(
result.generated,
loader => { loader => {
val pos = RangePosition(name, range shift 1) val pos = RangePosition(name, range shift 1)
result.getValue(loader).asInstanceOf[DslEntry].withPos(pos) result.getValue(loader).asInstanceOf[DslEntry].withPos(pos)
}) }
)
} }
/** /**

View File

@ -16,9 +16,24 @@ import sbt.internal.inc.{ Analysis, ClasspathOptionsUtil, ModuleUtilities }
import sbt.internal.inc.classpath.ClasspathUtilities import sbt.internal.inc.classpath.ClasspathUtilities
import Project.inScope import Project.inScope
import Def.{ isDummy, ScopedKey, ScopeLocal, Setting } import Def.{ isDummy, ScopedKey, ScopeLocal, Setting }
import Keys.{ appConfiguration, baseDirectory, configuration, exportedProducts, fullClasspath, fullResolvers, import Keys.{
loadedBuild, onLoadMessage, pluginData, resolvedScoped, sbtPlugin, scalacOptions, streams, appConfiguration,
thisProject, thisProjectRef, update } baseDirectory,
configuration,
exportedProducts,
fullClasspath,
fullResolvers,
loadedBuild,
onLoadMessage,
pluginData,
resolvedScoped,
sbtPlugin,
scalacOptions,
streams,
thisProject,
thisProjectRef,
update
}
import tools.nsc.reporters.ConsoleReporter import tools.nsc.reporters.ConsoleReporter
import sbt.internal.util.{ Attributed, Eval => Ev, Settings, Show, ~> } import sbt.internal.util.{ Attributed, Eval => Ev, Settings, Show, ~> }
import sbt.internal.util.Attributed.data import sbt.internal.util.Attributed.data
@ -437,7 +452,7 @@ private[sbt] object Load {
val plugs = plugins(defDir, s, config.copy(pluginManagement = config.pluginManagement.forPlugin)) val plugs = plugins(defDir, s, config.copy(pluginManagement = config.pluginManagement.forPlugin))
val defsScala = plugs.detected.builds.values val defsScala = plugs.detected.builds.values
val buildLevelExtraProjects = plugs.detected.autoPlugins flatMap { d => val buildLevelExtraProjects = plugs.detected.autoPlugins flatMap { d =>
d.value.extraProjects map {_.setProjectOrigin(ProjectOrigin.ExtraProject)} d.value.extraProjects map { _.setProjectOrigin(ProjectOrigin.ExtraProject) }
} }
// NOTE - because we create an eval here, we need a clean-eval later for this URI. // NOTE - because we create an eval here, we need a clean-eval later for this URI.
@ -547,7 +562,8 @@ private[sbt] object Load {
makeOrDiscoverRoot: Boolean, makeOrDiscoverRoot: Boolean,
buildUri: URI, buildUri: URI,
context: PluginManagement.Context, context: PluginManagement.Context,
generatedConfigClassFiles: Seq[File]): LoadedProjects = generatedConfigClassFiles: Seq[File]
): LoadedProjects =
{ {
// load all relevant configuration files (.sbt, as .scala already exists at this point) // load all relevant configuration files (.sbt, as .scala already exists at this point)
def discover(auto: AddSettings, base: File): DiscoveredProjects = def discover(auto: AddSettings, base: File): DiscoveredProjects =
@ -567,7 +583,7 @@ private[sbt] object Load {
catch { case e: AutoPluginException => throw translateAutoPluginException(e, p) } catch { case e: AutoPluginException => throw translateAutoPluginException(e, p) }
val p2 = this.resolveProject(p1, autoPlugins, plugins, injectSettings, memoSettings, log) val p2 = this.resolveProject(p1, autoPlugins, plugins, injectSettings, memoSettings, log)
val projectLevelExtra = val projectLevelExtra =
if (expand) autoPlugins flatMap { _.derivedProjects(p2) map {_.setProjectOrigin(ProjectOrigin.DerivedProject)} } if (expand) autoPlugins flatMap { _.derivedProjects(p2) map { _.setProjectOrigin(ProjectOrigin.DerivedProject) } }
else Nil else Nil
(p2, projectLevelExtra) (p2, projectLevelExtra)
} }
@ -638,7 +654,8 @@ private[sbt] object Load {
root: Option[Project], root: Option[Project],
nonRoot: Seq[Project], nonRoot: Seq[Project],
sbtFiles: Seq[File], sbtFiles: Seq[File],
generatedFiles: Seq[File]) generatedFiles: Seq[File]
)
/** /**
* This method attempts to resolve/apply all configuration loaded for a project. It is responsible for the following: * This method attempts to resolve/apply all configuration loaded for a project. It is responsible for the following:
@ -660,7 +677,8 @@ private[sbt] object Load {
loadedPlugins: LoadedPlugins, loadedPlugins: LoadedPlugins,
globalUserSettings: InjectSettings, globalUserSettings: InjectSettings,
memoSettings: mutable.Map[File, LoadedSbtFile], memoSettings: mutable.Map[File, LoadedSbtFile],
log: Logger): Project = { log: Logger
): Project = {
import AddSettings._ import AddSettings._
val autoConfigs = projectPlugins.flatMap(_.projectConfigurations) val autoConfigs = projectPlugins.flatMap(_.projectConfigurations)
@ -707,7 +725,8 @@ private[sbt] object Load {
projectBase: File, projectBase: File,
loadedPlugins: LoadedPlugins, loadedPlugins: LoadedPlugins,
eval: () => Eval, eval: () => Eval,
memoSettings: mutable.Map[File, LoadedSbtFile]): DiscoveredProjects = { memoSettings: mutable.Map[File, LoadedSbtFile]
): DiscoveredProjects = {
// Default sbt files to read, if needed // Default sbt files to read, if needed
lazy val defaultSbtFiles = configurationSources(projectBase) lazy val defaultSbtFiles = configurationSources(projectBase)
@ -915,7 +934,8 @@ final case class LoadBuildConfiguration(
injectSettings: Load.InjectSettings, injectSettings: Load.InjectSettings,
globalPlugin: Option[GlobalPlugin], globalPlugin: Option[GlobalPlugin],
extraBuilds: Seq[URI], extraBuilds: Seq[URI],
log: Logger) { log: Logger
) {
lazy val (globalPluginClasspath, _) = Load.pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin)) lazy val (globalPluginClasspath, _) = Load.pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin))
private[sbt] lazy val globalPluginDefs = { private[sbt] lazy val globalPluginDefs = {

View File

@ -16,7 +16,8 @@ private[sbt] final class LoadedSbtFile(
// TODO - we may want to expose a simpler interface on top of here for the set command, // TODO - we may want to expose a simpler interface on top of here for the set command,
// rather than what we have now... // rather than what we have now...
val definitions: DefinedSbtValues, val definitions: DefinedSbtValues,
val generatedFiles: Seq[File]) { val generatedFiles: Seq[File]
) {
// We still use merge for now. We track originating sbt file in an alternative manner. // We still use merge for now. We track originating sbt file in an alternative manner.
def merge(o: LoadedSbtFile): LoadedSbtFile = def merge(o: LoadedSbtFile): LoadedSbtFile =
new LoadedSbtFile( new LoadedSbtFile(
@ -25,7 +26,8 @@ private[sbt] final class LoadedSbtFile(
importedDefs ++ o.importedDefs, importedDefs ++ o.importedDefs,
manipulations, manipulations,
definitions zip o.definitions, definitions zip o.definitions,
generatedFiles ++ o.generatedFiles) generatedFiles ++ o.generatedFiles
)
def clearProjects = new LoadedSbtFile(settings, Nil, importedDefs, manipulations, definitions, generatedFiles) def clearProjects = new LoadedSbtFile(settings, Nil, importedDefs, manipulations, definitions, generatedFiles)
} }

View File

@ -4,16 +4,18 @@ package internal
import sbt.internal.util.{ AttributeKey, Dag, Relation, Util } import sbt.internal.util.{ AttributeKey, Dag, Relation, Util }
import sbt.util.Logger import sbt.util.Logger
import Def.Setting import Def.Setting
import Plugins._ import Plugins._
import PluginsDebug._ import PluginsDebug._
import java.net.URI import java.net.URI
private[sbt] class PluginsDebug(val available: List[AutoPlugin], val nameToKey: Map[String, AttributeKey[_]], val provided: Relation[AutoPlugin, AttributeKey[_]]) { private[sbt] class PluginsDebug(val available: List[AutoPlugin], val nameToKey: Map[String, AttributeKey[_]], val provided: Relation[AutoPlugin, AttributeKey[_]]) {
/** The set of [[AutoPlugin]]s that might define a key named `keyName`. /**
* Because plugins can define keys in different scopes, this should only be used as a guideline. */ * The set of [[AutoPlugin]]s that might define a key named `keyName`.
* Because plugins can define keys in different scopes, this should only be used as a guideline.
*/
def providers(keyName: String): Set[AutoPlugin] = nameToKey.get(keyName) match { def providers(keyName: String): Set[AutoPlugin] = nameToKey.get(keyName) match {
case None => Set.empty case None => Set.empty
case Some(key) => provided.reverse(key) case Some(key) => provided.reverse(key)
} }
/** Describes alternative approaches for defining key [[keyName]] in [[context]].*/ /** Describes alternative approaches for defining key [[keyName]] in [[context]].*/
@ -24,28 +26,27 @@ private[sbt] class PluginsDebug(val available: List[AutoPlugin], val nameToKey:
def debug(notFoundKey: String, context: Context): String = def debug(notFoundKey: String, context: Context): String =
{ {
val (activated, deactivated) = Util.separate(toEnable(notFoundKey, context)) { val (activated, deactivated) = Util.separate(toEnable(notFoundKey, context)) {
case pa: PluginActivated => Left(pa) case pa: PluginActivated => Left(pa)
case pd: EnableDeactivated => Right(pd) case pd: EnableDeactivated => Right(pd)
} }
val activePrefix = if(activated.nonEmpty) s"Some already activated plugins define $notFoundKey: ${activated.mkString(", ")}\n" else "" val activePrefix = if (activated.nonEmpty) s"Some already activated plugins define $notFoundKey: ${activated.mkString(", ")}\n" else ""
activePrefix + debugDeactivated(notFoundKey, deactivated) activePrefix + debugDeactivated(notFoundKey, deactivated)
} }
private[this] def debugDeactivated(notFoundKey: String, deactivated: Seq[EnableDeactivated]): String = private[this] def debugDeactivated(notFoundKey: String, deactivated: Seq[EnableDeactivated]): String =
{ {
val (impossible, possible) = Util.separate(deactivated) { val (impossible, possible) = Util.separate(deactivated) {
case pi: PluginImpossible => Left(pi) case pi: PluginImpossible => Left(pi)
case pr: PluginRequirements => Right(pr) case pr: PluginRequirements => Right(pr)
} }
if(possible.nonEmpty) { if (possible.nonEmpty) {
val explained = possible.map(explainPluginEnable) val explained = possible.map(explainPluginEnable)
val possibleString = val possibleString =
if(explained.size > 1) explained.zipWithIndex.map{case (s,i) => s"$i. $s"}.mkString(s"Multiple plugins are available that can provide $notFoundKey:\n", "\n", "") if (explained.size > 1) explained.zipWithIndex.map { case (s, i) => s"$i. $s" }.mkString(s"Multiple plugins are available that can provide $notFoundKey:\n", "\n", "")
else s"$notFoundKey is provided by an available (but not activated) plugin:\n${explained.mkString}" else s"$notFoundKey is provided by an available (but not activated) plugin:\n${explained.mkString}"
def impossiblePlugins = impossible.map(_.plugin.label).mkString(", ") def impossiblePlugins = impossible.map(_.plugin.label).mkString(", ")
val imPostfix = if(impossible.isEmpty) "" else s"\n\nThere are other available plugins that provide $notFoundKey, but they are impossible to add: $impossiblePlugins" val imPostfix = if (impossible.isEmpty) "" else s"\n\nThere are other available plugins that provide $notFoundKey, but they are impossible to add: $impossiblePlugins"
possibleString + imPostfix possibleString + imPostfix
} } else if (impossible.isEmpty)
else if(impossible.isEmpty)
s"No available plugin provides key $notFoundKey." s"No available plugin provides key $notFoundKey."
else { else {
val explanations = impossible.map(explainPluginEnable) val explanations = impossible.map(explainPluginEnable)
@ -61,44 +62,42 @@ private[sbt] class PluginsDebug(val available: List[AutoPlugin], val nameToKey:
{ {
val prefix = s"${plugin.label} is activated." val prefix = s"${plugin.label} is activated."
val keys = provided.forward(plugin) val keys = provided.forward(plugin)
val keysString = if(keys.isEmpty) "" else s"\nIt may affect these keys: ${multi(keys.toList.map(_.label))}" val keysString = if (keys.isEmpty) "" else s"\nIt may affect these keys: ${multi(keys.toList.map(_.label))}"
val configs = plugin.projectConfigurations val configs = plugin.projectConfigurations
val confsString = if(configs.isEmpty) "" else s"\nIt defines these configurations: ${multi(configs.map(_.name))}" val confsString = if (configs.isEmpty) "" else s"\nIt defines these configurations: ${multi(configs.map(_.name))}"
prefix + keysString + confsString prefix + keysString + confsString
} }
private def deactivatedHelp(plugin: AutoPlugin, context: Context): String = private def deactivatedHelp(plugin: AutoPlugin, context: Context): String =
{ {
val prefix = s"${plugin.label} is NOT activated." val prefix = s"${plugin.label} is NOT activated."
val keys = provided.forward(plugin) val keys = provided.forward(plugin)
val keysString = if(keys.isEmpty) "" else s"\nActivating it may affect these keys: ${multi(keys.toList.map(_.label))}" val keysString = if (keys.isEmpty) "" else s"\nActivating it may affect these keys: ${multi(keys.toList.map(_.label))}"
val configs = plugin.projectConfigurations val configs = plugin.projectConfigurations
val confsString = if(configs.isEmpty) "" else s"\nActivating it will define these configurations: ${multi(configs.map(_.name))}" val confsString = if (configs.isEmpty) "" else s"\nActivating it will define these configurations: ${multi(configs.map(_.name))}"
val toActivate = explainPluginEnable(pluginEnable(context, plugin)) val toActivate = explainPluginEnable(pluginEnable(context, plugin))
s"$prefix$keysString$confsString\n$toActivate" s"$prefix$keysString$confsString\n$toActivate"
} }
private[this] def multi(strs: Seq[String]): String = strs.mkString(if(strs.size > 4) "\n\t" else ", ") private[this] def multi(strs: Seq[String]): String = strs.mkString(if (strs.size > 4) "\n\t" else ", ")
} }
private[sbt] object PluginsDebug { private[sbt] object PluginsDebug {
def helpAll(s: State): String = def helpAll(s: State): String =
if(Project.isProjectLoaded(s)) if (Project.isProjectLoaded(s)) {
{ val extracted = Project.extract(s)
val extracted = Project.extract(s) import extracted._
import extracted._ def helpBuild(uri: URI, build: LoadedBuildUnit): String =
def helpBuild(uri: URI, build: LoadedBuildUnit): String =
{ {
val pluginStrings = for(plugin <- availableAutoPlugins(build)) yield { val pluginStrings = for (plugin <- availableAutoPlugins(build)) yield {
val activatedIn = build.defined.values.toList.filter(_.autoPlugins.contains(plugin)).map(_.id) val activatedIn = build.defined.values.toList.filter(_.autoPlugins.contains(plugin)).map(_.id)
val actString = if(activatedIn.nonEmpty) activatedIn.mkString(": enabled in ", ", ", "") else "" // TODO: deal with large builds val actString = if (activatedIn.nonEmpty) activatedIn.mkString(": enabled in ", ", ", "") else "" // TODO: deal with large builds
s"\n\t${plugin.label}$actString" s"\n\t${plugin.label}$actString"
} }
s"In $uri${pluginStrings.mkString}" s"In $uri${pluginStrings.mkString}"
} }
val buildStrings = for((uri, build) <- structure.units) yield helpBuild(uri, build) val buildStrings = for ((uri, build) <- structure.units) yield helpBuild(uri, build)
buildStrings.mkString("\n") buildStrings.mkString("\n")
} } else "No project is currently loaded."
else "No project is currently loaded."
def autoPluginMap(s: State): Map[String, AutoPlugin] = def autoPluginMap(s: State): Map[String, AutoPlugin] =
{ {
@ -107,7 +106,7 @@ private[sbt] object PluginsDebug {
structure.units.values.toList.flatMap(availableAutoPlugins).map(plugin => (plugin.label, plugin)).toMap structure.units.values.toList.flatMap(availableAutoPlugins).map(plugin => (plugin.label, plugin)).toMap
} }
private[this] def availableAutoPlugins(build: LoadedBuildUnit): Seq[AutoPlugin] = private[this] def availableAutoPlugins(build: LoadedBuildUnit): Seq[AutoPlugin] =
build.unit.plugins.detected.autoPlugins map {_.value} build.unit.plugins.detected.autoPlugins map { _.value }
def help(plugin: AutoPlugin, s: State): String = def help(plugin: AutoPlugin, s: State): String =
{ {
@ -119,21 +118,21 @@ private[sbt] object PluginsDebug {
val pluginsThisBuild = perBuild.getOrElse(currentRef.build, Set.empty).toList val pluginsThisBuild = perBuild.getOrElse(currentRef.build, Set.empty).toList
lazy val context = Context(currentProject.plugins, currentProject.autoPlugins, Plugins.deducer(pluginsThisBuild), pluginsThisBuild, s.log) lazy val context = Context(currentProject.plugins, currentProject.autoPlugins, Plugins.deducer(pluginsThisBuild), pluginsThisBuild, s.log)
lazy val debug = PluginsDebug(context.available) lazy val debug = PluginsDebug(context.available)
if(!pluginsThisBuild.contains(plugin)) { if (!pluginsThisBuild.contains(plugin)) {
val availableInBuilds: List[URI] = perBuild.toList.filter(_._2(plugin)).map(_._1) val availableInBuilds: List[URI] = perBuild.toList.filter(_._2(plugin)).map(_._1)
s"Plugin ${plugin.label} is only available in builds:\n\t${availableInBuilds.mkString("\n\t")}\nSwitch to a project in one of those builds using `project` and rerun this command for more information." s"Plugin ${plugin.label} is only available in builds:\n\t${availableInBuilds.mkString("\n\t")}\nSwitch to a project in one of those builds using `project` and rerun this command for more information."
} else if(definesPlugin(currentProject)) } else if (definesPlugin(currentProject))
debug.activatedHelp(plugin) debug.activatedHelp(plugin)
else { else {
val thisAggregated = BuildUtil.dependencies(structure.units).aggregateTransitive.getOrElse(currentRef, Nil) val thisAggregated = BuildUtil.dependencies(structure.units).aggregateTransitive.getOrElse(currentRef, Nil)
val definedInAggregated = thisAggregated.filter(ref => definesPlugin(projectForRef(ref))) val definedInAggregated = thisAggregated.filter(ref => definesPlugin(projectForRef(ref)))
if(definedInAggregated.nonEmpty) { if (definedInAggregated.nonEmpty) {
val projectNames = definedInAggregated.map(_.project) // TODO: usually in this build, but could technically require the build to be qualified val projectNames = definedInAggregated.map(_.project) // TODO: usually in this build, but could technically require the build to be qualified
s"Plugin ${plugin.label} is not activated on this project, but this project aggregates projects where it is activated:\n\t${projectNames.mkString("\n\t")}" s"Plugin ${plugin.label} is not activated on this project, but this project aggregates projects where it is activated:\n\t${projectNames.mkString("\n\t")}"
} else { } else {
val base = debug.deactivatedHelp(plugin, context) val base = debug.deactivatedHelp(plugin, context)
val aggNote = if(thisAggregated.nonEmpty) "Note: This project aggregates other projects and this" else "Note: This" val aggNote = if (thisAggregated.nonEmpty) "Note: This project aggregates other projects and this" else "Note: This"
val common = " information is for this project only." val common = " information is for this project only."
val helpOther = "To see how to activate this plugin for another project, change to the project using `project <name>` and rerun this command." val helpOther = "To see how to activate this plugin for another project, change to the project using `project <name>` and rerun this command."
s"$base\n$aggNote$common\n$helpOther" s"$base\n$aggNote$common\n$helpOther"
} }
@ -148,11 +147,13 @@ private[sbt] object PluginsDebug {
new PluginsDebug(available, nameToKey, keyR) new PluginsDebug(available, nameToKey, keyR)
} }
/** The context for debugging a plugin (de)activation. /**
* @param initial The initially defined [[AutoPlugin]]s. * The context for debugging a plugin (de)activation.
* @param enabled The resulting model. * @param initial The initially defined [[AutoPlugin]]s.
* @param deducePlugin The function used to compute the model. * @param enabled The resulting model.
* @param available All [[AutoPlugin]]s available for consideration. */ * @param deducePlugin The function used to compute the model.
* @param available All [[AutoPlugin]]s available for consideration.
*/
final case class Context(initial: Plugins, enabled: Seq[AutoPlugin], deducePlugin: (Plugins, Logger) => Seq[AutoPlugin], available: List[AutoPlugin], log: Logger) final case class Context(initial: Plugins, enabled: Seq[AutoPlugin], deducePlugin: (Plugins, Logger) => Seq[AutoPlugin], available: List[AutoPlugin], log: Logger)
/** Describes the steps to activate a plugin in some context. */ /** Describes the steps to activate a plugin in some context. */
@ -163,24 +164,28 @@ private[sbt] object PluginsDebug {
/** Describes a [[plugin]] that cannot be activated in a [[context]] due to [[contradictions]] in requirements. */ /** Describes a [[plugin]] that cannot be activated in a [[context]] due to [[contradictions]] in requirements. */
final case class PluginImpossible(plugin: AutoPlugin, context: Context, contradictions: Set[AutoPlugin]) extends EnableDeactivated final case class PluginImpossible(plugin: AutoPlugin, context: Context, contradictions: Set[AutoPlugin]) extends EnableDeactivated
/** Describes the requirements for activating [[plugin]] in [[context]]. /**
* @param context The base plugins, exclusions, and ultimately activated plugins * Describes the requirements for activating [[plugin]] in [[context]].
* @param blockingExcludes Existing exclusions that prevent [[plugin]] from being activated and must be dropped * @param context The base plugins, exclusions, and ultimately activated plugins
* @param enablingPlugins [[AutoPlugin]]s that are not currently enabled, but need to be enabled for [[plugin]] to activate * @param blockingExcludes Existing exclusions that prevent [[plugin]] from being activated and must be dropped
* @param extraEnabledPlugins Plugins that will be enabled as a result of [[plugin]] activating, but are not required for [[plugin]] to activate * @param enablingPlugins [[AutoPlugin]]s that are not currently enabled, but need to be enabled for [[plugin]] to activate
* @param willRemove Plugins that will be deactivated as a result of [[plugin]] activating * @param extraEnabledPlugins Plugins that will be enabled as a result of [[plugin]] activating, but are not required for [[plugin]] to activate
* @param deactivate Describes plugins that must be deactivated for [[plugin]] to activate. These require an explicit exclusion or dropping a transitive [[AutoPlugin]].*/ * @param willRemove Plugins that will be deactivated as a result of [[plugin]] activating
* @param deactivate Describes plugins that must be deactivated for [[plugin]] to activate. These require an explicit exclusion or dropping a transitive [[AutoPlugin]].
*/
final case class PluginRequirements(plugin: AutoPlugin, context: Context, blockingExcludes: Set[AutoPlugin], enablingPlugins: Set[AutoPlugin], extraEnabledPlugins: Set[AutoPlugin], willRemove: Set[AutoPlugin], deactivate: List[DeactivatePlugin]) extends EnableDeactivated final case class PluginRequirements(plugin: AutoPlugin, context: Context, blockingExcludes: Set[AutoPlugin], enablingPlugins: Set[AutoPlugin], extraEnabledPlugins: Set[AutoPlugin], willRemove: Set[AutoPlugin], deactivate: List[DeactivatePlugin]) extends EnableDeactivated
/** Describes a [[plugin]] that must be removed in order to activate another plugin in some context. /**
* The [[plugin]] can always be directly, explicitly excluded. * Describes a [[plugin]] that must be removed in order to activate another plugin in some context.
* @param removeOneOf If non-empty, removing one of these [[AutoPlugin]]s will deactivate [[plugin]] without affecting the other plugin. If empty, a direct exclusion is required. * The [[plugin]] can always be directly, explicitly excluded.
* @param newlySelected If false, this plugin was selected in the original context. */ * @param removeOneOf If non-empty, removing one of these [[AutoPlugin]]s will deactivate [[plugin]] without affecting the other plugin. If empty, a direct exclusion is required.
* @param newlySelected If false, this plugin was selected in the original context.
*/
final case class DeactivatePlugin(plugin: AutoPlugin, removeOneOf: Set[AutoPlugin], newlySelected: Boolean) final case class DeactivatePlugin(plugin: AutoPlugin, removeOneOf: Set[AutoPlugin], newlySelected: Boolean)
/** Determines how to enable [[plugin]] in [[context]]. */ /** Determines how to enable [[plugin]] in [[context]]. */
def pluginEnable(context: Context, plugin: AutoPlugin): PluginEnable = def pluginEnable(context: Context, plugin: AutoPlugin): PluginEnable =
if(context.enabled.contains(plugin)) if (context.enabled.contains(plugin))
PluginActivated(plugin, context) PluginActivated(plugin, context)
else else
enableDeactivated(context, plugin) enableDeactivated(context, plugin)
@ -248,7 +253,7 @@ private[sbt] object PluginsDebug {
// So, in either of these cases, A doesn't need to be considered further and won't be included in this set. // So, in either of these cases, A doesn't need to be considered further and won't be included in this set.
val minDeactivate = minAbsentPlugins.filter(p => Plugins.satisfied(p.requires, incrementalModel)) val minDeactivate = minAbsentPlugins.filter(p => Plugins.satisfied(p.requires, incrementalModel))
val deactivate = for(d <- minDeactivate.toList) yield { val deactivate = for (d <- minDeactivate.toList) yield {
// removing any one of these plugins will deactivate `d`. TODO: This is not an especially efficient implementation. // removing any one of these plugins will deactivate `d`. TODO: This is not an especially efficient implementation.
val removeToDeactivate = plugins(minimalModel(d)) -- minRequiredPlugins val removeToDeactivate = plugins(minimalModel(d)) -- minRequiredPlugins
val newlySelected = !initialModel(d) val newlySelected = !initialModel(d)
@ -273,7 +278,7 @@ private[sbt] object PluginsDebug {
// It might not be valid, such as if there are contradictions or if there are cycles that are unsatisfiable. // It might not be valid, such as if there are contradictions or if there are cycles that are unsatisfiable.
// The actual model might be larger, since other plugins might be enabled by the selected plugins. // The actual model might be larger, since other plugins might be enabled by the selected plugins.
private[this] def minimalModel(plugin: AutoPlugin): Seq[Basic] = Dag.topologicalSortUnchecked(plugin: Basic) { private[this] def minimalModel(plugin: AutoPlugin): Seq[Basic] = Dag.topologicalSortUnchecked(plugin: Basic) {
case _: Exclude => Nil case _: Exclude => Nil
case ap: AutoPlugin => Plugins.flatten(ap.requires) :+ plugin case ap: AutoPlugin => Plugins.flatten(ap.requires) :+ plugin
} }
@ -281,29 +286,31 @@ private[sbt] object PluginsDebug {
def explainPluginEnable(ps: PluginEnable): String = def explainPluginEnable(ps: PluginEnable): String =
ps match { ps match {
case PluginRequirements(plugin, context, blockingExcludes, enablingPlugins, extraEnabledPlugins, toBeRemoved, deactivate) => case PluginRequirements(plugin, context, blockingExcludes, enablingPlugins, extraEnabledPlugins, toBeRemoved, deactivate) =>
def indent(str: String) = if(str.isEmpty) "" else s"\t$str" def indent(str: String) = if (str.isEmpty) "" else s"\t$str"
def note(str: String) = if(str.isEmpty) "" else s"Note: $str" def note(str: String) = if (str.isEmpty) "" else s"Note: $str"
val parts = val parts =
indent(excludedError(false /* TODO */, blockingExcludes.toList)) :: indent(excludedError(false /* TODO */ , blockingExcludes.toList)) ::
indent(required(enablingPlugins.toList)) :: indent(required(enablingPlugins.toList)) ::
indent(needToDeactivate(deactivate)) :: indent(needToDeactivate(deactivate)) ::
note(willAdd(plugin, extraEnabledPlugins.toList)) :: note(willAdd(plugin, extraEnabledPlugins.toList)) ::
note(willRemove(plugin, toBeRemoved.toList)) :: note(willRemove(plugin, toBeRemoved.toList)) ::
Nil Nil
parts.filterNot(_.isEmpty).mkString("\n") parts.filterNot(_.isEmpty).mkString("\n")
case PluginImpossible(plugin, context, contradictions) => pluginImpossible(plugin, contradictions) case PluginImpossible(plugin, context, contradictions) => pluginImpossible(plugin, contradictions)
case PluginActivated(plugin, context) => s"Plugin ${plugin.label} already activated." case PluginActivated(plugin, context) => s"Plugin ${plugin.label} already activated."
} }
/** Provides a [[Relation]] between plugins and the keys they potentially define. /**
* Because plugins can define keys in different scopes and keys can be overridden, this is not definitive.*/ * Provides a [[Relation]] between plugins and the keys they potentially define.
* Because plugins can define keys in different scopes and keys can be overridden, this is not definitive.
*/
def definedKeys(available: List[AutoPlugin]): Relation[AutoPlugin, AttributeKey[_]] = def definedKeys(available: List[AutoPlugin]): Relation[AutoPlugin, AttributeKey[_]] =
{ {
def extractDefinedKeys(ss: Seq[Setting[_]]): Seq[AttributeKey[_]] = def extractDefinedKeys(ss: Seq[Setting[_]]): Seq[AttributeKey[_]] =
ss.map(_.key.key) ss.map(_.key.key)
def allSettings(p: AutoPlugin): Seq[Setting[_]] = p.projectSettings ++ p.buildSettings ++ p.globalSettings def allSettings(p: AutoPlugin): Seq[Setting[_]] = p.projectSettings ++ p.buildSettings ++ p.globalSettings
val empty = Relation.empty[AutoPlugin, AttributeKey[_]] val empty = Relation.empty[AutoPlugin, AttributeKey[_]]
(empty /: available)( (r,p) => r + (p, extractDefinedKeys(allSettings(p))) ) (empty /: available)((r, p) => r + (p, extractDefinedKeys(allSettings(p))))
} }
private[this] def excludedError(transitive: Boolean, dependencies: List[AutoPlugin]): String = private[this] def excludedError(transitive: Boolean, dependencies: List[AutoPlugin]): String =
@ -314,7 +321,7 @@ private[sbt] object PluginsDebug {
private[this] def excludedPluginsError(transitive: Boolean)(dependencies: List[AutoPlugin]) = private[this] def excludedPluginsError(transitive: Boolean)(dependencies: List[AutoPlugin]) =
s"Required ${transitiveString(transitive)}dependencies were excluded:\n\t${labels(dependencies).mkString("\n\t")}" s"Required ${transitiveString(transitive)}dependencies were excluded:\n\t${labels(dependencies).mkString("\n\t")}"
private[this] def transitiveString(transitive: Boolean) = private[this] def transitiveString(transitive: Boolean) =
if(transitive) "(transitive) " else "" if (transitive) "(transitive) " else ""
private[this] def required(plugins: List[AutoPlugin]): String = private[this] def required(plugins: List[AutoPlugin]): String =
str(plugins)(requiredPlugin, requiredPlugins) str(plugins)(requiredPlugin, requiredPlugins)
@ -360,9 +367,9 @@ private[sbt] object PluginsDebug {
{ {
val removePluginsString: String = val removePluginsString: String =
d.removeOneOf.toList match { d.removeOneOf.toList match {
case Nil => "" case Nil => ""
case x :: Nil => s" or no longer include $x" case x :: Nil => s" or no longer include $x"
case xs => s" or remove one of ${xs.mkString(", ")}" case xs => s" or remove one of ${xs.mkString(", ")}"
} }
s"${d.plugin.label}: directly exclude it${removePluginsString}" s"${d.plugin.label}: directly exclude it${removePluginsString}"
} }

View File

@ -12,13 +12,13 @@ object RetrieveUnit {
def apply(info: ResolveInfo): Option[() => File] = def apply(info: ResolveInfo): Option[() => File] =
{ {
info.uri match { info.uri match {
case Scheme("svn") | Scheme("svn+ssh") => Resolvers.subversion(info) case Scheme("svn") | Scheme("svn+ssh") => Resolvers.subversion(info)
case Scheme("hg") => Resolvers.mercurial(info) case Scheme("hg") => Resolvers.mercurial(info)
case Scheme("git") => Resolvers.git(info) case Scheme("git") => Resolvers.git(info)
case Path(path) if path.endsWith(".git") => Resolvers.git(info) case Path(path) if path.endsWith(".git") => Resolvers.git(info)
case Scheme("http") | Scheme("https") | Scheme("ftp") => Resolvers.remote(info) case Scheme("http") | Scheme("https") | Scheme("ftp") => Resolvers.remote(info)
case Scheme("file") => Resolvers.local(info) case Scheme("file") => Resolvers.local(info)
case _ => None case _ => None
} }
} }

View File

@ -190,7 +190,7 @@ object SessionSettings {
case ((in, oth, keys), s) => case ((in, oth, keys), s) =>
s.pos match { s.pos match {
case RangePosition(`path`, _) if !keys.contains(s.key) => (s :: in, oth, keys + s.key) case RangePosition(`path`, _) if !keys.contains(s.key) => (s :: in, oth, keys + s.key)
case _ => (in, s :: oth, keys) case _ => (in, s :: oth, keys)
} }
} }

View File

@ -34,12 +34,14 @@ object SettingGraph {
} }
} }
case class SettingGraph(name: String, case class SettingGraph(
name: String,
definedIn: Option[String], definedIn: Option[String],
data: Option[ScopedKeyData[_]], data: Option[ScopedKeyData[_]],
description: Option[String], description: Option[String],
basedir: File, basedir: File,
depends: Set[SettingGraph]) { depends: Set[SettingGraph]
) {
def dataString: String = def dataString: String =
data map { d => data map { d =>
d.settingValue map { d.settingValue map {
@ -48,9 +50,11 @@ case class SettingGraph(name: String,
} getOrElse { d.typeName } } getOrElse { d.typeName }
} getOrElse { "" } } getOrElse { "" }
def dependsAscii: String = Graph.toAscii(this, def dependsAscii: String = Graph.toAscii(
this,
(x: SettingGraph) => x.depends.toSeq.sortBy(_.name), (x: SettingGraph) => x.depends.toSeq.sortBy(_.name),
(x: SettingGraph) => "%s = %s" format (x.definedIn getOrElse { "" }, x.dataString)) (x: SettingGraph) => "%s = %s" format (x.definedIn getOrElse { "" }, x.dataString)
)
} }
object Graph { object Graph {

View File

@ -9,8 +9,10 @@ import Def._
trait TaskSequential { trait TaskSequential {
def sequential[B](last: Initialize[Task[B]]): Initialize[Task[B]] = def sequential[B](last: Initialize[Task[B]]): Initialize[Task[B]] =
sequential(Nil, last) sequential(Nil, last)
def sequential[A0, B](task0: Initialize[Task[A0]], def sequential[A0, B](
last: Initialize[Task[B]]): Initialize[Task[B]] = task0: Initialize[Task[A0]],
last: Initialize[Task[B]]
): Initialize[Task[B]] =
sequential(List(unitTask(task0)), last) sequential(List(unitTask(task0)), last)
def sequential[A0, A1, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], def sequential[A0, A1, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]],
last: Initialize[Task[B]]): Initialize[Task[B]] = last: Initialize[Task[B]]): Initialize[Task[B]] =

View File

@ -19,8 +19,8 @@ object IvyPlugin extends AutoPlugin {
override def requires = CorePlugin override def requires = CorePlugin
override def trigger = allRequirements override def trigger = allRequirements
override lazy val projectSettings: Seq[Setting[_]] = override lazy val projectSettings: Seq[Setting[_]] =
Classpaths.ivyPublishSettings ++ Classpaths.ivyBaseSettings Classpaths.ivyPublishSettings ++ Classpaths.ivyBaseSettings
override lazy val globalSettings: Seq[Setting[_]] = override lazy val globalSettings: Seq[Setting[_]] =
Defaults.globalIvyCore Defaults.globalIvyCore
} }

View File

@ -4,7 +4,8 @@ package plugins
import Def.Setting import Def.Setting
import Keys._ import Keys._
/** An experimental plugin that adds the ability for junit-xml to be generated. /**
* An experimental plugin that adds the ability for junit-xml to be generated.
* *
* To disable this plugin, you need to add: * To disable this plugin, you need to add:
* {{{ * {{{
@ -17,7 +18,7 @@ object JUnitXmlReportPlugin extends AutoPlugin {
// TODO - If testing becomes its own plugin, we only rely on the core settings. // TODO - If testing becomes its own plugin, we only rely on the core settings.
override def requires = JvmPlugin override def requires = JvmPlugin
override def trigger = allRequirements override def trigger = allRequirements
// Right now we add to the global test listeners which should capture *all* tests. // Right now we add to the global test listeners which should capture *all* tests.
// It might be a good idea to derive this setting into specific test scopes. // It might be a good idea to derive this setting into specific test scopes.
override lazy val projectSettings: Seq[Setting[_]] = override lazy val projectSettings: Seq[Setting[_]] =

View File

@ -5,7 +5,8 @@ import sbt.librarymanagement.{ Configuration, Configurations }
import Def.Setting import Def.Setting
/** A plugin representing the ability to build a JVM project. /**
* A plugin representing the ability to build a JVM project.
* *
* Core tasks/keys: * Core tasks/keys:
* - `run` * - `run`
@ -21,18 +22,18 @@ object JvmPlugin extends AutoPlugin {
// for ours to work. // for ours to work.
override def requires = IvyPlugin override def requires = IvyPlugin
override def trigger = allRequirements override def trigger = allRequirements
override lazy val projectSettings: Seq[Setting[_]] =
Defaults.runnerSettings ++
Defaults.paths ++
Classpaths.jvmPublishSettings ++
Classpaths.jvmBaseSettings ++
Defaults.baseTasks ++
Defaults.compileBase ++
Defaults.defaultConfigs
override lazy val globalSettings: Seq[Setting[_]] =
Defaults.globalJvmCore
override def projectConfigurations: Seq[Configuration] = override lazy val projectSettings: Seq[Setting[_]] =
Defaults.runnerSettings ++
Defaults.paths ++
Classpaths.jvmPublishSettings ++
Classpaths.jvmBaseSettings ++
Defaults.baseTasks ++
Defaults.compileBase ++
Defaults.defaultConfigs
override lazy val globalSettings: Seq[Setting[_]] =
Defaults.globalJvmCore
override def projectConfigurations: Seq[Configuration] =
Configurations.default Configurations.default
} }

View File

@ -4,87 +4,80 @@ import org.specs2._
import mutable.Specification import mutable.Specification
import sbt.util.Logger import sbt.util.Logger
object PluginsTest extends Specification object PluginsTest extends Specification {
{ import AI._
import AI._
"Auto plugin" should { "Auto plugin" should {
"enable plugins with trigger=allRequirements AND requirements met" in { "enable plugins with trigger=allRequirements AND requirements met" in {
deducePlugin(A && B, log) must contain(Q) deducePlugin(A && B, log) must contain(Q)
} }
"enable transitive plugins with trigger=allRequirements AND requirements met" in { "enable transitive plugins with trigger=allRequirements AND requirements met" in {
deducePlugin(A && B, log) must contain(R) deducePlugin(A && B, log) must contain(R)
} }
"order enable plugins after required plugins" in { "order enable plugins after required plugins" in {
val ns = deducePlugin(A && B, log) val ns = deducePlugin(A && B, log)
( (ns indexOf Q) must beGreaterThan(ns indexOf A) ) and ((ns indexOf Q) must beGreaterThan(ns indexOf A)) and
( (ns indexOf Q) must beGreaterThan(ns indexOf B) ) and ((ns indexOf Q) must beGreaterThan(ns indexOf B)) and
( (ns indexOf R) must beGreaterThan(ns indexOf A) ) and ((ns indexOf R) must beGreaterThan(ns indexOf A)) and
( (ns indexOf R) must beGreaterThan(ns indexOf B) ) and ((ns indexOf R) must beGreaterThan(ns indexOf B)) and
( (ns indexOf R) must beGreaterThan(ns indexOf Q) ) ((ns indexOf R) must beGreaterThan(ns indexOf Q))
} }
"not enable plugins with trigger=allRequirements but conflicting requirements" in { "not enable plugins with trigger=allRequirements but conflicting requirements" in {
deducePlugin(A && B, log) must not contain(S) deducePlugin(A && B, log) must not contain (S)
} }
"enable plugins that are required by the requested plugins" in { "enable plugins that are required by the requested plugins" in {
val ns = deducePlugin(Q, log) val ns = deducePlugin(Q, log)
(ns must contain(A)) and (ns must contain(A)) and
(ns must contain(B)) (ns must contain(B))
} }
"throw an AutoPluginException on conflicting requirements" in { "throw an AutoPluginException on conflicting requirements" in {
deducePlugin(S, log) must throwAn[AutoPluginException](message = """Contradiction in enabled plugins: deducePlugin(S, log) must throwAn[AutoPluginException](message = """Contradiction in enabled plugins:
- requested: sbt.AI\$S - requested: sbt.AI\$S
- enabled: sbt.AI\$S, sbt.AI\$Q, sbt.AI\$R, sbt.AI\$B, sbt.AI\$A - enabled: sbt.AI\$S, sbt.AI\$Q, sbt.AI\$R, sbt.AI\$B, sbt.AI\$A
- conflict: sbt.AI\$R is enabled by sbt.AI\$Q; excluded by sbt.AI\$S""") - conflict: sbt.AI\$R is enabled by sbt.AI\$Q; excluded by sbt.AI\$S""")
} }
"generates a detailed report on conflicting requirements" in { "generates a detailed report on conflicting requirements" in {
deducePlugin(T && U, log) must throwAn[AutoPluginException](message = """Contradiction in enabled plugins: deducePlugin(T && U, log) must throwAn[AutoPluginException](message = """Contradiction in enabled plugins:
- requested: sbt.AI\$T && sbt.AI\$U - requested: sbt.AI\$T && sbt.AI\$U
- enabled: sbt.AI\$U, sbt.AI\$T, sbt.AI\$A, sbt.AI\$Q, sbt.AI\$R, sbt.AI\$B - enabled: sbt.AI\$U, sbt.AI\$T, sbt.AI\$A, sbt.AI\$Q, sbt.AI\$R, sbt.AI\$B
- conflict: sbt.AI\$Q is enabled by sbt.AI\$A && sbt.AI\$B; required by sbt.AI\$T, sbt.AI\$R; excluded by sbt.AI\$U - conflict: sbt.AI\$Q is enabled by sbt.AI\$A && sbt.AI\$B; required by sbt.AI\$T, sbt.AI\$R; excluded by sbt.AI\$U
- conflict: sbt.AI\$R is enabled by sbt.AI\$Q; excluded by sbt.AI\$T""") - conflict: sbt.AI\$R is enabled by sbt.AI\$Q; excluded by sbt.AI\$T""")
} }
} }
} }
object AI object AI {
{ lazy val allPlugins: List[AutoPlugin] = List(A, B, Q, R, S, T, U)
lazy val allPlugins: List[AutoPlugin] = List(A, B, Q, R, S, T, U) lazy val deducePlugin = Plugins.deducer(allPlugins)
lazy val deducePlugin = Plugins.deducer(allPlugins) lazy val log = Logger.Null
lazy val log = Logger.Null
object A extends AutoPlugin { override def requires = empty } object A extends AutoPlugin { override def requires = empty }
object B extends AutoPlugin { override def requires = empty } object B extends AutoPlugin { override def requires = empty }
object Q extends AutoPlugin object Q extends AutoPlugin {
{ override def requires: Plugins = A && B
override def requires: Plugins = A && B override def trigger = allRequirements
override def trigger = allRequirements }
}
object R extends AutoPlugin object R extends AutoPlugin {
{ override def requires = Q
override def requires = Q override def trigger = allRequirements
override def trigger = allRequirements }
}
object S extends AutoPlugin object S extends AutoPlugin {
{ override def requires = Q && !R
override def requires = Q && !R override def trigger = allRequirements
override def trigger = allRequirements }
}
// This is an opt-in plugin with a requirement // This is an opt-in plugin with a requirement
// Unless explicitly loaded by the build user, this will not be activated. // Unless explicitly loaded by the build user, this will not be activated.
object T extends AutoPlugin object T extends AutoPlugin {
{ override def requires = Q && !R
override def requires = Q && !R }
}
// This is an opt-in plugin with a requirement // This is an opt-in plugin with a requirement
// Unless explicitly loaded by the build user, this will not be activated. // Unless explicitly loaded by the build user, this will not be activated.
object U extends AutoPlugin object U extends AutoPlugin {
{ override def requires = A && !Q
override def requires = A && !Q }
}
} }

View File

@ -13,7 +13,8 @@ class CommentedXmlSpec extends CheckIfParsedSpec {
| |
|val tra = "</scm>" |val tra = "</scm>"
| |
""".stripMargin, "Xml in string", false, true), """.stripMargin, "Xml in string", false, true
),
(""" ("""
|val scmpom = taskKey[xml.NodeBuffer]("Node buffer") |val scmpom = taskKey[xml.NodeBuffer]("Node buffer")
| |

View File

@ -139,7 +139,8 @@ class EmbeddedXmlSpec extends CheckIfParsedSpec {
| |
| |
| |
""".stripMargin, "xml with blank line", false, true) """.stripMargin, "xml with blank line", false, true
)
) )
} }

View File

@ -36,7 +36,8 @@ lazy val root = (project in file(".")).enablePlugins­(PlayScala)""")
"""import foo.Bar """import foo.Bar
import foo.Bar import foo.Bar
version := "1.0" version := "1.0"
""".stripMargin) """.stripMargin
)
imports.size === 2 imports.size === 2
settingsAndDefs.size === 1 settingsAndDefs.size === 1
} }

View File

@ -2,54 +2,102 @@ import sbt._
import Keys._ import Keys._
object Dependencies { object Dependencies {
lazy val scala282 = "2.8.2" val scala282 = "2.8.2"
lazy val scala292 = "2.9.2" val scala292 = "2.9.2"
lazy val scala293 = "2.9.3" val scala293 = "2.9.3"
lazy val scala210 = "2.10.6" val scala210 = "2.10.6"
lazy val scala211 = "2.11.8" val scala211 = "2.11.8"
// sbt modules // sbt modules
val ioVersion = "1.0.0-M6" private val ioVersion = "1.0.0-M6"
val utilVersion = "0.1.0-M14" private val utilVersion = "0.1.0-M14"
val librarymanagementVersion = "0.1.0-X1" private val lmVersion = "0.1.0-X1"
val zincVersion = "1.0.0-X3" private val zincVersion = "1.0.0-X3"
lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion
lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion
lazy val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion
lazy val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion
lazy val utilControl = "org.scala-sbt" %% "util-control" % utilVersion
lazy val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion
lazy val utilApplyMacro = "org.scala-sbt" %% "util-apply-macro" % utilVersion
lazy val utilRelation = "org.scala-sbt" %% "util-relation" % utilVersion
lazy val utilLogic = "org.scala-sbt" %% "util-logic" % utilVersion
lazy val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion
lazy val utilTracking = "org.scala-sbt" %% "util-tracking" % utilVersion
lazy val utilScripted = "org.scala-sbt" %% "util-scripted" % utilVersion
lazy val libraryManagement = "org.scala-sbt" %% "librarymanagement" % librarymanagementVersion
lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0"
lazy val rawLauncher = "org.scala-sbt" % "launcher" % "1.0.0"
lazy val testInterface = "org.scala-sbt" % "test-interface" % "1.0"
lazy val zinc = "org.scala-sbt" %% "zinc" % zincVersion private val sbtIO = "org.scala-sbt" %% "io" % ioVersion
lazy val zincCompile = "org.scala-sbt" %% "zinc-compile" % zincVersion
lazy val compilerInterface = "org.scala-sbt" % "compiler-interface" % zincVersion
lazy val compilerBrdige = "org.scala-sbt" %% "compiler-bridge" % zincVersion
lazy val compilerClasspath = "org.scala-sbt" %% "zinc-classpath" % zincVersion
lazy val compilerApiInfo = "org.scala-sbt" %% "zinc-apiinfo" % zincVersion
lazy val compilerIvyIntegration = "org.scala-sbt" %% "zinc-ivy-integration" % zincVersion
lazy val sjsonNewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % "0.4.2"
lazy val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.11.4" private val utilApplyMacro = "org.scala-sbt" %% "util-apply-macro" % utilVersion
lazy val specs2 = "org.specs2" %% "specs2" % "2.3.11" private val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion
lazy val junit = "junit" % "junit" % "4.11" private val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion
private val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion
private val utilControl = "org.scala-sbt" %% "util-control" % utilVersion
private val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion
private val utilLogic = "org.scala-sbt" %% "util-logic" % utilVersion
private val utilRelation = "org.scala-sbt" %% "util-relation" % utilVersion
private val utilScripted = "org.scala-sbt" %% "util-scripted" % utilVersion
private val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion
private val utilTracking = "org.scala-sbt" %% "util-tracking" % utilVersion
private def scala211Module(name: String, moduleVersion: String) = private val libraryManagement = "org.scala-sbt" %% "librarymanagement" % lmVersion
Def.setting {
scalaVersion.value match { val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0"
case sv if (sv startsWith "2.9.") || (sv startsWith "2.10.") => Nil val rawLauncher = "org.scala-sbt" % "launcher" % "1.0.0"
case _ => ("org.scala-lang.modules" %% name % moduleVersion) :: Nil val testInterface = "org.scala-sbt" % "test-interface" % "1.0"
}
private val compilerApiInfo = "org.scala-sbt" %% "zinc-apiinfo" % zincVersion
private val compilerBridge = "org.scala-sbt" %% "compiler-bridge" % zincVersion
private val compilerClasspath = "org.scala-sbt" %% "zinc-classpath" % zincVersion
private val compilerInterface = "org.scala-sbt" % "compiler-interface" % zincVersion
private val compilerIvyIntegration = "org.scala-sbt" %% "zinc-ivy-integration" % zincVersion
private val zinc = "org.scala-sbt" %% "zinc" % zincVersion
private val zincCompile = "org.scala-sbt" %% "zinc-compile" % zincVersion
def getSbtModulePath(key: String, name: String) = {
val localProps = new java.util.Properties()
IO.load(localProps, file("project/local.properties"))
val path = Option(localProps getProperty key) orElse (sys.props get key)
path foreach (f => println(s"Using $name from $f"))
path
}
lazy val sbtIoPath = getSbtModulePath("sbtio.path", "sbt/io")
lazy val sbtUtilPath = getSbtModulePath("sbtutil.path", "sbt/util")
lazy val sbtLmPath = getSbtModulePath("sbtlm.path", "sbt/lm")
lazy val sbtZincPath = getSbtModulePath("sbtzinc.path", "sbt/zinc")
def addSbtModule(p: Project, path: Option[String], projectName: String, m: ModuleID, c: Option[Configuration] = None) =
path match {
case Some(f) => p dependsOn c.fold[ClasspathDependency](ProjectRef(file(f), projectName))(ProjectRef(file(f), projectName) % _)
case None => p settings (libraryDependencies += c.fold(m)(m % _))
} }
lazy val scalaXml = scala211Module("scala-xml", "1.0.1")
lazy val scalaParsers = scala211Module("scala-parser-combinators", "1.0.1") def addSbtIO(p: Project): Project = addSbtModule(p, sbtIoPath, "io", sbtIO)
def addSbtUtilApplyMacro(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilApplyMacro", utilApplyMacro)
def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache)
def addSbtUtilCollection(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCollection", utilCollection)
def addSbtUtilCompletion(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilComplete", utilCompletion)
def addSbtUtilControl(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilControl", utilControl)
def addSbtUtilLogging(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging)
def addSbtUtilLogic(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilLogic", utilLogic)
def addSbtUtilRelation(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilRelation", utilRelation)
def addSbtUtilScripted(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilScripted", utilScripted)
def addSbtUtilTesting(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilTesting", utilTesting, Some(Test))
def addSbtUtilTracking(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilTracking", utilTracking)
def addSbtLm(p: Project): Project = addSbtModule(p, sbtLmPath, "lm", libraryManagement)
def addSbtCompilerApiInfo(p: Project): Project = addSbtModule(p, sbtZincPath, "zincApiInfo", compilerApiInfo)
def addSbtCompilerBridge(p: Project): Project = addSbtModule(p, sbtZincPath, "compilerBridge", compilerBridge)
def addSbtCompilerClasspath(p: Project): Project = addSbtModule(p, sbtZincPath, "zincClasspath", compilerClasspath)
def addSbtCompilerInterface(p: Project): Project = addSbtModule(p, sbtZincPath, "compilerInterface", compilerInterface)
def addSbtCompilerIvyIntegration(p: Project): Project = addSbtModule(p, sbtZincPath, "zincIvyIntegration", compilerIvyIntegration)
def addSbtZinc(p: Project): Project = addSbtModule(p, sbtZincPath, "zinc", zinc)
def addSbtZincCompile(p: Project): Project = addSbtModule(p, sbtZincPath, "zincCompile", zincCompile)
val sjsonNewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % "0.4.2"
val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.11.4"
val specs2 = "org.specs2" %% "specs2" % "2.3.11"
val junit = "junit" % "junit" % "4.11"
private def scala211Module(name: String, moduleVersion: String) = Def setting (
scalaBinaryVersion.value match {
case "2.9" | "2.10" => Nil
case _ => ("org.scala-lang.modules" %% name % moduleVersion) :: Nil
}
)
val scalaXml = scala211Module("scala-xml", "1.0.1")
val scalaParsers = scala211Module("scala-parser-combinators", "1.0.1")
} }

View File

@ -9,13 +9,18 @@ object Formatting {
val scalariformCheck = taskKey[Unit]("Checks that the existing code is formatted, via git diff") val scalariformCheck = taskKey[Unit]("Checks that the existing code is formatted, via git diff")
lazy val settings: Seq[Setting[_]] = Seq() ++ scalariformSettings ++ prefs
lazy val prefs: Seq[Setting[_]] = { lazy val prefs: Seq[Setting[_]] = {
import scalariform.formatter.preferences._ import scalariform.formatter.preferences._
Seq( Seq(
scalariformPreferences ~= (_.setPreference(AlignSingleLineCaseStatements, true)) scalariformPreferences ~= (_
.setPreference(AlignSingleLineCaseStatements, true)
.setPreference(AlignSingleLineCaseStatements.MaxArrowIndent, 100)
.setPreference(DanglingCloseParenthesis, Force)
)
) )
} }
lazy val settings: Seq[Setting[_]] = Seq() ++ scalariformSettings ++ prefs
lazy val sbtFilesSettings: Seq[Setting[_]] = Seq() ++ scalariformSettings ++ prefs ++ lazy val sbtFilesSettings: Seq[Setting[_]] = Seq() ++ scalariformSettings ++ prefs ++
inConfig(BuildConfig)(configScalariformSettings) ++ inConfig(BuildConfig)(configScalariformSettings) ++
inConfig(BuildSbtConfig)(configScalariformSettings) ++ inConfig(BuildSbtConfig)(configScalariformSettings) ++

View File

@ -12,6 +12,8 @@ object PublishBinPlugin extends AutoPlugin {
import autoImport._ import autoImport._
override def globalSettings = Seq(publishLocalBin := (()))
override def projectSettings = Def settings ( override def projectSettings = Def settings (
publishLocalBin := Classpaths.publishTask(publishLocalBinConfig, deliverLocal).value, publishLocalBin := Classpaths.publishTask(publishLocalBinConfig, deliverLocal).value,
publishLocalBinConfig := Classpaths.publishConfig( publishLocalBinConfig := Classpaths.publishConfig(

View File

@ -1 +1 @@
sbt.version=0.13.11 sbt.version=0.13.13

View File

@ -5,6 +5,6 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.8")
addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.4") addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.4")
addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.8.5") addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.8.5")
addSbtPlugin("com.typesafe.sbt" % "sbt-javaversioncheck" % "0.1.0") addSbtPlugin("com.typesafe.sbt" % "sbt-javaversioncheck" % "0.1.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0") // 1.6.0 is out but is a hard upgrade addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.6.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "0.8.2") addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "0.8.2")
addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0") addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0")

View File

@ -285,7 +285,7 @@ private final class TrapExit(delegateManager: SecurityManager) extends SecurityM
val group = t.getThreadGroup val group = t.getThreadGroup
val previousHandler = t.getUncaughtExceptionHandler match { val previousHandler = t.getUncaughtExceptionHandler match {
case null | `group` | (_: LoggingExceptionHandler) => None case null | `group` | (_: LoggingExceptionHandler) => None
case x => Some(x) // delegate to a custom handler only case x => Some(x) // delegate to a custom handler only
} }
t.setUncaughtExceptionHandler(new LoggingExceptionHandler(log, previousHandler)) t.setUncaughtExceptionHandler(new LoggingExceptionHandler(log, previousHandler))
} }

View File

@ -178,7 +178,6 @@ trait Import {
val ~> = sbt.internal.util.~> val ~> = sbt.internal.util.~>
type ~>[-K[_], +V[_]] = sbt.internal.util.~>[K, V] type ~>[-K[_], +V[_]] = sbt.internal.util.~>[K, V]
// sbt.internal.util.complete // sbt.internal.util.complete
object complete { object complete {
val Completion = sbt.internal.util.complete.Completion val Completion = sbt.internal.util.complete.Completion
@ -302,7 +301,6 @@ trait Import {
type VersionNumber = sbt.librarymanagement.VersionNumber type VersionNumber = sbt.librarymanagement.VersionNumber
type VersionNumberCompatibility = sbt.librarymanagement.VersionNumberCompatibility type VersionNumberCompatibility = sbt.librarymanagement.VersionNumberCompatibility
// sbt.internal.librarymanagement // sbt.internal.librarymanagement
type IvyPaths = sbt.internal.librarymanagement.IvyPaths type IvyPaths = sbt.internal.librarymanagement.IvyPaths
val UpdateLogging = sbt.internal.librarymanagement.UpdateLogging val UpdateLogging = sbt.internal.librarymanagement.UpdateLogging

View File

@ -85,7 +85,8 @@ object ScriptedPlugin extends AutoPlugin {
try { try {
scriptedRun.value.invoke( scriptedRun.value.invoke(
scriptedTests.value, sbtTestDirectory.value, scriptedBufferLog.value: java.lang.Boolean, scriptedTests.value, sbtTestDirectory.value, scriptedBufferLog.value: java.lang.Boolean,
args.toArray, sbtLauncher.value, scriptedLaunchOpts.value.toArray) args.toArray, sbtLauncher.value, scriptedLaunchOpts.value.toArray
)
} catch { case e: java.lang.reflect.InvocationTargetException => throw e.getCause } } catch { case e: java.lang.reflect.InvocationTargetException => throw e.getCause }
} }

View File

@ -4,8 +4,20 @@
package sbt package sbt
package std package std
import java.io.{ BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter, Closeable, File, import java.io.{
FileInputStream, FileOutputStream, IOException, InputStreamReader, OutputStreamWriter, PrintWriter } BufferedInputStream,
BufferedOutputStream,
BufferedReader,
BufferedWriter,
Closeable,
File,
FileInputStream,
FileOutputStream,
IOException,
InputStreamReader,
OutputStreamWriter,
PrintWriter
}
import sbt.internal.io.DeferredWriter import sbt.internal.io.DeferredWriter
import sbt.io.IO import sbt.io.IO

View File

@ -33,5 +33,5 @@ object TaskRunnerCircularTest extends Properties("TaskRunner Circular") {
try { tryRun(top, true, workers); false } try { tryRun(top, true, workers); false }
catch { case i: Incomplete => cyclic(i) } catch { case i: Incomplete => cyclic(i) }
} }
def cyclic(i: Incomplete) = Incomplete.allExceptions(i).exists(_.isInstanceOf[Execute[({ type A[_] <: AnyRef})#A]#CyclicException[_]]) def cyclic(i: Incomplete) = Incomplete.allExceptions(i).exists(_.isInstanceOf[Execute[({ type A[_] <: AnyRef })#A]#CyclicException[_]])
} }

View File

@ -29,11 +29,10 @@ object CompletionService {
() => future.get() () => future.get()
} }
def manage[A, T](service: CompletionService[A, T])(setup: A => Unit, cleanup: A => Unit): CompletionService[A, T] = def manage[A, T](service: CompletionService[A, T])(setup: A => Unit, cleanup: A => Unit): CompletionService[A, T] =
wrap(service) { (node, work) => wrap(service) { (node, work) => () =>
() => setup(node)
setup(node) try { work() }
try { work() } finally { cleanup(node) }
finally { cleanup(node) }
} }
def wrap[A, T](service: CompletionService[A, T])(w: (A, () => T) => (() => T)): CompletionService[A, T] = def wrap[A, T](service: CompletionService[A, T])(w: (A, () => T) => (() => T)): CompletionService[A, T] =
new CompletionService[A, T] { new CompletionService[A, T] {

View File

@ -179,7 +179,9 @@ private[sbt] final class Execute[A[_] <: AnyRef](config: Config, triggers: Trigg
val v = register(node) val v = register(node)
val deps = dependencies(v) ++ runBefore(node) val deps = dependencies(v) ++ runBefore(node)
val active = IDSet[A[_]](deps filter notDone) val active = IDSet[A[_]](deps filter notDone)
progressState = progress.registered(progressState, node, deps, active.toList /** active is mutable, so take a snapshot */ ) progressState = progress.registered(progressState, node, deps, active.toList
/** active is mutable, so take a snapshot */
)
if (active.isEmpty) if (active.isEmpty)
ready(node) ready(node)

View File

@ -85,12 +85,12 @@ class JUnitXmlTestsListener(val outputDir: String) extends TestsListener {
"" ""
} }
e.status match { e.status match {
case TStatus.Error if (e.throwable.isDefined) => <error message={ e.throwable.get.getMessage } type={ e.throwable.get.getClass.getName }>{ trace }</error> case TStatus.Error if (e.throwable.isDefined)=> <error message={ e.throwable.get.getMessage } type={ e.throwable.get.getClass.getName }>{ trace }</error>
case TStatus.Error => <error message={ "No Exception or message provided" }/> case TStatus.Error=> <error message={ "No Exception or message provided" }/>
case TStatus.Failure if (e.throwable.isDefined) => <failure message={ e.throwable.get.getMessage } type={ e.throwable.get.getClass.getName }>{ trace }</failure> case TStatus.Failure if (e.throwable.isDefined)=> <failure message={ e.throwable.get.getMessage } type={ e.throwable.get.getClass.getName }>{ trace }</failure>
case TStatus.Failure => <failure message={ "No Exception or message provided" }/> case TStatus.Failure=> <failure message={ "No Exception or message provided" }/>
case TStatus.Ignored | TStatus.Skipped | TStatus.Pending => <skipped/> case TStatus.Ignored | TStatus.Skipped | TStatus.Pending=> <skipped/>
case _ => {} case _ => {}
} }
} }
</testcase> </testcase>

View File

@ -116,9 +116,9 @@ object TestFramework {
} }
def matches(a: Fingerprint, b: Fingerprint) = def matches(a: Fingerprint, b: Fingerprint) =
(a, b) match { (a, b) match {
case (a: SubclassFingerprint, b: SubclassFingerprint) => a.isModule == b.isModule && a.superclassName == b.superclassName case (a: SubclassFingerprint, b: SubclassFingerprint) => a.isModule == b.isModule && a.superclassName == b.superclassName
case (a: AnnotatedFingerprint, b: AnnotatedFingerprint) => a.isModule == b.isModule && a.annotationName == b.annotationName case (a: AnnotatedFingerprint, b: AnnotatedFingerprint) => a.isModule == b.isModule && a.annotationName == b.annotationName
case _ => false case _ => false
} }
def toString(f: Fingerprint): String = def toString(f: Fingerprint): String =
f match { f match {
@ -127,12 +127,14 @@ object TestFramework {
case _ => f.toString case _ => f.toString
} }
def testTasks(frameworks: Map[TestFramework, Framework], def testTasks(
frameworks: Map[TestFramework, Framework],
runners: Map[TestFramework, Runner], runners: Map[TestFramework, Runner],
testLoader: ClassLoader, testLoader: ClassLoader,
tests: Seq[TestDefinition], tests: Seq[TestDefinition],
log: Logger, log: Logger,
listeners: Seq[TestReportListener]): (() => Unit, Seq[(String, TestFunction)], TestResult.Value => () => Unit) = listeners: Seq[TestReportListener]
): (() => Unit, Seq[(String, TestFunction)], TestResult.Value => () => Unit) =
{ {
val mappedTests = testMap(frameworks.values.toSeq, tests) val mappedTests = testMap(frameworks.values.toSeq, tests)
if (mappedTests.isEmpty) if (mappedTests.isEmpty)

View File

@ -37,7 +37,8 @@ trait TestsListener extends TestReportListener {
final class SuiteResult( final class SuiteResult(
val result: TestResult.Value, val result: TestResult.Value,
val passedCount: Int, val failureCount: Int, val errorCount: Int, val passedCount: Int, val failureCount: Int, val errorCount: Int,
val skippedCount: Int, val ignoredCount: Int, val canceledCount: Int, val pendingCount: Int) { val skippedCount: Int, val ignoredCount: Int, val canceledCount: Int, val pendingCount: Int
) {
def +(other: SuiteResult): SuiteResult = { def +(other: SuiteResult): SuiteResult = {
val combinedTestResult = val combinedTestResult =
(result, other.result) match { (result, other.result) match {