mirror of https://github.com/sbt/sbt.git
commit
b18140c14b
|
|
@ -20,7 +20,7 @@ object ContextUtil {
|
||||||
* Constructs an object with utility methods for operating in the provided macro context `c`.
|
* Constructs an object with utility methods for operating in the provided macro context `c`.
|
||||||
* Callers should explicitly specify the type parameter as `c.type` in order to preserve the path dependent types.
|
* Callers should explicitly specify the type parameter as `c.type` in order to preserve the path dependent types.
|
||||||
*/
|
*/
|
||||||
def apply[C <: blackbox.Context with Singleton](c: C): ContextUtil[C] = new ContextUtil(c)
|
def apply[C <: blackbox.Context with Singleton](c: C): ContextUtil[C] = new ContextUtil(c: C)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper for implementing a no-argument macro that is introduced via an implicit.
|
* Helper for implementing a no-argument macro that is introduced via an implicit.
|
||||||
|
|
@ -33,6 +33,7 @@ object ContextUtil {
|
||||||
c: blackbox.Context
|
c: blackbox.Context
|
||||||
)(f: (c.Expr[Any], c.Position) => c.Expr[T]): c.Expr[T] = {
|
)(f: (c.Expr[Any], c.Position) => c.Expr[T]): c.Expr[T] = {
|
||||||
import c.universe._
|
import c.universe._
|
||||||
|
|
||||||
c.macroApplication match {
|
c.macroApplication match {
|
||||||
case s @ Select(Apply(_, t :: Nil), _) => f(c.Expr[Any](t), s.pos)
|
case s @ Select(Apply(_, t :: Nil), _) => f(c.Expr[Any](t), s.pos)
|
||||||
case a @ Apply(_, t :: Nil) => f(c.Expr[Any](t), a.pos)
|
case a @ Apply(_, t :: Nil) => f(c.Expr[Any](t), a.pos)
|
||||||
|
|
@ -106,7 +107,10 @@ final class ContextUtil[C <: blackbox.Context](val ctx: C) {
|
||||||
if isWrapper(nme.decodedName.toString, tpe.tpe, qual) =>
|
if isWrapper(nme.decodedName.toString, tpe.tpe, qual) =>
|
||||||
()
|
()
|
||||||
case tree =>
|
case tree =>
|
||||||
if (tree.symbol ne null) defs += tree.symbol;
|
if (tree.symbol ne null) {
|
||||||
|
defs += tree.symbol
|
||||||
|
()
|
||||||
|
}
|
||||||
super.traverse(tree)
|
super.traverse(tree)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ object Instance {
|
||||||
val param =
|
val param =
|
||||||
treeCopy.ValDef(variable, util.parameterModifiers, variable.name, variable.tpt, EmptyTree)
|
treeCopy.ValDef(variable, util.parameterModifiers, variable.name, variable.tpt, EmptyTree)
|
||||||
val typeApplied =
|
val typeApplied =
|
||||||
TypeApply(util.select(instance, MapName), variable.tpt :: TypeTree(treeType) :: Nil)
|
TypeApply(util.select(instance, MapName), variable.tpt :: (TypeTree(treeType): Tree) :: Nil)
|
||||||
val f = util.createFunction(param :: Nil, body, functionSym)
|
val f = util.createFunction(param :: Nil, body, functionSym)
|
||||||
val mapped = ApplyTree(typeApplied, input.expr :: f :: Nil)
|
val mapped = ApplyTree(typeApplied, input.expr :: f :: Nil)
|
||||||
if (t.isLeft) mapped else flatten(mapped)
|
if (t.isLeft) mapped else flatten(mapped)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,9 @@ object MixedBuilder extends TupleBuilder {
|
||||||
def make(
|
def make(
|
||||||
c: blackbox.Context
|
c: blackbox.Context
|
||||||
)(mt: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type] = {
|
)(mt: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type] = {
|
||||||
val delegate = if (inputs.size > TupleNBuilder.MaxInputs) KListBuilder else TupleNBuilder
|
val delegate =
|
||||||
|
if (inputs.size > TupleNBuilder.MaxInputs) (KListBuilder: TupleBuilder)
|
||||||
|
else (TupleNBuilder: TupleBuilder)
|
||||||
delegate.make(c)(mt, inputs)
|
delegate.make(c)(mt, inputs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -216,16 +216,17 @@ private class BasicAttributeMap(private val backing: Map[AttributeKey[_], Any])
|
||||||
def contains[T](k: AttributeKey[T]) = backing.contains(k)
|
def contains[T](k: AttributeKey[T]) = backing.contains(k)
|
||||||
|
|
||||||
def put[T](k: AttributeKey[T], value: T): AttributeMap =
|
def put[T](k: AttributeKey[T], value: T): AttributeMap =
|
||||||
new BasicAttributeMap(backing.updated(k, value))
|
new BasicAttributeMap(backing.updated(k, value: Any))
|
||||||
|
|
||||||
def keys: Iterable[AttributeKey[_]] = backing.keys
|
def keys: Iterable[AttributeKey[_]] = backing.keys
|
||||||
|
|
||||||
def ++(o: Iterable[AttributeEntry[_]]): AttributeMap =
|
def ++(o: Iterable[AttributeEntry[_]]): AttributeMap =
|
||||||
new BasicAttributeMap(o.foldLeft(backing)((b, e) => b.updated(e.key, e.value)))
|
new BasicAttributeMap(o.foldLeft(backing)((b, e) => b.updated(e.key, e.value: Any)))
|
||||||
|
|
||||||
def ++(o: AttributeMap): AttributeMap = o match {
|
def ++(o: AttributeMap): AttributeMap = o match {
|
||||||
case bam: BasicAttributeMap => new BasicAttributeMap(backing ++ bam.backing)
|
case bam: BasicAttributeMap =>
|
||||||
case _ => o ++ this
|
new BasicAttributeMap(Map(backing.toSeq ++ bam.backing.toSeq: _*))
|
||||||
|
case _ => o ++ this
|
||||||
}
|
}
|
||||||
|
|
||||||
def entries: Iterable[AttributeEntry[_]] =
|
def entries: Iterable[AttributeEntry[_]] =
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import sjsonnew._
|
||||||
import Types.:+:
|
import Types.:+:
|
||||||
|
|
||||||
trait HListFormats {
|
trait HListFormats {
|
||||||
implicit val lnilFormat1: JsonFormat[HNil] = forHNil(HNil)
|
implicit val lnilFormat1: JsonFormat[HNil] = forHNil(HNil: HNil)
|
||||||
implicit val lnilFormat2: JsonFormat[HNil.type] = forHNil(HNil)
|
implicit val lnilFormat2: JsonFormat[HNil.type] = forHNil(HNil)
|
||||||
|
|
||||||
private def forHNil[A <: HNil](hnil: A): JsonFormat[A] = new JsonFormat[A] {
|
private def forHNil[A <: HNil](hnil: A): JsonFormat[A] = new JsonFormat[A] {
|
||||||
|
|
@ -73,7 +73,7 @@ trait HListFormats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicit val lnilHListJF1: HListJF[HNil] = hnilHListJF(HNil)
|
implicit val lnilHListJF1: HListJF[HNil] = hnilHListJF(HNil: HNil)
|
||||||
implicit val lnilHListJF2: HListJF[HNil.type] = hnilHListJF(HNil)
|
implicit val lnilHListJF2: HListJF[HNil.type] = hnilHListJF(HNil)
|
||||||
|
|
||||||
implicit def hnilHListJF[A <: HNil](hnil: A): HListJF[A] = new HListJF[A] {
|
implicit def hnilHListJF[A <: HNil](hnil: A): HListJF[A] = new HListJF[A] {
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,11 @@ trait IDSet[T] {
|
||||||
|
|
||||||
object IDSet {
|
object IDSet {
|
||||||
implicit def toTraversable[T]: IDSet[T] => Traversable[T] = _.all
|
implicit def toTraversable[T]: IDSet[T] => Traversable[T] = _.all
|
||||||
def apply[T](values: T*): IDSet[T] = apply(values)
|
def apply[T](values: T*): IDSet[T] = fromIterable(values)
|
||||||
|
|
||||||
def apply[T](values: Iterable[T]): IDSet[T] = {
|
def apply[T](values: Iterable[T]): IDSet[T] = fromIterable(values)
|
||||||
|
|
||||||
|
private def fromIterable[T](values: Iterable[T]): IDSet[T] = {
|
||||||
val s = create[T]
|
val s = create[T]
|
||||||
s ++= values
|
s ++= values
|
||||||
s
|
s
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ abstract class EvaluateSettings[ScopeType] {
|
||||||
)
|
)
|
||||||
case b: Bind[s, A1$] @unchecked => new BindNode[s, A1$](transform(b.in), x => transform(b.f(x)))
|
case b: Bind[s, A1$] @unchecked => new BindNode[s, A1$](transform(b.in), x => transform(b.f(x)))
|
||||||
case v: Value[A1$] @unchecked => constant(v.value)
|
case v: Value[A1$] @unchecked => constant(v.value)
|
||||||
case v: ValidationCapture[A1$] @unchecked => strictConstant(v.key)
|
case v: ValidationCapture[A1$] @unchecked => strictConstant(v.key: A1$)
|
||||||
case t: TransformCapture => strictConstant(t.f)
|
case t: TransformCapture => strictConstant(t.f: A1$)
|
||||||
case o: Optional[s, A1$] @unchecked =>
|
case o: Optional[s, A1$] @unchecked =>
|
||||||
o.a match {
|
o.a match {
|
||||||
case None => constant(() => o.f(None))
|
case None => constant(() => o.f(None))
|
||||||
|
|
@ -120,7 +120,8 @@ abstract class EvaluateSettings[ScopeType] {
|
||||||
|
|
||||||
private[this] def keyString =
|
private[this] def keyString =
|
||||||
(static.toSeq.flatMap {
|
(static.toSeq.flatMap {
|
||||||
case (key, value) => if (value eq this) init.showFullKey.show(key) :: Nil else Nil
|
case (key, value) =>
|
||||||
|
if (value eq this) init.showFullKey.show(key) :: Nil else List.empty[String]
|
||||||
}).headOption getOrElse "non-static"
|
}).headOption getOrElse "non-static"
|
||||||
|
|
||||||
final def get: T = synchronized {
|
final def get: T = synchronized {
|
||||||
|
|
@ -130,7 +131,10 @@ abstract class EvaluateSettings[ScopeType] {
|
||||||
|
|
||||||
final def doneOrBlock(from: INode[_]): Boolean = synchronized {
|
final def doneOrBlock(from: INode[_]): Boolean = synchronized {
|
||||||
val ready = state == Evaluated
|
val ready = state == Evaluated
|
||||||
if (!ready) blocking += from
|
if (!ready) {
|
||||||
|
blocking += from
|
||||||
|
()
|
||||||
|
}
|
||||||
registerIfNew()
|
registerIfNew()
|
||||||
ready
|
ready
|
||||||
}
|
}
|
||||||
|
|
@ -191,9 +195,10 @@ abstract class EvaluateSettings[ScopeType] {
|
||||||
registerIfNew()
|
registerIfNew()
|
||||||
state match {
|
state match {
|
||||||
case Evaluated => submitCallComplete(by, value)
|
case Evaluated => submitCallComplete(by, value)
|
||||||
case _ => calledBy += by
|
case _ =>
|
||||||
|
calledBy += by
|
||||||
|
()
|
||||||
}
|
}
|
||||||
()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected def dependsOn: Seq[INode[_]]
|
protected def dependsOn: Seq[INode[_]]
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ sealed abstract class KNil extends KList[NothingK] {
|
||||||
final def apply[N[x], Z](f: KNil => Z)(implicit ap: Applicative[N]): N[Z] = ap.pure(f(KNil))
|
final def apply[N[x], Z](f: KNil => Z)(implicit ap: Applicative[N]): N[Z] = ap.pure(f(KNil))
|
||||||
|
|
||||||
final def traverse[N[_], P[_]](f: NothingK ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[KNil] =
|
final def traverse[N[_], P[_]](f: NothingK ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[KNil] =
|
||||||
np.pure(KNil)
|
np.pure(KNil: KNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
case object KNil extends KNil {
|
case object KNil extends KNil {
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,8 @@ object IMap {
|
||||||
val mapped = backing.iterator.map {
|
val mapped = backing.iterator.map {
|
||||||
case (k, v) =>
|
case (k, v) =>
|
||||||
f(v) match {
|
f(v) match {
|
||||||
case Left(l) => Left((k, l))
|
case Left(l) => Left((k, l)): Either[(K[_], VL[_]), (K[_], VR[_])]
|
||||||
case Right(r) => Right((k, r))
|
case Right(r) => Right((k, r)): Either[(K[_], VL[_]), (K[_], VR[_])]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val (l, r) = Util.separateE[(K[_], VL[_]), (K[_], VR[_])](mapped.toList)
|
val (l, r) = Util.separateE[(K[_], VL[_]), (K[_], VR[_])](mapped.toList)
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import scala.language.existentials
|
||||||
|
|
||||||
import Types._
|
import Types._
|
||||||
import sbt.util.Show
|
import sbt.util.Show
|
||||||
|
import Util.{ nil, nilSeq }
|
||||||
|
|
||||||
sealed trait Settings[ScopeType] {
|
sealed trait Settings[ScopeType] {
|
||||||
def data: Map[ScopeType, AttributeMap]
|
def data: Map[ScopeType, AttributeMap]
|
||||||
|
|
@ -177,7 +178,7 @@ trait Init[ScopeType] {
|
||||||
val (defaults, others) = Util.separate[Setting[_], DefaultSetting[_], Setting[_]](ss) {
|
val (defaults, others) = Util.separate[Setting[_], DefaultSetting[_], Setting[_]](ss) {
|
||||||
case u: DefaultSetting[_] => Left(u); case s => Right(s)
|
case u: DefaultSetting[_] => Left(u); case s => Right(s)
|
||||||
}
|
}
|
||||||
defaults.distinct ++ others
|
(defaults.distinct: Seq[Setting[_]]) ++ others
|
||||||
}
|
}
|
||||||
|
|
||||||
def compiled(init: Seq[Setting[_]], actual: Boolean = true)(
|
def compiled(init: Seq[Setting[_]], actual: Boolean = true)(
|
||||||
|
|
@ -382,10 +383,16 @@ trait Init[ScopeType] {
|
||||||
|
|
||||||
def flattenLocals(compiled: CompiledMap): Map[ScopedKey[_], Flattened] = {
|
def flattenLocals(compiled: CompiledMap): Map[ScopedKey[_], Flattened] = {
|
||||||
val locals = compiled flatMap {
|
val locals = compiled flatMap {
|
||||||
case (key, comp) => if (key.key.isLocal) Seq[Compiled[_]](comp) else Nil
|
case (key, comp) =>
|
||||||
|
if (key.key.isLocal) Seq(comp)
|
||||||
|
else nilSeq[Compiled[_]]
|
||||||
}
|
}
|
||||||
val ordered = Dag.topologicalSort(locals)(
|
val ordered = Dag.topologicalSort(locals)(
|
||||||
_.dependencies.flatMap(dep => if (dep.key.isLocal) Seq[Compiled[_]](compiled(dep)) else Nil)
|
_.dependencies.flatMap(
|
||||||
|
dep =>
|
||||||
|
if (dep.key.isLocal) Seq[Compiled[_]](compiled(dep))
|
||||||
|
else nilSeq[Compiled[_]]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
def flatten(
|
def flatten(
|
||||||
cmap: Map[ScopedKey[_], Flattened],
|
cmap: Map[ScopedKey[_], Flattened],
|
||||||
|
|
@ -394,7 +401,9 @@ trait Init[ScopeType] {
|
||||||
): Flattened =
|
): Flattened =
|
||||||
new Flattened(
|
new Flattened(
|
||||||
key,
|
key,
|
||||||
deps.flatMap(dep => if (dep.key.isLocal) cmap(dep).dependencies else dep :: Nil)
|
deps.flatMap(
|
||||||
|
dep => if (dep.key.isLocal) cmap(dep).dependencies else Seq[ScopedKey[_]](dep).toIterable
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val empty = Map.empty[ScopedKey[_], Flattened]
|
val empty = Map.empty[ScopedKey[_], Flattened]
|
||||||
|
|
@ -405,8 +414,7 @@ trait Init[ScopeType] {
|
||||||
|
|
||||||
compiled flatMap {
|
compiled flatMap {
|
||||||
case (key, comp) =>
|
case (key, comp) =>
|
||||||
if (key.key.isLocal)
|
if (key.key.isLocal) nilSeq[(ScopedKey[_], Flattened)]
|
||||||
Nil
|
|
||||||
else
|
else
|
||||||
Seq[(ScopedKey[_], Flattened)]((key, flatten(flattenedLocals, key, comp.dependencies)))
|
Seq[(ScopedKey[_], Flattened)]((key, flatten(flattenedLocals, key, comp.dependencies)))
|
||||||
}
|
}
|
||||||
|
|
@ -515,8 +523,8 @@ trait Init[ScopeType] {
|
||||||
d.outputs ++= out
|
d.outputs ++= out
|
||||||
out
|
out
|
||||||
} else
|
} else
|
||||||
Nil
|
nilSeq
|
||||||
} getOrElse Nil
|
} getOrElse nilSeq
|
||||||
}
|
}
|
||||||
derivedForKey.flatMap(localAndDerived)
|
derivedForKey.flatMap(localAndDerived)
|
||||||
}
|
}
|
||||||
|
|
@ -527,7 +535,7 @@ trait Init[ScopeType] {
|
||||||
def process(rem: List[Setting[_]]): Unit = rem match {
|
def process(rem: List[Setting[_]]): Unit = rem match {
|
||||||
case s :: ss =>
|
case s :: ss =>
|
||||||
val sk = s.key
|
val sk = s.key
|
||||||
val ds = if (processed.add(sk)) deriveFor(sk) else Nil
|
val ds = if (processed.add(sk)) deriveFor(sk) else nil
|
||||||
addDefs(ds)
|
addDefs(ds)
|
||||||
process(ds ::: ss)
|
process(ds ::: ss)
|
||||||
case Nil =>
|
case Nil =>
|
||||||
|
|
@ -539,7 +547,7 @@ trait Init[ScopeType] {
|
||||||
val allDefs = addLocal(init)(scopeLocal)
|
val allDefs = addLocal(init)(scopeLocal)
|
||||||
allDefs.flatMap {
|
allDefs.flatMap {
|
||||||
case d: DerivedSetting[_] => (derivedToStruct get d map (_.outputs)).toSeq.flatten
|
case d: DerivedSetting[_] => (derivedToStruct get d map (_.outputs)).toSeq.flatten
|
||||||
case s => s :: Nil
|
case s => s :: nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -608,7 +616,8 @@ trait Init[ScopeType] {
|
||||||
) extends SettingsDefinition {
|
) extends SettingsDefinition {
|
||||||
def settings = this :: Nil
|
def settings = this :: Nil
|
||||||
def definitive: Boolean = !init.dependencies.contains(key)
|
def definitive: Boolean = !init.dependencies.contains(key)
|
||||||
def dependencies: Seq[ScopedKey[_]] = remove(init.dependencies, key)
|
def dependencies: Seq[ScopedKey[_]] =
|
||||||
|
remove(init.dependencies.asInstanceOf[Seq[ScopedKey[T]]], key)
|
||||||
def mapReferenced(g: MapScoped): Setting[T] = make(key, init mapReferenced g, pos)
|
def mapReferenced(g: MapScoped): Setting[T] = make(key, init mapReferenced g, pos)
|
||||||
|
|
||||||
def validateReferenced(g: ValidateRef): Either[Seq[Undefined], Setting[T]] =
|
def validateReferenced(g: ValidateRef): Either[Seq[Undefined], Setting[T]] =
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ object Signals {
|
||||||
try {
|
try {
|
||||||
val signals = new Signals0
|
val signals = new Signals0
|
||||||
signals.withHandler(signal, handler, action)
|
signals.withHandler(signal, handler, action)
|
||||||
} catch { case _: LinkageError => Right(action()) }
|
} catch { case _: LinkageError => Right(action()): Either[Throwable, T] }
|
||||||
|
|
||||||
result match {
|
result match {
|
||||||
case Left(e) => throw e
|
case Left(e) => throw e
|
||||||
|
|
|
||||||
|
|
@ -55,4 +55,12 @@ object Util {
|
||||||
|
|
||||||
lazy val isNonCygwinWindows: Boolean = isWindows && !isCygwin
|
lazy val isNonCygwinWindows: Boolean = isWindows && !isCygwin
|
||||||
lazy val isCygwinWindows: Boolean = isWindows && isCygwin
|
lazy val isCygwinWindows: Boolean = isWindows && isCygwin
|
||||||
|
|
||||||
|
def nil[A]: List[A] = List.empty[A]
|
||||||
|
def nilSeq[A]: Seq[A] = Seq.empty[A]
|
||||||
|
def none[A]: Option[A] = (None: Option[A])
|
||||||
|
|
||||||
|
implicit class AnyOps[A](private val value: A) extends AnyVal {
|
||||||
|
def some: Option[A] = (Some(value): Option[A])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,8 +108,10 @@ private[sbt] object JLine {
|
||||||
case "jline.UnsupportedTerminal" => "none"
|
case "jline.UnsupportedTerminal" => "none"
|
||||||
case x => x
|
case x => x
|
||||||
}
|
}
|
||||||
if (newValue != null) System.setProperty(TerminalProperty, newValue)
|
if (newValue != null) {
|
||||||
()
|
System.setProperty(TerminalProperty, newValue)
|
||||||
|
()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected[this] val originalIn = new FileInputStream(FileDescriptor.in)
|
protected[this] val originalIn = new FileInputStream(FileDescriptor.in)
|
||||||
|
|
@ -149,7 +151,7 @@ private[sbt] object JLine {
|
||||||
cr.setBellEnabled(false)
|
cr.setBellEnabled(false)
|
||||||
val h = historyPath match {
|
val h = historyPath match {
|
||||||
case None => new MemoryHistory
|
case None => new MemoryHistory
|
||||||
case Some(file) => new FileHistory(file)
|
case Some(file) => (new FileHistory(file): MemoryHistory)
|
||||||
}
|
}
|
||||||
h.setMaxSize(MaxHistorySize)
|
h.setMaxSize(MaxHistorySize)
|
||||||
cr.setHistory(h)
|
cr.setHistory(h)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ package sbt.internal.util
|
||||||
package complete
|
package complete
|
||||||
|
|
||||||
import sbt.io.IO
|
import sbt.io.IO
|
||||||
|
import Util.{ AnyOps, nil }
|
||||||
|
|
||||||
object HistoryCommands {
|
object HistoryCommands {
|
||||||
val Start = "!"
|
val Start = "!"
|
||||||
|
|
@ -57,7 +58,7 @@ object HistoryCommands {
|
||||||
lazy val last = Last ^^^ { execute(_.!!) }
|
lazy val last = Last ^^^ { execute(_.!!) }
|
||||||
|
|
||||||
lazy val list = ListCommands ~> (num ?? Int.MaxValue) map { show => (h: History) =>
|
lazy val list = ListCommands ~> (num ?? Int.MaxValue) map { show => (h: History) =>
|
||||||
{ printHistory(h, MaxLines, show); Some(Nil) }
|
{ printHistory(h, MaxLines, show); nil[String].some }
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val execStr = flag('?') ~ token(any.+.string, "<string>") map {
|
lazy val execStr = flag('?') ~ token(any.+.string, "<string>") map {
|
||||||
|
|
@ -70,7 +71,7 @@ object HistoryCommands {
|
||||||
execute(h => if (neg) h !- value else h ! value)
|
execute(h => if (neg) h !- value else h ! value)
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val help = success((h: History) => { printHelp(); Some(Nil) })
|
lazy val help = success((h: History) => { printHelp(); nil[String].some })
|
||||||
|
|
||||||
def execute(f: History => Option[String]): History => Option[List[String]] = (h: History) => {
|
def execute(f: History => Option[String]): History => Option[List[String]] = (h: History) => {
|
||||||
val command = f(h).filterNot(_.startsWith(Start))
|
val command = f(h).filterNot(_.startsWith(Start))
|
||||||
|
|
@ -79,7 +80,7 @@ object HistoryCommands {
|
||||||
h.path foreach { h =>
|
h.path foreach { h =>
|
||||||
IO.writeLines(h, lines)
|
IO.writeLines(h, lines)
|
||||||
}
|
}
|
||||||
Some(command.toList)
|
command.toList.some
|
||||||
}
|
}
|
||||||
|
|
||||||
val actionParser: Parser[complete.History => Option[List[String]]] =
|
val actionParser: Parser[complete.History => Option[List[String]]] =
|
||||||
|
|
|
||||||
|
|
@ -319,7 +319,7 @@ trait ParserMain {
|
||||||
implicit def richParser[A](a: Parser[A]): RichParser[A] = new RichParser[A] {
|
implicit def richParser[A](a: Parser[A]): RichParser[A] = new RichParser[A] {
|
||||||
def ~[B](b: Parser[B]) = seqParser(a, b)
|
def ~[B](b: Parser[B]) = seqParser(a, b)
|
||||||
def ||[B](b: Parser[B]) = choiceParser(a, b)
|
def ||[B](b: Parser[B]) = choiceParser(a, b)
|
||||||
def |[B >: A](b: Parser[B]) = homParser(a, b)
|
def |[B >: A](b: Parser[B]) = homParser[B](a, b)
|
||||||
def ? = opt(a)
|
def ? = opt(a)
|
||||||
def * = zeroOrMore(a)
|
def * = zeroOrMore(a)
|
||||||
def + = oneOrMore(a)
|
def + = oneOrMore(a)
|
||||||
|
|
@ -327,7 +327,9 @@ trait ParserMain {
|
||||||
def id = a
|
def id = a
|
||||||
|
|
||||||
def ^^^[B](value: B): Parser[B] = a map (_ => value)
|
def ^^^[B](value: B): Parser[B] = a map (_ => value)
|
||||||
def ??[B >: A](alt: B): Parser[B] = a.? map { _ getOrElse alt }
|
def ??[B >: A](alt: B): Parser[B] = a.? map { x =>
|
||||||
|
x.getOrElse[B](alt)
|
||||||
|
}
|
||||||
def <~[B](b: Parser[B]): Parser[A] = (a ~ b) map { case av ~ _ => av }
|
def <~[B](b: Parser[B]): Parser[A] = (a ~ b) map { case av ~ _ => av }
|
||||||
def ~>[B](b: Parser[B]): Parser[B] = (a ~ b) map { case _ ~ bv => bv }
|
def ~>[B](b: Parser[B]): Parser[B] = (a ~ b) map { case _ ~ bv => bv }
|
||||||
def !!!(msg: String): Parser[A] = onFailure(a, msg)
|
def !!!(msg: String): Parser[A] = onFailure(a, msg)
|
||||||
|
|
@ -477,7 +479,7 @@ trait ParserMain {
|
||||||
if (ci >= s.length)
|
if (ci >= s.length)
|
||||||
a.resultEmpty.toEither.left.map { msgs0 => () =>
|
a.resultEmpty.toEither.left.map { msgs0 => () =>
|
||||||
val msgs = msgs0()
|
val msgs = msgs0()
|
||||||
val nonEmpty = if (msgs.isEmpty) "Unexpected end of input" :: Nil else msgs
|
val nonEmpty = if (msgs.isEmpty) Seq("Unexpected end of input") else msgs
|
||||||
(nonEmpty, ci)
|
(nonEmpty, ci)
|
||||||
} else
|
} else
|
||||||
loop(ci, a derive s(ci))
|
loop(ci, a derive s(ci))
|
||||||
|
|
@ -601,7 +603,8 @@ trait ParserMain {
|
||||||
|
|
||||||
def seq0[T](p: Seq[Parser[T]], errors: => Seq[String]): Parser[Seq[T]] = {
|
def seq0[T](p: Seq[Parser[T]], errors: => Seq[String]): Parser[Seq[T]] = {
|
||||||
val (newErrors, valid) = separate(p) {
|
val (newErrors, valid) = separate(p) {
|
||||||
case Invalid(f) => Left(f.errors _); case ok => Right(ok)
|
case Invalid(f) => Left(f.errors _): Either[() => Seq[String], Parser[T]]
|
||||||
|
case ok => Right(ok): Either[() => Seq[String], Parser[T]]
|
||||||
}
|
}
|
||||||
def combinedErrors = errors ++ newErrors.flatMap(_())
|
def combinedErrors = errors ++ newErrors.flatMap(_())
|
||||||
if (valid.isEmpty) invalid(combinedErrors) else new ParserSeq(valid, combinedErrors)
|
if (valid.isEmpty) invalid(combinedErrors) else new ParserSeq(valid, combinedErrors)
|
||||||
|
|
@ -966,10 +969,11 @@ private final class Repeat[T](
|
||||||
lazy val resultEmpty: Result[Seq[T]] = {
|
lazy val resultEmpty: Result[Seq[T]] = {
|
||||||
val partialAccumulatedOption =
|
val partialAccumulatedOption =
|
||||||
partial match {
|
partial match {
|
||||||
case None => Value(accumulatedReverse)
|
case None => (Value(accumulatedReverse): Result[List[T]])
|
||||||
case Some(partialPattern) => partialPattern.resultEmpty.map(_ :: accumulatedReverse)
|
case Some(partialPattern) =>
|
||||||
|
partialPattern.resultEmpty.map(_ :: accumulatedReverse)
|
||||||
}
|
}
|
||||||
(partialAccumulatedOption app repeatedParseEmpty)(_ reverse_::: _)
|
(partialAccumulatedOption app repeatedParseEmpty)((x, y) => (x reverse_::: y): Seq[T])
|
||||||
}
|
}
|
||||||
|
|
||||||
private def repeatedParseEmpty: Result[List[T]] = {
|
private def repeatedParseEmpty: Result[List[T]] = {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import java.lang.Character.{
|
||||||
}
|
}
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
|
import sbt.internal.util.Util.nilSeq
|
||||||
|
|
||||||
/** Provides standard implementations of commonly useful [[Parser]]s. */
|
/** Provides standard implementations of commonly useful [[Parser]]s. */
|
||||||
trait Parsers {
|
trait Parsers {
|
||||||
|
|
@ -130,7 +131,7 @@ trait Parsers {
|
||||||
* Matches a non-empty String consisting of whitespace characters.
|
* Matches a non-empty String consisting of whitespace characters.
|
||||||
* The suggested tab completion is a single, constant space character.
|
* The suggested tab completion is a single, constant space character.
|
||||||
*/
|
*/
|
||||||
lazy val Space = SpaceClass.+.examples(" ")
|
lazy val Space: Parser[Seq[Char]] = SpaceClass.+.examples(" ")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches a possibly empty String consisting of whitespace characters.
|
* Matches a possibly empty String consisting of whitespace characters.
|
||||||
|
|
@ -274,7 +275,7 @@ trait Parsers {
|
||||||
* The result is the (possibly empty) sequence of results from the multiple `rep` applications. The `sep` results are discarded.
|
* The result is the (possibly empty) sequence of results from the multiple `rep` applications. The `sep` results are discarded.
|
||||||
*/
|
*/
|
||||||
def repsep[T](rep: Parser[T], sep: Parser[_]): Parser[Seq[T]] =
|
def repsep[T](rep: Parser[T], sep: Parser[_]): Parser[Seq[T]] =
|
||||||
rep1sep(rep, sep) ?? Nil
|
rep1sep(rep, sep) ?? nilSeq[T]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies `rep` one or more times, separated by `sep`.
|
* Applies `rep` one or more times, separated by `sep`.
|
||||||
|
|
|
||||||
|
|
@ -118,9 +118,9 @@ object Logic {
|
||||||
val (pos, neg) = (posSeq.toSet, negSeq.toSet)
|
val (pos, neg) = (posSeq.toSet, negSeq.toSet)
|
||||||
|
|
||||||
val problem =
|
val problem =
|
||||||
checkContradictions(pos, neg) orElse
|
(checkContradictions(pos, neg): Option[LogicException]) orElse
|
||||||
checkOverlap(clauses, pos) orElse
|
(checkOverlap(clauses, pos): Option[LogicException]) orElse
|
||||||
checkAcyclic(clauses)
|
(checkAcyclic(clauses): Option[LogicException])
|
||||||
|
|
||||||
problem.toLeft(
|
problem.toLeft(
|
||||||
reduce0(clauses, initialFacts, Matched.empty)
|
reduce0(clauses, initialFacts, Matched.empty)
|
||||||
|
|
@ -249,7 +249,8 @@ object Logic {
|
||||||
else {
|
else {
|
||||||
val unproven = Clauses(unprovenClauses)
|
val unproven = Clauses(unprovenClauses)
|
||||||
val nextFacts: Set[Literal] =
|
val nextFacts: Set[Literal] =
|
||||||
if (newlyProven.nonEmpty) newlyProven.toSet else inferFailure(unproven)
|
if (newlyProven.nonEmpty) newlyProven.toSet[Literal]
|
||||||
|
else inferFailure(unproven)
|
||||||
reduce0(unproven, nextFacts, newState)
|
reduce0(unproven, nextFacts, newState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -283,7 +284,7 @@ object Logic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private[this] def negated(atoms: Set[Atom]): Set[Literal] = atoms.map(a => Negated(a))
|
private[this] def negated(atoms: Set[Atom]): Set[Literal] = atoms.map(a => (Negated(a): Literal))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the set of atoms in `clauses` that directly or transitively take a negated atom as input.
|
* Computes the set of atoms in `clauses` that directly or transitively take a negated atom as input.
|
||||||
|
|
@ -386,7 +387,9 @@ object Logic {
|
||||||
None
|
None
|
||||||
else {
|
else {
|
||||||
val newLits = lits -- facts
|
val newLits = lits -- facts
|
||||||
val newF = if (newLits.isEmpty) True else And(newLits)
|
val newF =
|
||||||
|
if (newLits.isEmpty) (True: Formula)
|
||||||
|
else (And(newLits): Formula)
|
||||||
Some(newF) // 1.
|
Some(newF) // 1.
|
||||||
}
|
}
|
||||||
case True => Some(True)
|
case True => Some(True)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import sbt.util.Logger
|
||||||
import sbt.ConcurrentRestrictions.Tag
|
import sbt.ConcurrentRestrictions.Tag
|
||||||
import sbt.protocol.testing._
|
import sbt.protocol.testing._
|
||||||
import sbt.internal.util.ConsoleAppender
|
import sbt.internal.util.ConsoleAppender
|
||||||
|
import sbt.internal.util.Util.{ AnyOps, none }
|
||||||
|
|
||||||
private[sbt] object ForkTests {
|
private[sbt] object ForkTests {
|
||||||
def apply(
|
def apply(
|
||||||
|
|
@ -56,8 +57,8 @@ private[sbt] object ForkTests {
|
||||||
std.TaskExtra.task {
|
std.TaskExtra.task {
|
||||||
val server = new ServerSocket(0)
|
val server = new ServerSocket(0)
|
||||||
val testListeners = opts.testListeners flatMap {
|
val testListeners = opts.testListeners flatMap {
|
||||||
case tl: TestsListener => Some(tl)
|
case tl: TestsListener => tl.some
|
||||||
case _ => None
|
case _ => none[TestsListener]
|
||||||
}
|
}
|
||||||
|
|
||||||
object Acceptor extends Runnable {
|
object Acceptor extends Runnable {
|
||||||
|
|
@ -124,7 +125,7 @@ private[sbt] object ForkTests {
|
||||||
val acceptorThread = new Thread(Acceptor)
|
val acceptorThread = new Thread(Acceptor)
|
||||||
acceptorThread.start()
|
acceptorThread.start()
|
||||||
|
|
||||||
val fullCp = classpath ++: Seq(
|
val fullCp = classpath ++ Seq(
|
||||||
IO.classLocationPath[ForkMain].toFile,
|
IO.classLocationPath[ForkMain].toFile,
|
||||||
IO.classLocationPath[Framework].toFile
|
IO.classLocationPath[Framework].toFile
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@ object Package {
|
||||||
val entryMap = manifest.getEntries.asScala
|
val entryMap = manifest.getEntries.asScala
|
||||||
for ((key, value) <- mergeManifest.getEntries.asScala) {
|
for ((key, value) <- mergeManifest.getEntries.asScala) {
|
||||||
entryMap.get(key) match {
|
entryMap.get(key) match {
|
||||||
case Some(attributes) => mergeAttributes(attributes, value)
|
case Some(attributes) => mergeAttributes(attributes, value); ()
|
||||||
case None => entryMap put (key, value)
|
case None => entryMap put (key, value); ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -81,9 +81,9 @@ object Package {
|
||||||
val main = manifest.getMainAttributes
|
val main = manifest.getMainAttributes
|
||||||
for (option <- conf.options) {
|
for (option <- conf.options) {
|
||||||
option match {
|
option match {
|
||||||
case JarManifest(mergeManifest) => mergeManifests(manifest, mergeManifest)
|
case JarManifest(mergeManifest) => mergeManifests(manifest, mergeManifest); ()
|
||||||
case MainClass(mainClassName) => main.put(Attributes.Name.MAIN_CLASS, mainClassName)
|
case MainClass(mainClassName) => main.put(Attributes.Name.MAIN_CLASS, mainClassName); ()
|
||||||
case ManifestAttributes(attributes @ _*) => main.asScala ++= attributes
|
case ManifestAttributes(attributes @ _*) => main.asScala ++= attributes; ()
|
||||||
case _ => log.warn("Ignored unknown package option " + option)
|
case _ => log.warn("Ignored unknown package option " + option)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -98,6 +98,7 @@ object Package {
|
||||||
if (inChanged || outChanged) {
|
if (inChanged || outChanged) {
|
||||||
makeJar(sources, jar.file, manifest, log)
|
makeJar(sources, jar.file, manifest, log)
|
||||||
jar.file
|
jar.file
|
||||||
|
()
|
||||||
} else
|
} else
|
||||||
log.debug("Jar uptodate: " + jar.file)
|
log.debug("Jar uptodate: " + jar.file)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import testing.{
|
||||||
SubclassFingerprint,
|
SubclassFingerprint,
|
||||||
Runner,
|
Runner,
|
||||||
TaskDef,
|
TaskDef,
|
||||||
|
Selector,
|
||||||
SuiteSelector,
|
SuiteSelector,
|
||||||
Task => TestTask
|
Task => TestTask
|
||||||
}
|
}
|
||||||
|
|
@ -155,14 +156,15 @@ object Tests {
|
||||||
|
|
||||||
for (option <- config.options) {
|
for (option <- config.options) {
|
||||||
option match {
|
option match {
|
||||||
case Filter(include) => testFilters += include
|
case Filter(include) => testFilters += include; ()
|
||||||
case Filters(includes) =>
|
case Filters(includes) =>
|
||||||
if (orderedFilters.nonEmpty) sys.error("Cannot define multiple ordered test filters.")
|
if (orderedFilters.nonEmpty) sys.error("Cannot define multiple ordered test filters.")
|
||||||
else orderedFilters = includes
|
else orderedFilters = includes
|
||||||
case Exclude(exclude) => excludeTestsSet ++= exclude
|
()
|
||||||
case Listeners(listeners) => testListeners ++= listeners
|
case Exclude(exclude) => excludeTestsSet ++= exclude; ()
|
||||||
case Setup(setupFunction) => setup += setupFunction
|
case Listeners(listeners) => testListeners ++= listeners; ()
|
||||||
case Cleanup(cleanupFunction) => cleanup += cleanupFunction
|
case Setup(setupFunction) => setup += setupFunction; ()
|
||||||
|
case Cleanup(cleanupFunction) => cleanup += cleanupFunction; ()
|
||||||
case _: Argument => // now handled by whatever constructs `runners`
|
case _: Argument => // now handled by whatever constructs `runners`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -239,16 +241,18 @@ object Tests {
|
||||||
val setupTasks = fj(partApp(userSetup) :+ frameworkSetup)
|
val setupTasks = fj(partApp(userSetup) :+ frameworkSetup)
|
||||||
val mainTasks =
|
val mainTasks =
|
||||||
if (config.parallel)
|
if (config.parallel)
|
||||||
makeParallel(loader, runnables, setupTasks, config.tags) //.toSeq.join
|
makeParallel(loader, runnables, setupTasks, config.tags).map(_.toList)
|
||||||
else
|
else
|
||||||
makeSerial(loader, runnables, setupTasks)
|
makeSerial(loader, runnables, setupTasks)
|
||||||
val taggedMainTasks = mainTasks.tagw(config.tags: _*)
|
val taggedMainTasks = mainTasks.tagw(config.tags: _*)
|
||||||
taggedMainTasks map processResults flatMap { results =>
|
taggedMainTasks
|
||||||
val cleanupTasks = fj(partApp(userCleanup) :+ frameworkCleanup(results.overall))
|
.map(processResults)
|
||||||
cleanupTasks map { _ =>
|
.flatMap { results =>
|
||||||
results
|
val cleanupTasks = fj(partApp(userCleanup) :+ frameworkCleanup(results.overall))
|
||||||
|
cleanupTasks map { _ =>
|
||||||
|
results
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
type TestRunnable = (String, TestFunction)
|
type TestRunnable = (String, TestFunction)
|
||||||
|
|
||||||
|
|
@ -367,13 +371,20 @@ object Tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
def foldTasks(results: Seq[Task[Output]], parallel: Boolean): Task[Output] =
|
def foldTasks(results: Seq[Task[Output]], parallel: Boolean): Task[Output] =
|
||||||
if (results.isEmpty)
|
if (results.isEmpty) {
|
||||||
task { Output(TestResult.Passed, Map.empty, Nil) } else if (parallel)
|
task { Output(TestResult.Passed, Map.empty, Nil) }
|
||||||
reduced(results.toIndexedSeq, {
|
} else if (parallel) {
|
||||||
case (Output(v1, m1, _), Output(v2, m2, _)) =>
|
reduced[Output](
|
||||||
Output(if (severity(v1) < severity(v2)) v2 else v1, m1 ++ m2, Iterable.empty)
|
results.toIndexedSeq, {
|
||||||
})
|
case (Output(v1, m1, _), Output(v2, m2, _)) =>
|
||||||
else {
|
Output(
|
||||||
|
(if (severity(v1) < severity(v2)) v2 else v1): TestResult,
|
||||||
|
Map((m1.toSeq ++ m2.toSeq): _*),
|
||||||
|
Iterable.empty[Summary]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
def sequence(tasks: List[Task[Output]], acc: List[Output]): Task[List[Output]] =
|
def sequence(tasks: List[Task[Output]], acc: List[Output]): Task[List[Output]] =
|
||||||
tasks match {
|
tasks match {
|
||||||
case Nil => task(acc.reverse)
|
case Nil => task(acc.reverse)
|
||||||
|
|
@ -386,7 +397,10 @@ object Tests {
|
||||||
val (rs, ms) = ress.unzip { e =>
|
val (rs, ms) = ress.unzip { e =>
|
||||||
(e.overall, e.events)
|
(e.overall, e.events)
|
||||||
}
|
}
|
||||||
Output(overall(rs), ms reduce (_ ++ _), Iterable.empty)
|
val m = ms reduce { (m1: Map[String, SuiteResult], m2: Map[String, SuiteResult]) =>
|
||||||
|
Map((m1.toSeq ++ m2.toSeq): _*)
|
||||||
|
}
|
||||||
|
Output(overall(rs), m, Iterable.empty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def overall(results: Iterable[TestResult]): TestResult =
|
def overall(results: Iterable[TestResult]): TestResult =
|
||||||
|
|
@ -406,9 +420,11 @@ object Tests {
|
||||||
acs.flatMap { ac =>
|
acs.flatMap { ac =>
|
||||||
val companions = ac.api
|
val companions = ac.api
|
||||||
val all =
|
val all =
|
||||||
Seq(companions.classApi, companions.objectApi) ++
|
Seq(companions.classApi: Definition, companions.objectApi: Definition) ++
|
||||||
companions.classApi.structure.declared ++ companions.classApi.structure.inherited ++
|
(companions.classApi.structure.declared.toSeq: Seq[Definition]) ++
|
||||||
companions.objectApi.structure.declared ++ companions.objectApi.structure.inherited
|
(companions.classApi.structure.inherited.toSeq: Seq[Definition]) ++
|
||||||
|
(companions.objectApi.structure.declared.toSeq: Seq[Definition]) ++
|
||||||
|
(companions.objectApi.structure.inherited.toSeq: Seq[Definition])
|
||||||
|
|
||||||
all
|
all
|
||||||
}.toSeq
|
}.toSeq
|
||||||
|
|
@ -446,8 +462,10 @@ object Tests {
|
||||||
})
|
})
|
||||||
// TODO: To pass in correct explicitlySpecified and selectors
|
// TODO: To pass in correct explicitlySpecified and selectors
|
||||||
val tests =
|
val tests =
|
||||||
for ((df, di) <- discovered; fingerprint <- toFingerprints(di))
|
for {
|
||||||
yield new TestDefinition(df.name, fingerprint, false, Array(new SuiteSelector))
|
(df, di) <- discovered
|
||||||
|
fingerprint <- toFingerprints(di)
|
||||||
|
} yield new TestDefinition(df.name, fingerprint, false, Array(new SuiteSelector: Selector))
|
||||||
val mains = discovered collect { case (df, di) if di.hasMain => df.name }
|
val mains = discovered collect { case (df, di) if di.hasMain => df.name }
|
||||||
(tests, mains.toSet)
|
(tests, mains.toSet)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,8 @@ final class Eval(
|
||||||
|
|
||||||
val (extra, loader) = backing match {
|
val (extra, loader) = backing match {
|
||||||
case Some(back) if classExists(back, moduleName) =>
|
case Some(back) if classExists(back, moduleName) =>
|
||||||
val loader = (parent: ClassLoader) => new URLClassLoader(Array(back.toURI.toURL), parent)
|
val loader = (parent: ClassLoader) =>
|
||||||
|
(new URLClassLoader(Array(back.toURI.toURL), parent): ClassLoader)
|
||||||
val extra = ev.read(cacheFile(back, moduleName))
|
val extra = ev.read(cacheFile(back, moduleName))
|
||||||
(extra, loader)
|
(extra, loader)
|
||||||
case _ =>
|
case _ =>
|
||||||
|
|
@ -313,9 +314,10 @@ final class Eval(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def moduleBody = Template(List(gen.scalaAnyRefConstr), noSelfType, emptyInit :: definitions)
|
def moduleBody =
|
||||||
|
Template(List(gen.scalaAnyRefConstr), noSelfType, (emptyInit: Tree) :: definitions)
|
||||||
def moduleDef = ModuleDef(NoMods, newTermName(objectName), moduleBody)
|
def moduleDef = ModuleDef(NoMods, newTermName(objectName), moduleBody)
|
||||||
parser.makePackaging(0, emptyPkg, (imports :+ moduleDef).toList)
|
parser.makePackaging(0, emptyPkg, (imports :+ (moduleDef: Tree)).toList)
|
||||||
}
|
}
|
||||||
|
|
||||||
private[this] final class TypeExtractor extends Traverser {
|
private[this] final class TypeExtractor extends Traverser {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import sbt.internal.util.complete.{
|
||||||
TokenCompletions
|
TokenCompletions
|
||||||
}
|
}
|
||||||
import sbt.internal.util.Types.{ const, idFun }
|
import sbt.internal.util.Types.{ const, idFun }
|
||||||
|
import sbt.internal.util.Util.{ AnyOps, nil, nilSeq, none }
|
||||||
import sbt.internal.inc.classpath.ClasspathUtilities.toLoader
|
import sbt.internal.inc.classpath.ClasspathUtilities.toLoader
|
||||||
import sbt.internal.inc.ModuleUtilities
|
import sbt.internal.inc.ModuleUtilities
|
||||||
import sbt.internal.client.NetworkClient
|
import sbt.internal.client.NetworkClient
|
||||||
|
|
@ -67,7 +68,7 @@ object BasicCommands {
|
||||||
Iterator(Level.Debug, Level.Info, Level.Warn, Level.Error) map (l => token(l.toString)) reduce (_ | _)
|
Iterator(Level.Debug, Level.Info, Level.Warn, Level.Error) map (l => token(l.toString)) reduce (_ | _)
|
||||||
|
|
||||||
private[this] def addPluginSbtFileParser: Parser[File] = {
|
private[this] def addPluginSbtFileParser: Parser[File] = {
|
||||||
token(AddPluginSbtFileCommand) ~> (":" | "=" | Space) ~> (StringBasic).examples(
|
token(AddPluginSbtFileCommand) ~> (":" | "=" | Space.map(_.toString)) ~> (StringBasic).examples(
|
||||||
"/some/extra.sbt"
|
"/some/extra.sbt"
|
||||||
) map {
|
) map {
|
||||||
new File(_)
|
new File(_)
|
||||||
|
|
@ -76,7 +77,7 @@ object BasicCommands {
|
||||||
|
|
||||||
private[this] def addPluginSbtFileStringParser: Parser[String] = {
|
private[this] def addPluginSbtFileStringParser: Parser[String] = {
|
||||||
token(
|
token(
|
||||||
token(AddPluginSbtFileCommand) ~ (":" | "=" | Space) ~ (StringBasic)
|
token(AddPluginSbtFileCommand) ~ (":" | "=" | Space.map(_.toString)) ~ (StringBasic)
|
||||||
.examples("/some/extra.sbt") map {
|
.examples("/some/extra.sbt") map {
|
||||||
case s1 ~ s2 ~ s3 => s1 + s2 + s3
|
case s1 ~ s2 ~ s3 => s1 + s2 + s3
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +100,7 @@ object BasicCommands {
|
||||||
def addPluginSbtFile: Command = Command.arb(_ => addPluginSbtFileParser, addPluginSbtFileHelp) {
|
def addPluginSbtFile: Command = Command.arb(_ => addPluginSbtFileParser, addPluginSbtFileHelp) {
|
||||||
(s, extraSbtFile) =>
|
(s, extraSbtFile) =>
|
||||||
val extraFiles = s.get(BasicKeys.extraMetaSbtFiles).toList.flatten
|
val extraFiles = s.get(BasicKeys.extraMetaSbtFiles).toList.flatten
|
||||||
s.put(BasicKeys.extraMetaSbtFiles, extraFiles :+ extraSbtFile)
|
s.put(BasicKeys.extraMetaSbtFiles, (extraFiles: Seq[File]) :+ extraSbtFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
def help: Command = Command.make(HelpCommand, helpBrief, helpDetailed)(helpParser)
|
def help: Command = Command.make(HelpCommand, helpBrief, helpDetailed)(helpParser)
|
||||||
|
|
@ -119,12 +120,12 @@ object BasicCommands {
|
||||||
|
|
||||||
val (extraArgs, remainingCommands) = s.remainingCommands match {
|
val (extraArgs, remainingCommands) = s.remainingCommands match {
|
||||||
case xs :+ exec if exec.commandLine == "shell" => (xs, exec :: Nil)
|
case xs :+ exec if exec.commandLine == "shell" => (xs, exec :: Nil)
|
||||||
case xs => (xs, Nil)
|
case xs => (xs, nil[Exec])
|
||||||
}
|
}
|
||||||
|
|
||||||
val topic = (arg.toList ++ extraArgs.map(_.commandLine)) match {
|
val topic = (arg.toList ++ extraArgs.map(_.commandLine)) match {
|
||||||
case Nil => None
|
case Nil => none[String]
|
||||||
case xs => Some(xs.mkString(" "))
|
case xs => xs.mkString(" ").some
|
||||||
}
|
}
|
||||||
val message = try Help.message(h, topic)
|
val message = try Help.message(h, topic)
|
||||||
catch { case NonFatal(ex) => ex.toString }
|
catch { case NonFatal(ex) => ex.toString }
|
||||||
|
|
@ -165,7 +166,8 @@ object BasicCommands {
|
||||||
val nonDelim = charClass(c => c != '"' && c != '{' && c != '}', label = "not '\"', '{', '}'")
|
val nonDelim = charClass(c => c != '"' && c != '{' && c != '}', label = "not '\"', '{', '}'")
|
||||||
// Accept empty commands to simplify the parser.
|
// Accept empty commands to simplify the parser.
|
||||||
val cmdPart =
|
val cmdPart =
|
||||||
matched(((nonSemi & nonDelim) | StringEscapable | braces('{', '}')).*).examples()
|
matched(((nonSemi & nonDelim).map(_.toString) | StringEscapable | braces('{', '}')).*)
|
||||||
|
.examples()
|
||||||
|
|
||||||
val completionParser: Option[Parser[String]] =
|
val completionParser: Option[Parser[String]] =
|
||||||
state.map(s => (matched(s.nonMultiParser) & cmdPart) | cmdPart)
|
state.map(s => (matched(s.nonMultiParser) & cmdPart) | cmdPart)
|
||||||
|
|
@ -189,8 +191,8 @@ object BasicCommands {
|
||||||
var fail = false
|
var fail = false
|
||||||
while (it.hasNext && !fail) {
|
while (it.hasNext && !fail) {
|
||||||
it.next match {
|
it.next match {
|
||||||
case "" => fail = it.hasNext
|
case "" => fail = it.hasNext; ()
|
||||||
case next => result += next
|
case next => result += next; ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fail) Parser.failure(s"Couldn't parse empty commands in ${s.mkString(";")}")
|
if (fail) Parser.failure(s"Couldn't parse empty commands in ${s.mkString(";")}")
|
||||||
|
|
@ -244,7 +246,7 @@ object BasicCommands {
|
||||||
val commandArgs =
|
val commandArgs =
|
||||||
(first.drop(commandName.length).trim :: Nil ::: tail).mkString(";")
|
(first.drop(commandName.length).trim :: Nil ::: tail).mkString(";")
|
||||||
parse(commandArgs, command.parser(state)).toOption
|
parse(commandArgs, command.parser(state)).toOption
|
||||||
case _ => None
|
case _ => none[() => State]
|
||||||
}
|
}
|
||||||
}.headOption match {
|
}.headOption match {
|
||||||
case Some(s) => s()
|
case Some(s) => s()
|
||||||
|
|
@ -261,7 +263,7 @@ object BasicCommands {
|
||||||
(s: State) => token(OptSpace ~> combinedLax(s, NotSpaceClass ~ any.*))
|
(s: State) => token(OptSpace ~> combinedLax(s, NotSpaceClass ~ any.*))
|
||||||
|
|
||||||
def combinedLax(s: State, any: Parser[_]): Parser[String] =
|
def combinedLax(s: State, any: Parser[_]): Parser[String] =
|
||||||
matched(s.combinedParser | token(any, hide = const(true)))
|
matched((s.combinedParser: Parser[_]) | token(any, hide = const(true)))
|
||||||
|
|
||||||
def ifLast: Command =
|
def ifLast: Command =
|
||||||
Command(IfLast, Help.more(IfLast, IfLastDetailed))(otherCommandParser)(
|
Command(IfLast, Help.more(IfLast, IfLastDetailed))(otherCommandParser)(
|
||||||
|
|
@ -286,7 +288,7 @@ object BasicCommands {
|
||||||
)
|
)
|
||||||
|
|
||||||
def popOnFailure: Command = Command.command(PopOnFailure) { s =>
|
def popOnFailure: Command = Command.command(PopOnFailure) { s =>
|
||||||
val stack = s.get(OnFailureStack).getOrElse(Nil)
|
val stack = s.get(OnFailureStack).getOrElse(nil)
|
||||||
val updated =
|
val updated =
|
||||||
if (stack.isEmpty) s.remove(OnFailureStack) else s.put(OnFailureStack, stack.tail)
|
if (stack.isEmpty) s.remove(OnFailureStack) else s.put(OnFailureStack, stack.tail)
|
||||||
updated.copy(onFailure = stack.headOption.flatten)
|
updated.copy(onFailure = stack.headOption.flatten)
|
||||||
|
|
@ -323,7 +325,7 @@ object BasicCommands {
|
||||||
}
|
}
|
||||||
|
|
||||||
def callParser: Parser[(Seq[String], Seq[String])] =
|
def callParser: Parser[(Seq[String], Seq[String])] =
|
||||||
token(Space) ~> ((classpathOptionParser ?? Nil) ~ rep1sep(className, token(Space)))
|
token(Space) ~> ((classpathOptionParser ?? nilSeq) ~ rep1sep(className, token(Space)))
|
||||||
|
|
||||||
private[this] def className: Parser[String] = {
|
private[this] def className: Parser[String] = {
|
||||||
val base = StringBasic & not('-' ~> any.*, "Class name cannot start with '-'.")
|
val base = StringBasic & not('-' ~> any.*, "Class name cannot start with '-'.")
|
||||||
|
|
@ -367,7 +369,7 @@ object BasicCommands {
|
||||||
}
|
}
|
||||||
|
|
||||||
def oldshell: Command = Command.command(OldShell, Help.more(Shell, OldShellDetailed)) { s =>
|
def oldshell: Command = Command.command(OldShell, Help.more(Shell, OldShellDetailed)) { s =>
|
||||||
val history = (s get historyPath) getOrElse Some(new File(s.baseDir, ".history"))
|
val history = (s get historyPath) getOrElse (new File(s.baseDir, ".history")).some
|
||||||
val prompt = (s get shellPrompt) match { case Some(pf) => pf(s); case None => "> " }
|
val prompt = (s get shellPrompt) match { case Some(pf) => pf(s); case None => "> " }
|
||||||
val reader = new FullReader(history, s.combinedParser)
|
val reader = new FullReader(history, s.combinedParser)
|
||||||
val line = reader.readLine(prompt)
|
val line = reader.readLine(prompt)
|
||||||
|
|
@ -388,12 +390,12 @@ object BasicCommands {
|
||||||
Command(Client, Help.more(Client, ClientDetailed))(_ => clientParser)(runClient)
|
Command(Client, Help.more(Client, ClientDetailed))(_ => clientParser)(runClient)
|
||||||
|
|
||||||
def clientParser: Parser[Seq[String]] =
|
def clientParser: Parser[Seq[String]] =
|
||||||
(token(Space) ~> repsep(StringBasic, token(Space))) | (token(EOF) map (_ => Nil))
|
(token(Space) ~> repsep(StringBasic, token(Space))) | (token(EOF) map (_ => nilSeq))
|
||||||
|
|
||||||
def runClient(s0: State, inputArg: Seq[String]): State = {
|
def runClient(s0: State, inputArg: Seq[String]): State = {
|
||||||
val arguments = inputArg.toList ++
|
val arguments = inputArg.toList ++
|
||||||
(s0.remainingCommands match {
|
(s0.remainingCommands match {
|
||||||
case e :: Nil if e.commandLine == "shell" => Nil
|
case e :: Nil if e.commandLine == "shell" => nil
|
||||||
case xs => xs map (_.commandLine)
|
case xs => xs map (_.commandLine)
|
||||||
})
|
})
|
||||||
NetworkClient.run(s0.configuration, arguments)
|
NetworkClient.run(s0.configuration, arguments)
|
||||||
|
|
@ -511,7 +513,9 @@ object BasicCommands {
|
||||||
val aliasRemoved = removeAlias(state, name)
|
val aliasRemoved = removeAlias(state, name)
|
||||||
// apply the alias value to the commands of `state` except for the alias to avoid recursion (#933)
|
// apply the alias value to the commands of `state` except for the alias to avoid recursion (#933)
|
||||||
val partiallyApplied = Parser(aliasRemoved.combinedParser)(value)
|
val partiallyApplied = Parser(aliasRemoved.combinedParser)(value)
|
||||||
val arg = matched(partiallyApplied & (success(()) | (SpaceClass ~ any.*)))
|
val arg: Parser[String] = matched(
|
||||||
|
partiallyApplied & (success((): Any) | ((SpaceClass ~ any.*): Parser[Any]))
|
||||||
|
)
|
||||||
// by scheduling the expanded alias instead of directly executing,
|
// by scheduling the expanded alias instead of directly executing,
|
||||||
// we get errors on the expanded string (#598)
|
// we get errors on the expanded string (#598)
|
||||||
arg.map(str => () => (value + str) :: state)
|
arg.map(str => () => (value + str) :: state)
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import sbt.internal.inc.ReflectUtilities
|
||||||
import sbt.internal.util.complete.{ DefaultParsers, EditDistance, Parser }
|
import sbt.internal.util.complete.{ DefaultParsers, EditDistance, Parser }
|
||||||
import sbt.internal.util.Types.const
|
import sbt.internal.util.Types.const
|
||||||
import sbt.internal.util.{ AttributeKey, AttributeMap, Util }
|
import sbt.internal.util.{ AttributeKey, AttributeMap, Util }
|
||||||
|
import sbt.internal.util.Util.{ nilSeq }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An operation that can be executed from the sbt console.
|
* An operation that can be executed from the sbt console.
|
||||||
|
|
@ -195,7 +196,7 @@ object Command {
|
||||||
s"Not a valid $label: $value" + similar(value, allowed)
|
s"Not a valid $label: $value" + similar(value, allowed)
|
||||||
|
|
||||||
def similar(value: String, allowed: Iterable[String]): String = {
|
def similar(value: String, allowed: Iterable[String]): String = {
|
||||||
val suggested = if (value.length > 2) suggestions(value, allowed.toSeq) else Nil
|
val suggested = if (value.length > 2) suggestions(value, allowed.toSeq) else nilSeq
|
||||||
if (suggested.isEmpty) "" else suggested.mkString(" (similar: ", ", ", ")")
|
if (suggested.isEmpty) "" else suggested.mkString(" (similar: ", ", ", ")")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,7 +241,11 @@ private final class Help0(
|
||||||
val more: Set[String]
|
val more: Set[String]
|
||||||
) extends Help {
|
) extends Help {
|
||||||
def ++(h: Help): Help =
|
def ++(h: Help): Help =
|
||||||
new Help0(Help0.this.brief ++ h.brief, Help0.this.detail ++ h.detail, more ++ h.more)
|
new Help0(
|
||||||
|
Help0.this.brief ++ h.brief,
|
||||||
|
Map(Help0.this.detail.toSeq ++ h.detail.toSeq: _*),
|
||||||
|
more ++ h.more
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
object Help {
|
object Help {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import java.util.regex.{ Pattern, PatternSyntaxException }
|
||||||
import sbt.internal.util.AttributeKey
|
import sbt.internal.util.AttributeKey
|
||||||
import sbt.internal.util.complete.Parser
|
import sbt.internal.util.complete.Parser
|
||||||
import sbt.internal.util.complete.DefaultParsers._
|
import sbt.internal.util.complete.DefaultParsers._
|
||||||
|
import sbt.internal.util.Util.nilSeq
|
||||||
|
|
||||||
import sbt.io.IO
|
import sbt.io.IO
|
||||||
import sbt.io.syntax._
|
import sbt.io.syntax._
|
||||||
|
|
@ -35,7 +36,7 @@ object CommandUtil {
|
||||||
catch { case _: NoSuchMethodError => new File(".").getAbsoluteFile }
|
catch { case _: NoSuchMethodError => new File(".").getAbsoluteFile }
|
||||||
|
|
||||||
def aligned(pre: String, sep: String, in: Seq[(String, String)]): Seq[String] =
|
def aligned(pre: String, sep: String, in: Seq[(String, String)]): Seq[String] =
|
||||||
if (in.isEmpty) Nil
|
if (in.isEmpty) nilSeq
|
||||||
else {
|
else {
|
||||||
val width = in.iterator.map(_._1.length).max
|
val width = in.iterator.map(_._1.length).max
|
||||||
for ((a, b) <- in) yield pre + fill(a, width) + sep + b
|
for ((a, b) <- in) yield pre + fill(a, width) + sep + b
|
||||||
|
|
@ -80,9 +81,9 @@ object CommandUtil {
|
||||||
val keyString = Highlight.bold(keyMatches getOrElse k)
|
val keyString = Highlight.bold(keyMatches getOrElse k)
|
||||||
val contentString = contentMatches getOrElse v
|
val contentString = contentMatches getOrElse v
|
||||||
if (keyMatches.isDefined || contentMatches.isDefined)
|
if (keyMatches.isDefined || contentMatches.isDefined)
|
||||||
(keyString, contentString) :: Nil
|
Seq((keyString, contentString))
|
||||||
else
|
else
|
||||||
Nil
|
nilSeq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -365,6 +365,7 @@ object State {
|
||||||
jars.toList,
|
jars.toList,
|
||||||
() => new UncloseableURLLoader(jars, fullScalaLoader)
|
() => new UncloseableURLLoader(jars, fullScalaLoader)
|
||||||
)
|
)
|
||||||
|
()
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,14 @@ abstract class CommandChannel {
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
def append(exec: Exec): Boolean = {
|
def append(exec: Exec): Boolean = {
|
||||||
registered.forEach(q => q.synchronized { if (!q.contains(this)) q.add(this); () })
|
registered.forEach(
|
||||||
|
q =>
|
||||||
|
q.synchronized {
|
||||||
|
if (!q.contains(this)) {
|
||||||
|
q.add(this); ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
commandQueue.add(exec)
|
commandQueue.add(exec)
|
||||||
}
|
}
|
||||||
def poll: Option[Exec] = Option(commandQueue.poll)
|
def poll: Option[Exec] = Option(commandQueue.poll)
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,12 @@ import BasicKeys._
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import sbt.protocol.EventMessage
|
import sbt.protocol.EventMessage
|
||||||
import sjsonnew.JsonFormat
|
import sjsonnew.JsonFormat
|
||||||
|
import Util.AnyOps
|
||||||
|
|
||||||
private[sbt] final class ConsoleChannel(val name: String) extends CommandChannel {
|
private[sbt] final class ConsoleChannel(val name: String) extends CommandChannel {
|
||||||
private var askUserThread: Option[Thread] = None
|
private var askUserThread: Option[Thread] = None
|
||||||
def makeAskUserThread(s: State): Thread = new Thread("ask-user-thread") {
|
def makeAskUserThread(s: State): Thread = new Thread("ask-user-thread") {
|
||||||
val history = (s get historyPath) getOrElse Some(new File(s.baseDir, ".history"))
|
val history = (s get historyPath) getOrElse (new File(s.baseDir, ".history")).some
|
||||||
val prompt = (s get shellPrompt) match {
|
val prompt = (s get shellPrompt) match {
|
||||||
case Some(pf) => pf(s)
|
case Some(pf) => pf(s)
|
||||||
case None => "> "
|
case None => "> "
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ private[sbt] object LegacyWatched {
|
||||||
override def close(): Unit = watchState.close()
|
override def close(): Unit = watchState.close()
|
||||||
}
|
}
|
||||||
(ClearOnFailure :: next :: FailureWall :: repeat :: s)
|
(ClearOnFailure :: next :: FailureWall :: repeat :: s)
|
||||||
.put(ContinuousEventMonitor, monitor)
|
.put(ContinuousEventMonitor, monitor: EventMonitor)
|
||||||
case Some(eventMonitor) =>
|
case Some(eventMonitor) =>
|
||||||
Watched.printIfDefined(watched watchingMessage eventMonitor.state)
|
Watched.printIfDefined(watched watchingMessage eventMonitor.state)
|
||||||
@tailrec def impl(): State = {
|
@tailrec def impl(): State = {
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ private[sbt] class ClassLoaderCache(
|
||||||
case ClassLoaderReference(key, classLoader) =>
|
case ClassLoaderReference(key, classLoader) =>
|
||||||
close(classLoader)
|
close(classLoader)
|
||||||
delegate.remove(key)
|
delegate.remove(key)
|
||||||
|
()
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
clearExpiredLoaders()
|
clearExpiredLoaders()
|
||||||
|
|
@ -145,8 +146,9 @@ private[sbt] class ClassLoaderCache(
|
||||||
ManagementFactory.getMemoryPoolMXBeans.asScala
|
ManagementFactory.getMemoryPoolMXBeans.asScala
|
||||||
.exists(b => (b.getName == "Metaspace") && (b.getUsage.getMax > 0))
|
.exists(b => (b.getName == "Metaspace") && (b.getUsage.getMax > 0))
|
||||||
private[this] val mkReference: (Key, ClassLoader) => Reference[ClassLoader] =
|
private[this] val mkReference: (Key, ClassLoader) => Reference[ClassLoader] =
|
||||||
if (metaspaceIsLimited)(_, cl) => new SoftReference(cl, referenceQueue)
|
if (metaspaceIsLimited) { (_, cl) =>
|
||||||
else ClassLoaderReference.apply
|
(new SoftReference[ClassLoader](cl, referenceQueue): Reference[ClassLoader])
|
||||||
|
} else ClassLoaderReference.apply
|
||||||
private[this] val cleanupThread = new CleanupThread(ClassLoaderCache.threadID.getAndIncrement())
|
private[this] val cleanupThread = new CleanupThread(ClassLoaderCache.threadID.getAndIncrement())
|
||||||
private[this] val lock = new Object
|
private[this] val lock = new Object
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@ class NetworkClient(configuration: xsbti.AppConfiguration, arguments: List[Strin
|
||||||
lock.synchronized {
|
lock.synchronized {
|
||||||
pendingExecIds -= execId
|
pendingExecIds -= execId
|
||||||
}
|
}
|
||||||
|
()
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ abstract class ServerConnection(connection: Socket) {
|
||||||
val in = connection.getInputStream
|
val in = connection.getInputStream
|
||||||
connection.setSoTimeout(5000)
|
connection.setSoTimeout(5000)
|
||||||
var buffer: Vector[Byte] = Vector.empty
|
var buffer: Vector[Byte] = Vector.empty
|
||||||
def readFrame: Array[Byte] = {
|
def readFrame: Vector[Byte] = {
|
||||||
def getContentLength: Int = {
|
def getContentLength: Int = {
|
||||||
readLine.drop(16).toInt
|
readLine.drop(16).toInt
|
||||||
}
|
}
|
||||||
|
|
@ -56,17 +56,17 @@ abstract class ServerConnection(connection: Socket) {
|
||||||
} else readLine
|
} else readLine
|
||||||
}
|
}
|
||||||
|
|
||||||
def readContentLength(length: Int): Array[Byte] = {
|
def readContentLength(length: Int): Vector[Byte] = {
|
||||||
if (buffer.size < length) {
|
if (buffer.size < length) {
|
||||||
val bytesRead = in.read(readBuffer)
|
val bytesRead = in.read(readBuffer)
|
||||||
if (bytesRead > 0) {
|
if (bytesRead > 0) {
|
||||||
buffer = buffer ++ readBuffer.toVector.take(bytesRead)
|
buffer = buffer ++ readBuffer.toVector.take(bytesRead)
|
||||||
}
|
} else ()
|
||||||
}
|
} else ()
|
||||||
if (length <= buffer.size) {
|
if (length <= buffer.size) {
|
||||||
val chunk = buffer.take(length)
|
val chunk = buffer.take(length)
|
||||||
buffer = buffer.drop(length)
|
buffer = buffer.drop(length)
|
||||||
chunk.toArray
|
chunk
|
||||||
} else readContentLength(length)
|
} else readContentLength(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,7 +77,7 @@ abstract class ServerConnection(connection: Socket) {
|
||||||
.deserializeJsonMessage(frame)
|
.deserializeJsonMessage(frame)
|
||||||
.fold(
|
.fold(
|
||||||
{ errorDesc =>
|
{ errorDesc =>
|
||||||
val s = new String(frame.toArray, "UTF-8")
|
val s = frame.mkString("") // new String(: Array[Byte], "UTF-8")
|
||||||
println(s"Got invalid chunk from server: $s \n" + errorDesc)
|
println(s"Got invalid chunk from server: $s \n" + errorDesc)
|
||||||
},
|
},
|
||||||
_ match {
|
_ match {
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,8 @@ object Append {
|
||||||
|
|
||||||
implicit def appendSeq[T, V <: T]: Sequence[Seq[T], Seq[V], V] =
|
implicit def appendSeq[T, V <: T]: Sequence[Seq[T], Seq[V], V] =
|
||||||
new Sequence[Seq[T], Seq[V], V] {
|
new Sequence[Seq[T], Seq[V], V] {
|
||||||
def appendValues(a: Seq[T], b: Seq[V]): Seq[T] = a ++ b
|
def appendValues(a: Seq[T], b: Seq[V]): Seq[T] = a ++ (b: Seq[T])
|
||||||
def appendValue(a: Seq[T], b: V): Seq[T] = a :+ b
|
def appendValue(a: Seq[T], b: V): Seq[T] = a :+ (b: T)
|
||||||
}
|
}
|
||||||
|
|
||||||
implicit def appendSeqImplicit[T, V](implicit ev: V => T): Sequence[Seq[T], Seq[V], V] =
|
implicit def appendSeqImplicit[T, V](implicit ev: V => T): Sequence[Seq[T], Seq[V], V] =
|
||||||
|
|
@ -50,8 +50,8 @@ object Append {
|
||||||
|
|
||||||
implicit def appendList[T, V <: T]: Sequence[List[T], List[V], V] =
|
implicit def appendList[T, V <: T]: Sequence[List[T], List[V], V] =
|
||||||
new Sequence[List[T], List[V], V] {
|
new Sequence[List[T], List[V], V] {
|
||||||
def appendValues(a: List[T], b: List[V]): List[T] = a ::: b
|
def appendValues(a: List[T], b: List[V]): List[T] = a ::: (b: List[T])
|
||||||
def appendValue(a: List[T], b: V): List[T] = a :+ b
|
def appendValue(a: List[T], b: V): List[T] = a :+ (b: T)
|
||||||
}
|
}
|
||||||
|
|
||||||
implicit def appendListImplicit[T, V](implicit ev: V => T): Sequence[List[T], List[V], V] =
|
implicit def appendListImplicit[T, V](implicit ev: V => T): Sequence[List[T], List[V], V] =
|
||||||
|
|
@ -80,14 +80,15 @@ object Append {
|
||||||
|
|
||||||
implicit def appendSet[T, V <: T]: Sequence[Set[T], Set[V], V] =
|
implicit def appendSet[T, V <: T]: Sequence[Set[T], Set[V], V] =
|
||||||
new Sequence[Set[T], Set[V], V] {
|
new Sequence[Set[T], Set[V], V] {
|
||||||
def appendValues(a: Set[T], b: Set[V]): Set[T] = a ++ b
|
def appendValues(a: Set[T], b: Set[V]): Set[T] = a ++ (b.toSeq: Seq[T]).toSet
|
||||||
def appendValue(a: Set[T], b: V): Set[T] = a + b
|
def appendValue(a: Set[T], b: V): Set[T] = a + (b: T)
|
||||||
}
|
}
|
||||||
|
|
||||||
implicit def appendMap[A, B, X <: A, Y <: B]: Sequence[Map[A, B], Map[X, Y], (X, Y)] =
|
implicit def appendMap[A, B, X <: A, Y <: B]: Sequence[Map[A, B], Map[X, Y], (X, Y)] =
|
||||||
new Sequence[Map[A, B], Map[X, Y], (X, Y)] {
|
new Sequence[Map[A, B], Map[X, Y], (X, Y)] {
|
||||||
def appendValues(a: Map[A, B], b: Map[X, Y]): Map[A, B] = a ++ b
|
def appendValues(a: Map[A, B], b: Map[X, Y]): Map[A, B] =
|
||||||
def appendValue(a: Map[A, B], b: (X, Y)): Map[A, B] = a + b
|
(a.toSeq ++ (b.toSeq: Seq[(A, B)])).toMap
|
||||||
|
def appendValue(a: Map[A, B], b: (X, Y)): Map[A, B] = a + (b: (A, B))
|
||||||
}
|
}
|
||||||
|
|
||||||
implicit def appendOption[T]: Sequence[Seq[T], Option[T], Option[T]] =
|
implicit def appendOption[T]: Sequence[Seq[T], Option[T], Option[T]] =
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import sbt.Scope.{ GlobalScope, ThisScope }
|
||||||
import sbt.internal.util.Types.const
|
import sbt.internal.util.Types.const
|
||||||
import sbt.internal.util.complete.Parser
|
import sbt.internal.util.complete.Parser
|
||||||
import sbt.internal.util._
|
import sbt.internal.util._
|
||||||
|
import Util._
|
||||||
import sbt.util.Show
|
import sbt.util.Show
|
||||||
|
|
||||||
/** A concrete settings system that uses `sbt.Scope` for the scope type. */
|
/** A concrete settings system that uses `sbt.Scope` for the scope type. */
|
||||||
|
|
@ -173,8 +174,8 @@ object Def extends Init[Scope] with TaskMacroExtra {
|
||||||
override def deriveAllowed[T](s: Setting[T], allowDynamic: Boolean): Option[String] =
|
override def deriveAllowed[T](s: Setting[T], allowDynamic: Boolean): Option[String] =
|
||||||
super.deriveAllowed(s, allowDynamic) orElse
|
super.deriveAllowed(s, allowDynamic) orElse
|
||||||
(if (s.key.scope != ThisScope)
|
(if (s.key.scope != ThisScope)
|
||||||
Some(s"Scope cannot be defined for ${definedSettingString(s)}")
|
s"Scope cannot be defined for ${definedSettingString(s)}".some
|
||||||
else None) orElse
|
else none) orElse
|
||||||
s.dependencies
|
s.dependencies
|
||||||
.find(k => k.scope != ThisScope)
|
.find(k => k.scope != ThisScope)
|
||||||
.map(
|
.map(
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,10 @@ private final class DelegateIndex0(refs: Map[ProjectRef, ProjectDelegates]) exte
|
||||||
refs.get(ref) match {
|
refs.get(ref) match {
|
||||||
case Some(pd) =>
|
case Some(pd) =>
|
||||||
pd.confs.get(conf) match {
|
pd.confs.get(conf) match {
|
||||||
case Some(cs) => cs; case None => Select(conf) :: Zero :: Nil
|
case Some(cs) => cs
|
||||||
|
case None => (Select(conf): ScopeAxis[ConfigKey]) :: (Zero: ScopeAxis[ConfigKey]) :: Nil
|
||||||
}
|
}
|
||||||
case None => Select(conf) :: Zero :: Nil
|
case None => (Select(conf): ScopeAxis[ConfigKey]) :: (Zero: ScopeAxis[ConfigKey]) :: Nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private final class ProjectDelegates(
|
private final class ProjectDelegates(
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import Def.{ Initialize, ScopedKey }
|
||||||
import std.TaskExtra._
|
import std.TaskExtra._
|
||||||
import sbt.internal.util.{ ~>, AttributeKey, Types }
|
import sbt.internal.util.{ ~>, AttributeKey, Types }
|
||||||
import sbt.internal.util.Types._
|
import sbt.internal.util.Types._
|
||||||
|
import sbt.internal.util.Util._
|
||||||
|
|
||||||
/** Parses input and produces a task to run. Constructed using the companion object. */
|
/** Parses input and produces a task to run. Constructed using the companion object. */
|
||||||
final class InputTask[T] private (val parser: State => Parser[Task[T]]) {
|
final class InputTask[T] private (val parser: State => Parser[Task[T]]) {
|
||||||
|
|
@ -109,7 +110,7 @@ object InputTask {
|
||||||
|
|
||||||
/** Implementation detail that is public because it is used by a macro.*/
|
/** Implementation detail that is public because it is used by a macro.*/
|
||||||
def initParserAsInput[T](i: Initialize[Parser[T]]): Initialize[State => Parser[T]] =
|
def initParserAsInput[T](i: Initialize[Parser[T]]): Initialize[State => Parser[T]] =
|
||||||
i(Types.const)
|
i(Types.const[State, Parser[T]])
|
||||||
|
|
||||||
@deprecated("Use another InputTask constructor or the `Def.inputTask` macro.", "0.13.0")
|
@deprecated("Use another InputTask constructor or the `Def.inputTask` macro.", "0.13.0")
|
||||||
def apply[I, T](
|
def apply[I, T](
|
||||||
|
|
@ -147,7 +148,7 @@ object InputTask {
|
||||||
val key = localKey[Option[I]]
|
val key = localKey[Option[I]]
|
||||||
val f: () => I = () =>
|
val f: () => I = () =>
|
||||||
sys.error(s"Internal sbt error: InputTask stub was not substituted properly.")
|
sys.error(s"Internal sbt error: InputTask stub was not substituted properly.")
|
||||||
val t: Task[I] = Task(Info[I]().set(key, None), Pure(f, false))
|
val t: Task[I] = Task(Info[I]().set(key, none), Pure(f, false))
|
||||||
(key, t)
|
(key, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +164,7 @@ object InputTask {
|
||||||
if (t0 == null) {
|
if (t0 == null) {
|
||||||
val newAction =
|
val newAction =
|
||||||
if (t.info.get(marker).isDefined)
|
if (t.info.get(marker).isDefined)
|
||||||
Pure(() => value.asInstanceOf[A], inline = true)
|
(Pure[A](() => value.asInstanceOf[A], inline = true): Action[A])
|
||||||
else
|
else
|
||||||
t.work.mapTask(f)
|
t.work.mapTask(f)
|
||||||
val newTask = Task(t.info, newAction)
|
val newTask = Task(t.info, newAction)
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ object Previous {
|
||||||
}
|
}
|
||||||
override def hashCode(): Int = (task.## * 31) ^ enclosing.##
|
override def hashCode(): Int = (task.## * 31) ^ enclosing.##
|
||||||
def cacheKey: AnyTaskKey = {
|
def cacheKey: AnyTaskKey = {
|
||||||
if (task == enclosing) task
|
if (task == enclosing) task.asInstanceOf[ScopedKey[Task[Any]]]
|
||||||
else {
|
else {
|
||||||
val am = enclosing.scope.extra match {
|
val am = enclosing.scope.extra match {
|
||||||
case Select(a) => a.put(scopedKeyAttribute, task.asInstanceOf[AnyTaskKey])
|
case Select(a) => a.put(scopedKeyAttribute, task.asInstanceOf[AnyTaskKey])
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ object Remove {
|
||||||
implicit def removeSeq[T, V <: T]: Sequence[Seq[T], Seq[V], V] =
|
implicit def removeSeq[T, V <: T]: Sequence[Seq[T], Seq[V], V] =
|
||||||
new Sequence[Seq[T], Seq[V], V] {
|
new Sequence[Seq[T], Seq[V], V] {
|
||||||
def removeValue(a: Seq[T], b: V): Seq[T] = a filterNot b.==
|
def removeValue(a: Seq[T], b: V): Seq[T] = a filterNot b.==
|
||||||
def removeValues(a: Seq[T], b: Seq[V]): Seq[T] = a diff b
|
def removeValues(a: Seq[T], b: Seq[V]): Seq[T] = a diff (b: Seq[T])
|
||||||
}
|
}
|
||||||
implicit def removeOption[T]: Sequence[Seq[T], Option[T], Option[T]] =
|
implicit def removeOption[T]: Sequence[Seq[T], Option[T], Option[T]] =
|
||||||
new Sequence[Seq[T], Option[T], Option[T]] {
|
new Sequence[Seq[T], Option[T], Option[T]] {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ package sbt
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
import sbt.internal.util.{ AttributeKey, AttributeMap, Dag }
|
import sbt.internal.util.{ AttributeKey, AttributeMap, Dag }
|
||||||
|
import sbt.internal.util.Util._
|
||||||
|
|
||||||
import sbt.io.IO
|
import sbt.io.IO
|
||||||
|
|
||||||
|
|
@ -213,7 +214,7 @@ object Scope {
|
||||||
val zeroConfig = if (showZeroConfig) "Zero /" else ""
|
val zeroConfig = if (showZeroConfig) "Zero /" else ""
|
||||||
val configPrefix = config.foldStrict(display, zeroConfig, "./")
|
val configPrefix = config.foldStrict(display, zeroConfig, "./")
|
||||||
val taskPrefix = task.foldStrict(_.label + " /", "", "./")
|
val taskPrefix = task.foldStrict(_.label + " /", "", "./")
|
||||||
val extras = extra.foldStrict(_.entries.map(_.toString).toList, Nil, Nil)
|
val extras = extra.foldStrict(_.entries.map(_.toString).toList, nil, nil)
|
||||||
val postfix = if (extras.isEmpty) "" else extras.mkString("(", ", ", ")")
|
val postfix = if (extras.isEmpty) "" else extras.mkString("(", ", ", ")")
|
||||||
if (scope == GlobalScope) "Global / " + sep + postfix
|
if (scope == GlobalScope) "Global / " + sep + postfix
|
||||||
else
|
else
|
||||||
|
|
@ -346,6 +347,7 @@ object Scope {
|
||||||
val t = tLinIt.next()
|
val t = tLinIt.next()
|
||||||
if (scope.extra.isSelect) {
|
if (scope.extra.isSelect) {
|
||||||
res += Scope(px, c, t, scope.extra)
|
res += Scope(px, c, t, scope.extra)
|
||||||
|
()
|
||||||
}
|
}
|
||||||
res += Scope(px, c, t, Zero)
|
res += Scope(px, c, t, Zero)
|
||||||
}
|
}
|
||||||
|
|
@ -361,7 +363,8 @@ object Scope {
|
||||||
val projAxes: Seq[ScopeAxis[ResolvedReference]] =
|
val projAxes: Seq[ScopeAxis[ResolvedReference]] =
|
||||||
resolvedProj match {
|
resolvedProj match {
|
||||||
case pr: ProjectRef => index.project(pr)
|
case pr: ProjectRef => index.project(pr)
|
||||||
case br: BuildRef => List(Select(br), Zero)
|
case br: BuildRef =>
|
||||||
|
List(Select(br): ScopeAxis[ResolvedReference], Zero: ScopeAxis[ResolvedReference])
|
||||||
}
|
}
|
||||||
expandDelegateScopes(resolvedProj)(projAxes)
|
expandDelegateScopes(resolvedProj)(projAxes)
|
||||||
}
|
}
|
||||||
|
|
@ -369,13 +372,15 @@ object Scope {
|
||||||
|
|
||||||
private val zeroL = List(Zero)
|
private val zeroL = List(Zero)
|
||||||
def withZeroAxis[T](base: ScopeAxis[T]): Seq[ScopeAxis[T]] =
|
def withZeroAxis[T](base: ScopeAxis[T]): Seq[ScopeAxis[T]] =
|
||||||
if (base.isSelect) List(base, Zero)
|
if (base.isSelect) List(base, Zero: ScopeAxis[T])
|
||||||
else zeroL
|
else zeroL
|
||||||
|
|
||||||
def withGlobalScope(base: Scope): Seq[Scope] =
|
def withGlobalScope(base: Scope): Seq[Scope] =
|
||||||
if (base == GlobalScope) GlobalScope :: Nil else base :: GlobalScope :: Nil
|
if (base == GlobalScope) GlobalScope :: Nil else base :: GlobalScope :: Nil
|
||||||
def withRawBuilds(ps: Seq[ScopeAxis[ProjectRef]]): Seq[ScopeAxis[ResolvedReference]] =
|
def withRawBuilds(ps: Seq[ScopeAxis[ProjectRef]]): Seq[ScopeAxis[ResolvedReference]] =
|
||||||
ps ++ (ps flatMap rawBuild).distinct :+ Zero
|
(ps: Seq[ScopeAxis[ResolvedReference]]) ++
|
||||||
|
((ps flatMap rawBuild).distinct: Seq[ScopeAxis[ResolvedReference]]) :+
|
||||||
|
(Zero: ScopeAxis[ResolvedReference])
|
||||||
|
|
||||||
def rawBuild(ps: ScopeAxis[ProjectRef]): Seq[ScopeAxis[BuildRef]] = ps match {
|
def rawBuild(ps: ScopeAxis[ProjectRef]): Seq[ScopeAxis[BuildRef]] = ps match {
|
||||||
case Select(ref) => Select(BuildRef(ref.build)) :: Nil; case _ => Nil
|
case Select(ref) => Select(BuildRef(ref.build)) :: Nil; case _ => Nil
|
||||||
|
|
@ -421,8 +426,8 @@ object Scope {
|
||||||
def topologicalSort[T](node: T, appendZero: Boolean)(
|
def topologicalSort[T](node: T, appendZero: Boolean)(
|
||||||
dependencies: T => Seq[T]
|
dependencies: T => Seq[T]
|
||||||
): Seq[ScopeAxis[T]] = {
|
): Seq[ScopeAxis[T]] = {
|
||||||
val o = Dag.topologicalSortUnchecked(node)(dependencies).map(Select.apply)
|
val o = Dag.topologicalSortUnchecked(node)(dependencies).map(x => Select(x): ScopeAxis[T])
|
||||||
if (appendZero) o ::: Zero :: Nil
|
if (appendZero) o ::: (Zero: ScopeAxis[T]) :: Nil
|
||||||
else o
|
else o
|
||||||
}
|
}
|
||||||
def globalProjectDelegates(scope: Scope): Seq[Scope] =
|
def globalProjectDelegates(scope: Scope): Seq[Scope] =
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import sbt.internal.util.Types.some
|
import sbt.internal.util.Util._
|
||||||
|
|
||||||
sealed trait ScopeAxis[+S] {
|
sealed trait ScopeAxis[+S] {
|
||||||
def foldStrict[T](f: S => T, ifZero: T, ifThis: T): T = fold(f, ifZero, ifThis)
|
def foldStrict[T](f: S => T, ifZero: T, ifThis: T): T = fold(f, ifZero, ifThis)
|
||||||
|
|
@ -16,8 +16,9 @@ sealed trait ScopeAxis[+S] {
|
||||||
case Zero => ifZero
|
case Zero => ifZero
|
||||||
case Select(s) => f(s)
|
case Select(s) => f(s)
|
||||||
}
|
}
|
||||||
def toOption: Option[S] = foldStrict(some.fn, None, None)
|
def toOption: Option[S] = foldStrict(Option(_), none, none)
|
||||||
def map[T](f: S => T): ScopeAxis[T] = foldStrict(s => Select(f(s)), Zero, This)
|
def map[T](f: S => T): ScopeAxis[T] =
|
||||||
|
foldStrict(s => Select(f(s)): ScopeAxis[T], Zero: ScopeAxis[T], This: ScopeAxis[T])
|
||||||
def isSelect: Boolean = false
|
def isSelect: Boolean = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,19 @@ final case class ScopeMask(
|
||||||
) {
|
) {
|
||||||
def concatShow(p: String, c: String, t: String, sep: String, x: String): String = {
|
def concatShow(p: String, c: String, t: String, sep: String, x: String): String = {
|
||||||
val sb = new StringBuilder
|
val sb = new StringBuilder
|
||||||
if (project) sb.append(p)
|
if (project) {
|
||||||
if (config) sb.append(c)
|
sb.append(p); ()
|
||||||
if (task) sb.append(t)
|
}
|
||||||
|
if (config) {
|
||||||
|
sb.append(c); ()
|
||||||
|
}
|
||||||
|
if (task) {
|
||||||
|
sb.append(t); ()
|
||||||
|
}
|
||||||
sb.append(sep)
|
sb.append(sep)
|
||||||
if (extra) sb.append(x)
|
if (extra) {
|
||||||
|
sb.append(x); ()
|
||||||
|
}
|
||||||
sb.toString
|
sb.toString
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ object ClientSocket {
|
||||||
}
|
}
|
||||||
val sk = uri.getScheme match {
|
val sk = uri.getScheme match {
|
||||||
case "local" if isWindows =>
|
case "local" if isWindows =>
|
||||||
new Win32NamedPipeSocket("""\\.\pipe\""" + uri.getSchemeSpecificPart)
|
(new Win32NamedPipeSocket("""\\.\pipe\""" + uri.getSchemeSpecificPart): Socket)
|
||||||
case "local" => new UnixDomainSocket(uri.getSchemeSpecificPart)
|
case "local" => (new UnixDomainSocket(uri.getSchemeSpecificPart): Socket)
|
||||||
case "tcp" => new Socket(InetAddress.getByName(uri.getHost), uri.getPort)
|
case "tcp" => new Socket(InetAddress.getByName(uri.getHost), uri.getPort)
|
||||||
case _ => sys.error(s"Unsupported uri: $uri")
|
case _ => sys.error(s"Unsupported uri: $uri")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import java.lang.ProcessBuilder.Redirect
|
||||||
import scala.sys.process.Process
|
import scala.sys.process.Process
|
||||||
import OutputStrategy._
|
import OutputStrategy._
|
||||||
import sbt.internal.util.Util
|
import sbt.internal.util.Util
|
||||||
|
import Util.{ AnyOps, none }
|
||||||
|
|
||||||
import java.lang.{ ProcessBuilder => JProcessBuilder }
|
import java.lang.{ ProcessBuilder => JProcessBuilder }
|
||||||
|
|
||||||
|
|
@ -52,11 +53,13 @@ final class Fork(val commandName: String, val runnerClass: Option[String]) {
|
||||||
val jpb = new JProcessBuilder(command.toArray: _*)
|
val jpb = new JProcessBuilder(command.toArray: _*)
|
||||||
workingDirectory foreach (jpb directory _)
|
workingDirectory foreach (jpb directory _)
|
||||||
environment foreach { case (k, v) => jpb.environment.put(k, v) }
|
environment foreach { case (k, v) => jpb.environment.put(k, v) }
|
||||||
if (connectInput)
|
if (connectInput) {
|
||||||
jpb.redirectInput(Redirect.INHERIT)
|
jpb.redirectInput(Redirect.INHERIT)
|
||||||
|
()
|
||||||
|
}
|
||||||
val process = Process(jpb)
|
val process = Process(jpb)
|
||||||
|
|
||||||
outputStrategy.getOrElse(StdoutOutput) match {
|
outputStrategy.getOrElse(StdoutOutput: OutputStrategy) match {
|
||||||
case StdoutOutput => process.run(connectInput = false)
|
case StdoutOutput => process.run(connectInput = false)
|
||||||
case out: BufferedOutput =>
|
case out: BufferedOutput =>
|
||||||
out.logger.buffer { process.run(out.logger, connectInput = false) }
|
out.logger.buffer { process.run(out.logger, connectInput = false) }
|
||||||
|
|
@ -70,9 +73,9 @@ final class Fork(val commandName: String, val runnerClass: Option[String]) {
|
||||||
arguments: Seq[String]
|
arguments: Seq[String]
|
||||||
): Seq[String] = {
|
): Seq[String] = {
|
||||||
val boot =
|
val boot =
|
||||||
if (bootJars.isEmpty) None
|
if (bootJars.isEmpty) none[String]
|
||||||
else
|
else
|
||||||
Some("-Xbootclasspath/a:" + bootJars.map(_.getAbsolutePath).mkString(File.pathSeparator))
|
("-Xbootclasspath/a:" + bootJars.map(_.getAbsolutePath).mkString(File.pathSeparator)).some
|
||||||
jvmOptions ++ boot.toList ++ runnerClass.toList ++ arguments
|
jvmOptions ++ boot.toList ++ runnerClass.toList ++ arguments
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
|
import sbt.internal.util.Util.{ AnyOps, none }
|
||||||
|
|
||||||
object SelectMainClass {
|
object SelectMainClass {
|
||||||
// Some(SimpleReader.readLine _)
|
// Some(SimpleReader.readLine _)
|
||||||
def apply(
|
def apply(
|
||||||
|
|
@ -28,18 +30,18 @@ object SelectMainClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private def trim(s: Option[String]) = s.getOrElse("")
|
private def trim(s: Option[String]) = s.getOrElse("")
|
||||||
private def toInt(s: String, size: Int) =
|
private def toInt(s: String, size: Int): Option[Int] =
|
||||||
try {
|
try {
|
||||||
val i = s.toInt
|
val i = s.toInt
|
||||||
if (i > 0 && i <= size)
|
if (i > 0 && i <= size)
|
||||||
Some(i - 1)
|
(i - 1).some
|
||||||
else {
|
else {
|
||||||
println("Number out of range: was " + i + ", expected number between 1 and " + size)
|
println("Number out of range: was " + i + ", expected number between 1 and " + size)
|
||||||
None
|
none
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
case nfe: NumberFormatException =>
|
case nfe: NumberFormatException =>
|
||||||
println("Invalid number: " + nfe.toString)
|
println("Invalid number: " + nfe.toString)
|
||||||
None
|
none
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import java.util.function.Supplier
|
||||||
|
|
||||||
import sbt.util.Logger
|
import sbt.util.Logger
|
||||||
import sbt.util.InterfaceUtil
|
import sbt.util.InterfaceUtil
|
||||||
|
import sbt.internal.util.Util.{ AnyOps, none }
|
||||||
import TrapExit._
|
import TrapExit._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -294,8 +295,8 @@ private final class TrapExit(delegateManager: SecurityManager) extends SecurityM
|
||||||
private[this] def setExceptionHandler(t: Thread): Unit = {
|
private[this] def setExceptionHandler(t: Thread): Unit = {
|
||||||
val group = t.getThreadGroup
|
val group = t.getThreadGroup
|
||||||
val previousHandler = t.getUncaughtExceptionHandler match {
|
val previousHandler = t.getUncaughtExceptionHandler match {
|
||||||
case null | `group` | (_: LoggingExceptionHandler) => None
|
case null | `group` | (_: LoggingExceptionHandler) => none[Thread.UncaughtExceptionHandler]
|
||||||
case x => Some(x) // delegate to a custom handler only
|
case x => x.some // delegate to a custom handler only
|
||||||
}
|
}
|
||||||
t.setUncaughtExceptionHandler(new LoggingExceptionHandler(log, previousHandler))
|
t.setUncaughtExceptionHandler(new LoggingExceptionHandler(log, previousHandler))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import java.io.File
|
||||||
import sbt.internal.TestLogger
|
import sbt.internal.TestLogger
|
||||||
import sbt.io.{ IO, Path }
|
import sbt.io.{ IO, Path }
|
||||||
import OutputStrategy._
|
import OutputStrategy._
|
||||||
|
import sbt.internal.util.Util._
|
||||||
|
|
||||||
object ForkTest extends Properties("Fork") {
|
object ForkTest extends Properties("Fork") {
|
||||||
|
|
||||||
|
|
@ -25,7 +26,7 @@ object ForkTest extends Properties("Fork") {
|
||||||
*/
|
*/
|
||||||
final val MaximumClasspathLength = 100000
|
final val MaximumClasspathLength = 100000
|
||||||
|
|
||||||
lazy val genOptionName = frequency((9, Some("-cp")), (9, Some("-classpath")), (1, None))
|
lazy val genOptionName = frequency((9, "-cp".some), (9, "-classpath".some), (1, none))
|
||||||
lazy val pathElement = nonEmptyListOf(alphaNumChar).map(_.mkString)
|
lazy val pathElement = nonEmptyListOf(alphaNumChar).map(_.mkString)
|
||||||
lazy val path = nonEmptyListOf(pathElement).map(_.mkString(File.separator))
|
lazy val path = nonEmptyListOf(pathElement).map(_.mkString(File.separator))
|
||||||
lazy val genRelClasspath = nonEmptyListOf(path)
|
lazy val genRelClasspath = nonEmptyListOf(path)
|
||||||
|
|
|
||||||
|
|
@ -63,9 +63,14 @@ final case class Task[T](info: Info[T], work: Action[T]) {
|
||||||
override def hashCode = info.hashCode
|
override def hashCode = info.hashCode
|
||||||
|
|
||||||
def tag(tags: Tag*): Task[T] = tagw(tags.map(t => (t, 1)): _*)
|
def tag(tags: Tag*): Task[T] = tagw(tags.map(t => (t, 1)): _*)
|
||||||
def tagw(tags: (Tag, Int)*): Task[T] =
|
def tagw(tags: (Tag, Int)*): Task[T] = {
|
||||||
copy(info = info.set(tagsKey, info.get(tagsKey).getOrElse(Map.empty) ++ tags))
|
val tgs: TagMap = info.get(tagsKey).getOrElse(TagMap.empty)
|
||||||
def tags: TagMap = info get tagsKey getOrElse Map.empty
|
val value = tags.foldLeft(tgs)((acc, tag) => acc + tag)
|
||||||
|
val nextInfo = info.set(tagsKey, value)
|
||||||
|
copy(info = nextInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
def tags: TagMap = info get tagsKey getOrElse TagMap.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -83,7 +88,7 @@ final case class Info[T](
|
||||||
def setName(n: String) = set(Name, n)
|
def setName(n: String) = set(Name, n)
|
||||||
def setDescription(d: String) = set(Description, d)
|
def setDescription(d: String) = set(Description, d)
|
||||||
def set[A](key: AttributeKey[A], value: A) = copy(attributes = this.attributes.put(key, value))
|
def set[A](key: AttributeKey[A], value: A) = copy(attributes = this.attributes.put(key, value))
|
||||||
def get[A](key: AttributeKey[A]) = attributes.get(key)
|
def get[A](key: AttributeKey[A]): Option[A] = attributes.get(key)
|
||||||
def postTransform(f: (T, AttributeMap) => AttributeMap) = copy(post = (t: T) => f(t, post(t)))
|
def postTransform(f: (T, AttributeMap) => AttributeMap) = copy(post = (t: T) => f(t, post(t)))
|
||||||
|
|
||||||
override def toString = if (attributes.isEmpty) "_" else attributes.toString
|
override def toString = if (attributes.isEmpty) "_" else attributes.toString
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
import sbt.internal.io.DeferredWriter
|
import sbt.internal.io.DeferredWriter
|
||||||
import sbt.internal.util.ManagedLogger
|
import sbt.internal.util.ManagedLogger
|
||||||
|
import sbt.internal.util.Util.{ nil }
|
||||||
import sbt.io.IO
|
import sbt.io.IO
|
||||||
import sbt.io.syntax._
|
import sbt.io.syntax._
|
||||||
import sbt.util._
|
import sbt.util._
|
||||||
|
|
@ -141,7 +142,7 @@ object Streams {
|
||||||
): Streams[Key] = new Streams[Key] {
|
): Streams[Key] = new Streams[Key] {
|
||||||
|
|
||||||
def apply(a: Key): ManagedStreams[Key] = new ManagedStreams[Key] {
|
def apply(a: Key): ManagedStreams[Key] = new ManagedStreams[Key] {
|
||||||
private[this] var opened: List[Closeable] = Nil
|
private[this] var opened: List[Closeable] = nil
|
||||||
private[this] var closed = false
|
private[this] var closed = false
|
||||||
|
|
||||||
def getInput(a: Key, sid: String = default): Input =
|
def getInput(a: Key, sid: String = default): Input =
|
||||||
|
|
@ -199,7 +200,7 @@ object Streams {
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
val t = f(file)
|
val t = f(file)
|
||||||
opened ::= t
|
opened ::= (t: Closeable)
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,8 @@ trait TaskExtra {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
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: T)
|
||||||
|
case Inc(_) => alt
|
||||||
}
|
}
|
||||||
def &&[T](alt: Task[T]): Task[T] = flatMap(_ => alt)
|
def &&[T](alt: Task[T]): Task[T] = flatMap(_ => alt)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ object ConcurrentRestrictions {
|
||||||
val All = Tag("all")
|
val All = Tag("all")
|
||||||
|
|
||||||
type TagMap = Map[Tag, Int]
|
type TagMap = Map[Tag, Int]
|
||||||
|
val TagMap = Map.empty[Tag, Int]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements concurrency restrictions on tasks based on Tags.
|
* Implements concurrency restrictions on tasks based on Tags.
|
||||||
|
|
@ -129,7 +130,10 @@ object ConcurrentRestrictions {
|
||||||
warn: String => Unit
|
warn: String => Unit
|
||||||
): (CompletionService[A, R], () => Unit) = {
|
): (CompletionService[A, R], () => Unit) = {
|
||||||
val pool = Executors.newCachedThreadPool()
|
val pool = Executors.newCachedThreadPool()
|
||||||
(completionService[A, R](pool, tags, warn), () => { pool.shutdownNow(); () })
|
(completionService[A, R](pool, tags, warn), () => {
|
||||||
|
pool.shutdownNow()
|
||||||
|
()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -166,26 +170,31 @@ object ConcurrentRestrictions {
|
||||||
if (tags valid newState) {
|
if (tags valid newState) {
|
||||||
tagState = newState
|
tagState = newState
|
||||||
submitValid(node, work)
|
submitValid(node, work)
|
||||||
|
()
|
||||||
} else {
|
} else {
|
||||||
if (running == 0) errorAddingToIdle()
|
if (running == 0) errorAddingToIdle()
|
||||||
pending.add(new Enqueue(node, work))
|
pending.add(new Enqueue(node, work))
|
||||||
|
()
|
||||||
}
|
}
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
private[this] def submitValid(node: A, work: () => R) = {
|
private[this] def submitValid(node: A, work: () => R): Unit = {
|
||||||
running += 1
|
running += 1
|
||||||
val wrappedWork = () =>
|
val wrappedWork = () =>
|
||||||
try work()
|
try work()
|
||||||
finally cleanup(node)
|
finally cleanup(node)
|
||||||
CompletionService.submit(wrappedWork, jservice)
|
CompletionService.submit(wrappedWork, jservice)
|
||||||
|
()
|
||||||
}
|
}
|
||||||
private[this] def cleanup(node: A): Unit = synchronized {
|
private[this] def cleanup(node: A): Unit = synchronized {
|
||||||
running -= 1
|
running -= 1
|
||||||
tagState = tags.remove(tagState, node)
|
tagState = tags.remove(tagState, node)
|
||||||
if (!tags.valid(tagState))
|
if (!tags.valid(tagState)) {
|
||||||
warn(
|
warn(
|
||||||
"Invalid restriction: removing a completed node from a valid system must result in a valid system."
|
"Invalid restriction: removing a completed node from a valid system must result in a valid system."
|
||||||
)
|
)
|
||||||
|
()
|
||||||
|
}
|
||||||
submitValid(new LinkedList)
|
submitValid(new LinkedList)
|
||||||
}
|
}
|
||||||
private[this] def errorAddingToIdle() =
|
private[this] def errorAddingToIdle() =
|
||||||
|
|
@ -205,8 +214,11 @@ object ConcurrentRestrictions {
|
||||||
if (tags.valid(newState)) {
|
if (tags.valid(newState)) {
|
||||||
tagState = newState
|
tagState = newState
|
||||||
submitValid(next.node, next.work)
|
submitValid(next.node, next.work)
|
||||||
} else
|
()
|
||||||
|
} else {
|
||||||
tried.add(next)
|
tried.add(next)
|
||||||
|
()
|
||||||
|
}
|
||||||
submitValid(tried)
|
submitValid(tried)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import java.util.concurrent.ExecutionException
|
||||||
import sbt.internal.util.ErrorHandling.wideConvert
|
import sbt.internal.util.ErrorHandling.wideConvert
|
||||||
import sbt.internal.util.{ DelegatingPMap, IDSet, PMap, RMap, ~> }
|
import sbt.internal.util.{ DelegatingPMap, IDSet, PMap, RMap, ~> }
|
||||||
import sbt.internal.util.Types._
|
import sbt.internal.util.Types._
|
||||||
|
import sbt.internal.util.Util.nilSeq
|
||||||
import Execute._
|
import Execute._
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
|
|
@ -167,7 +168,7 @@ private[sbt] final class Execute[F[_] <: AnyRef](
|
||||||
results(node) = result
|
results(node) = result
|
||||||
state(node) = Done
|
state(node) = Done
|
||||||
progress.afterCompleted(node, result)
|
progress.afterCompleted(node, result)
|
||||||
remove(reverse, node) foreach { dep =>
|
remove(reverse.asInstanceOf[Map[F[A], Iterable[F[_]]]], node) foreach { dep =>
|
||||||
notifyDone(node, dep)
|
notifyDone(node, dep)
|
||||||
}
|
}
|
||||||
callers.remove(node).toList.flatten.foreach { c =>
|
callers.remove(node).toList.flatten.foreach { c =>
|
||||||
|
|
@ -196,7 +197,7 @@ private[sbt] final class Execute[F[_] <: AnyRef](
|
||||||
val f = forward(dependent)
|
val f = forward(dependent)
|
||||||
f -= node
|
f -= node
|
||||||
if (f.isEmpty) {
|
if (f.isEmpty) {
|
||||||
remove(forward, dependent)
|
remove[F[_], IDSet[F[_]]](forward, dependent)
|
||||||
ready(dependent)
|
ready(dependent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -323,7 +324,7 @@ private[sbt] final class Execute[F[_] <: AnyRef](
|
||||||
def runBefore(node: F[_]): Seq[F[_]] = getSeq(triggers.runBefore, node)
|
def runBefore(node: F[_]): Seq[F[_]] = getSeq(triggers.runBefore, node)
|
||||||
def triggeredBy(node: F[_]): Seq[F[_]] = getSeq(triggers.injectFor, node)
|
def triggeredBy(node: F[_]): Seq[F[_]] = getSeq(triggers.injectFor, node)
|
||||||
def getSeq(map: collection.Map[F[_], Seq[F[_]]], node: F[_]): Seq[F[_]] =
|
def getSeq(map: collection.Map[F[_], Seq[F[_]]], node: F[_]): Seq[F[_]] =
|
||||||
map.getOrElse(node, Nil)
|
map.getOrElse(node, nilSeq[F[_]])
|
||||||
|
|
||||||
// Contracts
|
// Contracts
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,10 +77,10 @@ final class SuiteResult(
|
||||||
def +(other: SuiteResult): SuiteResult = {
|
def +(other: SuiteResult): SuiteResult = {
|
||||||
val combinedTestResult =
|
val combinedTestResult =
|
||||||
(result, other.result) match {
|
(result, other.result) match {
|
||||||
case (TestResult.Passed, TestResult.Passed) => TestResult.Passed
|
case (TestResult.Passed, TestResult.Passed) => TestResult.Passed: TestResult
|
||||||
case (_, TestResult.Error) => TestResult.Error
|
case (_, TestResult.Error) => TestResult.Error: TestResult
|
||||||
case (TestResult.Error, _) => TestResult.Error
|
case (TestResult.Error, _) => TestResult.Error: TestResult
|
||||||
case _ => TestResult.Failed
|
case _ => TestResult.Failed: TestResult
|
||||||
}
|
}
|
||||||
new SuiteResult(
|
new SuiteResult(
|
||||||
combinedTestResult,
|
combinedTestResult,
|
||||||
|
|
|
||||||
|
|
@ -93,16 +93,19 @@ object TestLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
private[sbt] def toTestItemEvent(event: TestEvent): TestItemEvent =
|
private[sbt] def toTestItemEvent(event: TestEvent): TestItemEvent =
|
||||||
TestItemEvent(event.result, event.detail.toVector map { d =>
|
TestItemEvent(
|
||||||
TestItemDetail(
|
event.result,
|
||||||
d.fullyQualifiedName,
|
event.detail.toVector map { d =>
|
||||||
d.status,
|
TestItemDetail(
|
||||||
d.duration match {
|
d.fullyQualifiedName,
|
||||||
case -1 => None
|
d.status,
|
||||||
case x => Some(x)
|
d.duration match {
|
||||||
}
|
case -1 => (None: Option[Long]) // util.Util is not in classpath
|
||||||
)
|
case x => (Some(x): Option[Long])
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
final class TestLogging(
|
final class TestLogging(
|
||||||
val global: TLogger,
|
val global: TLogger,
|
||||||
|
|
@ -129,8 +132,9 @@ class TestLogger(val logging: TestLogging) extends TestsListener {
|
||||||
log.error(s"Could not run test $name: $t")
|
log.error(s"Could not run test $name: $t")
|
||||||
managed.logEvent(
|
managed.logEvent(
|
||||||
Level.Info,
|
Level.Info,
|
||||||
EndTestGroupErrorEvent(name, (t.getMessage +: t.getStackTrace).mkString("\n"))
|
EndTestGroupErrorEvent(name, (t.getMessage + t.getStackTrace.toString).mkString("\n"))
|
||||||
)
|
)
|
||||||
|
()
|
||||||
}
|
}
|
||||||
|
|
||||||
def doComplete(finalResult: TestResult): Unit =
|
def doComplete(finalResult: TestResult): Unit =
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,12 @@ abstract class IvyBridgeProviderSpecification extends FlatSpec with Matchers {
|
||||||
def secondaryCacheDirectory: File = file("target").getAbsoluteFile / "zinc-components"
|
def secondaryCacheDirectory: File = file("target").getAbsoluteFile / "zinc-components"
|
||||||
|
|
||||||
val resolvers = Array(
|
val resolvers = Array(
|
||||||
ZincComponentCompiler.LocalResolver,
|
ZincComponentCompiler.LocalResolver: Resolver,
|
||||||
Resolver.mavenCentral,
|
Resolver.mavenCentral: Resolver,
|
||||||
MavenRepository(
|
MavenRepository(
|
||||||
"scala-integration",
|
"scala-integration",
|
||||||
"https://scala-ci.typesafe.com/artifactory/scala-integration/"
|
"https://scala-ci.typesafe.com/artifactory/scala-integration/"
|
||||||
),
|
): Resolver,
|
||||||
)
|
)
|
||||||
|
|
||||||
private def ivyConfiguration(log: Logger) =
|
private def ivyConfiguration(log: Logger) =
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue