mirror of https://github.com/sbt/sbt.git
commit
00f292524f
|
|
@ -1,6 +1,7 @@
|
||||||
|
version = 2.0.0-RC5
|
||||||
maxColumn = 100
|
maxColumn = 100
|
||||||
project.git = true
|
project.git = true
|
||||||
project.excludeFilters = [ /sbt-test/, /input_sources/, /contraband-scala/ ]
|
project.excludeFilters = [ "\\Wsbt-test\\W", "\\Winput_sources\\W", "\\Wcontraband-scala\\W" ]
|
||||||
|
|
||||||
# http://docs.scala-lang.org/style/scaladoc.html recommends the JavaDoc style.
|
# http://docs.scala-lang.org/style/scaladoc.html recommends the JavaDoc style.
|
||||||
# scala/scala is written that way too https://github.com/scala/scala/blob/v2.12.2/src/library/scala/Predef.scala
|
# scala/scala is written that way too https://github.com/scala/scala/blob/v2.12.2/src/library/scala/Predef.scala
|
||||||
|
|
@ -16,3 +17,5 @@ align.openParenDefnSite = false
|
||||||
|
|
||||||
# For better code clarity
|
# For better code clarity
|
||||||
danglingParentheses = true
|
danglingParentheses = true
|
||||||
|
|
||||||
|
trailingCommas = preserve
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ env:
|
||||||
# WHITESOURCE_PASSWORD=
|
# WHITESOURCE_PASSWORD=
|
||||||
- secure: d3bu2KNwsVHwfhbGgO+gmRfDKBJhfICdCJFGWKf2w3Gv86AJZX9nuTYRxz0KtdvEHO5Xw8WTBZLPb2thSJqhw9OCm4J8TBAVqCP0ruUj4+aqBUFy4bVexQ6WKE6nWHs4JPzPk8c6uC1LG3hMuzlC8RGETXtL/n81Ef1u7NjyXjs=
|
- secure: d3bu2KNwsVHwfhbGgO+gmRfDKBJhfICdCJFGWKf2w3Gv86AJZX9nuTYRxz0KtdvEHO5Xw8WTBZLPb2thSJqhw9OCm4J8TBAVqCP0ruUj4+aqBUFy4bVexQ6WKE6nWHs4JPzPk8c6uC1LG3hMuzlC8RGETXtL/n81Ef1u7NjyXjs=
|
||||||
matrix:
|
matrix:
|
||||||
- SBT_CMD=";mimaReportBinaryIssues ;scalafmtCheck ;headerCheck ;test:headerCheck ;whitesourceOnPush ;test:compile ;mainSettingsProj/test ;safeUnitTests ;otherUnitTests; doc"
|
- SBT_CMD=";mimaReportBinaryIssues ;scalafmtCheckAll ;headerCheck ;test:headerCheck ;whitesourceOnPush ;test:compile ;mainSettingsProj/test ;safeUnitTests ;otherUnitTests; doc"
|
||||||
- SBT_CMD="scripted actions/*"
|
- SBT_CMD="scripted actions/*"
|
||||||
- SBT_CMD="scripted apiinfo/* compiler-project/* ivy-deps-management/*"
|
- SBT_CMD="scripted apiinfo/* compiler-project/* ivy-deps-management/*"
|
||||||
- SBT_CMD="scripted dependency-management/*1of4"
|
- SBT_CMD="scripted dependency-management/*1of4"
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,9 @@ object Dag {
|
||||||
def visit(node: T): Unit = {
|
def visit(node: T): Unit = {
|
||||||
if (!discovered(node)) {
|
if (!discovered(node)) {
|
||||||
discovered(node) = true;
|
discovered(node) = true;
|
||||||
try { visitAll(dependencies(node)); } catch { case c: Cyclic => throw node :: c }
|
try {
|
||||||
|
visitAll(dependencies(node));
|
||||||
|
} catch { case c: Cyclic => throw node :: c }
|
||||||
finished += node
|
finished += node
|
||||||
()
|
()
|
||||||
} else if (!finished(node))
|
} else if (!finished(node))
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,10 @@ object IDSet {
|
||||||
def isEmpty = backing.isEmpty
|
def isEmpty = backing.isEmpty
|
||||||
|
|
||||||
def process[S](t: T)(ifSeen: S)(ifNew: => S) =
|
def process[S](t: T)(ifSeen: S)(ifNew: => S) =
|
||||||
if (contains(t)) ifSeen else { this += t; ifNew }
|
if (contains(t)) ifSeen
|
||||||
|
else {
|
||||||
|
this += t; ifNew
|
||||||
|
}
|
||||||
|
|
||||||
override def toString = backing.toString
|
override def toString = backing.toString
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,9 @@ abstract class EvaluateSettings[ScopeType] {
|
||||||
}
|
}
|
||||||
|
|
||||||
private[this] def run0(work: => Unit): Unit = {
|
private[this] def run0(work: => Unit): Unit = {
|
||||||
try { work } catch { case e: Throwable => complete.put(Some(e)) }
|
try {
|
||||||
|
work
|
||||||
|
} catch { case e: Throwable => complete.put(Some(e)) }
|
||||||
workComplete()
|
workComplete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,9 @@ trait Init[ScopeType] {
|
||||||
// order the initializations. cyclic references are detected here.
|
// order the initializations. cyclic references are detected here.
|
||||||
val ordered: Seq[Compiled[_]] = sort(cMap)
|
val ordered: Seq[Compiled[_]] = sort(cMap)
|
||||||
// evaluation: apply the initializations.
|
// evaluation: apply the initializations.
|
||||||
try { applyInits(ordered) } catch {
|
try {
|
||||||
|
applyInits(ordered)
|
||||||
|
} catch {
|
||||||
case rru: RuntimeUndefined =>
|
case rru: RuntimeUndefined =>
|
||||||
throw Uninitialized(cMap.keys.toSeq, delegates, rru.undefined, true)
|
throw Uninitialized(cMap.keys.toSeq, delegates, rru.undefined, true)
|
||||||
}
|
}
|
||||||
|
|
@ -285,7 +287,9 @@ trait Init[ScopeType] {
|
||||||
def executor = x
|
def executor = x
|
||||||
}
|
}
|
||||||
eval.run
|
eval.run
|
||||||
} finally { x.shutdown() }
|
} finally {
|
||||||
|
x.shutdown()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def showUndefined(
|
def showUndefined(
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,9 @@ object Signals {
|
||||||
private final class Signals0 {
|
private final class Signals0 {
|
||||||
def supported(signal: String): Boolean = {
|
def supported(signal: String): Boolean = {
|
||||||
import sun.misc.Signal
|
import sun.misc.Signal
|
||||||
try { new Signal(signal); true } catch { case _: IllegalArgumentException => false }
|
try {
|
||||||
|
new Signal(signal); true
|
||||||
|
} catch { case _: IllegalArgumentException => false }
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns a LinkageError in `action` as Left(t) in order to avoid it being
|
// returns a LinkageError in `action` as Left(t) in order to avoid it being
|
||||||
|
|
@ -85,6 +87,8 @@ private final class Signals0 {
|
||||||
val oldHandler = Signal.handle(intSignal, newHandler)
|
val oldHandler = Signal.handle(intSignal, newHandler)
|
||||||
|
|
||||||
try Right(action())
|
try Right(action())
|
||||||
catch { case e: LinkageError => Left(e) } finally { Signal.handle(intSignal, oldHandler); () }
|
catch { case e: LinkageError => Left(e) } finally {
|
||||||
|
Signal.handle(intSignal, oldHandler); ()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,9 @@ case class SettingsExample() extends Init[Scope] {
|
||||||
val delegates: Scope => Seq[Scope] = {
|
val delegates: Scope => Seq[Scope] = {
|
||||||
case s @ Scope(index, proj) =>
|
case s @ Scope(index, proj) =>
|
||||||
s +: (if (index <= 0) Nil
|
s +: (if (index <= 0) Nil
|
||||||
else { (if (proj > 0) List(Scope(index)) else Nil) ++: delegates(Scope(index - 1)) })
|
else {
|
||||||
|
(if (proj > 0) List(Scope(index)) else Nil) ++: delegates(Scope(index - 1))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not using this feature in this example.
|
// Not using this feature in this example.
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,9 @@ object SettingsTest extends Properties("settings") {
|
||||||
// property("Catches circular references") = forAll(chainLengthGen) { checkCircularReferences _ }
|
// property("Catches circular references") = forAll(chainLengthGen) { checkCircularReferences _ }
|
||||||
final def checkCircularReferences(intermediate: Int): Prop = {
|
final def checkCircularReferences(intermediate: Int): Prop = {
|
||||||
val ccr = new CCR(intermediate)
|
val ccr = new CCR(intermediate)
|
||||||
try { evaluate(setting(chk, ccr.top) :: Nil); false } catch {
|
try {
|
||||||
|
evaluate(setting(chk, ccr.top) :: Nil); false
|
||||||
|
} catch {
|
||||||
case _: java.lang.Exception => true
|
case _: java.lang.Exception => true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -195,7 +197,9 @@ object SettingsTest extends Properties("settings") {
|
||||||
}
|
}
|
||||||
|
|
||||||
def evaluate(settings: Seq[Setting[_]]): Settings[Scope] =
|
def evaluate(settings: Seq[Setting[_]]): Settings[Scope] =
|
||||||
try { make(settings)(delegates, scopeLocal, showFullKey) } catch {
|
try {
|
||||||
|
make(settings)(delegates, scopeLocal, showFullKey)
|
||||||
|
} catch {
|
||||||
case e: Throwable => e.printStackTrace(); throw e
|
case e: Throwable => e.printStackTrace(); throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,11 @@ private[sbt] object JLine {
|
||||||
def withJLine[T](action: => T): T =
|
def withJLine[T](action: => T): T =
|
||||||
withTerminal { t =>
|
withTerminal { t =>
|
||||||
t.init
|
t.init
|
||||||
try { action } finally { t.restore }
|
try {
|
||||||
|
action
|
||||||
|
} finally {
|
||||||
|
t.restore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def simple(
|
def simple(
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,10 @@ final class History private (val lines: IndexedSeq[String], val path: Option[Fil
|
||||||
def !! : Option[String] = !-(1)
|
def !! : Option[String] = !-(1)
|
||||||
|
|
||||||
def apply(i: Int): Option[String] =
|
def apply(i: Int): Option[String] =
|
||||||
if (0 <= i && i < size) Some(lines(i)) else { sys.error("Invalid history index: " + i) }
|
if (0 <= i && i < size) Some(lines(i))
|
||||||
|
else {
|
||||||
|
sys.error("Invalid history index: " + i)
|
||||||
|
}
|
||||||
|
|
||||||
def !(i: Int): Option[String] = apply(i)
|
def !(i: Int): Option[String] = apply(i)
|
||||||
|
|
||||||
|
|
@ -54,5 +57,7 @@ object History {
|
||||||
new History(lines.toIndexedSeq, path)
|
new History(lines.toIndexedSeq, path)
|
||||||
|
|
||||||
def number(s: String): Option[Int] =
|
def number(s: String): Option[Int] =
|
||||||
try { Some(s.toInt) } catch { case _: NumberFormatException => None }
|
try {
|
||||||
|
Some(s.toInt)
|
||||||
|
} catch { case _: NumberFormatException => None }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -641,16 +641,28 @@ private final case class SoftInvalid(fail: Failure) extends ValidParser[Nothing]
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class TrapAndFail[A](a: Parser[A]) extends ValidParser[A] {
|
private final class TrapAndFail[A](a: Parser[A]) extends ValidParser[A] {
|
||||||
def result = try { a.result } catch { case _: Exception => None }
|
def result =
|
||||||
def resultEmpty = try { a.resultEmpty } catch { case e: Exception => fail(e) }
|
try {
|
||||||
|
a.result
|
||||||
|
} catch { case _: Exception => None }
|
||||||
|
def resultEmpty =
|
||||||
|
try {
|
||||||
|
a.resultEmpty
|
||||||
|
} catch { case e: Exception => fail(e) }
|
||||||
|
|
||||||
def derive(c: Char) = try { trapAndFail(a derive c) } catch {
|
def derive(c: Char) =
|
||||||
case e: Exception => Invalid(fail(e))
|
try {
|
||||||
}
|
trapAndFail(a derive c)
|
||||||
|
} catch {
|
||||||
|
case e: Exception => Invalid(fail(e))
|
||||||
|
}
|
||||||
|
|
||||||
def completions(level: Int) = try { a.completions(level) } catch {
|
def completions(level: Int) =
|
||||||
case _: Exception => Completions.nil
|
try {
|
||||||
}
|
a.completions(level)
|
||||||
|
} catch {
|
||||||
|
case _: Exception => Completions.nil
|
||||||
|
}
|
||||||
|
|
||||||
override def toString = "trap(" + a + ")"
|
override def toString = "trap(" + a + ")"
|
||||||
override def isTokenStart = a.isTokenStart
|
override def isTokenStart = a.isTokenStart
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,9 @@ trait Parsers {
|
||||||
*/
|
*/
|
||||||
def mapOrFail[S, T](p: Parser[S])(f: S => T): Parser[T] =
|
def mapOrFail[S, T](p: Parser[S])(f: S => T): Parser[T] =
|
||||||
p flatMap { s =>
|
p flatMap { s =>
|
||||||
try { success(f(s)) } catch { case e: Exception => failure(e.toString) }
|
try {
|
||||||
|
success(f(s))
|
||||||
|
} catch { case e: Exception => failure(e.toString) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ object RawCompileLike {
|
||||||
FilesInfo[HashFileInfo] :+: FilesInfo[ModifiedFileInfo] :+: Seq[File] :+: File :+:
|
FilesInfo[HashFileInfo] :+: FilesInfo[ModifiedFileInfo] :+: Seq[File] :+: File :+:
|
||||||
Seq[String] :+: Int :+: HNil
|
Seq[String] :+: Int :+: HNil
|
||||||
val inputs
|
val inputs
|
||||||
: Inputs = hash(sources.toSet ++ optionFiles(options, fileInputOpts)) :+: lastModified(
|
: Inputs = hash(sources.toSet ++ optionFiles(options, fileInputOpts)) :+: lastModified(
|
||||||
classpath.toSet
|
classpath.toSet
|
||||||
) :+: classpath :+: outputDirectory :+: options :+: maxErrors :+: HNil
|
) :+: classpath :+: outputDirectory :+: options :+: maxErrors :+: HNil
|
||||||
val cachedComp = inputChanged(cacheStoreFactory make "inputs") { (inChanged, in: Inputs) =>
|
val cachedComp = inputChanged(cacheStoreFactory make "inputs") { (inChanged, in: Inputs) =>
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,9 @@ object Sync {
|
||||||
def readInfo[F <: FileInfo](
|
def readInfo[F <: FileInfo](
|
||||||
store: CacheStore
|
store: CacheStore
|
||||||
)(implicit infoFormat: JsonFormat[F]): RelationInfo[F] =
|
)(implicit infoFormat: JsonFormat[F]): RelationInfo[F] =
|
||||||
try { readUncaught[F](store)(infoFormat) } catch {
|
try {
|
||||||
|
readUncaught[F](store)(infoFormat)
|
||||||
|
} catch {
|
||||||
case _: IOException => (Relation.empty[File, File], Map.empty[File, F])
|
case _: IOException => (Relation.empty[File, File], Map.empty[File, F])
|
||||||
case _: ZipException => (Relation.empty[File, File], Map.empty[File, F])
|
case _: ZipException => (Relation.empty[File, File], Map.empty[File, F])
|
||||||
case e: TranslatedException =>
|
case e: TranslatedException =>
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,11 @@ final class Eval(
|
||||||
val extra = ev.read(cacheFile(back, moduleName))
|
val extra = ev.read(cacheFile(back, moduleName))
|
||||||
(extra, loader)
|
(extra, loader)
|
||||||
case _ =>
|
case _ =>
|
||||||
try { compileAndLoad(run, unit, imports, backing, moduleName, ev) } finally { unlinkAll() }
|
try {
|
||||||
|
compileAndLoad(run, unit, imports, backing, moduleName, ev)
|
||||||
|
} finally {
|
||||||
|
unlinkAll()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val generatedFiles = getGeneratedFiles(backing, moduleName)
|
val generatedFiles = getGeneratedFiles(backing, moduleName)
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ val p = {
|
||||||
i =>
|
i =>
|
||||||
value(eval.eval("abs(" + i + ")", new EvalImports(imports.zipWithIndex, "imp"))) == math.abs(
|
value(eval.eval("abs(" + i + ")", new EvalImports(imports.zipWithIndex, "imp"))) == math.abs(
|
||||||
i
|
i
|
||||||
)
|
)
|
||||||
|
|
||||||
private[this] def local(i: Int) = "{ class ETest(val i: Int); new ETest(" + i + ") }"
|
private[this] def local(i: Int) = "{ class ETest(val i: Int); new ETest(" + i + ") }"
|
||||||
val LocalType = "AnyRef{val i: Int}"
|
val LocalType = "AnyRef{val i: Int}"
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ object Def extends Init[Scope] with TaskMacroExtra {
|
||||||
key.scope,
|
key.scope,
|
||||||
withColor(key.key.label, keyNameColor),
|
withColor(key.key.label, keyNameColor),
|
||||||
ref => displayRelative2(current, ref)
|
ref => displayRelative2(current, ref)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private[sbt] def showShortKey(
|
private[sbt] def showShortKey(
|
||||||
|
|
@ -81,7 +81,7 @@ object Def extends Init[Scope] with TaskMacroExtra {
|
||||||
key.scope,
|
key.scope,
|
||||||
withColor(key.key.label, keyNameColor),
|
withColor(key.key.label, keyNameColor),
|
||||||
ref => displayShort(ref)
|
ref => displayShort(ref)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ object Def extends Init[Scope] with TaskMacroExtra {
|
||||||
key.scope,
|
key.scope,
|
||||||
withColor(key.key.label, keyNameColor),
|
withColor(key.key.label, keyNameColor),
|
||||||
ref => displayBuildRelative(currentBuild, ref)
|
ref => displayBuildRelative(currentBuild, ref)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ final class InputTask[T] private (val parser: State => Parser[Task[T]]) {
|
||||||
case Left(msg) =>
|
case Left(msg) =>
|
||||||
val indented = msg.linesIterator.map(" " + _).mkString("\n")
|
val indented = msg.linesIterator.map(" " + _).mkString("\n")
|
||||||
Parser.failure(s"Invalid programmatic input:\n$indented")
|
Parser.failure(s"Invalid programmatic input:\n$indented")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ object InputTask {
|
||||||
val indented = msg.linesIterator.map(" " + _).mkString("\n")
|
val indented = msg.linesIterator.map(" " + _).mkString("\n")
|
||||||
sys.error(s"Invalid programmatic input:\n$indented")
|
sys.error(s"Invalid programmatic input:\n$indented")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ object Scope {
|
||||||
subThis(thisScope.config, scope.config),
|
subThis(thisScope.config, scope.config),
|
||||||
subThis(thisScope.task, scope.task),
|
subThis(thisScope.task, scope.task),
|
||||||
subThis(thisScope.extra, scope.extra)
|
subThis(thisScope.extra, scope.extra)
|
||||||
)
|
)
|
||||||
|
|
||||||
def subThis[T](sub: ScopeAxis[T], into: ScopeAxis[T]): ScopeAxis[T] =
|
def subThis[T](sub: ScopeAxis[T], into: ScopeAxis[T]): ScopeAxis[T] =
|
||||||
if (into == This) sub else into
|
if (into == This) sub else into
|
||||||
|
|
@ -273,8 +273,7 @@ object Scope {
|
||||||
taskInherit: AttributeKey[_] => Seq[AttributeKey[_]],
|
taskInherit: AttributeKey[_] => Seq[AttributeKey[_]],
|
||||||
): Scope => Seq[Scope] = {
|
): Scope => Seq[Scope] = {
|
||||||
val index = delegates(refs, configurations, projectInherit, configInherit)
|
val index = delegates(refs, configurations, projectInherit, configInherit)
|
||||||
scope =>
|
scope => indexedDelegates(resolve, index, rootProject, taskInherit)(scope)
|
||||||
indexedDelegates(resolve, index, rootProject, taskInherit)(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@deprecated("Use variant without extraInherit", "1.1.1")
|
@deprecated("Use variant without extraInherit", "1.1.1")
|
||||||
|
|
|
||||||
|
|
@ -48,16 +48,15 @@ abstract class BackgroundJobService extends Closeable {
|
||||||
object BackgroundJobService {
|
object BackgroundJobService {
|
||||||
private[sbt] def jobIdParser: (State, Seq[JobHandle]) => Parser[Seq[JobHandle]] = {
|
private[sbt] def jobIdParser: (State, Seq[JobHandle]) => Parser[Seq[JobHandle]] = {
|
||||||
import DefaultParsers._
|
import DefaultParsers._
|
||||||
(state, handles) =>
|
(state, handles) => {
|
||||||
{
|
val stringIdParser: Parser[Seq[String]] = Space ~> token(
|
||||||
val stringIdParser: Parser[Seq[String]] = Space ~> token(
|
NotSpace examples handles.map(_.id.toString).toSet,
|
||||||
NotSpace examples handles.map(_.id.toString).toSet,
|
description = "<job id>"
|
||||||
description = "<job id>"
|
).+
|
||||||
).+
|
stringIdParser.map { strings =>
|
||||||
stringIdParser.map { strings =>
|
strings.map(Integer.parseInt(_)).flatMap(id => handles.find(_.id == id))
|
||||||
strings.map(Integer.parseInt(_)).flatMap(id => handles.find(_.id == id))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -268,8 +268,7 @@ object Defaults extends BuildCommon {
|
||||||
taskTemporaryDirectory := { val dir = IO.createTemporaryDirectory; dir.deleteOnExit(); dir },
|
taskTemporaryDirectory := { val dir = IO.createTemporaryDirectory; dir.deleteOnExit(); dir },
|
||||||
onComplete := {
|
onComplete := {
|
||||||
val tempDirectory = taskTemporaryDirectory.value
|
val tempDirectory = taskTemporaryDirectory.value
|
||||||
() =>
|
() => Clean.deleteContents(tempDirectory, _ => false)
|
||||||
Clean.deleteContents(tempDirectory, _ => false)
|
|
||||||
},
|
},
|
||||||
useSuperShell := { if (insideCI.value) false else sbt.internal.TaskProgress.isEnabled },
|
useSuperShell := { if (insideCI.value) false else sbt.internal.TaskProgress.isEnabled },
|
||||||
progressReports := { (s: State) =>
|
progressReports := { (s: State) =>
|
||||||
|
|
@ -295,8 +294,7 @@ object Defaults extends BuildCommon {
|
||||||
Continuous.dynamicInputs := Continuous.dynamicInputsImpl.value,
|
Continuous.dynamicInputs := Continuous.dynamicInputsImpl.value,
|
||||||
externalHooks := {
|
externalHooks := {
|
||||||
val repository = fileTreeRepository.value
|
val repository = fileTreeRepository.value
|
||||||
compileOptions =>
|
compileOptions => Some(ExternalHooks(compileOptions, repository))
|
||||||
Some(ExternalHooks(compileOptions, repository))
|
|
||||||
},
|
},
|
||||||
logBuffered :== false,
|
logBuffered :== false,
|
||||||
commands :== Nil,
|
commands :== Nil,
|
||||||
|
|
@ -757,7 +755,7 @@ object Defaults extends BuildCommon {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
lazy val testTasks
|
lazy val testTasks
|
||||||
: Seq[Setting[_]] = testTaskOptions(test) ++ testTaskOptions(testOnly) ++ testTaskOptions(
|
: Seq[Setting[_]] = testTaskOptions(test) ++ testTaskOptions(testOnly) ++ testTaskOptions(
|
||||||
testQuick
|
testQuick
|
||||||
) ++ testDefaults ++ Seq(
|
) ++ testDefaults ++ Seq(
|
||||||
testLoader := ClassLoaders.testTask.value,
|
testLoader := ClassLoaders.testTask.value,
|
||||||
|
|
@ -1686,10 +1684,11 @@ object Defaults extends BuildCommon {
|
||||||
private[sbt] def foldMappers[A](mappers: Seq[A => Option[A]]) =
|
private[sbt] def foldMappers[A](mappers: Seq[A => Option[A]]) =
|
||||||
mappers.foldRight({ p: A =>
|
mappers.foldRight({ p: A =>
|
||||||
p
|
p
|
||||||
}) { (mapper, mappers) =>
|
}) {
|
||||||
{ p: A =>
|
(mapper, mappers) =>
|
||||||
mapper(p).getOrElse(mappers(p))
|
{ p: A =>
|
||||||
}
|
mapper(p).getOrElse(mappers(p))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private[sbt] def none[A]: Option[A] = (None: Option[A])
|
private[sbt] def none[A]: Option[A] = (None: Option[A])
|
||||||
private[sbt] def jnone[A]: Optional[A] = none[A].toOptional
|
private[sbt] def jnone[A]: Optional[A] = none[A].toOptional
|
||||||
|
|
@ -2773,7 +2772,7 @@ object Classpaths {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
implicit val RangePositionFormat
|
implicit val RangePositionFormat
|
||||||
: IsoLList.Aux[RangePosition, String :*: LineRange :*: LNil] = LList.iso(
|
: IsoLList.Aux[RangePosition, String :*: LineRange :*: LNil] = LList.iso(
|
||||||
{ r: RangePosition =>
|
{ r: RangePosition =>
|
||||||
("path", r.path) :*: ("range", r.range) :*: LNil
|
("path", r.path) :*: ("range", r.range) :*: LNil
|
||||||
}, { in: String :*: LineRange :*: LNil =>
|
}, { in: String :*: LineRange :*: LNil =>
|
||||||
|
|
@ -3188,8 +3187,7 @@ object Classpaths {
|
||||||
case _ => sys.error("Invalid configuration '" + confString + "'") // shouldn't get here
|
case _ => sys.error("Invalid configuration '" + confString + "'") // shouldn't get here
|
||||||
}
|
}
|
||||||
val m = ms.toMap
|
val m = ms.toMap
|
||||||
s =>
|
s => m.getOrElse(s, Nil)
|
||||||
m.getOrElse(s, Nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def union[A, B](maps: Seq[A => Seq[B]]): A => Seq[B] =
|
def union[A, B](maps: Seq[A => Seq[B]]): A => Seq[B] =
|
||||||
|
|
@ -3365,12 +3363,16 @@ object Classpaths {
|
||||||
|
|
||||||
// try/catch for supporting earlier launchers
|
// try/catch for supporting earlier launchers
|
||||||
def bootIvyHome(app: xsbti.AppConfiguration): Option[File] =
|
def bootIvyHome(app: xsbti.AppConfiguration): Option[File] =
|
||||||
try { Option(app.provider.scalaProvider.launcher.ivyHome) } catch {
|
try {
|
||||||
|
Option(app.provider.scalaProvider.launcher.ivyHome)
|
||||||
|
} catch {
|
||||||
case _: NoSuchMethodError => None
|
case _: NoSuchMethodError => None
|
||||||
}
|
}
|
||||||
|
|
||||||
def bootChecksums(app: xsbti.AppConfiguration): Vector[String] =
|
def bootChecksums(app: xsbti.AppConfiguration): Vector[String] =
|
||||||
try { app.provider.scalaProvider.launcher.checksums.toVector } catch {
|
try {
|
||||||
|
app.provider.scalaProvider.launcher.checksums.toVector
|
||||||
|
} catch {
|
||||||
case _: NoSuchMethodError => IvySbt.DefaultChecksums
|
case _: NoSuchMethodError => IvySbt.DefaultChecksums
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3380,23 +3382,33 @@ object Classpaths {
|
||||||
|
|
||||||
/** Loads the `appRepositories` configured for this launcher, if supported. */
|
/** Loads the `appRepositories` configured for this launcher, if supported. */
|
||||||
def appRepositories(app: xsbti.AppConfiguration): Option[Vector[Resolver]] =
|
def appRepositories(app: xsbti.AppConfiguration): Option[Vector[Resolver]] =
|
||||||
try { Some(app.provider.scalaProvider.launcher.appRepositories.toVector map bootRepository) } catch {
|
try {
|
||||||
|
Some(app.provider.scalaProvider.launcher.appRepositories.toVector map bootRepository)
|
||||||
|
} catch {
|
||||||
case _: NoSuchMethodError => None
|
case _: NoSuchMethodError => None
|
||||||
}
|
}
|
||||||
|
|
||||||
def bootRepositories(app: xsbti.AppConfiguration): Option[Vector[Resolver]] =
|
def bootRepositories(app: xsbti.AppConfiguration): Option[Vector[Resolver]] =
|
||||||
try { Some(app.provider.scalaProvider.launcher.ivyRepositories.toVector map bootRepository) } catch {
|
try {
|
||||||
|
Some(app.provider.scalaProvider.launcher.ivyRepositories.toVector map bootRepository)
|
||||||
|
} catch {
|
||||||
case _: NoSuchMethodError => None
|
case _: NoSuchMethodError => None
|
||||||
}
|
}
|
||||||
|
|
||||||
private[this] def mavenCompatible(ivyRepo: xsbti.IvyRepository): Boolean =
|
private[this] def mavenCompatible(ivyRepo: xsbti.IvyRepository): Boolean =
|
||||||
try { ivyRepo.mavenCompatible } catch { case _: NoSuchMethodError => false }
|
try {
|
||||||
|
ivyRepo.mavenCompatible
|
||||||
|
} catch { case _: NoSuchMethodError => false }
|
||||||
|
|
||||||
private[this] def skipConsistencyCheck(ivyRepo: xsbti.IvyRepository): Boolean =
|
private[this] def skipConsistencyCheck(ivyRepo: xsbti.IvyRepository): Boolean =
|
||||||
try { ivyRepo.skipConsistencyCheck } catch { case _: NoSuchMethodError => false }
|
try {
|
||||||
|
ivyRepo.skipConsistencyCheck
|
||||||
|
} catch { case _: NoSuchMethodError => false }
|
||||||
|
|
||||||
private[this] def descriptorOptional(ivyRepo: xsbti.IvyRepository): Boolean =
|
private[this] def descriptorOptional(ivyRepo: xsbti.IvyRepository): Boolean =
|
||||||
try { ivyRepo.descriptorOptional } catch { case _: NoSuchMethodError => false }
|
try {
|
||||||
|
ivyRepo.descriptorOptional
|
||||||
|
} catch { case _: NoSuchMethodError => false }
|
||||||
|
|
||||||
private[this] def bootRepository(repo: xsbti.Repository): Resolver = {
|
private[this] def bootRepository(repo: xsbti.Repository): Resolver = {
|
||||||
import xsbti.Predefined
|
import xsbti.Predefined
|
||||||
|
|
|
||||||
|
|
@ -367,7 +367,11 @@ object EvaluateTask {
|
||||||
|
|
||||||
def withStreams[T](structure: BuildStructure, state: State)(f: Streams => T): T = {
|
def withStreams[T](structure: BuildStructure, state: State)(f: Streams => T): T = {
|
||||||
val str = std.Streams.closeable(structure.streams(state))
|
val str = std.Streams.closeable(structure.streams(state))
|
||||||
try { f(str) } finally { str.close() }
|
try {
|
||||||
|
f(str)
|
||||||
|
} finally {
|
||||||
|
str.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def getTask[T](
|
def getTask[T](
|
||||||
|
|
@ -585,5 +589,5 @@ object EvaluateTask {
|
||||||
(transitiveClasspathDependency in scoped.scope := { () }) :: Nil
|
(transitiveClasspathDependency in scoped.scope := { () }) :: Nil
|
||||||
} else {
|
} else {
|
||||||
Nil
|
Nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -624,7 +624,9 @@ object BuiltinCommands {
|
||||||
catch {
|
catch {
|
||||||
case NonFatal(e) =>
|
case NonFatal(e) =>
|
||||||
try export0(s)
|
try export0(s)
|
||||||
finally { throw e }
|
finally {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export0(newS)
|
export0(newS)
|
||||||
}
|
}
|
||||||
|
|
@ -704,7 +706,7 @@ object BuiltinCommands {
|
||||||
s =>
|
s =>
|
||||||
CommandStrings.showHelp ++ CommandStrings.printHelp ++ CommandStrings.multiTaskHelp ++ keysHelp(
|
CommandStrings.showHelp ++ CommandStrings.printHelp ++ CommandStrings.multiTaskHelp ++ keysHelp(
|
||||||
s
|
s
|
||||||
)
|
)
|
||||||
|
|
||||||
def keysHelp(s: State): Help =
|
def keysHelp(s: State): Help =
|
||||||
if (Project.isProjectLoaded(s))
|
if (Project.isProjectLoaded(s))
|
||||||
|
|
@ -850,7 +852,7 @@ object BuiltinCommands {
|
||||||
if (version != app.id.version()) {
|
if (version != app.id.version()) {
|
||||||
state.log.warn(s"""sbt version mismatch, current: ${app.id
|
state.log.warn(s"""sbt version mismatch, current: ${app.id
|
||||||
.version()}, in build.properties: "$version", use 'reboot' to use the new value.""")
|
.version()}, in build.properties: "$version", use 'reboot' to use the new value.""")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -189,49 +189,48 @@ object Plugins extends PluginsFunctions {
|
||||||
val allEnabledByClause = defined.filterNot(_.isRoot).flatMap(d => asEnabledByClauses(d))
|
val allEnabledByClause = defined.filterNot(_.isRoot).flatMap(d => asEnabledByClauses(d))
|
||||||
|
|
||||||
// Note: Here is where the function begins. We're given a list of plugins now.
|
// Note: Here is where the function begins. We're given a list of plugins now.
|
||||||
(requestedPlugins, log) =>
|
(requestedPlugins, log) => {
|
||||||
{
|
timed("Plugins.deducer#function", log) {
|
||||||
timed("Plugins.deducer#function", log) {
|
def explicitlyDisabled(p: AutoPlugin): Boolean = hasExclude(requestedPlugins, p)
|
||||||
def explicitlyDisabled(p: AutoPlugin): Boolean = hasExclude(requestedPlugins, p)
|
val alwaysEnabled: List[AutoPlugin] =
|
||||||
val alwaysEnabled: List[AutoPlugin] =
|
defined.filter(_.isAlwaysEnabled).filterNot(explicitlyDisabled)
|
||||||
defined.filter(_.isAlwaysEnabled).filterNot(explicitlyDisabled)
|
val knowledge0: Set[Atom] = ((flatten(requestedPlugins) ++ alwaysEnabled) collect {
|
||||||
val knowledge0: Set[Atom] = ((flatten(requestedPlugins) ++ alwaysEnabled) collect {
|
case x: AutoPlugin => Atom(x.label)
|
||||||
case x: AutoPlugin => Atom(x.label)
|
}).toSet
|
||||||
}).toSet
|
val clauses = Clauses((allRequirementsClause ::: allEnabledByClause) filterNot {
|
||||||
val clauses = Clauses((allRequirementsClause ::: allEnabledByClause) filterNot {
|
_.head subsetOf knowledge0
|
||||||
_.head subsetOf knowledge0
|
})
|
||||||
})
|
log.debug(
|
||||||
log.debug(
|
s"deducing auto plugins based on known facts ${knowledge0.toString} and clauses ${clauses.toString}"
|
||||||
s"deducing auto plugins based on known facts ${knowledge0.toString} and clauses ${clauses.toString}"
|
)
|
||||||
)
|
Logic.reduce(
|
||||||
Logic.reduce(
|
clauses,
|
||||||
clauses,
|
(flattenConvert(requestedPlugins) ++ convertAll(alwaysEnabled)).toSet
|
||||||
(flattenConvert(requestedPlugins) ++ convertAll(alwaysEnabled)).toSet
|
) match {
|
||||||
) match {
|
case Left(problem) => throw AutoPluginException(problem)
|
||||||
case Left(problem) => throw AutoPluginException(problem)
|
case Right(results) =>
|
||||||
case Right(results) =>
|
log.debug(s" :: deduced result: ${results}")
|
||||||
log.debug(s" :: deduced result: ${results}")
|
val selectedAtoms: List[Atom] = results.ordered
|
||||||
val selectedAtoms: List[Atom] = results.ordered
|
val selectedPlugins = selectedAtoms map { a =>
|
||||||
val selectedPlugins = selectedAtoms map { a =>
|
byAtomMap.getOrElse(
|
||||||
byAtomMap.getOrElse(
|
a,
|
||||||
a,
|
throw AutoPluginException(s"${a} was not found in atom map.")
|
||||||
throw AutoPluginException(s"${a} was not found in atom map.")
|
)
|
||||||
)
|
}
|
||||||
}
|
val forbidden: Set[AutoPlugin] =
|
||||||
val forbidden: Set[AutoPlugin] =
|
(selectedPlugins flatMap { Plugins.asExclusions }).toSet
|
||||||
(selectedPlugins flatMap { Plugins.asExclusions }).toSet
|
val c = selectedPlugins.toSet & forbidden
|
||||||
val c = selectedPlugins.toSet & forbidden
|
if (c.nonEmpty) {
|
||||||
if (c.nonEmpty) {
|
exclusionConflictError(requestedPlugins, selectedPlugins, c.toSeq sortBy {
|
||||||
exclusionConflictError(requestedPlugins, selectedPlugins, c.toSeq sortBy {
|
_.label
|
||||||
_.label
|
})
|
||||||
})
|
}
|
||||||
}
|
val retval = topologicalSort(selectedPlugins)
|
||||||
val retval = topologicalSort(selectedPlugins)
|
// log.debug(s" :: sorted deduced result: ${retval.toString}")
|
||||||
// log.debug(s" :: sorted deduced result: ${retval.toString}")
|
retval
|
||||||
retval
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private[sbt] def topologicalSort(ns: List[AutoPlugin]): List[AutoPlugin] = {
|
private[sbt] def topologicalSort(ns: List[AutoPlugin]): List[AutoPlugin] = {
|
||||||
|
|
|
||||||
|
|
@ -837,7 +837,7 @@ object Project extends ProjectExtra {
|
||||||
task,
|
task,
|
||||||
(state, value) =>
|
(state, value) =>
|
||||||
persistAndSet(resolveContext(key, scoped.scope, state), state, value)(f)
|
persistAndSet(resolveContext(key, scoped.scope, state), state, value)(f)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,7 @@ object ScopeFilter {
|
||||||
val pf = projects(data)
|
val pf = projects(data)
|
||||||
val cf = configurations(data)
|
val cf = configurations(data)
|
||||||
val tf = tasks(data)
|
val tf = tasks(data)
|
||||||
s =>
|
s => pf(s.project) && cf(s.config) && tf(s.task)
|
||||||
pf(s.project) && cf(s.config) && tf(s.task)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,12 +48,11 @@ object ScopeFilter {
|
||||||
new ScopeFilter {
|
new ScopeFilter {
|
||||||
private[sbt] def apply(data: Data): Scope => Boolean = {
|
private[sbt] def apply(data: Data): Scope => Boolean = {
|
||||||
val d = delegate(data)
|
val d = delegate(data)
|
||||||
scope =>
|
scope => {
|
||||||
{
|
val accept = d(scope)
|
||||||
val accept = d(scope)
|
println((if (accept) "ACCEPT " else "reject ") + scope)
|
||||||
println((if (accept) "ACCEPT " else "reject ") + scope)
|
accept
|
||||||
accept
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,7 +201,7 @@ object ScopeFilter {
|
||||||
(p, thisRef) match {
|
(p, thisRef) match {
|
||||||
case (ThisProject, Some(pref)) => pref
|
case (ThisProject, Some(pref)) => pref
|
||||||
case _ => Scope.resolveProjectRef(current, rootProject, p)
|
case _ => Scope.resolveProjectRef(current, rootProject, p)
|
||||||
}
|
}
|
||||||
new Data(build.units, resolve, scopes)
|
new Data(build.units, resolve, scopes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,7 +214,7 @@ object ScopeFilter {
|
||||||
Project.getProject(ref, structure).toList flatMap { p =>
|
Project.getProject(ref, structure).toList flatMap { p =>
|
||||||
(if (classpath) p.dependencies.map(_.project) else Nil) ++
|
(if (classpath) p.dependencies.map(_.project) else Nil) ++
|
||||||
(if (aggregate) p.aggregate else Nil)
|
(if (aggregate) p.aggregate else Nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
private[this] def byDeps(
|
private[this] def byDeps(
|
||||||
ref: ProjectReference,
|
ref: ProjectReference,
|
||||||
|
|
@ -273,8 +271,7 @@ object ScopeFilter {
|
||||||
private[sbt] def apply(data: Data): In => Boolean = {
|
private[sbt] def apply(data: Data): In => Boolean = {
|
||||||
val a = self(data)
|
val a = self(data)
|
||||||
val b = other(data)
|
val b = other(data)
|
||||||
s =>
|
s => a(s) && b(s)
|
||||||
a(s) && b(s)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,8 +280,7 @@ object ScopeFilter {
|
||||||
private[sbt] def apply(data: Data): In => Boolean = {
|
private[sbt] def apply(data: Data): In => Boolean = {
|
||||||
val a = self(data)
|
val a = self(data)
|
||||||
val b = other(data)
|
val b = other(data)
|
||||||
s =>
|
s => a(s) || b(s)
|
||||||
a(s) || b(s)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,8 +288,7 @@ object ScopeFilter {
|
||||||
def unary_- : Base[In] = new Base[In] {
|
def unary_- : Base[In] = new Base[In] {
|
||||||
private[sbt] def apply(data: Data): In => Boolean = {
|
private[sbt] def apply(data: Data): In => Boolean = {
|
||||||
val a = self(data)
|
val a = self(data)
|
||||||
s =>
|
s => !a(s)
|
||||||
!a(s)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ object ScriptedPlugin extends AutoPlugin {
|
||||||
import DefaultParsers._
|
import DefaultParsers._
|
||||||
|
|
||||||
val scriptedFiles
|
val scriptedFiles
|
||||||
: NameFilter = ("test": NameFilter) | "test.script" | "pending" | "pending.script"
|
: NameFilter = ("test": NameFilter) | "test.script" | "pending" | "pending.script"
|
||||||
val pairs = (scriptedBase * AllPassFilter * AllPassFilter * scriptedFiles).get map {
|
val pairs = (scriptedBase * AllPassFilter * AllPassFilter * scriptedFiles).get map {
|
||||||
(f: File) =>
|
(f: File) =>
|
||||||
val p = f.getParentFile
|
val p = f.getParentFile
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,9 @@ object SessionVar {
|
||||||
|
|
||||||
def read[T](key: ScopedKey[Task[T]], state: State)(implicit f: JsonFormat[T]): Option[T] =
|
def read[T](key: ScopedKey[Task[T]], state: State)(implicit f: JsonFormat[T]): Option[T] =
|
||||||
Project.structure(state).streams(state).use(key) { s =>
|
Project.structure(state).streams(state).use(key) { s =>
|
||||||
try { Some(s.getInput(key, DefaultDataID).read[T]) } catch { case NonFatal(_) => None }
|
try {
|
||||||
|
Some(s.getInput(key, DefaultDataID).read[T])
|
||||||
|
} catch { case NonFatal(_) => None }
|
||||||
}
|
}
|
||||||
|
|
||||||
def load[T](key: ScopedKey[Task[T]], state: State)(implicit f: JsonFormat[T]): Option[T] =
|
def load[T](key: ScopedKey[Task[T]], state: State)(implicit f: JsonFormat[T]): Option[T] =
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,9 @@ private[sbt] object TemplateCommandUtil {
|
||||||
val interfaceClass = getInterfaceClass(interfaceClassName, loader)
|
val interfaceClass = getInterfaceClass(interfaceClassName, loader)
|
||||||
val interface = interfaceClass.getDeclaredConstructor().newInstance().asInstanceOf[AnyRef]
|
val interface = interfaceClass.getDeclaredConstructor().newInstance().asInstanceOf[AnyRef]
|
||||||
val method = interfaceClass.getMethod(methodName, argTypes: _*)
|
val method = interfaceClass.getMethod(methodName, argTypes: _*)
|
||||||
try { method.invoke(interface, args: _*) } catch {
|
try {
|
||||||
|
method.invoke(interface, args: _*)
|
||||||
|
} catch {
|
||||||
case e: InvocationTargetException => throw e.getCause
|
case e: InvocationTargetException => throw e.getCause
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -261,7 +261,7 @@ object Watch {
|
||||||
case Update(prev, cur, _) if prev.value != cur.value => action
|
case Update(prev, cur, _) if prev.value != cur.value => action
|
||||||
case _: Creation[_] | _: Deletion[_] => action
|
case _: Creation[_] | _: Deletion[_] => action
|
||||||
case _ => Ignore
|
case _ => Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The minimum delay between build triggers for the same file. If the file is detected
|
* The minimum delay between build triggers for the same file. If the file is detected
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ object AddSettings {
|
||||||
|
|
||||||
/** Adds all settings from autoplugins. */
|
/** Adds all settings from autoplugins. */
|
||||||
val autoPlugins
|
val autoPlugins
|
||||||
: AddSettings = new AutoPlugins(const(true)) // Note: We do not expose fine-grained autoplugins because
|
: AddSettings = new AutoPlugins(const(true)) // Note: We do not expose fine-grained autoplugins because
|
||||||
// it's dangerous to control at that level right now.
|
// it's dangerous to control at that level right now.
|
||||||
// Leaving the hook in place in case we need to expose
|
// Leaving the hook in place in case we need to expose
|
||||||
// it, but most likely it will remain locked out
|
// it, but most likely it will remain locked out
|
||||||
|
|
|
||||||
|
|
@ -64,19 +64,16 @@ object Clean {
|
||||||
// Don't use a regular logger because the logger actually writes to the target directory.
|
// Don't use a regular logger because the logger actually writes to the target directory.
|
||||||
val debug = (logLevel in scope).?.value.orElse(state.value.get(logLevel.key)) match {
|
val debug = (logLevel in scope).?.value.orElse(state.value.get(logLevel.key)) match {
|
||||||
case Some(Level.Debug) =>
|
case Some(Level.Debug) =>
|
||||||
(string: String) =>
|
(string: String) => println(s"[debug] $string")
|
||||||
println(s"[debug] $string")
|
|
||||||
case _ =>
|
case _ =>
|
||||||
(_: String) =>
|
(_: String) => {}
|
||||||
{}
|
|
||||||
}
|
}
|
||||||
val delete = tryDelete(debug)
|
val delete = tryDelete(debug)
|
||||||
cleanFiles.value.sorted.reverseIterator.foreach(delete)
|
cleanFiles.value.sorted.reverseIterator.foreach(delete)
|
||||||
(fileOutputs in scope).value.foreach { g =>
|
(fileOutputs in scope).value.foreach { g =>
|
||||||
val filter: TypedPath => Boolean = {
|
val filter: TypedPath => Boolean = {
|
||||||
val globFilter = g.toTypedPathFilter
|
val globFilter = g.toTypedPathFilter
|
||||||
tp =>
|
tp => !globFilter(tp) || excludeFilter(tp)
|
||||||
!globFilter(tp) || excludeFilter(tp)
|
|
||||||
}
|
}
|
||||||
deleteContents(g.base.toFile, filter, FileTreeView.DEFAULT, delete)
|
deleteContents(g.base.toFile, filter, FileTreeView.DEFAULT, delete)
|
||||||
delete(g.base.toFile)
|
delete(g.base.toFile)
|
||||||
|
|
|
||||||
|
|
@ -456,14 +456,13 @@ object Continuous extends DeprecatedContinuous {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
() =>
|
() => {
|
||||||
{
|
val res = f.view.map(_()).min
|
||||||
val res = f.view.map(_()).min
|
// Print the default watch message if there are multiple tasks
|
||||||
// Print the default watch message if there are multiple tasks
|
if (configs.size > 1)
|
||||||
if (configs.size > 1)
|
Watch.defaultStartWatch(count.get(), project, commands).foreach(logger.info(_))
|
||||||
Watch.defaultStartWatch(count.get(), project, commands).foreach(logger.info(_))
|
res
|
||||||
res
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private def getFileEvents(
|
private def getFileEvents(
|
||||||
configs: Seq[Config],
|
configs: Seq[Config],
|
||||||
|
|
@ -500,11 +499,9 @@ object Continuous extends DeprecatedContinuous {
|
||||||
if (excludedBuildFilter(entry)) onMetaBuildEvent(c, event) else Watch.Ignore
|
if (excludedBuildFilter(entry)) onMetaBuildEvent(c, event) else Watch.Ignore
|
||||||
).min
|
).min
|
||||||
}
|
}
|
||||||
event: Event =>
|
event: Event => event -> oe(event)
|
||||||
event -> oe(event)
|
|
||||||
}
|
}
|
||||||
event: Event =>
|
event: Event => f.view.map(_.apply(event)).minBy(_._2)
|
||||||
f.view.map(_.apply(event)).minBy(_._2)
|
|
||||||
}
|
}
|
||||||
val monitor: FileEventMonitor[FileAttributes] = new FileEventMonitor[FileAttributes] {
|
val monitor: FileEventMonitor[FileAttributes] = new FileEventMonitor[FileAttributes] {
|
||||||
|
|
||||||
|
|
@ -654,26 +651,23 @@ object Continuous extends DeprecatedContinuous {
|
||||||
.map { inputStreamKey =>
|
.map { inputStreamKey =>
|
||||||
val is = extracted.runTask(inputStreamKey, state)._2
|
val is = extracted.runTask(inputStreamKey, state)._2
|
||||||
val handler = c.watchSettings.inputHandler.getOrElse(defaultInputHandler(inputParser))
|
val handler = c.watchSettings.inputHandler.getOrElse(defaultInputHandler(inputParser))
|
||||||
() =>
|
() => handler(is)
|
||||||
handler(is)
|
|
||||||
}
|
}
|
||||||
.getOrElse(() => Watch.Ignore)
|
.getOrElse(() => Watch.Ignore)
|
||||||
(string: String) =>
|
(string: String) => (default(string) :: alternative() :: Nil).min
|
||||||
(default(string) :: alternative() :: Nil).min
|
}
|
||||||
|
() => {
|
||||||
|
val stringBuilder = new StringBuilder
|
||||||
|
while (inputStream.available > 0) stringBuilder += inputStream.read().toChar
|
||||||
|
val newBytes = stringBuilder.toString
|
||||||
|
val parse: ActionParser => Watch.Action = parser => parser(newBytes)
|
||||||
|
val allEvents = inputHandlers.map(parse).filterNot(_ == Watch.Ignore)
|
||||||
|
if (allEvents.exists(_ != Watch.Ignore)) {
|
||||||
|
val res = allEvents.min
|
||||||
|
logger.debug(s"Received input events: ${allEvents mkString ","}. Taking $res")
|
||||||
|
res
|
||||||
|
} else Watch.Ignore
|
||||||
}
|
}
|
||||||
() =>
|
|
||||||
{
|
|
||||||
val stringBuilder = new StringBuilder
|
|
||||||
while (inputStream.available > 0) stringBuilder += inputStream.read().toChar
|
|
||||||
val newBytes = stringBuilder.toString
|
|
||||||
val parse: ActionParser => Watch.Action = parser => parser(newBytes)
|
|
||||||
val allEvents = inputHandlers.map(parse).filterNot(_ == Watch.Ignore)
|
|
||||||
if (allEvents.exists(_ != Watch.Ignore)) {
|
|
||||||
val res = allEvents.min
|
|
||||||
logger.debug(s"Received input events: ${allEvents mkString ","}. Taking $res")
|
|
||||||
res
|
|
||||||
} else Watch.Ignore
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private def combineInputAndFileEvents(
|
private def combineInputAndFileEvents(
|
||||||
|
|
|
||||||
|
|
@ -119,8 +119,7 @@ private[sbt] object EvaluateConfigurations {
|
||||||
offset: Int
|
offset: Int
|
||||||
): LazyClassLoaded[Seq[Setting[_]]] = {
|
): LazyClassLoaded[Seq[Setting[_]]] = {
|
||||||
val l = evaluateSbtFile(eval, file, lines, imports, offset)
|
val l = evaluateSbtFile(eval, file, lines, imports, offset)
|
||||||
loader =>
|
loader => l(loader).settings
|
||||||
l(loader).settings
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -160,36 +159,35 @@ private[sbt] object EvaluateConfigurations {
|
||||||
eval.unlinkDeferred()
|
eval.unlinkDeferred()
|
||||||
// Tracks all the files we generated from evaluating the sbt file.
|
// Tracks all the files we generated from evaluating the sbt file.
|
||||||
val allGeneratedFiles = (definitions.generated ++ dslEntries.flatMap(_.generated))
|
val allGeneratedFiles = (definitions.generated ++ dslEntries.flatMap(_.generated))
|
||||||
loader =>
|
loader => {
|
||||||
{
|
val projects = {
|
||||||
val projects = {
|
val compositeProjects = definitions.values(loader).collect {
|
||||||
val compositeProjects = definitions.values(loader).collect {
|
case p: CompositeProject => p
|
||||||
case p: CompositeProject => p
|
|
||||||
}
|
|
||||||
CompositeProject.expand(compositeProjects).map(resolveBase(file.getParentFile, _))
|
|
||||||
}
|
}
|
||||||
val (settingsRaw, manipulationsRaw) =
|
CompositeProject.expand(compositeProjects).map(resolveBase(file.getParentFile, _))
|
||||||
dslEntries map (_.result apply loader) partition {
|
|
||||||
case DslEntry.ProjectSettings(_) => true
|
|
||||||
case _ => false
|
|
||||||
}
|
|
||||||
val settings = settingsRaw flatMap {
|
|
||||||
case DslEntry.ProjectSettings(settings) => settings
|
|
||||||
case _ => Nil
|
|
||||||
}
|
|
||||||
val manipulations = manipulationsRaw map {
|
|
||||||
case DslEntry.ProjectManipulation(f) => f
|
|
||||||
}
|
|
||||||
// TODO -get project manipulations.
|
|
||||||
new LoadedSbtFile(
|
|
||||||
settings,
|
|
||||||
projects,
|
|
||||||
importDefs,
|
|
||||||
manipulations,
|
|
||||||
definitions,
|
|
||||||
allGeneratedFiles
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
val (settingsRaw, manipulationsRaw) =
|
||||||
|
dslEntries map (_.result apply loader) partition {
|
||||||
|
case DslEntry.ProjectSettings(_) => true
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
val settings = settingsRaw flatMap {
|
||||||
|
case DslEntry.ProjectSettings(settings) => settings
|
||||||
|
case _ => Nil
|
||||||
|
}
|
||||||
|
val manipulations = manipulationsRaw map {
|
||||||
|
case DslEntry.ProjectManipulation(f) => f
|
||||||
|
}
|
||||||
|
// TODO -get project manipulations.
|
||||||
|
new LoadedSbtFile(
|
||||||
|
settings,
|
||||||
|
projects,
|
||||||
|
importDefs,
|
||||||
|
manipulations,
|
||||||
|
definitions,
|
||||||
|
allGeneratedFiles
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** move a project to be relative to this file after we've evaluated it. */
|
/** move a project to be relative to this file after we've evaluated it. */
|
||||||
|
|
@ -337,7 +335,7 @@ object Index {
|
||||||
case AttributeEntry(key, value: Task[_]) =>
|
case AttributeEntry(key, value: Task[_]) =>
|
||||||
(value, ScopedKey(scope, key.asInstanceOf[AttributeKey[Task[_]]]))
|
(value, ScopedKey(scope, key.asInstanceOf[AttributeKey[Task[_]]]))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
pairs.toMap[Task[_], ScopedKey[Task[_]]]
|
pairs.toMap[Task[_], ScopedKey[Task[_]]]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ object Inspect {
|
||||||
(s: State) =>
|
(s: State) =>
|
||||||
spacedModeParser(s) flatMap { mode =>
|
spacedModeParser(s) flatMap { mode =>
|
||||||
commandHandler(s, mode) | keyHandler(s)(mode)
|
commandHandler(s, mode) | keyHandler(s)(mode)
|
||||||
}
|
}
|
||||||
val spacedModeParser: State => Parser[Mode] = (_: State) => {
|
val spacedModeParser: State => Parser[Mode] = (_: State) => {
|
||||||
val default = "-" ^^^ Details(false)
|
val default = "-" ^^^ Details(false)
|
||||||
val actual = "actual" ^^^ Details(true)
|
val actual = "actual" ^^^ Details(true)
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,9 @@ private[sbt] object Load {
|
||||||
}
|
}
|
||||||
|
|
||||||
private def bootIvyHome(app: xsbti.AppConfiguration): Option[File] =
|
private def bootIvyHome(app: xsbti.AppConfiguration): Option[File] =
|
||||||
try { Option(app.provider.scalaProvider.launcher.ivyHome) } catch {
|
try {
|
||||||
|
Option(app.provider.scalaProvider.launcher.ivyHome)
|
||||||
|
} catch {
|
||||||
case _: NoSuchMethodError => None
|
case _: NoSuchMethodError => None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,14 +178,13 @@ private[sbt] object Load {
|
||||||
val imports =
|
val imports =
|
||||||
BuildUtil.baseImports ++ config.detectedGlobalPlugins.imports
|
BuildUtil.baseImports ++ config.detectedGlobalPlugins.imports
|
||||||
|
|
||||||
loader =>
|
loader => {
|
||||||
{
|
val loaded = EvaluateConfigurations(eval, files, imports)(loader)
|
||||||
val loaded = EvaluateConfigurations(eval, files, imports)(loader)
|
// TODO - We have a potential leak of config-classes in the global directory right now.
|
||||||
// TODO - We have a potential leak of config-classes in the global directory right now.
|
// We need to find a way to clean these safely, or at least warn users about
|
||||||
// We need to find a way to clean these safely, or at least warn users about
|
// unused class files that could be cleaned when multiple sbt instances are not running.
|
||||||
// unused class files that could be cleaned when multiple sbt instances are not running.
|
loaded.settings
|
||||||
loaded.settings
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
def loadGlobal(
|
def loadGlobal(
|
||||||
state: State,
|
state: State,
|
||||||
|
|
@ -303,13 +304,13 @@ private[sbt] object Load {
|
||||||
case tk: Task[t] => setDefinitionKey(tk, key).asInstanceOf[T]
|
case tk: Task[t] => setDefinitionKey(tk, key).asInstanceOf[T]
|
||||||
case ik: InputTask[t] => ik.mapTask(tk => setDefinitionKey(tk, key)).asInstanceOf[T]
|
case ik: InputTask[t] => ik.mapTask(tk => setDefinitionKey(tk, key)).asInstanceOf[T]
|
||||||
case _ => value
|
case _ => value
|
||||||
}
|
}
|
||||||
def setResolved(defining: ScopedKey[_]) = λ[ScopedKey ~> Option](
|
def setResolved(defining: ScopedKey[_]) = λ[ScopedKey ~> Option](
|
||||||
(key: ScopedKey[_]) =>
|
(key: ScopedKey[_]) =>
|
||||||
key.key match {
|
key.key match {
|
||||||
case resolvedScoped.key => Some(defining.asInstanceOf[A1$])
|
case resolvedScoped.key => Some(defining.asInstanceOf[A1$])
|
||||||
case _ => None
|
case _ => None
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
ss.map(
|
ss.map(
|
||||||
s => s mapConstant setResolved(s.key) mapReferenced mapSpecial(s.key) mapInit setDefining
|
s => s mapConstant setResolved(s.key) mapReferenced mapSpecial(s.key) mapInit setDefining
|
||||||
|
|
@ -421,8 +422,7 @@ private[sbt] object Load {
|
||||||
|
|
||||||
def lazyEval(unit: BuildUnit): () => Eval = {
|
def lazyEval(unit: BuildUnit): () => Eval = {
|
||||||
lazy val eval = mkEval(unit)
|
lazy val eval = mkEval(unit)
|
||||||
() =>
|
() => eval
|
||||||
eval
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def mkEval(unit: BuildUnit): Eval =
|
def mkEval(unit: BuildUnit): Eval =
|
||||||
|
|
@ -616,8 +616,7 @@ private[sbt] object Load {
|
||||||
checkProjectBase(against, fResolved)
|
checkProjectBase(against, fResolved)
|
||||||
fResolved
|
fResolved
|
||||||
}
|
}
|
||||||
p =>
|
p => p.copy(base = resolve(p.base))
|
||||||
p.copy(base = resolve(p.base))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def resolveProjects(loaded: PartBuild): LoadedBuild = {
|
def resolveProjects(loaded: PartBuild): LoadedBuild = {
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,7 @@ object Resolve {
|
||||||
:: resolveConfig(index, key, mask) _
|
:: resolveConfig(index, key, mask) _
|
||||||
:: Nil
|
:: Nil
|
||||||
)
|
)
|
||||||
scope =>
|
scope => rs.foldLeft(scope)((s, f) => f(s))
|
||||||
rs.foldLeft(scope)((s, f) => f(s))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def resolveTask(mask: ScopeMask)(scope: Scope): Scope =
|
def resolveTask(mask: ScopeMask)(scope: Scope): Scope =
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ private[sbt] object TaskProgress {
|
||||||
case LogOption.Always => Some(true)
|
case LogOption.Always => Some(true)
|
||||||
case LogOption.Never => Some(false)
|
case LogOption.Never => Some(false)
|
||||||
case _ => None
|
case _ => None
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.getOrElse(true)
|
.getOrElse(true)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ final class NetworkChannel(
|
||||||
errorDesc =>
|
errorDesc =>
|
||||||
log.error(
|
log.error(
|
||||||
s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc
|
s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc
|
||||||
),
|
),
|
||||||
onCommand
|
onCommand
|
||||||
)
|
)
|
||||||
case _ =>
|
case _ =>
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ object SettingQuery {
|
||||||
getJsonWriter(key.key) map { implicit jw: JsonWriter[A] =>
|
getJsonWriter(key.key) map { implicit jw: JsonWriter[A] =>
|
||||||
toJson(value)
|
toJson(value)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def handleSettingQueryEither(
|
def handleSettingQueryEither(
|
||||||
req: SettingQuery,
|
req: SettingQuery,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ scalaVersion := "2.12.8"
|
||||||
scalacOptions ++= Seq("-feature", "-language:postfixOps")
|
scalacOptions ++= Seq("-feature", "-language:postfixOps")
|
||||||
|
|
||||||
addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.9")
|
addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.9")
|
||||||
addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.5.1")
|
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.0")
|
||||||
addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.1")
|
addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.1")
|
||||||
addSbtPlugin("de.heikoseeberger" % "sbt-header" % "3.0.2")
|
addSbtPlugin("de.heikoseeberger" % "sbt-header" % "3.0.2")
|
||||||
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0")
|
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0")
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import sjsonnew.shaded.scalajson.ast.unsafe.JValue
|
||||||
trait JsonRpcNotificationMessageFormats {
|
trait JsonRpcNotificationMessageFormats {
|
||||||
self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol =>
|
self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol =>
|
||||||
implicit lazy val JsonRpcNotificationMessageFormat
|
implicit lazy val JsonRpcNotificationMessageFormat
|
||||||
: JsonFormat[sbt.internal.protocol.JsonRpcNotificationMessage] =
|
: JsonFormat[sbt.internal.protocol.JsonRpcNotificationMessage] =
|
||||||
new JsonFormat[sbt.internal.protocol.JsonRpcNotificationMessage] {
|
new JsonFormat[sbt.internal.protocol.JsonRpcNotificationMessage] {
|
||||||
override def read[J](
|
override def read[J](
|
||||||
jsOpt: Option[J],
|
jsOpt: Option[J],
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import sjsonnew.{ Builder, DeserializationException, JsonFormat, Unbuilder, dese
|
||||||
trait JsonRpcRequestMessageFormats {
|
trait JsonRpcRequestMessageFormats {
|
||||||
self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol =>
|
self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol =>
|
||||||
implicit lazy val JsonRpcRequestMessageFormat
|
implicit lazy val JsonRpcRequestMessageFormat
|
||||||
: JsonFormat[sbt.internal.protocol.JsonRpcRequestMessage] =
|
: JsonFormat[sbt.internal.protocol.JsonRpcRequestMessage] =
|
||||||
new JsonFormat[sbt.internal.protocol.JsonRpcRequestMessage] {
|
new JsonFormat[sbt.internal.protocol.JsonRpcRequestMessage] {
|
||||||
override def read[J](
|
override def read[J](
|
||||||
jsOpt: Option[J],
|
jsOpt: Option[J],
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import sjsonnew.shaded.scalajson.ast.unsafe.JValue
|
||||||
trait JsonRpcResponseErrorFormats {
|
trait JsonRpcResponseErrorFormats {
|
||||||
self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol =>
|
self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol =>
|
||||||
implicit lazy val JsonRpcResponseErrorFormat
|
implicit lazy val JsonRpcResponseErrorFormat
|
||||||
: JsonFormat[sbt.internal.protocol.JsonRpcResponseError] =
|
: JsonFormat[sbt.internal.protocol.JsonRpcResponseError] =
|
||||||
new JsonFormat[sbt.internal.protocol.JsonRpcResponseError] {
|
new JsonFormat[sbt.internal.protocol.JsonRpcResponseError] {
|
||||||
override def read[J](
|
override def read[J](
|
||||||
jsOpt: Option[J],
|
jsOpt: Option[J],
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ trait JsonRpcResponseMessageFormats {
|
||||||
with sbt.internal.protocol.codec.JsonRpcResponseErrorFormats
|
with sbt.internal.protocol.codec.JsonRpcResponseErrorFormats
|
||||||
with sjsonnew.BasicJsonProtocol =>
|
with sjsonnew.BasicJsonProtocol =>
|
||||||
implicit lazy val JsonRpcResponseMessageFormat
|
implicit lazy val JsonRpcResponseMessageFormat
|
||||||
: JsonFormat[sbt.internal.protocol.JsonRpcResponseMessage] =
|
: JsonFormat[sbt.internal.protocol.JsonRpcResponseMessage] =
|
||||||
new JsonFormat[sbt.internal.protocol.JsonRpcResponseMessage] {
|
new JsonFormat[sbt.internal.protocol.JsonRpcResponseMessage] {
|
||||||
override def read[J](
|
override def read[J](
|
||||||
jsOpt: Option[J],
|
jsOpt: Option[J],
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,9 @@ class Run(newLoader: Seq[File] => ClassLoader, trapExit: Boolean) extends ScalaR
|
||||||
log.info("Running " + mainClass + " " + options.mkString(" "))
|
log.info("Running " + mainClass + " " + options.mkString(" "))
|
||||||
|
|
||||||
def execute() =
|
def execute() =
|
||||||
try { run0(mainClass, classpath, options, log) } catch {
|
try {
|
||||||
|
run0(mainClass, classpath, options, log)
|
||||||
|
} catch {
|
||||||
case e: java.lang.reflect.InvocationTargetException => throw e.getCause
|
case e: java.lang.reflect.InvocationTargetException => throw e.getCause
|
||||||
}
|
}
|
||||||
def directExecute(): Try[Unit] =
|
def directExecute(): Try[Unit] =
|
||||||
|
|
@ -109,7 +111,9 @@ class Run(newLoader: Seq[File] => ClassLoader, trapExit: Boolean) extends ScalaR
|
||||||
val currentThread = Thread.currentThread
|
val currentThread = Thread.currentThread
|
||||||
val oldLoader = Thread.currentThread.getContextClassLoader
|
val oldLoader = Thread.currentThread.getContextClassLoader
|
||||||
currentThread.setContextClassLoader(loader)
|
currentThread.setContextClassLoader(loader)
|
||||||
try { main.invoke(null, options.toArray[String]); () } catch {
|
try {
|
||||||
|
main.invoke(null, options.toArray[String]); ()
|
||||||
|
} catch {
|
||||||
case t: Throwable =>
|
case t: Throwable =>
|
||||||
t.getCause match {
|
t.getCause match {
|
||||||
case e: java.lang.IllegalAccessError =>
|
case e: java.lang.IllegalAccessError =>
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,9 @@ object TrapExit {
|
||||||
|
|
||||||
private[this] def runUnmanaged(execute: => Unit, log: Logger): Int = {
|
private[this] def runUnmanaged(execute: => Unit, log: Logger): Int = {
|
||||||
log.warn("Managed execution not possible: security manager not installed.")
|
log.warn("Managed execution not possible: security manager not installed.")
|
||||||
try { execute; 0 } catch {
|
try {
|
||||||
|
execute; 0
|
||||||
|
} catch {
|
||||||
case e: Exception =>
|
case e: Exception =>
|
||||||
log.error("Error during execution: " + e.toString)
|
log.error("Error during execution: " + e.toString)
|
||||||
log.trace(e)
|
log.trace(e)
|
||||||
|
|
@ -153,7 +155,9 @@ private final class TrapExit(delegateManager: SecurityManager) extends SecurityM
|
||||||
def runManaged(f: Supplier[Unit], xlog: xsbti.Logger): Int = {
|
def runManaged(f: Supplier[Unit], xlog: xsbti.Logger): Int = {
|
||||||
val _ = running.incrementAndGet()
|
val _ = running.incrementAndGet()
|
||||||
try runManaged0(f, xlog)
|
try runManaged0(f, xlog)
|
||||||
finally { running.decrementAndGet(); () }
|
finally {
|
||||||
|
running.decrementAndGet(); ()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private[this] def runManaged0(f: Supplier[Unit], xlog: xsbti.Logger): Int = {
|
private[this] def runManaged0(f: Supplier[Unit], xlog: xsbti.Logger): Int = {
|
||||||
val log: Logger = xlog
|
val log: Logger = xlog
|
||||||
|
|
|
||||||
|
|
@ -176,10 +176,14 @@ object TestServer {
|
||||||
try {
|
try {
|
||||||
f(testServer)
|
f(testServer)
|
||||||
} finally {
|
} finally {
|
||||||
try { testServer.bye() } finally {}
|
try {
|
||||||
|
testServer.bye()
|
||||||
|
} finally {}
|
||||||
}
|
}
|
||||||
case _ =>
|
case _ =>
|
||||||
try { testServer.bye() } finally {}
|
try {
|
||||||
|
testServer.bye()
|
||||||
|
} finally {}
|
||||||
hostLog("Server started but not connected properly... restarting...")
|
hostLog("Server started but not connected properly... restarting...")
|
||||||
withTestServer(testBuild)(f)
|
withTestServer(testBuild)(f)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,22 +61,21 @@ final class ScriptedTests(
|
||||||
val g = groupDir.getName
|
val g = groupDir.getName
|
||||||
val n = nme.getName
|
val n = nme.getName
|
||||||
val label = s"$g / $n"
|
val label = s"$g / $n"
|
||||||
() =>
|
() => {
|
||||||
{
|
println(s"Running $label")
|
||||||
println(s"Running $label")
|
val result = testResources.readWriteResourceDirectory(g, n) { testDirectory =>
|
||||||
val result = testResources.readWriteResourceDirectory(g, n) { testDirectory =>
|
val buffer = new BufferedLogger(new FullLogger(log))
|
||||||
val buffer = new BufferedLogger(new FullLogger(log))
|
val singleTestRunner = () => {
|
||||||
val singleTestRunner = () => {
|
val handlers =
|
||||||
val handlers =
|
createScriptedHandlers(testDirectory, buffer, RemoteSbtCreatorKind.LauncherBased)
|
||||||
createScriptedHandlers(testDirectory, buffer, RemoteSbtCreatorKind.LauncherBased)
|
val runner = new BatchScriptRunner
|
||||||
val runner = new BatchScriptRunner
|
val states = new mutable.HashMap[StatementHandler, StatementHandler#State]()
|
||||||
val states = new mutable.HashMap[StatementHandler, StatementHandler#State]()
|
commonRunTest(label, testDirectory, prescripted, handlers, runner, states, buffer)
|
||||||
commonRunTest(label, testDirectory, prescripted, handlers, runner, states, buffer)
|
|
||||||
}
|
|
||||||
runOrHandleDisabled(label, testDirectory, singleTestRunner, buffer)
|
|
||||||
}
|
}
|
||||||
Seq(result)
|
runOrHandleDisabled(label, testDirectory, singleTestRunner, buffer)
|
||||||
}
|
}
|
||||||
|
Seq(result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,7 +139,7 @@ final class ScriptedTests(
|
||||||
|
|
||||||
def logTests(size: Int, how: String) =
|
def logTests(size: Int, how: String) =
|
||||||
log.info(
|
log.info(
|
||||||
f"Running $size / $totalSize (${size * 100D / totalSize}%3.2f%%) scripted tests with $how"
|
f"Running $size / $totalSize (${size * 100d / totalSize}%3.2f%%) scripted tests with $how"
|
||||||
)
|
)
|
||||||
logTests(runFromSourceBasedTests.size, "RunFromSourceMain")
|
logTests(runFromSourceBasedTests.size, "RunFromSourceMain")
|
||||||
logTests(launcherBasedTests.size, "sbt/launcher")
|
logTests(launcherBasedTests.size, "sbt/launcher")
|
||||||
|
|
|
||||||
|
|
@ -100,13 +100,19 @@ trait Streams[Key] {
|
||||||
def use[T](key: Key)(f: TaskStreams[Key] => T): T = {
|
def use[T](key: Key)(f: TaskStreams[Key] => T): T = {
|
||||||
val s = apply(key)
|
val s = apply(key)
|
||||||
s.open()
|
s.open()
|
||||||
try { f(s) } finally { s.close() }
|
try {
|
||||||
|
f(s)
|
||||||
|
} finally {
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trait CloseableStreams[Key] extends Streams[Key] with java.io.Closeable
|
trait CloseableStreams[Key] extends Streams[Key] with java.io.Closeable
|
||||||
object Streams {
|
object Streams {
|
||||||
private[this] val closeQuietly = (c: Closeable) =>
|
private[this] val closeQuietly = (c: Closeable) =>
|
||||||
try { c.close() } catch { case _: IOException => () }
|
try {
|
||||||
|
c.close()
|
||||||
|
} catch { case _: IOException => () }
|
||||||
|
|
||||||
def closeable[Key](delegate: Streams[Key]): CloseableStreams[Key] = new CloseableStreams[Key] {
|
def closeable[Key](delegate: Streams[Key]): CloseableStreams[Key] = new CloseableStreams[Key] {
|
||||||
private[this] val streams = new collection.mutable.HashMap[Key, ManagedStreams[Key]]
|
private[this] val streams = new collection.mutable.HashMap[Key, ManagedStreams[Key]]
|
||||||
|
|
@ -160,7 +166,7 @@ object Streams {
|
||||||
new OutputStreamWriter(new FileOutputStream(f), IO.defaultCharset)
|
new OutputStreamWriter(new FileOutputStream(f), IO.defaultCharset)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def binary(sid: String = default): BufferedOutputStream =
|
def binary(sid: String = default): BufferedOutputStream =
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ trait TaskExtra {
|
||||||
x =>
|
x =>
|
||||||
t.result.map { tx =>
|
t.result.map { tx =>
|
||||||
Result.tryValues[S](tx :: Nil, x)
|
Result.tryValues[S](tx :: Nil, x)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
def ||[T >: S](alt: Task[T]): Task[T] = flatMapR {
|
def ||[T >: S](alt: Task[T]): Task[T] = flatMapR {
|
||||||
case Value(v) => task(v); case Inc(_) => alt
|
case Value(v) => task(v); case Inc(_) => alt
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,11 @@ object TaskGen extends std.TaskExtra {
|
||||||
Execute.noTriggers,
|
Execute.noTriggers,
|
||||||
ExecuteProgress.empty[Task]
|
ExecuteProgress.empty[Task]
|
||||||
)(std.Transform(dummies))
|
)(std.Transform(dummies))
|
||||||
try { x.run(root)(service) } finally { shutdown() }
|
try {
|
||||||
|
x.run(root)(service)
|
||||||
|
} finally {
|
||||||
|
shutdown()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
def tryRun[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): T =
|
def tryRun[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): T =
|
||||||
run(root, checkCycles, maxWorkers) match {
|
run(root, checkCycles, maxWorkers) match {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,9 @@ object TaskRunnerCircularTest extends Properties("TaskRunner Circular") {
|
||||||
else
|
else
|
||||||
iterate(task(t - 1).named((t - 1).toString))
|
iterate(task(t - 1).named((t - 1).toString))
|
||||||
}
|
}
|
||||||
try { checkResult(tryRun(iterate(top), true, workers), intermediate) } catch {
|
try {
|
||||||
|
checkResult(tryRun(iterate(top), true, workers), intermediate)
|
||||||
|
} catch {
|
||||||
case i: Incomplete if cyclic(i) => ("Unexpected cyclic exception: " + i) |: false
|
case i: Incomplete if cyclic(i) => ("Unexpected cyclic exception: " + i) |: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +42,9 @@ object TaskRunnerCircularTest extends Properties("TaskRunner Circular") {
|
||||||
else
|
else
|
||||||
iterate(task(t - 1).named((t - 1).toString), i - 1)
|
iterate(task(t - 1).named((t - 1).toString), i - 1)
|
||||||
}
|
}
|
||||||
try { tryRun(top, true, workers); false } catch { case i: Incomplete => cyclic(i) }
|
try {
|
||||||
|
tryRun(top, true, workers); false
|
||||||
|
} catch { case i: Incomplete => cyclic(i) }
|
||||||
}
|
}
|
||||||
|
|
||||||
def cyclic(i: Incomplete) =
|
def cyclic(i: Incomplete) =
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,11 @@ object TaskTest {
|
||||||
Execute.noTriggers,
|
Execute.noTriggers,
|
||||||
ExecuteProgress.empty[Task]
|
ExecuteProgress.empty[Task]
|
||||||
)(taskToNode(idK[Task]))
|
)(taskToNode(idK[Task]))
|
||||||
try { x.run(root)(service) } finally { shutdown() }
|
try {
|
||||||
|
x.run(root)(service)
|
||||||
|
} finally {
|
||||||
|
shutdown()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
def tryRun[T](
|
def tryRun[T](
|
||||||
root: Task[T],
|
root: Task[T],
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,15 @@ object checkResult {
|
||||||
def apply[T](run: => T, expected: T) = {
|
def apply[T](run: => T, expected: T) = {
|
||||||
("Expected: " + expected) |:
|
("Expected: " + expected) |:
|
||||||
(try {
|
(try {
|
||||||
val actual = run
|
val actual = run
|
||||||
("Actual: " + actual) |: (actual == expected)
|
("Actual: " + actual) |: (actual == expected)
|
||||||
} catch {
|
} catch {
|
||||||
case i: Incomplete =>
|
case i: Incomplete =>
|
||||||
println(i)
|
println(i)
|
||||||
"One or more tasks failed" |: false
|
"One or more tasks failed" |: false
|
||||||
case NonFatal(e) =>
|
case NonFatal(e) =>
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
"Error in framework" |: false
|
"Error in framework" |: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,15 +37,18 @@ object CompletionService {
|
||||||
val future = try completion.submit { new Callable[T] { def call = work() } } catch {
|
val future = try completion.submit { new Callable[T] { def call = work() } } catch {
|
||||||
case _: RejectedExecutionException => throw Incomplete(None, message = Some("cancelled"))
|
case _: RejectedExecutionException => throw Incomplete(None, message = Some("cancelled"))
|
||||||
}
|
}
|
||||||
() =>
|
() => future.get()
|
||||||
future.get()
|
|
||||||
}
|
}
|
||||||
def manage[A, T](
|
def manage[A, T](
|
||||||
service: CompletionService[A, T]
|
service: CompletionService[A, T]
|
||||||
)(setup: A => Unit, cleanup: A => Unit): CompletionService[A, T] =
|
)(setup: A => Unit, cleanup: A => Unit): CompletionService[A, T] =
|
||||||
wrap(service) { (node, work) => () =>
|
wrap(service) { (node, work) => () =>
|
||||||
setup(node)
|
setup(node)
|
||||||
try { work() } finally { cleanup(node) }
|
try {
|
||||||
|
work()
|
||||||
|
} finally {
|
||||||
|
cleanup(node)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
def wrap[A, T](
|
def wrap[A, T](
|
||||||
service: CompletionService[A, T]
|
service: CompletionService[A, T]
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ private[sbt] final class Execute[F[_] <: AnyRef](
|
||||||
view.inline(a) match {
|
view.inline(a) match {
|
||||||
case Some(v) => Value(v())
|
case Some(v) => Value(v())
|
||||||
case None => results(a)
|
case None => results(a)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
private[this] type State = State.Value
|
private[this] type State = State.Value
|
||||||
private[this] object State extends Enumeration {
|
private[this] object State extends Enumeration {
|
||||||
|
|
@ -81,7 +81,9 @@ private[sbt] final class Execute[F[_] <: AnyRef](
|
||||||
"State: " + state.toString + "\n\nResults: " + results + "\n\nCalls: " + callers + "\n\n"
|
"State: " + state.toString + "\n\nResults: " + results + "\n\nCalls: " + callers + "\n\n"
|
||||||
|
|
||||||
def run[A](root: F[A])(implicit strategy: Strategy): Result[A] =
|
def run[A](root: F[A])(implicit strategy: Strategy): Result[A] =
|
||||||
try { runKeep(root)(strategy)(root) } catch { case i: Incomplete => Inc(i) }
|
try {
|
||||||
|
runKeep(root)(strategy)(root)
|
||||||
|
} catch { case i: Incomplete => Inc(i) }
|
||||||
|
|
||||||
def runKeep[A](root: F[A])(implicit strategy: Strategy): RMap[F, Result] = {
|
def runKeep[A](root: F[A])(implicit strategy: Strategy): RMap[F, Result] = {
|
||||||
assert(state.isEmpty, "Execute already running/ran.")
|
assert(state.isEmpty, "Execute already running/ran.")
|
||||||
|
|
|
||||||
|
|
@ -62,16 +62,16 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
||||||
val properties =
|
val properties =
|
||||||
<properties>
|
<properties>
|
||||||
{
|
{
|
||||||
// create a clone, defending against [[ConcurrentModificationException]]
|
// create a clone, defending against [[ConcurrentModificationException]]
|
||||||
val clonedProperties = System.getProperties.clone.asInstanceOf[Hashtable[AnyRef, AnyRef]]
|
val clonedProperties = System.getProperties.clone.asInstanceOf[Hashtable[AnyRef, AnyRef]]
|
||||||
val iter = clonedProperties.entrySet.iterator
|
val iter = clonedProperties.entrySet.iterator
|
||||||
val props: ListBuffer[XNode] = new ListBuffer()
|
val props: ListBuffer[XNode] = new ListBuffer()
|
||||||
while (iter.hasNext) {
|
while (iter.hasNext) {
|
||||||
val next = iter.next
|
val next = iter.next
|
||||||
props += <property name={ next.getKey.toString } value={ next.getValue.toString }/>
|
props += <property name={next.getKey.toString} value={next.getValue.toString}/>
|
||||||
}
|
|
||||||
props
|
|
||||||
}
|
}
|
||||||
|
props
|
||||||
|
}
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -104,38 +104,51 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests
|
||||||
)
|
)
|
||||||
|
|
||||||
val result =
|
val result =
|
||||||
<testsuite hostname={ hostname } name={ name } tests={ tests + "" } errors={ errors + "" } failures={ failures + "" } skipped={ ignoredSkippedPending + "" } time={ (duration / 1000.0).toString } timestamp={formatISO8601DateTime(timestamp)}>
|
<testsuite hostname={hostname} name={name} tests={tests + ""} errors={errors + ""} failures={
|
||||||
{ properties }
|
failures + ""
|
||||||
|
} skipped={ignoredSkippedPending + ""} time={(duration / 1000.0).toString} timestamp={
|
||||||
|
formatISO8601DateTime(timestamp)
|
||||||
|
}>
|
||||||
|
{properties}
|
||||||
{
|
{
|
||||||
for (e <- events) yield <testcase classname={ name } name={
|
for (e <- events)
|
||||||
e.selector match {
|
yield
|
||||||
case selector: TestSelector => selector.testName.split('.').last
|
<testcase classname={name} name={
|
||||||
case nested: NestedTestSelector => nested.suiteId().split('.').last + "." + nested.testName()
|
e.selector match {
|
||||||
case other => s"(It is not a test it is a ${other.getClass.getCanonicalName})"
|
case selector: TestSelector => selector.testName.split('.').last
|
||||||
}
|
case nested: NestedTestSelector =>
|
||||||
} time={ (e.duration() / 1000.0).toString }>
|
nested.suiteId().split('.').last + "." + nested.testName()
|
||||||
|
case other => s"(It is not a test it is a ${other.getClass.getCanonicalName})"
|
||||||
|
}
|
||||||
|
} time={(e.duration() / 1000.0).toString}>
|
||||||
{
|
{
|
||||||
val trace: String = if (e.throwable.isDefined) {
|
val trace: String = if (e.throwable.isDefined) {
|
||||||
val stringWriter = new StringWriter()
|
val stringWriter = new StringWriter()
|
||||||
val writer = new PrintWriter(stringWriter)
|
val writer = new PrintWriter(stringWriter)
|
||||||
e.throwable.get.printStackTrace(writer)
|
e.throwable.get.printStackTrace(writer)
|
||||||
writer.flush()
|
writer.flush()
|
||||||
stringWriter.toString
|
stringWriter.toString
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
e.status match {
|
e.status match {
|
||||||
case TStatus.Error if (e.throwable.isDefined)=> <error message={ e.throwable.get.getMessage } type={ e.throwable.get.getClass.getName }>{ trace }</error>
|
case TStatus.Error if (e.throwable.isDefined) =>
|
||||||
case TStatus.Error=> <error message={ "No Exception or message provided" }/>
|
<error message={e.throwable.get.getMessage} type={
|
||||||
case TStatus.Failure if (e.throwable.isDefined)=> <failure message={ e.throwable.get.getMessage } type={ e.throwable.get.getClass.getName }>{ trace }</failure>
|
e.throwable.get.getClass.getName
|
||||||
case TStatus.Failure=> <failure message={ "No Exception or message provided" }/>
|
}>{trace}</error>
|
||||||
case TStatus.Ignored | TStatus.Skipped | TStatus.Pending=> <skipped/>
|
case TStatus.Error => <error message={"No Exception or message provided"}/>
|
||||||
case _ => {}
|
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>
|
</testcase>
|
||||||
|
|
||||||
}
|
}
|
||||||
<system-out><![CDATA[]]></system-out>
|
<system-out><![CDATA[]]></system-out>
|
||||||
<system-err><![CDATA[]]></system-err>
|
<system-err><![CDATA[]]></system-err>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,11 @@ object TestFramework {
|
||||||
private[this] def withContextLoader[T](loader: ClassLoader)(eval: => T): T = {
|
private[this] def withContextLoader[T](loader: ClassLoader)(eval: => T): T = {
|
||||||
val oldLoader = Thread.currentThread.getContextClassLoader
|
val oldLoader = Thread.currentThread.getContextClassLoader
|
||||||
Thread.currentThread.setContextClassLoader(loader)
|
Thread.currentThread.setContextClassLoader(loader)
|
||||||
try { eval } finally { Thread.currentThread.setContextClassLoader(oldLoader) }
|
try {
|
||||||
|
eval
|
||||||
|
} finally {
|
||||||
|
Thread.currentThread.setContextClassLoader(oldLoader)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@deprecated("1.3.0", "This has been replaced by the ClassLoaders.test task.")
|
@deprecated("1.3.0", "This has been replaced by the ClassLoaders.test task.")
|
||||||
def createTestLoader(
|
def createTestLoader(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue