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(
baseSettings,
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.
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")).
settings(
testedBaseSettings,
name := "Tasks",
libraryDependencies ++= Seq(utilControl, utilCollection)
)
name := "Tasks"
).
configure(addSbtUtilControl, addSbtUtilCollection)
// 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")).
@ -133,46 +134,45 @@ lazy val stdTaskProj = (project in file("tasks-standard")).
settings(
testedBaseSettings,
name := "Task System",
testExclusive,
libraryDependencies ++= Seq(utilCollection, utilLogging, sbtIO)
)
testExclusive
).
configure(addSbtUtilCollection, addSbtUtilLogging, addSbtIO)
// Embedded Scala code runner
lazy val runProj = (project in file("run")).
settings(
testedBaseSettings,
name := "Run",
libraryDependencies ++= Seq(sbtIO,
utilLogging, compilerClasspath)
)
name := "Run"
).
configure(addSbtIO, addSbtUtilLogging, addSbtCompilerClasspath)
lazy val scriptedSbtProj = (project in scriptedPath / "sbt").
dependsOn(commandProj).
settings(
baseSettings,
name := "Scripted sbt",
libraryDependencies ++= Seq(launcherInterface % "provided",
sbtIO, utilLogging, compilerInterface, utilScripted)
)
libraryDependencies ++= Seq(launcherInterface % "provided")
).
configure(addSbtIO, addSbtUtilLogging, addSbtCompilerInterface, addSbtUtilScripted)
lazy val scriptedPluginProj = (project in scriptedPath / "plugin").
dependsOn(sbtProj).
settings(
baseSettings,
name := "Scripted Plugin",
libraryDependencies ++= Seq(compilerClasspath)
)
name := "Scripted Plugin"
).
configure(addSbtCompilerClasspath)
// Implementation and support code for defining actions.
lazy val actionsProj = (project in file("main-actions")).
dependsOn(runProj, stdTaskProj, taskProj, testingProj).
settings(
testedBaseSettings,
name := "Actions",
libraryDependencies ++= Seq(compilerClasspath, utilCompletion, compilerApiInfo,
zinc, compilerIvyIntegration, compilerInterface,
sbtIO, utilLogging, utilRelation, libraryManagement, utilTracking)
)
name := "Actions"
).
configure(addSbtCompilerClasspath, addSbtUtilCompletion, addSbtCompilerApiInfo,
addSbtZinc, addSbtCompilerIvyIntegration, addSbtCompilerInterface,
addSbtIO, addSbtUtilLogging, addSbtUtilRelation, addSbtLm, addSbtUtilTracking)
// General command support and core commands not specific to a build system
lazy val commandProj = (project in file("main-command")).
@ -180,30 +180,31 @@ lazy val commandProj = (project in file("main-command")).
settings(
testedBaseSettings,
name := "Command",
libraryDependencies ++= Seq(launcherInterface, compilerInterface,
sbtIO, utilLogging, utilCompletion, compilerClasspath, sjsonNewScalaJson),
libraryDependencies ++= Seq(launcherInterface, sjsonNewScalaJson),
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
lazy val mainSettingsProj = (project in file("main-settings")).
dependsOn(commandProj, stdTaskProj).
settings(
testedBaseSettings,
name := "Main Settings",
libraryDependencies ++= Seq(utilCache, utilApplyMacro, compilerInterface, utilRelation,
utilLogging, sbtIO, utilCompletion, compilerClasspath, libraryManagement)
)
name := "Main Settings"
).
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")).
dependsOn(actionsProj, mainSettingsProj, runProj, commandProj).
settings(
testedBaseSettings,
name := "Main",
libraryDependencies ++= scalaXml.value ++ Seq(launcherInterface, compilerInterface,
sbtIO, utilLogging, utilLogic, libraryManagement, zincCompile)
)
libraryDependencies ++= scalaXml.value ++ Seq(launcherInterface)
).
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
// 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",
normalizedName := "sbt",
crossScalaVersions := Seq(scala211),
crossPaths := false,
libraryDependencies ++= Seq(compilerBrdige)
)
crossPaths := false
).
configure(addSbtCompilerBridge)
def scriptedTask: Def.Initialize[InputTask[Unit]] = Def.inputTask {
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] = {
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),
{ 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] = {
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] =
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] =
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),
{ case (c, cc, ea, fd, cd, td, df) => new Caller(c, cc, ea, fd, cd, td, df) })
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),
{ 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] =
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)

View File

@ -18,7 +18,7 @@ object Compiler {
private[sbt] def defaultCompilerBridgeSource(sv: String): ModuleID =
VersionNumber(sv) match {
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 =
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 =
javadoc(label, cache, doc, log, reporter, Seq())
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) => {
// doc.doc
???
})))
}
)))
val javaSourcesOnly: File => Boolean = _.getName.endsWith(".java")

View File

@ -77,7 +77,8 @@ object TestResultLogger {
printSummary: TestResultLogger = Defaults.printSummary,
printStandard: TestResultLogger = Defaults.printStandard,
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 = {
def run(r: TestResultLogger): Unit = r.run(log, results, taskName)
@ -154,7 +155,6 @@ object TestResultLogger {
})
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 setup: 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 =
{
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 }
override def traverse(tree: Tree): Unit = tree match {
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`.*/

View File

@ -55,7 +55,8 @@ class CacheIvyTest extends Properties("CacheIvy") {
} yield ModuleID(
organization = o, name = n, revision = r, configurations = cs, isChanging = isChanging, isTransitive = isTransitive,
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) =>

View File

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

View File

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

View File

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

View File

@ -24,21 +24,29 @@ object Serialization {
def toMessage(event: Event): EventMessage =
event match {
case LogEvent(level, message) =>
EventMessage(`type` = "logEvent",
EventMessage(
`type` = "logEvent",
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) =>
EventMessage(`type` = "statusEvent",
EventMessage(
`type` = "statusEvent",
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)) =>
EventMessage(`type` = "statusEvent",
EventMessage(
`type` = "statusEvent",
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) =>
EventMessage(`type` = "executionEvent",
EventMessage(
`type` = "executionEvent",
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) =>
val indented = msg.lines.map(" " + _).mkString("\n")
Parser.failure(s"Invalid programmatic input:\n$indented")
}
)
})
}
object InputTask {
@ -38,9 +37,7 @@ object InputTask {
case Left(msg) =>
val indented = msg.lines.map(" " + _).mkString("\n")
sys.error(s"Invalid programmatic input:\n$indented")
}
)
)
}))
)
}

View File

@ -142,7 +142,8 @@ object Scope {
projectInherit: ProjectRef => Seq[ProjectRef],
configInherit: (ResolvedReference, ConfigKey) => Seq[ConfigKey],
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)
scope => indexedDelegates(resolve, index, rootProject, taskInherit, extraInherit)(scope)
@ -153,7 +154,8 @@ object Scope {
index: DelegateIndex,
rootProject: URI => String,
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)
@ -190,7 +192,8 @@ object Scope {
refs: Seq[(ProjectRef, Proj)],
configurations: Proj => Seq[ConfigKey],
projectInherit: ProjectRef => Seq[ProjectRef],
configInherit: (ResolvedReference, ConfigKey) => Seq[ConfigKey]): DelegateIndex =
configInherit: (ResolvedReference, ConfigKey) => Seq[ConfigKey]
): DelegateIndex =
{
val pDelegates = refs map {
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) = {
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.*/
@ -216,12 +216,12 @@ object ParserInput {
private def wrapParser[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree, pos: c.Position) = {
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) = {
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)
}

View File

@ -33,8 +33,8 @@ private[sbt] object KeyMacro {
def enclosingVal(trees: List[c.Tree]): String =
{
trees match {
case vd @ ValDef(_, name, _, _) :: ts => processName(name)
case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs)
case vd @ ValDef(_, name, _, _) :: ts => processName(name)
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)
case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: xs if mods.hasFlag(Flag.LAZY) => processName(name)
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]] =
{
import Scoped._
(in, settingsData, Def.capturedTransformations) apply {
(a: Task[S => Initialize[Task[T]]], data: Task[SS], f) =>
(s: S) =>
import TaskExtra.multT2Task
(a, data) flatMap { case (af, d) => f(af(s)) evaluate d }
(in, settingsData, Def.capturedTransformations) apply { (a: Task[S => Initialize[Task[T]]], data: Task[SS], f) => (s: S) =>
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(
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,
crossVersion := (if (crossPaths.value) CrossVersion.binary else CrossVersion.Disabled),
crossTarget := makeCrossTarget(target.value, scalaBinaryVersion.value, sbtBinaryVersion.value, sbtPlugin.value, crossPaths.value),
@ -678,7 +679,8 @@ object Defaults extends BuildCommon {
}
)) ++
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(packageSrc, packageSrcMappings) ++
packageTaskSettings(packageDoc, packageDocMappings) ++
@ -947,7 +949,8 @@ object Defaults extends BuildCommon {
(compilerReporter in compile).value,
o2m(None),
// TODO - task / setting for extra,
Array.empty)
Array.empty
)
}
def compileInputsSettings: Seq[Setting[_]] = {
Seq(
@ -959,13 +962,15 @@ object Defaults extends BuildCommon {
javacOptions.value.toArray,
maxErrors.value,
f1(Compiler.foldMappers(sourcePositionMappers.value)),
compileOrder.value),
compileOrder.value
),
compilerReporter := new LoggerReporter(maxErrors.value, streams.value.log, Compiler.foldMappers(sourcePositionMappers.value)),
compileInputs := new Inputs(
compilers.value,
compileOptions.value,
compileIncSetup.value,
previousCompile.value)
previousCompile.value
)
)
}
def compileAnalysisSettings: Seq[Setting[_]] = Seq(
@ -1484,8 +1489,8 @@ object Classpaths {
import UpdateLogging.{ Full, DownloadOnly, Default }
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(x) if uc0.logging == Default => uc0.copy(logging = DownloadOnly)
case _ => uc0
case Some(x) if uc0.logging == Default => uc0.copy(logging = DownloadOnly)
case _ => uc0
}
val ewo =
if (executionRoots.value exists { _.key == evicted.key }) EvictionWarningOptions.empty
@ -1543,7 +1548,7 @@ object Classpaths {
Tracked.inputChanged(cacheFile / "inputs") { (inChanged: Boolean, in: In) =>
val outCache = Tracked.lastOutput[In, UpdateReport](outCacheFile) {
case (_, Some(out)) if uptodate(inChanged, out) => out
case _ => work(in)
case _ => work(in)
}
try {
outCache(in)

View File

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

View File

@ -63,7 +63,8 @@ final case class Extracted(structure: BuildStructure, session: SessionSettings,
import EvaluateTask._
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 inputTask = get(Scoped.scopedSetting(rkey.scope, rkey.key))
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 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(),
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 =
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 BuiltinCommands.defaults
import sbt.internal.CommandStrings.{ BootCommand, DefaultsCommand, InitCommand }
runManaged(initialState(configuration,
runManaged(initialState(
configuration,
Seq(defaults, early),
runEarly(DefaultsCommand) :: runEarly(InitCommand) :: BootCommand :: Nil)
)
runEarly(DefaultsCommand) :: runEarly(InitCommand) :: BootCommand :: Nil
))
}
}
final class ScriptMain extends xsbti.AppMain {
def run(configuration: xsbti.AppConfiguration): xsbti.MainResult =
{
import BasicCommandStrings.runEarly
runManaged(initialState(configuration,
runManaged(initialState(
configuration,
BuiltinCommands.ScriptCommands,
runEarly(Level.Error.toString) :: Script.Name :: Nil)
)
runEarly(Level.Error.toString) :: Script.Name :: Nil
))
}
}
final class ConsoleMain extends xsbti.AppMain {
def run(configuration: xsbti.AppConfiguration): xsbti.MainResult =
runManaged(initialState(configuration,
runManaged(initialState(
configuration,
BuiltinCommands.ConsoleCommands,
IvyConsole.Name :: Nil)
)
IvyConsole.Name :: Nil
))
}
object StandardMain {

View File

@ -7,8 +7,8 @@ TODO:
import sbt.librarymanagement.Configuration
import sbt.internal.util.logic.{Atom, Clause, Clauses, Formula, Literal, Logic, Negated}
import Logic.{CyclicNegation, InitialContradictions, InitialOverlap, LogicException}
import sbt.internal.util.logic.{ Atom, Clause, Clauses, Formula, Literal, Logic, Negated }
import Logic.{ CyclicNegation, InitialContradictions, InitialOverlap, LogicException }
import Def.Setting
import Plugins._
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.
*/
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
* 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
* 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
/** 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
@ -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. */
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
* regardless of how many projects for that build activate this AutoPlugin. */
/**
* 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
* regardless of how many projects for that build activate this AutoPlugin.
*/
def buildSettings: Seq[Setting[_]] = Nil
/** 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)
/** If this plugin does not have any requirements, it means it is actually a root plugin. */
private[sbt] final def isRoot: Boolean =
requires match {
case Empty => true
case _ => false
case _ => false
}
/** 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)
}
/** 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. */
final class AutoPluginException private(val message: String, val origin: Option[LogicException]) extends RuntimeException(message) {
/**
* 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.
*/
final class AutoPluginException private (val message: String, val origin: Option[LogicException]) extends RuntimeException(message) {
/** Prepends `p` to the error message derived from `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. */
sealed trait Plugins {
def && (o: Basic): Plugins
def &&(o: Basic): Plugins
}
sealed trait PluginsFunctions {
/** [[Plugins]] instance that doesn't require any [[Plugins]]s. */
def empty: Plugins = Plugins.Empty
@ -146,20 +151,22 @@ sealed trait 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] =
if(defined0.isEmpty) (_, _) => Nil
if (defined0.isEmpty) (_, _) => Nil
else {
// TODO: defined should return all the plugins
val allReqs = (defined0 flatMap { asRequirements }).toSet
val diff = allReqs diff defined0.toSet
val defined = if (diff.nonEmpty) diff.toList ::: defined0
else defined0
else defined0
val byAtom = defined map { x => (Atom(x.label), x) }
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.
// Avoids the requirement for pure Nature strings *and* possible
// circular dependencies in the logic.
@ -186,7 +193,7 @@ object Plugins extends PluginsFunctions {
val forbidden: Set[AutoPlugin] = (selectedPlugins flatMap { Plugins.asExclusions }).toSet
val c = selectedPlugins.toSet & forbidden
if (c.nonEmpty) {
exlusionConflictError(requestedPlugins, selectedPlugins, c.toSeq sortBy {_.label})
exlusionConflictError(requestedPlugins, selectedPlugins, c.toSeq sortBy { _.label })
}
val retval = topologicalSort(selectedPlugins, log)
log.debug(s" :: sorted deduced result: ${retval.toString}")
@ -210,26 +217,25 @@ object Plugins extends PluginsFunctions {
}
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 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 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)}"
}
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 = {
val dupsByAtom = byAtom.groupBy(_._1).mapValues(_.map(_._2))
val dupStrings = for( (atom, dups) <- dupsByAtom if dups.size > 1 ) yield
s"${atom.label} by ${dups.mkString(", ")}"
val (ns, nl) = if(dupStrings.size > 1) ("s", "\n\t") else ("", " ")
val dupStrings = for ((atom, dups) <- dupsByAtom if dups.size > 1) yield s"${atom.label} by ${dups.mkString(", ")}"
val (ns, nl) = if (dupStrings.size > 1) ("s", "\n\t") else ("", " ")
val message = s"Plugin$ns provided by multiple AutoPlugins:$nl${dupStrings.mkString(nl)}"
throw AutoPluginException(message)
}
private[this] def exlusionConflictError(requested: Plugins, selected: Seq[AutoPlugin], conflicting: Seq[AutoPlugin]): Unit = {
def listConflicts(ns: Seq[AutoPlugin]) = (ns map { c =>
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}")
else Nil) ++
else Nil) ++
{
val reqs = selected filter { x => asRequirements(x) contains c }
if (reqs.nonEmpty) List(s"""required by ${reqs.mkString(", ")}""")
@ -258,7 +264,7 @@ ${listConflicts(conflicting)}""")
sealed abstract class Basic extends Plugins {
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"
}
private[sbt] final case class And(plugins: List[Basic]) extends Plugins {
@ -266,27 +272,27 @@ ${listConflicts(conflicting)}""")
override def toString = plugins.mkString(" && ")
}
private[sbt] def and(a: Plugins, b: Plugins) = b match {
case Empty => a
case And(ns) => (a /: ns)(_ && _)
case Empty => a
case And(ns) => (a /: ns)(_ && _)
case b: Basic => a && b
}
private[sbt] def remove(a: Plugins, del: Set[Basic]): Plugins = a match {
case b: Basic => if(del(b)) Empty else b
case Empty => Empty
case b: Basic => if (del(b)) Empty else b
case Empty => Empty
case And(ns) =>
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`. */
private[sbt] def asEnabledByClauses(ap: AutoPlugin): List[Clause] =
// `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
/** Defines requirements clauses for `ap`. */
private[sbt] def asRequirementsClauses(ap: AutoPlugin): List[Clause] =
// 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 {
case x: AutoPlugin => x
}
@ -295,41 +301,41 @@ ${listConflicts(conflicting)}""")
}
// TODO - This doesn't handle nested AND boolean logic...
private[sbt] def hasExclude(n: Plugins, p: AutoPlugin): Boolean = n match {
case `p` => false
case `p` => false
case Exclude(`p`) => true
// 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.
// This would handle things like !!p or !(p && z)
case Exclude(n) => hasInclude(n, p)
case And(ns) => ns.forall(n => hasExclude(n, p))
case b: Basic => false
case Empty => false
case Exclude(n) => hasInclude(n, p)
case And(ns) => ns.forall(n => hasExclude(n, p))
case b: Basic => false
case Empty => false
}
private[sbt] def hasInclude(n: Plugins, p: AutoPlugin): Boolean = n match {
case `p` => true
case `p` => true
case Exclude(n) => hasExclude(n, p)
case And(ns) => ns.forall(n => hasInclude(n, p))
case b: Basic => false
case Empty => false
case And(ns) => ns.forall(n => hasInclude(n, p))
case b: Basic => false
case Empty => false
}
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 Empty => Nil
case Empty => Nil
}
private[sbt] def flatten(n: Plugins): Seq[Basic] = n match {
case And(ns) => ns
case And(ns) => ns
case b: Basic => b :: Nil
case Empty => Nil
case Empty => Nil
}
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 Empty => Formula.True
case Empty => Formula.True
}
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)
}
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`. */
def satisfied(n: Plugins, model: Set[AutoPlugin]): Boolean =
flatten(n) forall {
case Exclude(a) => !model(a)
case Exclude(a) => !model(a)
case ap: AutoPlugin => model(ap)
}
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
val m = ru.runtimeMirror(loader)
val im = m.reflect(ap)
val hasGetterOpt = catching(classOf[ScalaReflectionException]) opt {
im.symbol.asType.toType.decl(ru.TermName("autoImport")) match {
case ru.NoSymbol => false
case sym => sym.asTerm.isGetter || sym.asTerm.isModule
case sym => sym.asTerm.isGetter || sym.asTerm.isModule
}
}
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 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)
private[sbt] def copy(id: String = id,
private[sbt] def copy(
id: String = id,
base: File = base,
aggregateEval: Eval[Seq[ProjectReference]] = aggregateEval,
dependenciesEval: Eval[Seq[ClasspathDep[ProjectReference]]] = dependenciesEval,
delegatesEval: Eval[Seq[ProjectReference]] = delegatesEval,
settingsEval: Eval[Seq[Setting[_]]] = settingsEval,
configurations: Seq[Configuration] = configurations,
auto: AddSettings = auto): Project =
auto: AddSettings = auto
): Project =
unresolved(id, base,
aggregateEval = aggregateEval,
dependenciesEval = dependenciesEval,
@ -261,10 +262,10 @@ final case class ClasspathDependency(project: ProjectReference, configuration: O
*/
sealed trait ProjectOrigin
object ProjectOrigin {
case object Organic extends ProjectOrigin
case object ExtraProject extends ProjectOrigin
case object Organic extends ProjectOrigin
case object ExtraProject extends ProjectOrigin
case object DerivedProject extends ProjectOrigin
case object GenericRoot extends ProjectOrigin
case object GenericRoot extends ProjectOrigin
}
object Project extends ProjectExtra {
@ -280,7 +281,8 @@ object Project extends ProjectExtra {
val auto: AddSettings,
val plugins: Plugins,
val autoPlugins: Seq[AutoPlugin],
val projectOrigin: ProjectOrigin) extends ProjectDefinition[PR] {
val projectOrigin: ProjectOrigin
) extends ProjectDefinition[PR] {
def aggregate: Seq[PR] = aggregateEval.get
def dependencies: Seq[ClasspathDep[PR]] = dependenciesEval.get
def delegates: Seq[PR] = delegatesEval.get
@ -649,7 +651,7 @@ object Project extends ProjectExtra {
private[sbt] trait GeneratedRootProject
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) }
}
@ -665,7 +667,6 @@ trait ProjectExtra extends ProjectExtra0 {
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)
// 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
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 =
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)

View File

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

View File

@ -150,11 +150,10 @@ object Aggregation {
} else {
val base = if (tasks.isEmpty) success(() => s) else
applyTasks(s, structure, maps(tasks)(x => success(castToAny(x))), show)
base.map { res =>
() =>
val newState = res()
if (show.settingValues && settings.nonEmpty) printSettings(settings, show.print)
newState
base.map { res => () =>
val newState = res()
if (show.settingValues && settings.nonEmpty) printSettings(settings, show.print)
newState
}
}
}
@ -169,8 +168,7 @@ object Aggregation {
{
val resRef = proj.map(p => extra.projectRefFor(extra.resolveRef(p)))
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]] =

View File

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

View File

@ -30,7 +30,8 @@ final class StructureIndex(
val taskToKey: Map[Task[_], ScopedKey[Task[_]]],
val triggers: Triggers[Task],
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`.)
@ -92,13 +93,16 @@ final class LoadedDefinitions(
val builds: Seq[BuildDef],
val projects: Seq[Project],
val buildNames: Seq[String],
val dslDefinitions: DefinedSbtValues) {
def this(base: File,
val dslDefinitions: DefinedSbtValues
) {
def this(
base: File,
target: Seq[File],
loader: ClassLoader,
builds: Seq[BuildDef],
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. */

View File

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

View File

@ -181,11 +181,13 @@ private[sbt] object EvaluateConfigurations {
case e: sbt.compiler.EvalException => throw new MessageOnlyException(e.getMessage)
}
// TODO - keep track of configuration classes defined.
TrackedEvalResult(result.generated,
TrackedEvalResult(
result.generated,
loader => {
val pos = RangePosition(name, range shift 1)
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 Project.inScope
import Def.{ isDummy, ScopedKey, ScopeLocal, Setting }
import Keys.{ appConfiguration, baseDirectory, configuration, exportedProducts, fullClasspath, fullResolvers,
loadedBuild, onLoadMessage, pluginData, resolvedScoped, sbtPlugin, scalacOptions, streams,
thisProject, thisProjectRef, update }
import Keys.{
appConfiguration,
baseDirectory,
configuration,
exportedProducts,
fullClasspath,
fullResolvers,
loadedBuild,
onLoadMessage,
pluginData,
resolvedScoped,
sbtPlugin,
scalacOptions,
streams,
thisProject,
thisProjectRef,
update
}
import tools.nsc.reporters.ConsoleReporter
import sbt.internal.util.{ Attributed, Eval => Ev, Settings, Show, ~> }
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 defsScala = plugs.detected.builds.values
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.
@ -547,7 +562,8 @@ private[sbt] object Load {
makeOrDiscoverRoot: Boolean,
buildUri: URI,
context: PluginManagement.Context,
generatedConfigClassFiles: Seq[File]): LoadedProjects =
generatedConfigClassFiles: Seq[File]
): LoadedProjects =
{
// load all relevant configuration files (.sbt, as .scala already exists at this point)
def discover(auto: AddSettings, base: File): DiscoveredProjects =
@ -567,7 +583,7 @@ private[sbt] object Load {
catch { case e: AutoPluginException => throw translateAutoPluginException(e, p) }
val p2 = this.resolveProject(p1, autoPlugins, plugins, injectSettings, memoSettings, log)
val projectLevelExtra =
if (expand) autoPlugins flatMap { _.derivedProjects(p2) map {_.setProjectOrigin(ProjectOrigin.DerivedProject)} }
if (expand) autoPlugins flatMap { _.derivedProjects(p2) map { _.setProjectOrigin(ProjectOrigin.DerivedProject) } }
else Nil
(p2, projectLevelExtra)
}
@ -638,7 +654,8 @@ private[sbt] object Load {
root: Option[Project],
nonRoot: Seq[Project],
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:
@ -660,7 +677,8 @@ private[sbt] object Load {
loadedPlugins: LoadedPlugins,
globalUserSettings: InjectSettings,
memoSettings: mutable.Map[File, LoadedSbtFile],
log: Logger): Project = {
log: Logger
): Project = {
import AddSettings._
val autoConfigs = projectPlugins.flatMap(_.projectConfigurations)
@ -707,7 +725,8 @@ private[sbt] object Load {
projectBase: File,
loadedPlugins: LoadedPlugins,
eval: () => Eval,
memoSettings: mutable.Map[File, LoadedSbtFile]): DiscoveredProjects = {
memoSettings: mutable.Map[File, LoadedSbtFile]
): DiscoveredProjects = {
// Default sbt files to read, if needed
lazy val defaultSbtFiles = configurationSources(projectBase)
@ -915,7 +934,8 @@ final case class LoadBuildConfiguration(
injectSettings: Load.InjectSettings,
globalPlugin: Option[GlobalPlugin],
extraBuilds: Seq[URI],
log: Logger) {
log: Logger
) {
lazy val (globalPluginClasspath, _) = Load.pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin))
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,
// rather than what we have now...
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.
def merge(o: LoadedSbtFile): LoadedSbtFile =
new LoadedSbtFile(
@ -25,7 +26,8 @@ private[sbt] final class LoadedSbtFile(
importedDefs ++ o.importedDefs,
manipulations,
definitions zip o.definitions,
generatedFiles ++ o.generatedFiles)
generatedFiles ++ o.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.util.Logger
import Def.Setting
import Plugins._
import PluginsDebug._
import java.net.URI
import Def.Setting
import Plugins._
import PluginsDebug._
import java.net.URI
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 {
case None => Set.empty
case None => Set.empty
case Some(key) => provided.reverse(key)
}
/** 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 =
{
val (activated, deactivated) = Util.separate(toEnable(notFoundKey, context)) {
case pa: PluginActivated => Left(pa)
case pa: PluginActivated => Left(pa)
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)
}
private[this] def debugDeactivated(notFoundKey: String, deactivated: Seq[EnableDeactivated]): String =
{
val (impossible, possible) = Util.separate(deactivated) {
case pi: PluginImpossible => Left(pi)
case pi: PluginImpossible => Left(pi)
case pr: PluginRequirements => Right(pr)
}
if(possible.nonEmpty) {
if (possible.nonEmpty) {
val explained = possible.map(explainPluginEnable)
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}"
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
}
else if(impossible.isEmpty)
} else if (impossible.isEmpty)
s"No available plugin provides key $notFoundKey."
else {
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 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 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
}
private def deactivatedHelp(plugin: AutoPlugin, context: Context): String =
{
val prefix = s"${plugin.label} is NOT activated."
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 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))
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 {
def helpAll(s: State): String =
if(Project.isProjectLoaded(s))
{
val extracted = Project.extract(s)
import extracted._
def helpBuild(uri: URI, build: LoadedBuildUnit): String =
if (Project.isProjectLoaded(s)) {
val extracted = Project.extract(s)
import extracted._
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 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"In $uri${pluginStrings.mkString}"
}
val buildStrings = for((uri, build) <- structure.units) yield helpBuild(uri, build)
buildStrings.mkString("\n")
}
else "No project is currently loaded."
val buildStrings = for ((uri, build) <- structure.units) yield helpBuild(uri, build)
buildStrings.mkString("\n")
} else "No project is currently loaded."
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
}
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 =
{
@ -119,21 +118,21 @@ private[sbt] object PluginsDebug {
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 debug = PluginsDebug(context.available)
if(!pluginsThisBuild.contains(plugin)) {
if (!pluginsThisBuild.contains(plugin)) {
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."
} else if(definesPlugin(currentProject))
} else if (definesPlugin(currentProject))
debug.activatedHelp(plugin)
else {
val thisAggregated = BuildUtil.dependencies(structure.units).aggregateTransitive.getOrElse(currentRef, Nil)
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
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 {
val base = debug.deactivatedHelp(plugin, context)
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 aggNote = if (thisAggregated.nonEmpty) "Note: This project aggregates other projects and this" else "Note: This"
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."
s"$base\n$aggNote$common\n$helpOther"
}
@ -148,11 +147,13 @@ private[sbt] object PluginsDebug {
new PluginsDebug(available, nameToKey, keyR)
}
/** The context for debugging a plugin (de)activation.
* @param initial The initially defined [[AutoPlugin]]s.
* @param enabled The resulting model.
* @param deducePlugin The function used to compute the model.
* @param available All [[AutoPlugin]]s available for consideration. */
/**
* The context for debugging a plugin (de)activation.
* @param initial The initially defined [[AutoPlugin]]s.
* @param enabled The resulting model.
* @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)
/** 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. */
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
* @param blockingExcludes Existing exclusions that prevent [[plugin]] from being activated and must be dropped
* @param enablingPlugins [[AutoPlugin]]s that are not currently enabled, but need to be enabled for [[plugin]] to activate
* @param extraEnabledPlugins Plugins that will be enabled as a result of [[plugin]] activating, but are not required for [[plugin]] to activate
* @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]].*/
/**
* Describes the requirements for activating [[plugin]] in [[context]].
* @param context The base plugins, exclusions, and ultimately activated plugins
* @param blockingExcludes Existing exclusions that prevent [[plugin]] from being activated and must be dropped
* @param enablingPlugins [[AutoPlugin]]s that are not currently enabled, but need to be enabled for [[plugin]] to activate
* @param extraEnabledPlugins Plugins that will be enabled as a result of [[plugin]] activating, but are not required for [[plugin]] to activate
* @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
/** Describes a [[plugin]] that must be removed in order to activate another plugin in some context.
* The [[plugin]] can always be directly, explicitly excluded.
* @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. */
/**
* Describes a [[plugin]] that must be removed in order to activate another plugin in some context.
* The [[plugin]] can always be directly, explicitly excluded.
* @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)
/** Determines how to enable [[plugin]] in [[context]]. */
def pluginEnable(context: Context, plugin: AutoPlugin): PluginEnable =
if(context.enabled.contains(plugin))
if (context.enabled.contains(plugin))
PluginActivated(plugin, context)
else
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.
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.
val removeToDeactivate = plugins(minimalModel(d)) -- minRequiredPlugins
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.
// 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) {
case _: Exclude => Nil
case _: Exclude => Nil
case ap: AutoPlugin => Plugins.flatten(ap.requires) :+ plugin
}
@ -281,29 +286,31 @@ private[sbt] object PluginsDebug {
def explainPluginEnable(ps: PluginEnable): String =
ps match {
case PluginRequirements(plugin, context, blockingExcludes, enablingPlugins, extraEnabledPlugins, toBeRemoved, deactivate) =>
def indent(str: String) = if(str.isEmpty) "" else s"\t$str"
def note(str: String) = if(str.isEmpty) "" else s"Note: $str"
def indent(str: String) = if (str.isEmpty) "" else s"\t$str"
def note(str: String) = if (str.isEmpty) "" else s"Note: $str"
val parts =
indent(excludedError(false /* TODO */, blockingExcludes.toList)) ::
indent(required(enablingPlugins.toList)) ::
indent(needToDeactivate(deactivate)) ::
note(willAdd(plugin, extraEnabledPlugins.toList)) ::
note(willRemove(plugin, toBeRemoved.toList)) ::
Nil
indent(excludedError(false /* TODO */ , blockingExcludes.toList)) ::
indent(required(enablingPlugins.toList)) ::
indent(needToDeactivate(deactivate)) ::
note(willAdd(plugin, extraEnabledPlugins.toList)) ::
note(willRemove(plugin, toBeRemoved.toList)) ::
Nil
parts.filterNot(_.isEmpty).mkString("\n")
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 extractDefinedKeys(ss: Seq[Setting[_]]): Seq[AttributeKey[_]] =
ss.map(_.key.key)
def allSettings(p: AutoPlugin): Seq[Setting[_]] = p.projectSettings ++ p.buildSettings ++ p.globalSettings
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 =
@ -314,7 +321,7 @@ private[sbt] object PluginsDebug {
private[this] def excludedPluginsError(transitive: Boolean)(dependencies: List[AutoPlugin]) =
s"Required ${transitiveString(transitive)}dependencies were excluded:\n\t${labels(dependencies).mkString("\n\t")}"
private[this] def transitiveString(transitive: Boolean) =
if(transitive) "(transitive) " else ""
if (transitive) "(transitive) " else ""
private[this] def required(plugins: List[AutoPlugin]): String =
str(plugins)(requiredPlugin, requiredPlugins)
@ -360,9 +367,9 @@ private[sbt] object PluginsDebug {
{
val removePluginsString: String =
d.removeOneOf.toList match {
case Nil => ""
case Nil => ""
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}"
}

View File

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

View File

@ -190,7 +190,7 @@ object SessionSettings {
case ((in, oth, keys), s) =>
s.pos match {
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],
data: Option[ScopedKeyData[_]],
description: Option[String],
basedir: File,
depends: Set[SettingGraph]) {
depends: Set[SettingGraph]
) {
def dataString: String =
data map { d =>
d.settingValue map {
@ -48,9 +50,11 @@ case class SettingGraph(name: String,
} getOrElse { d.typeName }
} getOrElse { "" }
def dependsAscii: String = Graph.toAscii(this,
def dependsAscii: String = Graph.toAscii(
this,
(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 {

View File

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

View File

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

View File

@ -4,7 +4,8 @@ package plugins
import Def.Setting
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:
* {{{
@ -17,7 +18,7 @@ object JUnitXmlReportPlugin extends AutoPlugin {
// TODO - If testing becomes its own plugin, we only rely on the core settings.
override def requires = JvmPlugin
override def trigger = allRequirements
// 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.
override lazy val projectSettings: Seq[Setting[_]] =

View File

@ -5,7 +5,8 @@ import sbt.librarymanagement.{ Configuration, Configurations }
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:
* - `run`
@ -21,18 +22,18 @@ object JvmPlugin extends AutoPlugin {
// for ours to work.
override def requires = IvyPlugin
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
}

View File

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

View File

@ -13,7 +13,8 @@ class CommentedXmlSpec extends CheckIfParsedSpec {
|
|val tra = "</scm>"
|
""".stripMargin, "Xml in string", false, true),
""".stripMargin, "Xml in string", false, true
),
("""
|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
version := "1.0"
""".stripMargin)
""".stripMargin
)
imports.size === 2
settingsAndDefs.size === 1
}

View File

@ -2,54 +2,102 @@ import sbt._
import Keys._
object Dependencies {
lazy val scala282 = "2.8.2"
lazy val scala292 = "2.9.2"
lazy val scala293 = "2.9.3"
lazy val scala210 = "2.10.6"
lazy val scala211 = "2.11.8"
val scala282 = "2.8.2"
val scala292 = "2.9.2"
val scala293 = "2.9.3"
val scala210 = "2.10.6"
val scala211 = "2.11.8"
// sbt modules
val ioVersion = "1.0.0-M6"
val utilVersion = "0.1.0-M14"
val librarymanagementVersion = "0.1.0-X1"
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"
private val ioVersion = "1.0.0-M6"
private val utilVersion = "0.1.0-M14"
private val lmVersion = "0.1.0-X1"
private val zincVersion = "1.0.0-X3"
lazy val zinc = "org.scala-sbt" %% "zinc" % zincVersion
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"
private val sbtIO = "org.scala-sbt" %% "io" % ioVersion
lazy val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.11.4"
lazy val specs2 = "org.specs2" %% "specs2" % "2.3.11"
lazy val junit = "junit" % "junit" % "4.11"
private val utilApplyMacro = "org.scala-sbt" %% "util-apply-macro" % utilVersion
private val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion
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) =
Def.setting {
scalaVersion.value match {
case sv if (sv startsWith "2.9.") || (sv startsWith "2.10.") => Nil
case _ => ("org.scala-lang.modules" %% name % moduleVersion) :: Nil
}
private val libraryManagement = "org.scala-sbt" %% "librarymanagement" % lmVersion
val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0"
val rawLauncher = "org.scala-sbt" % "launcher" % "1.0.0"
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")
lazy val settings: Seq[Setting[_]] = Seq() ++ scalariformSettings ++ prefs
lazy val prefs: Seq[Setting[_]] = {
import scalariform.formatter.preferences._
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 ++
inConfig(BuildConfig)(configScalariformSettings) ++
inConfig(BuildSbtConfig)(configScalariformSettings) ++

View File

@ -12,6 +12,8 @@ object PublishBinPlugin extends AutoPlugin {
import autoImport._
override def globalSettings = Seq(publishLocalBin := (()))
override def projectSettings = Def settings (
publishLocalBin := Classpaths.publishTask(publishLocalBinConfig, deliverLocal).value,
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-git" % "0.8.5")
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("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 previousHandler = t.getUncaughtExceptionHandler match {
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))
}

View File

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

View File

@ -85,7 +85,8 @@ object ScriptedPlugin extends AutoPlugin {
try {
scriptedRun.value.invoke(
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 }
}

View File

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

View File

@ -33,5 +33,5 @@ object TaskRunnerCircularTest extends Properties("TaskRunner Circular") {
try { tryRun(top, true, workers); false }
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()
}
def manage[A, T](service: CompletionService[A, T])(setup: A => Unit, cleanup: A => Unit): CompletionService[A, T] =
wrap(service) { (node, work) =>
() =>
setup(node)
try { work() }
finally { cleanup(node) }
wrap(service) { (node, work) => () =>
setup(node)
try { work() }
finally { cleanup(node) }
}
def wrap[A, T](service: CompletionService[A, T])(w: (A, () => T) => (() => T)): 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 deps = dependencies(v) ++ runBefore(node)
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)
ready(node)

View File

@ -85,12 +85,12 @@ class JUnitXmlTestsListener(val outputDir: String) extends TestsListener {
""
}
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 => <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 => <failure message={ "No Exception or message provided" }/>
case TStatus.Ignored | TStatus.Skipped | TStatus.Pending => <skipped/>
case _ => {}
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.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.Ignored | TStatus.Skipped | TStatus.Pending=> <skipped/>
case _ => {}
}
}
</testcase>

View File

@ -116,9 +116,9 @@ object TestFramework {
}
def matches(a: Fingerprint, b: Fingerprint) =
(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 _ => false
case _ => false
}
def toString(f: Fingerprint): String =
f match {
@ -127,12 +127,14 @@ object TestFramework {
case _ => f.toString
}
def testTasks(frameworks: Map[TestFramework, Framework],
def testTasks(
frameworks: Map[TestFramework, Framework],
runners: Map[TestFramework, Runner],
testLoader: ClassLoader,
tests: Seq[TestDefinition],
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)
if (mappedTests.isEmpty)

View File

@ -37,7 +37,8 @@ trait TestsListener extends TestReportListener {
final class SuiteResult(
val result: TestResult.Value,
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 = {
val combinedTestResult =
(result, other.result) match {