mirror of https://github.com/sbt/sbt.git
commit
34d311f9ce
38
build.sbt
38
build.sbt
|
|
@ -157,6 +157,11 @@ val collectionProj = (project in file("internal") / "util-collection")
|
|||
exclude[MissingClassProblem]("sbt.internal.util.Fn1"),
|
||||
exclude[DirectMissingMethodProblem]("sbt.internal.util.TypeFunctions.toFn1"),
|
||||
exclude[DirectMissingMethodProblem]("sbt.internal.util.Types.toFn1"),
|
||||
|
||||
// Instead of defining foldr in KList & overriding in KCons,
|
||||
// it's now abstract in KList and defined in both KCons & KNil.
|
||||
exclude[FinalMethodProblem]("sbt.internal.util.KNil.foldr"),
|
||||
exclude[DirectAbstractMethodProblem]("sbt.internal.util.KList.foldr"),
|
||||
),
|
||||
)
|
||||
.configure(addSbtUtilPosition)
|
||||
|
|
@ -169,6 +174,11 @@ val completeProj = (project in file("internal") / "util-complete")
|
|||
name := "Completion",
|
||||
libraryDependencies += jline,
|
||||
mimaSettings,
|
||||
mimaBinaryIssueFilters ++= Seq(
|
||||
// Changed signature or removed something in the internal pacakge
|
||||
exclude[DirectMissingMethodProblem]("sbt.internal.*"),
|
||||
exclude[IncompatibleResultTypeProblem]("sbt.internal.*"),
|
||||
),
|
||||
)
|
||||
.configure(addSbtIO, addSbtUtilControl)
|
||||
|
||||
|
|
@ -275,6 +285,12 @@ lazy val actionsProj = (project in file("main-actions"))
|
|||
name := "Actions",
|
||||
libraryDependencies += sjsonNewScalaJson.value,
|
||||
mimaSettings,
|
||||
mimaBinaryIssueFilters ++= Seq(
|
||||
// Removed unused private[sbt] nested class
|
||||
exclude[MissingClassProblem]("sbt.Doc$Scaladoc"),
|
||||
// Removed no longer used private[sbt] method
|
||||
exclude[DirectMissingMethodProblem]("sbt.Doc.generate"),
|
||||
),
|
||||
)
|
||||
.configure(
|
||||
addSbtIO,
|
||||
|
|
@ -293,6 +309,8 @@ lazy val protocolProj = (project in file("protocol"))
|
|||
.enablePlugins(ContrabandPlugin, JsonCodecPlugin)
|
||||
.settings(
|
||||
testedBaseSettings,
|
||||
scalacOptions -= "-Ywarn-unused",
|
||||
scalacOptions += "-Xlint:-unused",
|
||||
name := "Protocol",
|
||||
libraryDependencies ++= Seq(sjsonNewScalaJson.value),
|
||||
managedSourceDirectories in Compile +=
|
||||
|
|
@ -345,7 +363,7 @@ lazy val commandProj = (project in file("main-command"))
|
|||
lazy val coreMacrosProj = (project in file("core-macros"))
|
||||
.dependsOn(collectionProj)
|
||||
.settings(
|
||||
commonSettings,
|
||||
baseSettings,
|
||||
name := "Core Macros",
|
||||
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value,
|
||||
mimaSettings,
|
||||
|
|
@ -403,17 +421,17 @@ lazy val mainProj = (project in file("main"))
|
|||
sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala",
|
||||
mimaSettings,
|
||||
mimaBinaryIssueFilters ++= Vector(
|
||||
// Changed the signature of NetworkChannel ctor. internal.
|
||||
exclude[DirectMissingMethodProblem]("sbt.internal.server.NetworkChannel.*"),
|
||||
// ctor for ConfigIndex. internal.
|
||||
exclude[DirectMissingMethodProblem]("sbt.internal.ConfigIndex.*"),
|
||||
// Changed signature or removed something in the internal pacakge
|
||||
exclude[DirectMissingMethodProblem]("sbt.internal.*"),
|
||||
|
||||
// New and changed methods on KeyIndex. internal.
|
||||
exclude[ReversedMissingMethodProblem]("sbt.internal.KeyIndex.*"),
|
||||
exclude[DirectMissingMethodProblem]("sbt.internal.KeyIndex.*"),
|
||||
// Removed unused val. internal.
|
||||
exclude[DirectMissingMethodProblem]("sbt.internal.RelayAppender.jsonFormat"),
|
||||
// Removed unused def. internal.
|
||||
exclude[DirectMissingMethodProblem]("sbt.internal.Load.isProjectThis"),
|
||||
|
||||
// Changed signature or removed private[sbt] methods
|
||||
exclude[DirectMissingMethodProblem]("sbt.Classpaths.unmanagedLibs0"),
|
||||
exclude[DirectMissingMethodProblem]("sbt.Defaults.allTestGroupsTask"),
|
||||
exclude[DirectMissingMethodProblem]("sbt.Plugins.topologicalSort"),
|
||||
exclude[IncompatibleMethTypeProblem]("sbt.Defaults.allTestGroupsTask"),
|
||||
)
|
||||
)
|
||||
.configure(
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ object ContextUtil {
|
|||
f: (c.Expr[Any], c.Position) => c.Expr[T]): c.Expr[T] = {
|
||||
import c.universe._
|
||||
c.macroApplication match {
|
||||
case s @ Select(Apply(_, t :: Nil), tp) => f(c.Expr[Any](t), s.pos)
|
||||
case a @ Apply(_, t :: Nil) => f(c.Expr[Any](t), a.pos)
|
||||
case x => unexpectedTree(x)
|
||||
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 x => unexpectedTree(x)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
package sbt.internal.util
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
|
||||
/** A mutable set interface that uses object identity to test for set membership.*/
|
||||
trait IDSet[T] {
|
||||
def apply(t: T): Boolean
|
||||
|
|
@ -41,7 +43,7 @@ object IDSet {
|
|||
def +=(t: T) = { backing.put(t, Dummy); () }
|
||||
def ++=(t: Iterable[T]) = t foreach +=
|
||||
def -=(t: T) = if (backing.remove(t) eq null) false else true
|
||||
def all = collection.JavaConverters.collectionAsScalaIterable(backing.keySet)
|
||||
def all = backing.keySet.asScala
|
||||
def toList = all.toList
|
||||
def isEmpty = backing.isEmpty
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ sealed trait KList[+M[_]] {
|
|||
def transform[N[_]](f: M ~> N): Transform[N]
|
||||
|
||||
/** Folds this list using a function that operates on the homogeneous type of the elements of this list. */
|
||||
def foldr[B](f: (M[_], B) => B, init: B): B = init // had trouble defining it in KNil
|
||||
def foldr[B](f: (M[_], B) => B, init: B): B
|
||||
|
||||
/** Applies `f` to the elements of this list in the applicative functor defined by `ap`. */
|
||||
def apply[N[x] >: M[x], Z](f: Transform[Id] => Z)(implicit ap: Applicative[N]): N[Z]
|
||||
|
|
@ -54,13 +54,14 @@ final case class KCons[H, +T <: KList[M], +M[_]](head: M[H], tail: T) extends KL
|
|||
override def foldr[B](f: (M[_], B) => B, init: B): B = f(head, tail.foldr(f, init))
|
||||
}
|
||||
|
||||
sealed abstract class KNil extends KList[Nothing] {
|
||||
sealed abstract class KNil extends KList[NothingK] {
|
||||
final type Transform[N[_]] = KNil
|
||||
final def transform[N[_]](f: Nothing ~> N): Transform[N] = KNil
|
||||
final def transform[N[_]](f: NothingK ~> N): Transform[N] = KNil
|
||||
final def foldr[B](f: (NothingK[_], B) => B, init: B): B = init
|
||||
final def toList = Nil
|
||||
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: Nothing ~> (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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ object Signals {
|
|||
}
|
||||
|
||||
// Must only be referenced using a
|
||||
// try { } catch { case e: LinkageError => ... }
|
||||
// try { } catch { case _: LinkageError => ... }
|
||||
// block to
|
||||
private final class Signals0 {
|
||||
def supported(signal: String): Boolean = {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ package sbt.internal.util
|
|||
|
||||
trait TypeFunctions {
|
||||
type Id[X] = X
|
||||
type NothingK[X] = Nothing
|
||||
sealed trait Const[A] { type Apply[B] = A }
|
||||
sealed trait ConstK[A] { type l[L[x]] = A }
|
||||
sealed trait Compose[A[_], B[_]] { type Apply[T] = A[B[T]] }
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
package sbt.internal.util
|
||||
|
||||
import org.scalacheck._
|
||||
import Prop._
|
||||
import org.scalacheck._, Prop._
|
||||
|
||||
object SettingsTest extends Properties("settings") {
|
||||
val settingsExample: SettingsExample = SettingsExample()
|
||||
|
|
@ -160,7 +159,7 @@ object SettingsTest extends Properties("settings") {
|
|||
final def checkCircularReferences(intermediate: Int): Prop = {
|
||||
val ccr = new CCR(intermediate)
|
||||
try { evaluate(setting(chk, ccr.top) :: Nil); false } catch {
|
||||
case e: java.lang.Exception => true
|
||||
case _: java.lang.Exception => true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,18 +196,18 @@ object SettingsTest extends Properties("settings") {
|
|||
|
||||
def evaluate(settings: Seq[Setting[_]]): Settings[Scope] =
|
||||
try { make(settings)(delegates, scopeLocal, showFullKey) } catch {
|
||||
case e: Throwable => e.printStackTrace; throw e
|
||||
case e: Throwable => e.printStackTrace(); throw e
|
||||
}
|
||||
}
|
||||
// This setup is a workaround for module synchronization issues
|
||||
final class CCR(intermediate: Int) {
|
||||
import SettingsTest.settingsExample._
|
||||
lazy val top = iterate(value(intermediate), intermediate)
|
||||
def iterate(init: Initialize[Int], i: Int): Initialize[Int] =
|
||||
lazy val top = iterate(value(intermediate))
|
||||
def iterate(init: Initialize[Int]): Initialize[Int] =
|
||||
bind(init) { t =>
|
||||
if (t <= 0)
|
||||
top
|
||||
else
|
||||
iterate(value(t - 1), t - 1)
|
||||
iterate(value(t - 1))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ package complete
|
|||
|
||||
import java.lang.Character.{ toLowerCase => lower }
|
||||
|
||||
/** @author Paul Phillips*/
|
||||
/** @author Paul Phillips */
|
||||
object EditDistance {
|
||||
|
||||
/**
|
||||
|
|
@ -24,7 +24,6 @@ object EditDistance {
|
|||
insertCost: Int = 1,
|
||||
deleteCost: Int = 1,
|
||||
subCost: Int = 1,
|
||||
transposeCost: Int = 1,
|
||||
matchCost: Int = 0,
|
||||
caseCost: Int = 1,
|
||||
transpositions: Boolean = false
|
||||
|
|
|
|||
|
|
@ -11,11 +11,7 @@ package complete
|
|||
import History.number
|
||||
import java.io.File
|
||||
|
||||
final class History private (
|
||||
val lines: IndexedSeq[String],
|
||||
val path: Option[File],
|
||||
error: String => Unit
|
||||
) {
|
||||
final class History private (val lines: IndexedSeq[String], val path: Option[File]) {
|
||||
private def reversed = lines.reverse
|
||||
|
||||
def all: Seq[String] = lines
|
||||
|
|
@ -52,8 +48,8 @@ final class History private (
|
|||
}
|
||||
|
||||
object History {
|
||||
def apply(lines: Seq[String], path: Option[File], error: String => Unit): History =
|
||||
new History(lines.toIndexedSeq, path, sys.error)
|
||||
def apply(lines: Seq[String], path: Option[File]): History =
|
||||
new History(lines.toIndexedSeq, path)
|
||||
|
||||
def number(s: String): Option[Int] =
|
||||
try { Some(s.toInt) } catch { case _: NumberFormatException => None }
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ package complete
|
|||
import jline.console.ConsoleReader
|
||||
import jline.console.completer.{ Completer, CompletionHandler }
|
||||
import scala.annotation.tailrec
|
||||
import scala.collection.JavaConverters
|
||||
import scala.collection.JavaConverters._
|
||||
|
||||
object JLineCompletion {
|
||||
def installCustomCompletor(reader: ConsoleReader, parser: Parser[_]): Unit =
|
||||
|
|
@ -154,7 +154,7 @@ object JLineCompletion {
|
|||
if (line.charAt(line.length - 1) != '\n')
|
||||
reader.println()
|
||||
}
|
||||
reader.printColumns(JavaConverters.seqAsJavaList(columns.map(_.trim)))
|
||||
reader.printColumns(columns.map(_.trim).asJava)
|
||||
}
|
||||
|
||||
def hasNewline(s: String): Boolean = s.indexOf('\n') >= 0
|
||||
|
|
|
|||
|
|
@ -9,60 +9,64 @@ package sbt.internal.util
|
|||
package complete
|
||||
|
||||
import java.io.File
|
||||
import sbt.io.IO._
|
||||
import sbt.io.IO
|
||||
|
||||
class FileExamplesTest extends UnitSpec {
|
||||
|
||||
"listing all files in an absolute base directory" should
|
||||
"produce the entire base directory's contents" in {
|
||||
val _ = new DirectoryStructure {
|
||||
fileExamples().toList should contain theSameElementsAs (allRelativizedPaths)
|
||||
withDirectoryStructure() { ds =>
|
||||
ds.fileExamples().toList should contain theSameElementsAs (ds.allRelativizedPaths)
|
||||
}
|
||||
}
|
||||
|
||||
"listing files with a prefix that matches none" should
|
||||
"produce an empty list" in {
|
||||
val _ = new DirectoryStructure(withCompletionPrefix = "z") {
|
||||
fileExamples().toList shouldBe empty
|
||||
"listing files with a prefix that matches none" should "produce an empty list" in {
|
||||
withDirectoryStructure(withCompletionPrefix = "z") { ds =>
|
||||
ds.fileExamples().toList shouldBe empty
|
||||
}
|
||||
}
|
||||
|
||||
"listing single-character prefixed files" should
|
||||
"produce matching paths only" in {
|
||||
val _ = new DirectoryStructure(withCompletionPrefix = "f") {
|
||||
fileExamples().toList should contain theSameElementsAs (prefixedPathsOnly)
|
||||
"listing single-character prefixed files" should "produce matching paths only" in {
|
||||
withDirectoryStructure(withCompletionPrefix = "f") { ds =>
|
||||
ds.fileExamples().toList should contain theSameElementsAs (ds.prefixedPathsOnly)
|
||||
}
|
||||
}
|
||||
|
||||
"listing directory-prefixed files" should
|
||||
"produce matching paths only" in {
|
||||
val _ = new DirectoryStructure(withCompletionPrefix = "far") {
|
||||
fileExamples().toList should contain theSameElementsAs (prefixedPathsOnly)
|
||||
"listing directory-prefixed files" should "produce matching paths only" in {
|
||||
withDirectoryStructure(withCompletionPrefix = "far") { ds =>
|
||||
ds.fileExamples().toList should contain theSameElementsAs (ds.prefixedPathsOnly)
|
||||
}
|
||||
}
|
||||
|
||||
it should "produce sub-dir contents only when appending a file separator to the directory" in {
|
||||
val _ = new DirectoryStructure(withCompletionPrefix = "far" + File.separator) {
|
||||
fileExamples().toList should contain theSameElementsAs (prefixedPathsOnly)
|
||||
withDirectoryStructure(withCompletionPrefix = "far" + File.separator) { ds =>
|
||||
ds.fileExamples().toList should contain theSameElementsAs (ds.prefixedPathsOnly)
|
||||
}
|
||||
}
|
||||
|
||||
"listing files with a sub-path prefix" should
|
||||
"produce matching paths only" in {
|
||||
val _ = new DirectoryStructure(withCompletionPrefix = "far" + File.separator + "ba") {
|
||||
fileExamples().toList should contain theSameElementsAs (prefixedPathsOnly)
|
||||
"listing files with a sub-path prefix" should "produce matching paths only" in {
|
||||
withDirectoryStructure(withCompletionPrefix = "far" + File.separator + "ba") { ds =>
|
||||
ds.fileExamples().toList should contain theSameElementsAs (ds.prefixedPathsOnly)
|
||||
}
|
||||
}
|
||||
|
||||
"completing a full path" should
|
||||
"produce a list with an empty string" in {
|
||||
val _ = new DirectoryStructure(withCompletionPrefix = "bazaar") {
|
||||
fileExamples().toList shouldEqual List("")
|
||||
"completing a full path" should "produce a list with an empty string" in {
|
||||
withDirectoryStructure(withCompletionPrefix = "bazaar") { ds =>
|
||||
ds.fileExamples().toList shouldEqual List("")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove DelayedInit - https://github.com/scala/scala/releases/tag/v2.11.0-RC1
|
||||
class DirectoryStructure(withCompletionPrefix: String = "") extends DelayedInit {
|
||||
def withDirectoryStructure[A](withCompletionPrefix: String = "")(
|
||||
thunk: DirectoryStructure => A): Unit = {
|
||||
IO.withTemporaryDirectory { tempDir =>
|
||||
val ds = new DirectoryStructure(withCompletionPrefix)
|
||||
ds.createSampleDirStructure(tempDir)
|
||||
ds.fileExamples = new FileExamples(ds.baseDir, withCompletionPrefix)
|
||||
thunk(ds)
|
||||
}
|
||||
}
|
||||
|
||||
final class DirectoryStructure(withCompletionPrefix: String) {
|
||||
var fileExamples: FileExamples = _
|
||||
var baseDir: File = _
|
||||
var childFiles: List[File] = _
|
||||
|
|
@ -72,22 +76,14 @@ class FileExamplesTest extends UnitSpec {
|
|||
|
||||
def allRelativizedPaths: List[String] =
|
||||
(childFiles ++ childDirectories ++ nestedFiles ++ nestedDirectories)
|
||||
.map(relativize(baseDir, _).get)
|
||||
.map(IO.relativize(baseDir, _).get)
|
||||
|
||||
def prefixedPathsOnly: List[String] =
|
||||
allRelativizedPaths
|
||||
.filter(_ startsWith withCompletionPrefix)
|
||||
.map(_ substring withCompletionPrefix.length)
|
||||
|
||||
override def delayedInit(testBody: => Unit): Unit = {
|
||||
withTemporaryDirectory { tempDir =>
|
||||
createSampleDirStructure(tempDir)
|
||||
fileExamples = new FileExamples(baseDir, withCompletionPrefix)
|
||||
testBody
|
||||
}
|
||||
}
|
||||
|
||||
private def createSampleDirStructure(tempDir: File): Unit = {
|
||||
def createSampleDirStructure(tempDir: File): Unit = {
|
||||
childFiles = toChildFiles(tempDir, List("foo", "bar", "bazaar"))
|
||||
childDirectories = toChildFiles(tempDir, List("moo", "far"))
|
||||
nestedFiles = toChildFiles(childDirectories(1), List("farfile1", "barfile2"))
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@ object LogicTest extends Properties("Logic") {
|
|||
property("Properly orders results.") = secure(expect(ordering, Set(B, A, C, E, F)))
|
||||
property("Detects cyclic negation") = secure(
|
||||
Logic.reduceAll(badClauses, Set()) match {
|
||||
case Right(res) => false
|
||||
case Left(err: Logic.CyclicNegation) => true
|
||||
case Left(err) => sys.error(s"Expected cyclic error, got: $err")
|
||||
case Right(_) => false
|
||||
case Left(_: Logic.CyclicNegation) => true
|
||||
case Left(err) => sys.error(s"Expected cyclic error, got: $err")
|
||||
}
|
||||
)
|
||||
|
||||
def expect(result: Either[LogicException, Matched], expected: Set[Atom]) = result match {
|
||||
case Left(err) => false
|
||||
case Left(_) => false
|
||||
case Right(res) =>
|
||||
val actual = res.provenSet
|
||||
if (actual != expected)
|
||||
|
|
|
|||
|
|
@ -10,10 +10,6 @@ package sbt
|
|||
import java.io.File
|
||||
import sbt.internal.inc.AnalyzingCompiler
|
||||
|
||||
import Predef.{ conforms => _, _ }
|
||||
import sbt.io.syntax._
|
||||
import sbt.io.IO
|
||||
|
||||
import sbt.util.CacheStoreFactory
|
||||
import xsbti.Reporter
|
||||
import xsbti.compile.JavaTools
|
||||
|
|
@ -23,10 +19,12 @@ import sbt.internal.util.ManagedLogger
|
|||
|
||||
object Doc {
|
||||
import RawCompileLike._
|
||||
|
||||
def scaladoc(label: String,
|
||||
cacheStoreFactory: CacheStoreFactory,
|
||||
compiler: AnalyzingCompiler): Gen =
|
||||
scaladoc(label, cacheStoreFactory, compiler, Seq())
|
||||
|
||||
def scaladoc(label: String,
|
||||
cacheStoreFactory: CacheStoreFactory,
|
||||
compiler: AnalyzingCompiler,
|
||||
|
|
@ -34,82 +32,32 @@ object Doc {
|
|||
cached(cacheStoreFactory,
|
||||
fileInputOptions,
|
||||
prepare(label + " Scala API documentation", compiler.doc))
|
||||
def javadoc(label: String,
|
||||
cacheStoreFactory: CacheStoreFactory,
|
||||
doc: JavaTools,
|
||||
log: Logger,
|
||||
reporter: Reporter): Gen =
|
||||
javadoc(label, cacheStoreFactory, doc, log, reporter, Seq())
|
||||
def javadoc(label: String,
|
||||
cacheStoreFactory: CacheStoreFactory,
|
||||
doc: JavaTools,
|
||||
log: Logger,
|
||||
reporter: Reporter,
|
||||
fileInputOptions: Seq[String]): Gen =
|
||||
cached(
|
||||
cacheStoreFactory,
|
||||
fileInputOptions,
|
||||
prepare(
|
||||
label + " Java API documentation",
|
||||
filterSources(
|
||||
javaSourcesOnly,
|
||||
(sources: Seq[File],
|
||||
classpath: Seq[File],
|
||||
outputDirectory: File,
|
||||
options: Seq[String],
|
||||
maxErrors: Int,
|
||||
log: Logger) => {
|
||||
// doc.doc
|
||||
???
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@deprecated("Going away", "1.1.1")
|
||||
def javadoc(
|
||||
label: String,
|
||||
cacheStoreFactory: CacheStoreFactory,
|
||||
doc: JavaTools,
|
||||
log: Logger,
|
||||
reporter: Reporter,
|
||||
): Gen = ???
|
||||
|
||||
@deprecated("Going away", "1.1.1")
|
||||
def javadoc(
|
||||
label: String,
|
||||
cacheStoreFactory: CacheStoreFactory,
|
||||
doc: JavaTools,
|
||||
log: Logger,
|
||||
reporter: Reporter,
|
||||
fileInputOptions: Seq[String],
|
||||
): Gen = ???
|
||||
|
||||
@deprecated("Going away", "1.1.1")
|
||||
val javaSourcesOnly: File => Boolean = _.getName.endsWith(".java")
|
||||
|
||||
private[sbt] final class Scaladoc(maximumErrors: Int, compiler: AnalyzingCompiler) extends Doc {
|
||||
def apply(label: String,
|
||||
sources: Seq[File],
|
||||
classpath: Seq[File],
|
||||
outputDirectory: File,
|
||||
options: Seq[String],
|
||||
log: ManagedLogger): Unit = {
|
||||
generate("Scala",
|
||||
label,
|
||||
compiler.doc,
|
||||
sources,
|
||||
classpath,
|
||||
outputDirectory,
|
||||
options,
|
||||
maximumErrors,
|
||||
log)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@deprecated("Going away", "1.1.1")
|
||||
sealed trait Doc {
|
||||
@deprecated("Going away", "1.1.1")
|
||||
type Gen = (Seq[File], Seq[File], File, Seq[String], Int, ManagedLogger) => Unit
|
||||
|
||||
private[sbt] final def generate(variant: String,
|
||||
label: String,
|
||||
docf: Gen,
|
||||
sources: Seq[File],
|
||||
classpath: Seq[File],
|
||||
outputDirectory: File,
|
||||
options: Seq[String],
|
||||
maxErrors: Int,
|
||||
log: ManagedLogger): Unit = {
|
||||
val logSnip = variant + " API documentation"
|
||||
if (sources.isEmpty)
|
||||
log.info("No sources available, skipping " + logSnip + "...")
|
||||
else {
|
||||
log.info(
|
||||
"Generating " + logSnip + " for " + label + " sources to " + outputDirectory.absolutePath + "...")
|
||||
IO.delete(outputDirectory)
|
||||
IO.createDirectory(outputDirectory)
|
||||
docf(sources, classpath, outputDirectory, options, maxErrors, log)
|
||||
log.info(logSnip + " generation successful.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import sbt.io.IO
|
|||
import sbt.util.Logger
|
||||
import sbt.ConcurrentRestrictions.Tag
|
||||
import sbt.protocol.testing._
|
||||
import sbt.internal.util.ConsoleAppender
|
||||
|
||||
private[sbt] object ForkTests {
|
||||
def apply(runners: Map[TestFramework, Runner],
|
||||
|
|
@ -78,7 +79,7 @@ private[sbt] object ForkTests {
|
|||
val is = new ObjectInputStream(socket.getInputStream)
|
||||
|
||||
try {
|
||||
val config = new ForkConfiguration(log.ansiCodesSupported, parallel)
|
||||
val config = new ForkConfiguration(ConsoleAppender.formatEnabledInEnv, parallel)
|
||||
os.writeObject(config)
|
||||
|
||||
val taskdefs = opts.tests.map(
|
||||
|
|
|
|||
|
|
@ -100,10 +100,18 @@ object Package {
|
|||
org: String,
|
||||
orgName: String): PackageOption = {
|
||||
import Attributes.Name._
|
||||
val attribKeys = Seq(IMPLEMENTATION_TITLE,
|
||||
IMPLEMENTATION_VERSION,
|
||||
IMPLEMENTATION_VENDOR,
|
||||
IMPLEMENTATION_VENDOR_ID)
|
||||
|
||||
// The ones in Attributes.Name are deprecated saying:
|
||||
// "Extension mechanism will be removed in a future release. Use class path instead."
|
||||
val IMPLEMENTATION_VENDOR_ID = new Attributes.Name("Implementation-Vendor-Id")
|
||||
val IMPLEMENTATION_URL = new Attributes.Name("Implementation-URL")
|
||||
|
||||
val attribKeys = Seq(
|
||||
IMPLEMENTATION_TITLE,
|
||||
IMPLEMENTATION_VERSION,
|
||||
IMPLEMENTATION_VENDOR,
|
||||
IMPLEMENTATION_VENDOR_ID,
|
||||
)
|
||||
val attribVals = Seq(name, version, orgName, org)
|
||||
ManifestAttributes((attribKeys zip attribVals) ++ {
|
||||
homepage map (h => (IMPLEMENTATION_URL, h.toString))
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
package sbt
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import java.io.File
|
||||
import sbt.internal.inc.{ RawCompiler, ScalaInstance }
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ object RawCompileLike {
|
|||
type Gen = (Seq[File], Seq[File], File, Seq[String], Int, ManagedLogger) => Unit
|
||||
|
||||
private def optionFiles(options: Seq[String], fileInputOpts: Seq[String]): List[File] = {
|
||||
@annotation.tailrec
|
||||
@tailrec
|
||||
def loop(opt: List[String], result: List[File]): List[File] = {
|
||||
opt.dropWhile(!fileInputOpts.contains(_)) match {
|
||||
case List(_, fileOpt, tail @ _*) => {
|
||||
|
|
@ -46,6 +47,7 @@ object RawCompileLike {
|
|||
|
||||
def cached(cacheStoreFactory: CacheStoreFactory, doCompile: Gen): Gen =
|
||||
cached(cacheStoreFactory, Seq(), doCompile)
|
||||
|
||||
def cached(cacheStoreFactory: CacheStoreFactory,
|
||||
fileInputOpts: Seq[String],
|
||||
doCompile: Gen): Gen =
|
||||
|
|
@ -67,6 +69,7 @@ object RawCompileLike {
|
|||
}
|
||||
cachedComp(inputs)(exists(outputDirectory.allPaths.get.toSet))
|
||||
}
|
||||
|
||||
def prepare(description: String, doCompile: Gen): Gen =
|
||||
(sources, classpath, outputDirectory, options, maxErrors, log) => {
|
||||
if (sources.isEmpty)
|
||||
|
|
@ -79,20 +82,22 @@ object RawCompileLike {
|
|||
log.info(description.capitalize + " successful.")
|
||||
}
|
||||
}
|
||||
|
||||
def filterSources(f: File => Boolean, doCompile: Gen): Gen =
|
||||
(sources, classpath, outputDirectory, options, maxErrors, log) =>
|
||||
doCompile(sources filter f, classpath, outputDirectory, options, maxErrors, log)
|
||||
|
||||
def rawCompile(instance: ScalaInstance, cpOptions: ClasspathOptions): Gen =
|
||||
(sources, classpath, outputDirectory, options, maxErrors, log) => {
|
||||
(sources, classpath, outputDirectory, options, _, log) => {
|
||||
val compiler = new RawCompiler(instance, cpOptions, log)
|
||||
compiler(sources, classpath, outputDirectory, options)
|
||||
}
|
||||
|
||||
def compile(label: String,
|
||||
cacheStoreFactory: CacheStoreFactory,
|
||||
instance: ScalaInstance,
|
||||
cpOptions: ClasspathOptions): Gen =
|
||||
cached(cacheStoreFactory, prepare(label + " sources", rawCompile(instance, cpOptions)))
|
||||
|
||||
val nop: Gen = (sources, classpath, outputDirectory, options, maxErrors, log) => ()
|
||||
val nop: Gen = (_, _, _, _, _, _) => ()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,10 +30,18 @@ import sjsonnew.{ Builder, JsonFormat, Unbuilder, deserializationError }
|
|||
* It is safe to use for its intended purpose: copying resources to a class output directory.
|
||||
*/
|
||||
object Sync {
|
||||
def apply(store: CacheStore,
|
||||
inStyle: FileInfo.Style = FileInfo.lastModified,
|
||||
outStyle: FileInfo.Style = FileInfo.exists)
|
||||
: Traversable[(File, File)] => Relation[File, File] =
|
||||
@deprecated("Use sync, which doesn't take the unused outStyle param", "1.1.1")
|
||||
def apply(
|
||||
store: CacheStore,
|
||||
inStyle: FileInfo.Style = FileInfo.lastModified,
|
||||
outStyle: FileInfo.Style = FileInfo.exists,
|
||||
): Traversable[(File, File)] => Relation[File, File] =
|
||||
sync(store, inStyle)
|
||||
|
||||
def sync(
|
||||
store: CacheStore,
|
||||
inStyle: FileInfo.Style = FileInfo.lastModified,
|
||||
): Traversable[(File, File)] => Relation[File, File] =
|
||||
mappings => {
|
||||
val relation = Relation.empty ++ mappings
|
||||
noDuplicateTargets(relation)
|
||||
|
|
@ -70,13 +78,9 @@ object Sync {
|
|||
}
|
||||
|
||||
def noDuplicateTargets(relation: Relation[File, File]): Unit = {
|
||||
val dups = relation.reverseMap.filter {
|
||||
case (_, srcs) =>
|
||||
srcs.size >= 2 && srcs.exists(!_.isDirectory)
|
||||
} map {
|
||||
case (target, srcs) =>
|
||||
"\n\t" + target + "\nfrom\n\t" + srcs.mkString("\n\t\t")
|
||||
}
|
||||
val dups = relation.reverseMap
|
||||
.filter { case (_, srcs) => srcs.size >= 2 && srcs.exists(!_.isDirectory) }
|
||||
.map { case (target, srcs) => "\n\t" + target + "\nfrom\n\t" + srcs.mkString("\n\t\t") }
|
||||
if (dups.nonEmpty)
|
||||
sys.error("Duplicate mappings:" + dups.mkString)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,17 +133,20 @@ object TestResultLogger {
|
|||
failuresCount,
|
||||
ignoredCount,
|
||||
canceledCount,
|
||||
pendingCount) =
|
||||
pendingCount,
|
||||
) =
|
||||
results.events.foldLeft((0, 0, 0, 0, 0, 0, 0)) {
|
||||
case ((skippedAcc, errorAcc, passedAcc, failureAcc, ignoredAcc, canceledAcc, pendingAcc),
|
||||
(name @ _, testEvent)) =>
|
||||
case (acc, (_, testEvent)) =>
|
||||
val (skippedAcc, errorAcc, passedAcc, failureAcc, ignoredAcc, canceledAcc, pendingAcc) =
|
||||
acc
|
||||
(skippedAcc + testEvent.skippedCount,
|
||||
errorAcc + testEvent.errorCount,
|
||||
passedAcc + testEvent.passedCount,
|
||||
failureAcc + testEvent.failureCount,
|
||||
ignoredAcc + testEvent.ignoredCount,
|
||||
canceledAcc + testEvent.canceledCount,
|
||||
pendingAcc + testEvent.pendingCount)
|
||||
pendingAcc + testEvent.pendingCount,
|
||||
)
|
||||
}
|
||||
val totalCount = failuresCount + errorsCount + skippedCount + passedCount
|
||||
val base =
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import sbt.util.Logger
|
|||
import sbt.protocol.testing.TestResult
|
||||
|
||||
sealed trait TestOption
|
||||
|
||||
object Tests {
|
||||
|
||||
/**
|
||||
|
|
@ -227,7 +228,7 @@ object Tests {
|
|||
if (config.parallel)
|
||||
makeParallel(loader, runnables, setupTasks, config.tags) //.toSeq.join
|
||||
else
|
||||
makeSerial(loader, runnables, setupTasks, config.tags)
|
||||
makeSerial(loader, runnables, setupTasks)
|
||||
val taggedMainTasks = mainTasks.tagw(config.tags: _*)
|
||||
taggedMainTasks map processResults flatMap { results =>
|
||||
val cleanupTasks = fj(partApp(userCleanup) :+ frameworkCleanup(results.overall))
|
||||
|
|
@ -294,10 +295,20 @@ object Tests {
|
|||
}
|
||||
}
|
||||
|
||||
def makeSerial(loader: ClassLoader,
|
||||
runnables: Seq[TestRunnable],
|
||||
setupTasks: Task[Unit],
|
||||
tags: Seq[(Tag, Int)]): Task[List[(String, SuiteResult)]] = {
|
||||
@deprecated("Use the variant without tags", "1.1.1")
|
||||
def makeSerial(
|
||||
loader: ClassLoader,
|
||||
runnables: Seq[TestRunnable],
|
||||
setupTasks: Task[Unit],
|
||||
tags: Seq[(Tag, Int)],
|
||||
): Task[List[(String, SuiteResult)]] =
|
||||
makeSerial(loader, runnables, setupTasks)
|
||||
|
||||
def makeSerial(
|
||||
loader: ClassLoader,
|
||||
runnables: Seq[TestRunnable],
|
||||
setupTasks: Task[Unit],
|
||||
): Task[List[(String, SuiteResult)]] = {
|
||||
@tailrec
|
||||
def processRunnable(runnableList: List[TestRunnable],
|
||||
acc: List[(String, SuiteResult)]): List[(String, SuiteResult)] =
|
||||
|
|
|
|||
|
|
@ -94,10 +94,13 @@ object BasicCommands {
|
|||
}
|
||||
|
||||
def completionsCommand: Command =
|
||||
Command(CompletionsCommand, CompletionsBrief, CompletionsDetailed)(completionsParser)(
|
||||
Command(CompletionsCommand, CompletionsBrief, CompletionsDetailed)(_ => completionsParser)(
|
||||
runCompletions(_)(_))
|
||||
|
||||
def completionsParser(state: State): Parser[String] = {
|
||||
@deprecated("No longer public", "1.1.1")
|
||||
def completionsParser(state: State): Parser[String] = completionsParser
|
||||
|
||||
private[this] def completionsParser: Parser[String] = {
|
||||
val notQuoted = (NotQuoted ~ any.*) map { case (nq, s) => nq ++ s }
|
||||
val quotedOrUnquotedSingleArgument = Space ~> (StringVerbatim | StringEscapable | notQuoted)
|
||||
token(quotedOrUnquotedSingleArgument ?? "" examples ("", " "))
|
||||
|
|
@ -175,19 +178,19 @@ object BasicCommands {
|
|||
}
|
||||
|
||||
def reboot: Command =
|
||||
Command(RebootCommand, Help.more(RebootCommand, RebootDetailed))(rebootOptionParser) {
|
||||
Command(RebootCommand, Help.more(RebootCommand, RebootDetailed))(_ => rebootOptionParser) {
|
||||
case (s, (full, currentOnly)) =>
|
||||
s.reboot(full, currentOnly)
|
||||
}
|
||||
|
||||
@deprecated("Use rebootOptionParser", "1.1.0")
|
||||
def rebootParser(s: State): Parser[Boolean] =
|
||||
rebootOptionParser(s) map { case (full, currentOnly) => full }
|
||||
def rebootParser(s: State): Parser[Boolean] = rebootOptionParser map { case (full, _) => full }
|
||||
|
||||
private[sbt] def rebootOptionParser(s: State): Parser[(Boolean, Boolean)] =
|
||||
token(
|
||||
Space ~> (("full" ^^^ ((true, false))) |
|
||||
("dev" ^^^ ((false, true))))) ?? ((false, false))
|
||||
private[sbt] def rebootOptionParser: Parser[(Boolean, Boolean)] = {
|
||||
val fullOption = "full" ^^^ ((true, false))
|
||||
val devOption = "dev" ^^^ ((false, true))
|
||||
token(Space ~> (fullOption | devOption)) ?? ((false, false))
|
||||
}
|
||||
|
||||
def call: Command =
|
||||
Command(ApplyCommand, Help.more(ApplyCommand, ApplyDetailed))(_ => callParser) {
|
||||
|
|
@ -236,10 +239,9 @@ object BasicCommands {
|
|||
|
||||
def historyParser(s: State): Parser[() => State] =
|
||||
Command.applyEffect(HistoryCommands.actionParser) { histFun =>
|
||||
val logError = (msg: String) => s.log.error(msg)
|
||||
val hp = s get historyPath getOrElse None
|
||||
val hp = (s get historyPath).flatten
|
||||
val lines = hp.toList.flatMap(p => IO.readLines(p)).toIndexedSeq
|
||||
histFun(CHistory(lines, hp, logError)) match {
|
||||
histFun(CHistory(lines, hp)) match {
|
||||
case Some(commands) =>
|
||||
commands foreach println //printing is more appropriate than logging
|
||||
(commands ::: s).continue
|
||||
|
|
|
|||
|
|
@ -178,15 +178,16 @@ object Command {
|
|||
bs map (b => (b, distance(a, b))) filter (_._2 <= maxDistance) sortBy (_._2) take (maxSuggestions) map (_._1)
|
||||
|
||||
def distance(a: String, b: String): Int =
|
||||
EditDistance.levenshtein(a,
|
||||
b,
|
||||
insertCost = 1,
|
||||
deleteCost = 1,
|
||||
subCost = 2,
|
||||
transposeCost = 1,
|
||||
matchCost = -1,
|
||||
caseCost = 1,
|
||||
transpositions = true)
|
||||
EditDistance.levenshtein(
|
||||
a,
|
||||
b,
|
||||
insertCost = 1,
|
||||
deleteCost = 1,
|
||||
subCost = 2,
|
||||
matchCost = -1,
|
||||
caseCost = 1,
|
||||
transpositions = true
|
||||
)
|
||||
|
||||
def spacedAny(name: String): Parser[String] = spacedC(name, any)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ import scala.util.Properties
|
|||
|
||||
trait Watched {
|
||||
|
||||
/** The files watched when an action is run with a preceeding ~ */
|
||||
def watchSources(s: State): Seq[Watched.WatchSource] = Nil
|
||||
/** The files watched when an action is run with a proceeding ~ */
|
||||
def watchSources(@deprecated("unused", "") s: State): Seq[Watched.WatchSource] = Nil
|
||||
def terminateWatch(key: Int): Boolean = Watched.isEnter(key)
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ private[sbt] final class ConsoleChannel(val name: String) extends CommandChannel
|
|||
case _ =>
|
||||
val x = makeAskUserThread(e.state)
|
||||
askUserThread = Some(x)
|
||||
x.start
|
||||
x.start()
|
||||
}
|
||||
case e: ConsoleUnpromptEvent =>
|
||||
e.lastSource match {
|
||||
|
|
@ -70,7 +70,7 @@ private[sbt] final class ConsoleChannel(val name: String) extends CommandChannel
|
|||
def shutdown(): Unit =
|
||||
askUserThread match {
|
||||
case Some(x) if x.isAlive =>
|
||||
x.interrupt
|
||||
x.interrupt()
|
||||
askUserThread = None
|
||||
case _ => ()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,30 +38,44 @@ object Def extends Init[Scope] with TaskMacroExtra {
|
|||
def showFullKey(keyNameColor: Option[String]): Show[ScopedKey[_]] =
|
||||
Show[ScopedKey[_]]((key: ScopedKey[_]) => displayFull(key, keyNameColor))
|
||||
|
||||
@deprecated("Use showRelativeKey2 which doesn't take the unused multi param", "1.1.1")
|
||||
def showRelativeKey(
|
||||
current: ProjectRef,
|
||||
multi: Boolean,
|
||||
keyNameColor: Option[String] = None
|
||||
): Show[ScopedKey[_]] =
|
||||
Show[ScopedKey[_]](
|
||||
key =>
|
||||
Scope.display(
|
||||
key.scope,
|
||||
withColor(key.key.label, keyNameColor),
|
||||
ref => displayRelative(current, multi, ref)
|
||||
))
|
||||
showRelativeKey2(current, keyNameColor)
|
||||
|
||||
def showBuildRelativeKey(
|
||||
currentBuild: URI,
|
||||
multi: Boolean,
|
||||
keyNameColor: Option[String] = None
|
||||
def showRelativeKey2(
|
||||
current: ProjectRef,
|
||||
keyNameColor: Option[String] = None,
|
||||
): Show[ScopedKey[_]] =
|
||||
Show[ScopedKey[_]](
|
||||
key =>
|
||||
Scope.display(
|
||||
key.scope,
|
||||
withColor(key.key.label, keyNameColor),
|
||||
ref => displayBuildRelative(currentBuild, multi, ref)
|
||||
ref => displayRelative2(current, ref)
|
||||
))
|
||||
|
||||
@deprecated("Use showBuildRelativeKey2 which doesn't take the unused multi param", "1.1.1")
|
||||
def showBuildRelativeKey(
|
||||
currentBuild: URI,
|
||||
multi: Boolean,
|
||||
keyNameColor: Option[String] = None,
|
||||
): Show[ScopedKey[_]] =
|
||||
showBuildRelativeKey2(currentBuild, keyNameColor)
|
||||
|
||||
def showBuildRelativeKey2(
|
||||
currentBuild: URI,
|
||||
keyNameColor: Option[String] = None,
|
||||
): Show[ScopedKey[_]] =
|
||||
Show[ScopedKey[_]](
|
||||
key =>
|
||||
Scope.display(
|
||||
key.scope,
|
||||
withColor(key.key.label, keyNameColor),
|
||||
ref => displayBuildRelative(currentBuild, ref)
|
||||
))
|
||||
|
||||
/**
|
||||
|
|
@ -71,8 +85,11 @@ object Def extends Init[Scope] with TaskMacroExtra {
|
|||
def displayRelativeReference(current: ProjectRef, project: Reference): String =
|
||||
displayRelative(current, project, false)
|
||||
|
||||
@deprecated("Use displayRelativeReference", "1.1.0")
|
||||
@deprecated("Use displayRelative2 which doesn't take the unused multi param", "1.1.1")
|
||||
def displayRelative(current: ProjectRef, multi: Boolean, project: Reference): String =
|
||||
displayRelative2(current, project)
|
||||
|
||||
def displayRelative2(current: ProjectRef, project: Reference): String =
|
||||
displayRelative(current, project, true)
|
||||
|
||||
/**
|
||||
|
|
@ -91,7 +108,11 @@ object Def extends Init[Scope] with TaskMacroExtra {
|
|||
}
|
||||
}
|
||||
|
||||
@deprecated("Use variant without multi", "1.1.1")
|
||||
def displayBuildRelative(currentBuild: URI, multi: Boolean, project: Reference): String =
|
||||
displayBuildRelative(currentBuild, project)
|
||||
|
||||
def displayBuildRelative(currentBuild: URI, project: Reference): String =
|
||||
project match {
|
||||
case BuildRef(`currentBuild`) => "ThisBuild /"
|
||||
case ProjectRef(`currentBuild`, x) => x + " /"
|
||||
|
|
@ -173,16 +194,31 @@ object Def extends Init[Scope] with TaskMacroExtra {
|
|||
// The following conversions enable the types Initialize[T], Initialize[Task[T]], and Task[T] to
|
||||
// be used in task and setting macros as inputs with an ultimate result of type T
|
||||
|
||||
implicit def macroValueI[T](in: Initialize[T]): MacroValue[T] = ???
|
||||
implicit def macroValueIT[T](in: Initialize[Task[T]]): MacroValue[T] = ???
|
||||
implicit def macroValueIInT[T](in: Initialize[InputTask[T]]): InputEvaluated[T] = ???
|
||||
implicit def taskMacroValueIT[T](in: Initialize[Task[T]]): MacroTaskValue[T] = ???
|
||||
implicit def macroPrevious[T](in: TaskKey[T]): MacroPrevious[T] = ???
|
||||
implicit def macroValueI[T](@deprecated("unused", "") in: Initialize[T]): MacroValue[T] = ???
|
||||
|
||||
// The following conversions enable the types Parser[T], Initialize[Parser[T]], and Initialize[State => Parser[T]] to
|
||||
// be used in the inputTask macro as an input with an ultimate result of type T
|
||||
implicit def parserInitToInput[T](p: Initialize[Parser[T]]): ParserInput[T] = ???
|
||||
implicit def parserInitStateToInput[T](p: Initialize[State => Parser[T]]): ParserInput[T] = ???
|
||||
implicit def macroValueIT[T](@deprecated("unused", "") in: Initialize[Task[T]]): MacroValue[T] =
|
||||
???
|
||||
|
||||
implicit def macroValueIInT[T](
|
||||
@deprecated("unused", "") in: Initialize[InputTask[T]]
|
||||
): InputEvaluated[T] = ???
|
||||
|
||||
implicit def taskMacroValueIT[T](
|
||||
@deprecated("unused", "") in: Initialize[Task[T]]
|
||||
): MacroTaskValue[T] = ???
|
||||
|
||||
implicit def macroPrevious[T](@deprecated("unused", "") in: TaskKey[T]): MacroPrevious[T] = ???
|
||||
|
||||
// The following conversions enable the types Parser[T], Initialize[Parser[T]], and
|
||||
// Initialize[State => Parser[T]] to be used in the inputTask macro as an input with an ultimate
|
||||
// result of type T
|
||||
implicit def parserInitToInput[T](
|
||||
@deprecated("unused", "") p: Initialize[Parser[T]]
|
||||
): ParserInput[T] = ???
|
||||
|
||||
implicit def parserInitStateToInput[T](
|
||||
@deprecated("unused", "") p: Initialize[State => Parser[T]]
|
||||
): ParserInput[T] = ???
|
||||
|
||||
def settingKey[T](description: String): SettingKey[T] = macro std.KeyMacro.settingKeyImpl[T]
|
||||
def taskKey[T](description: String): TaskKey[T] = macro std.KeyMacro.taskKeyImpl[T]
|
||||
|
|
@ -190,27 +226,40 @@ object Def extends Init[Scope] with TaskMacroExtra {
|
|||
|
||||
private[sbt] def dummy[T: Manifest](name: String, description: String): (TaskKey[T], Task[T]) =
|
||||
(TaskKey[T](name, description, DTask), dummyTask(name))
|
||||
|
||||
private[sbt] def dummyTask[T](name: String): Task[T] = {
|
||||
import std.TaskExtra.{ task => newTask, _ }
|
||||
val base: Task[T] = newTask(
|
||||
sys.error("Dummy task '" + name + "' did not get converted to a full task.")) named name
|
||||
base.copy(info = base.info.set(isDummyTask, true))
|
||||
}
|
||||
|
||||
private[sbt] def isDummy(t: Task[_]): Boolean =
|
||||
t.info.attributes.get(isDummyTask) getOrElse false
|
||||
|
||||
private[sbt] val isDummyTask = AttributeKey[Boolean](
|
||||
"is-dummy-task",
|
||||
"Internal: used to identify dummy tasks. sbt injects values for these tasks at the start of task execution.",
|
||||
Invisible)
|
||||
|
||||
private[sbt] val (stateKey, dummyState) = dummy[State]("state", "Current build state.")
|
||||
|
||||
private[sbt] val (streamsManagerKey, dummyStreamsManager) = Def.dummy[std.Streams[ScopedKey[_]]](
|
||||
"streams-manager",
|
||||
"Streams manager, which provides streams for different contexts.")
|
||||
}
|
||||
// these need to be mixed into the sbt package object because the target doesn't involve Initialize or anything in Def
|
||||
|
||||
// these need to be mixed into the sbt package object
|
||||
// because the target doesn't involve Initialize or anything in Def
|
||||
trait TaskMacroExtra {
|
||||
implicit def macroValueT[T](in: Task[T]): std.MacroValue[T] = ???
|
||||
implicit def macroValueIn[T](in: InputTask[T]): std.InputEvaluated[T] = ???
|
||||
implicit def parserToInput[T](in: Parser[T]): std.ParserInput[T] = ???
|
||||
implicit def stateParserToInput[T](in: State => Parser[T]): std.ParserInput[T] = ???
|
||||
implicit def macroValueT[T](@deprecated("unused", "") in: Task[T]): std.MacroValue[T] = ???
|
||||
|
||||
implicit def macroValueIn[T](@deprecated("unused", "") in: InputTask[T]): std.InputEvaluated[T] =
|
||||
???
|
||||
|
||||
implicit def parserToInput[T](@deprecated("unused", "") in: Parser[T]): std.ParserInput[T] = ???
|
||||
|
||||
implicit def stateParserToInput[T](
|
||||
@deprecated("unused", "") in: State => Parser[T]
|
||||
): std.ParserInput[T] = ???
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,8 +49,13 @@ object InputTask {
|
|||
)
|
||||
}
|
||||
|
||||
implicit def inputTaskParsed[T](in: InputTask[T]): std.ParserInputTask[T] = ???
|
||||
implicit def inputTaskInitParsed[T](in: Initialize[InputTask[T]]): std.ParserInputTask[T] = ???
|
||||
implicit def inputTaskParsed[T](
|
||||
@deprecated("unused", "") in: InputTask[T]
|
||||
): std.ParserInputTask[T] = ???
|
||||
|
||||
implicit def inputTaskInitParsed[T](
|
||||
@deprecated("unused", "") in: Initialize[InputTask[T]]
|
||||
): std.ParserInputTask[T] = ???
|
||||
|
||||
def make[T](p: State => Parser[Task[T]]): InputTask[T] = new InputTask[T](p)
|
||||
|
||||
|
|
|
|||
|
|
@ -201,23 +201,6 @@ object Scope {
|
|||
if (s == "") ""
|
||||
else s + " "
|
||||
|
||||
// sbt 0.12 style
|
||||
def display012StyleMasked(scope: Scope,
|
||||
sep: String,
|
||||
showProject: Reference => String,
|
||||
mask: ScopeMask): String = {
|
||||
import scope.{ project, config, task, extra }
|
||||
val configPrefix = config.foldStrict(displayConfigKey012Style, "*:", ".:")
|
||||
val taskPrefix = task.foldStrict(_.label + "::", "", ".::")
|
||||
val extras = extra.foldStrict(_.entries.map(_.toString).toList, Nil, Nil)
|
||||
val postfix = if (extras.isEmpty) "" else extras.mkString("(", ", ", ")")
|
||||
mask.concatShow(projectPrefix012Style(project, showProject012Style),
|
||||
configPrefix,
|
||||
taskPrefix,
|
||||
sep,
|
||||
postfix)
|
||||
}
|
||||
|
||||
def equal(a: Scope, b: Scope, mask: ScopeMask): Boolean =
|
||||
(!mask.project || a.project == b.project) &&
|
||||
(!mask.config || a.config == b.config) &&
|
||||
|
|
@ -241,7 +224,7 @@ object Scope {
|
|||
(parts.take(1) ++ parts.drop(1).map(_.capitalize)).mkString
|
||||
}
|
||||
|
||||
// *Inherit functions should be immediate delegates and not include argument itself. Transitivity will be provided by this method
|
||||
@deprecated("Use variant without extraInherit", "1.1.1")
|
||||
def delegates[Proj](
|
||||
refs: Seq[(ProjectRef, Proj)],
|
||||
configurations: Proj => Seq[ConfigKey],
|
||||
|
|
@ -251,18 +234,47 @@ object Scope {
|
|||
configInherit: (ResolvedReference, ConfigKey) => Seq[ConfigKey],
|
||||
taskInherit: AttributeKey[_] => Seq[AttributeKey[_]],
|
||||
extraInherit: (ResolvedReference, AttributeMap) => Seq[AttributeMap]
|
||||
): Scope => Seq[Scope] =
|
||||
delegates(
|
||||
refs,
|
||||
configurations,
|
||||
resolve,
|
||||
rootProject,
|
||||
projectInherit,
|
||||
configInherit,
|
||||
taskInherit,
|
||||
)
|
||||
|
||||
// *Inherit functions should be immediate delegates and not include argument itself. Transitivity will be provided by this method
|
||||
def delegates[Proj](
|
||||
refs: Seq[(ProjectRef, Proj)],
|
||||
configurations: Proj => Seq[ConfigKey],
|
||||
resolve: Reference => ResolvedReference,
|
||||
rootProject: URI => String,
|
||||
projectInherit: ProjectRef => Seq[ProjectRef],
|
||||
configInherit: (ResolvedReference, ConfigKey) => Seq[ConfigKey],
|
||||
taskInherit: AttributeKey[_] => Seq[AttributeKey[_]],
|
||||
): Scope => Seq[Scope] = {
|
||||
val index = delegates(refs, configurations, projectInherit, configInherit)
|
||||
scope =>
|
||||
indexedDelegates(resolve, index, rootProject, taskInherit, extraInherit)(scope)
|
||||
indexedDelegates(resolve, index, rootProject, taskInherit)(scope)
|
||||
}
|
||||
|
||||
@deprecated("Use variant without extraInherit", "1.1.1")
|
||||
def indexedDelegates(
|
||||
resolve: Reference => ResolvedReference,
|
||||
index: DelegateIndex,
|
||||
rootProject: URI => String,
|
||||
taskInherit: AttributeKey[_] => Seq[AttributeKey[_]],
|
||||
extraInherit: (ResolvedReference, AttributeMap) => Seq[AttributeMap]
|
||||
)(rawScope: Scope): Seq[Scope] =
|
||||
indexedDelegates(resolve, index, rootProject, taskInherit)(rawScope)
|
||||
|
||||
def indexedDelegates(
|
||||
resolve: Reference => ResolvedReference,
|
||||
index: DelegateIndex,
|
||||
rootProject: URI => String,
|
||||
taskInherit: AttributeKey[_] => Seq[AttributeKey[_]],
|
||||
)(rawScope: Scope): Seq[Scope] = {
|
||||
val scope = Scope.replaceThis(GlobalScope)(rawScope)
|
||||
|
||||
|
|
|
|||
|
|
@ -324,6 +324,8 @@ object Scoped {
|
|||
"0.13.2")
|
||||
def task: SettingKey[Task[S]] = scopedSetting(scope, key)
|
||||
|
||||
def toSettingKey: SettingKey[Task[S]] = scopedSetting(scope, key)
|
||||
|
||||
def get(settings: Settings[Scope]): Option[Task[S]] = settings.get(scope, key)
|
||||
|
||||
def ? : Initialize[Task[Option[S]]] = Def.optional(scopedKey) {
|
||||
|
|
@ -379,8 +381,10 @@ object Scoped {
|
|||
sealed abstract class RichInitTaskBase[S, R[_]] {
|
||||
protected def onTask[T](f: Task[S] => Task[T]): Initialize[R[T]]
|
||||
|
||||
def flatMap[T](f: S => Task[T]): Initialize[R[T]] = flatMapR(f compose successM)
|
||||
def map[T](f: S => T): Initialize[R[T]] = mapR(f compose successM)
|
||||
def flatMap[T](f: S => Task[T]): Initialize[R[T]] =
|
||||
onTask(_.result flatMap (f compose successM))
|
||||
|
||||
def map[T](f: S => T): Initialize[R[T]] = onTask(_.result map (f compose successM))
|
||||
def andFinally(fin: => Unit): Initialize[R[S]] = onTask(_ andFinally fin)
|
||||
def doFinally(t: Task[Unit]): Initialize[R[S]] = onTask(_ doFinally t)
|
||||
|
||||
|
|
@ -393,22 +397,23 @@ object Scoped {
|
|||
@deprecated(
|
||||
"Use the `result` method to create a task that returns the full Result of this task. Then, call `flatMap` on the new task.",
|
||||
"0.13.0")
|
||||
def flatMapR[T](f: Result[S] => Task[T]): Initialize[R[T]] = onTask(_ flatMapR f)
|
||||
def flatMapR[T](f: Result[S] => Task[T]): Initialize[R[T]] = onTask(_.result flatMap f)
|
||||
|
||||
@deprecated(
|
||||
"Use the `result` method to create a task that returns the full Result of this task. Then, call `map` on the new task.",
|
||||
"0.13.0")
|
||||
def mapR[T](f: Result[S] => T): Initialize[R[T]] = onTask(_ mapR f)
|
||||
def mapR[T](f: Result[S] => T): Initialize[R[T]] = onTask(_.result map f)
|
||||
|
||||
@deprecated(
|
||||
"Use the `failure` method to create a task that returns Incomplete when this task fails and then call `flatMap` on the new task.",
|
||||
"0.13.0")
|
||||
def flatFailure[T](f: Incomplete => Task[T]): Initialize[R[T]] = flatMapR(f compose failM)
|
||||
def flatFailure[T](f: Incomplete => Task[T]): Initialize[R[T]] =
|
||||
onTask(_.result flatMap (f compose failM))
|
||||
|
||||
@deprecated(
|
||||
"Use the `failure` method to create a task that returns Incomplete when this task fails and then call `map` on the new task.",
|
||||
"0.13.0")
|
||||
def mapFailure[T](f: Incomplete => T): Initialize[R[T]] = mapR(f compose failM)
|
||||
def mapFailure[T](f: Incomplete => T): Initialize[R[T]] = onTask(_.result map (f compose failM))
|
||||
}
|
||||
|
||||
type AnyInitTask = Initialize[Task[T]] forSome { type T }
|
||||
|
|
|
|||
|
|
@ -31,27 +31,27 @@ object InputWrapper {
|
|||
|
||||
@compileTimeOnly(
|
||||
"`value` can only be called on a task within a task definition macro, such as :=, +=, ++=, or Def.task.")
|
||||
def wrapTask_\u2603\u2603[T](in: Any): T = implDetailError
|
||||
def wrapTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
@compileTimeOnly(
|
||||
"`value` can only be used within a task or setting macro, such as :=, +=, ++=, Def.task, or Def.setting.")
|
||||
def wrapInit_\u2603\u2603[T](in: Any): T = implDetailError
|
||||
def wrapInit_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
@compileTimeOnly(
|
||||
"`value` can only be called on a task within a task definition macro, such as :=, +=, ++=, or Def.task.")
|
||||
def wrapInitTask_\u2603\u2603[T](in: Any): T = implDetailError
|
||||
def wrapInitTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
@compileTimeOnly(
|
||||
"`value` can only be called on an input task within a task definition macro, such as := or Def.inputTask.")
|
||||
def wrapInputTask_\u2603\u2603[T](in: Any): T = implDetailError
|
||||
def wrapInputTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
@compileTimeOnly(
|
||||
"`value` can only be called on an input task within a task definition macro, such as := or Def.inputTask.")
|
||||
def wrapInitInputTask_\u2603\u2603[T](in: Any): T = implDetailError
|
||||
def wrapInitInputTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
@compileTimeOnly(
|
||||
"`previous` can only be called on a task within a task or input task definition macro, such as :=, +=, ++=, Def.task, or Def.inputTask.")
|
||||
def wrapPrevious_\u2603\u2603[T](in: Any): T = implDetailError
|
||||
def wrapPrevious_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
private[this] def implDetailError =
|
||||
sys.error("This method is an implementation detail and should not be referenced.")
|
||||
|
|
@ -164,7 +164,7 @@ object InputWrapper {
|
|||
format: c.Expr[sjsonnew.JsonFormat[T]]): c.Expr[Option[T]] = {
|
||||
import c.universe._
|
||||
c.macroApplication match {
|
||||
case a @ Apply(Select(Apply(_, t :: Nil), tp), fmt) =>
|
||||
case a @ Apply(Select(Apply(_, t :: Nil), _), _) =>
|
||||
if (t.tpe <:< c.weakTypeOf[TaskKey[T]]) {
|
||||
val tsTyped = c.Expr[TaskKey[T]](t)
|
||||
val newTree = c.universe.reify { Previous.runtime[T](tsTyped.splice)(format.splice) }
|
||||
|
|
@ -224,12 +224,12 @@ object ParserInput {
|
|||
|
||||
@compileTimeOnly(
|
||||
"`parsed` can only be used within an input task macro, such as := or Def.inputTask.")
|
||||
def parser_\u2603\u2603[T](i: Any): T =
|
||||
def parser_\u2603\u2603[T](@deprecated("unused", "") i: Any): T =
|
||||
sys.error("This method is an implementation detail and should not be referenced.")
|
||||
|
||||
@compileTimeOnly(
|
||||
"`parsed` can only be used within an input task macro, such as := or Def.inputTask.")
|
||||
def initParser_\u2603\u2603[T](i: Any): T =
|
||||
def initParser_\u2603\u2603[T](@deprecated("unused", "") i: Any): T =
|
||||
sys.error("This method is an implementation detail and should not be referenced.")
|
||||
|
||||
private[std] def wrap[T: c.WeakTypeTag](c: blackbox.Context)(ts: c.Expr[Any],
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ private[sbt] object KeyMacro {
|
|||
n.decodedName.toString.trim // trim is not strictly correct, but macros don't expose the API necessary
|
||||
@tailrec def enclosingVal(trees: List[c.Tree]): String = {
|
||||
trees match {
|
||||
case vd @ ValDef(_, name, _, _) :: ts => processName(name)
|
||||
case ValDef(_, name, _, _) :: _ => processName(name)
|
||||
case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs)
|
||||
// lazy val x: X = <methodName> has this form for some reason (only when the explicit type is present, though)
|
||||
case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: xs if mods.hasFlag(Flag.LAZY) =>
|
||||
case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: _ if mods.hasFlag(Flag.LAZY) =>
|
||||
processName(name)
|
||||
case _ =>
|
||||
c.error(c.enclosingPosition, invalidEnclosingTree(methodName.decodedName.toString))
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ abstract class BaseTaskLinterDSL extends LinterDSL {
|
|||
val (qualName, isSettingKey) =
|
||||
Option(qual.symbol)
|
||||
.map(sym => (sym.name.decodedName.toString, qual.tpe <:< typeOf[SettingKey[_]]))
|
||||
.getOrElse((ap.pos.lineContent, false))
|
||||
.getOrElse((ap.pos.source.lineToString(ap.pos.line - 1), false))
|
||||
|
||||
if (!isSettingKey && !shouldIgnore && isTask(wrapperName, tpe.tpe, qual)) {
|
||||
if (insideIf && !isDynamicTask) {
|
||||
|
|
|
|||
|
|
@ -130,37 +130,41 @@ object TaskMacro {
|
|||
// These macros are there just so we can fail old operators like `<<=` and provide useful migration information.
|
||||
|
||||
def fakeSettingAssignPosition[T: c.WeakTypeTag](c: blackbox.Context)(
|
||||
app: c.Expr[Initialize[T]]): c.Expr[Setting[T]] =
|
||||
ContextUtil.selectMacroImpl[Setting[T]](c) { (ts, pos) =>
|
||||
c.abort(pos, assignMigration)
|
||||
}
|
||||
def fakeSettingAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](c: blackbox.Context)(
|
||||
v: c.Expr[Initialize[V]])(a: c.Expr[Append.Value[S, V]]): c.Expr[Setting[S]] =
|
||||
ContextUtil.selectMacroImpl[Setting[S]](c) { (ts, pos) =>
|
||||
c.abort(pos, append1Migration)
|
||||
}
|
||||
def fakeSettingAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](c: blackbox.Context)(
|
||||
vs: c.Expr[Initialize[V]])(a: c.Expr[Append.Values[S, V]]): c.Expr[Setting[S]] =
|
||||
ContextUtil.selectMacroImpl[Setting[S]](c) { (ts, pos) =>
|
||||
c.abort(pos, appendNMigration)
|
||||
}
|
||||
def fakeItaskAssignPosition[T: c.WeakTypeTag](c: blackbox.Context)(
|
||||
app: c.Expr[Initialize[Task[T]]]): c.Expr[Setting[Task[T]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[T]]](c) { (ts, pos) =>
|
||||
c.abort(pos, assignMigration)
|
||||
}
|
||||
def fakeTaskAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](c: blackbox.Context)(
|
||||
v: c.Expr[Initialize[Task[V]]])(a: c.Expr[Append.Value[S, V]]): c.Expr[Setting[Task[S]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[S]]](c) { (ts, pos) =>
|
||||
c.abort(pos, append1Migration)
|
||||
}
|
||||
def fakeTaskAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](c: blackbox.Context)(
|
||||
vs: c.Expr[Initialize[Task[V]]])(a: c.Expr[Append.Values[S, V]]): c.Expr[Setting[Task[S]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[S]]](c) { (ts, pos) =>
|
||||
c.abort(pos, appendNMigration)
|
||||
}
|
||||
@deprecated("unused", "") app: c.Expr[Initialize[T]]
|
||||
): c.Expr[Setting[T]] =
|
||||
ContextUtil.selectMacroImpl[Setting[T]](c)((_, pos) => c.abort(pos, assignMigration))
|
||||
|
||||
/* Implementations of <<= macro variations for tasks and settings. These just get the source position of the call site.*/
|
||||
def fakeSettingAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](c: blackbox.Context)(
|
||||
@deprecated("unused", "") v: c.Expr[Initialize[V]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Value[S, V]]
|
||||
): c.Expr[Setting[S]] =
|
||||
ContextUtil.selectMacroImpl[Setting[S]](c)((_, pos) => c.abort(pos, append1Migration))
|
||||
|
||||
def fakeSettingAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](c: blackbox.Context)(
|
||||
@deprecated("unused", "") vs: c.Expr[Initialize[V]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Values[S, V]]
|
||||
): c.Expr[Setting[S]] =
|
||||
ContextUtil.selectMacroImpl[Setting[S]](c)((_, pos) => c.abort(pos, appendNMigration))
|
||||
|
||||
def fakeItaskAssignPosition[T: c.WeakTypeTag](c: blackbox.Context)(
|
||||
@deprecated("unused", "") app: c.Expr[Initialize[Task[T]]]
|
||||
): c.Expr[Setting[Task[T]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[T]]](c)((_, pos) => c.abort(pos, assignMigration))
|
||||
|
||||
def fakeTaskAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](c: blackbox.Context)(
|
||||
@deprecated("unused", "") v: c.Expr[Initialize[Task[V]]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Value[S, V]]
|
||||
): c.Expr[Setting[Task[S]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[S]]](c)((_, pos) => c.abort(pos, append1Migration))
|
||||
|
||||
def fakeTaskAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](c: blackbox.Context)(
|
||||
@deprecated("unused", "") vs: c.Expr[Initialize[Task[V]]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Values[S, V]]
|
||||
): c.Expr[Setting[Task[S]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[S]]](c)((_, pos) => c.abort(pos, appendNMigration))
|
||||
|
||||
// Implementations of <<= macro variations for tasks and settings.
|
||||
// These just get the source position of the call site.
|
||||
|
||||
def itaskAssignPosition[T: c.WeakTypeTag](c: blackbox.Context)(
|
||||
app: c.Expr[Initialize[Task[T]]]): c.Expr[Setting[Task[T]]] =
|
||||
|
|
@ -221,7 +225,7 @@ object TaskMacro {
|
|||
if typeArgs.nonEmpty && (typeArgs.head weak_<:< c.weakTypeOf[Task[_]])
|
||||
&& (tpe weak_<:< c.weakTypeOf[Initialize[_]]) =>
|
||||
c.macroApplication match {
|
||||
case Apply(Apply(TypeApply(Select(preT, nmeT), targs), _), _) =>
|
||||
case Apply(Apply(TypeApply(Select(preT, _), _), _), _) =>
|
||||
val tree = Apply(
|
||||
TypeApply(Select(preT, TermName("+=").encodedName), TypeTree(typeArgs.head) :: Nil),
|
||||
Select(v.tree, TermName("taskValue").encodedName) :: Nil)
|
||||
|
|
@ -287,10 +291,14 @@ object TaskMacro {
|
|||
newName: String): c.Tree = {
|
||||
import c.universe._
|
||||
c.macroApplication match {
|
||||
case Apply(Apply(TypeApply(Select(preT, nmeT), targs), _), _) =>
|
||||
Apply(Apply(TypeApply(Select(preT, TermName(newName).encodedName), targs),
|
||||
init :: sourcePosition(c).tree :: Nil),
|
||||
append :: Nil)
|
||||
case Apply(Apply(TypeApply(Select(preT, _), targs), _), _) =>
|
||||
Apply(
|
||||
Apply(
|
||||
TypeApply(Select(preT, TermName(newName).encodedName), targs),
|
||||
init :: sourcePosition(c).tree :: Nil
|
||||
),
|
||||
append :: Nil
|
||||
)
|
||||
case x => ContextUtil.unexpectedTree(x)
|
||||
}
|
||||
}
|
||||
|
|
@ -299,10 +307,14 @@ object TaskMacro {
|
|||
newName: String): c.Tree = {
|
||||
import c.universe._
|
||||
c.macroApplication match {
|
||||
case Apply(Apply(TypeApply(Select(preT, nmeT), targs), _), r) =>
|
||||
Apply(Apply(TypeApply(Select(preT, TermName(newName).encodedName), targs),
|
||||
init :: sourcePosition(c).tree :: Nil),
|
||||
r)
|
||||
case Apply(Apply(TypeApply(Select(preT, _), targs), _), _) =>
|
||||
Apply(
|
||||
Apply(
|
||||
TypeApply(Select(preT, TermName(newName).encodedName), targs),
|
||||
init :: sourcePosition(c).tree :: Nil
|
||||
),
|
||||
remove :: Nil
|
||||
)
|
||||
case x => ContextUtil.unexpectedTree(x)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,12 +10,11 @@ package sbt.std
|
|||
class TaskPosSpec {
|
||||
// Dynamic tasks can have task invocations inside if branches
|
||||
locally {
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = taskKey[String]("")
|
||||
val bar = taskKey[String]("")
|
||||
var condition = true
|
||||
val baz = Def.taskDyn[String] {
|
||||
val condition = true
|
||||
Def.taskDyn[String] {
|
||||
if (condition) foo
|
||||
else bar
|
||||
}
|
||||
|
|
@ -23,23 +22,21 @@ class TaskPosSpec {
|
|||
|
||||
// Dynamic settings can have setting invocations inside if branches
|
||||
locally {
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = settingKey[String]("")
|
||||
val bar = settingKey[String]("")
|
||||
var condition = true
|
||||
val baz = Def.settingDyn[String] {
|
||||
val condition = true
|
||||
Def.settingDyn[String] {
|
||||
if (condition) foo
|
||||
else bar
|
||||
}
|
||||
}
|
||||
|
||||
locally {
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = taskKey[String]("")
|
||||
var condition = true
|
||||
val baz = Def.task[String] {
|
||||
val condition = true
|
||||
Def.task[String] {
|
||||
val fooAnon = () => foo.value: @sbtUnchecked
|
||||
if (condition) fooAnon()
|
||||
else fooAnon()
|
||||
|
|
@ -47,11 +44,10 @@ class TaskPosSpec {
|
|||
}
|
||||
|
||||
locally {
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = taskKey[String]("")
|
||||
var condition = true
|
||||
val baz = Def.task[String] {
|
||||
val condition = true
|
||||
Def.task[String] {
|
||||
val fooAnon = () => (foo.value: @sbtUnchecked) + ""
|
||||
if (condition) fooAnon()
|
||||
else fooAnon()
|
||||
|
|
@ -59,12 +55,11 @@ class TaskPosSpec {
|
|||
}
|
||||
|
||||
locally {
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = taskKey[String]("")
|
||||
val bar = taskKey[String]("")
|
||||
var condition = true
|
||||
val baz = Def.task[String] {
|
||||
val condition = true
|
||||
Def.task[String] {
|
||||
if (condition) foo.value: @sbtUnchecked
|
||||
else bar.value: @sbtUnchecked
|
||||
}
|
||||
|
|
@ -72,11 +67,10 @@ class TaskPosSpec {
|
|||
|
||||
locally {
|
||||
// This is fix 1 for appearance of tasks inside anons
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = taskKey[String]("")
|
||||
var condition = true
|
||||
val baz = Def.task[String] {
|
||||
val condition = true
|
||||
Def.task[String] {
|
||||
val fooResult = foo.value
|
||||
val anon = () => fooResult + " "
|
||||
if (condition) anon()
|
||||
|
|
@ -86,11 +80,10 @@ class TaskPosSpec {
|
|||
|
||||
locally {
|
||||
// This is fix 2 for appearance of tasks inside anons
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = taskKey[String]("")
|
||||
var condition = true
|
||||
val baz = Def.taskDyn[String] {
|
||||
val condition = true
|
||||
Def.taskDyn[String] {
|
||||
val anon1 = (value: String) => value + " "
|
||||
if (condition) {
|
||||
Def.task(anon1(foo.value))
|
||||
|
|
@ -100,31 +93,27 @@ class TaskPosSpec {
|
|||
|
||||
locally {
|
||||
// missing .value error should not happen inside task dyn
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = taskKey[String]("")
|
||||
val baz = Def.taskDyn[String] {
|
||||
Def.taskDyn[String] {
|
||||
foo
|
||||
}
|
||||
}
|
||||
|
||||
locally {
|
||||
// missing .value error should not happen inside task dyn
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = taskKey[String]("")
|
||||
val avoidDCE = ""
|
||||
val baz = Def.task[String] {
|
||||
foo: @sbtUnchecked
|
||||
Def.task[String] {
|
||||
val _ = foo: @sbtUnchecked
|
||||
avoidDCE
|
||||
}
|
||||
}
|
||||
|
||||
locally {
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = taskKey[String]("")
|
||||
val baz = Def.task[String] {
|
||||
Def.task[String] {
|
||||
def inner(s: KeyedInitialize[_]) = println(s)
|
||||
inner(foo)
|
||||
""
|
||||
|
|
@ -133,11 +122,10 @@ class TaskPosSpec {
|
|||
|
||||
locally {
|
||||
// In theory, this should be reported, but missing .value analysis is dumb at the cost of speed
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = taskKey[String]("")
|
||||
def avoidDCE = { println(""); "" }
|
||||
val baz = Def.task[String] {
|
||||
Def.task[String] {
|
||||
val (_, _) = "" match {
|
||||
case _ => (foo, 1 + 2)
|
||||
}
|
||||
|
|
@ -146,15 +134,14 @@ class TaskPosSpec {
|
|||
}
|
||||
|
||||
locally {
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = taskKey[String]("")
|
||||
def avoidDCE = { println(""); "" }
|
||||
val baz = Def.task[String] {
|
||||
def avoidDCE(x: TaskKey[String]) = x.toString
|
||||
Def.task[String] {
|
||||
val hehe = foo
|
||||
// We do not detect `hehe` because guessing that the user did the wrong thing would require
|
||||
// us to run the unused name traverser defined in Typer (and hence proxy it from context util)
|
||||
avoidDCE
|
||||
avoidDCE(hehe)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -168,11 +155,10 @@ class TaskPosSpec {
|
|||
}
|
||||
|
||||
locally {
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = settingKey[String]("")
|
||||
val condition = true
|
||||
val baz = Def.task[String] {
|
||||
Def.task[String] {
|
||||
// settings can be evaluated in a condition
|
||||
if (condition) foo.value
|
||||
else "..."
|
||||
|
|
@ -180,10 +166,9 @@ class TaskPosSpec {
|
|||
}
|
||||
|
||||
locally {
|
||||
import sbt._
|
||||
import sbt.Def._
|
||||
import sbt._, Def._
|
||||
val foo = settingKey[String]("")
|
||||
val baz = Def.task[Seq[String]] {
|
||||
Def.task[Seq[String]] {
|
||||
(1 to 10).map(_ => foo.value)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,9 @@
|
|||
|
||||
package sbt.std
|
||||
|
||||
import scala.reflect._
|
||||
import scala.tools.reflect.ToolBox
|
||||
|
||||
object TestUtil {
|
||||
import tools.reflect.ToolBox
|
||||
|
||||
def eval(code: String, compileOptions: String = ""): Any = {
|
||||
val tb = mkToolbox(compileOptions)
|
||||
tb.eval(tb.parse(code))
|
||||
|
|
|
|||
|
|
@ -72,8 +72,7 @@ object Cross {
|
|||
} & spacedFirst(CrossCommand)
|
||||
}
|
||||
|
||||
private def crossRestoreSessionParser(state: State): Parser[String] =
|
||||
token(CrossRestoreSessionCommand)
|
||||
private def crossRestoreSessionParser: Parser[String] = token(CrossRestoreSessionCommand)
|
||||
|
||||
private[sbt] def requireSession[T](p: State => Parser[T]): State => Parser[T] =
|
||||
s => if (s get sessionSettings isEmpty) failure("No project loaded") else p(s)
|
||||
|
|
@ -189,9 +188,10 @@ object Cross {
|
|||
}
|
||||
|
||||
def crossRestoreSession: Command =
|
||||
Command.arb(crossRestoreSessionParser, crossRestoreSessionHelp)(crossRestoreSessionImpl)
|
||||
Command.arb(_ => crossRestoreSessionParser, crossRestoreSessionHelp)((s, _) =>
|
||||
crossRestoreSessionImpl(s))
|
||||
|
||||
private def crossRestoreSessionImpl(state: State, arg: String): State = {
|
||||
private def crossRestoreSessionImpl(state: State): State = {
|
||||
restoreCapturedSession(state, Project.extract(state))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -671,7 +671,6 @@ object Defaults extends BuildCommon {
|
|||
(testGrouping in test).value,
|
||||
(testExecution in test).value,
|
||||
(fullClasspath in test).value,
|
||||
(javaHome in test).value,
|
||||
testForkedParallel.value,
|
||||
(javaOptions in test).value
|
||||
)
|
||||
|
|
@ -829,7 +828,6 @@ object Defaults extends BuildCommon {
|
|||
testGrouping.value,
|
||||
newConfig,
|
||||
fullClasspath.value,
|
||||
javaHome.value,
|
||||
testForkedParallel.value,
|
||||
javaOptions.value
|
||||
)
|
||||
|
|
@ -856,20 +854,20 @@ object Defaults extends BuildCommon {
|
|||
}
|
||||
}
|
||||
|
||||
private[sbt] def allTestGroupsTask(s: TaskStreams,
|
||||
frameworks: Map[TestFramework, Framework],
|
||||
loader: ClassLoader,
|
||||
groups: Seq[Tests.Group],
|
||||
config: Tests.Execution,
|
||||
cp: Classpath,
|
||||
javaHome: Option[File]): Initialize[Task[Tests.Output]] = {
|
||||
private[sbt] def allTestGroupsTask(
|
||||
s: TaskStreams,
|
||||
frameworks: Map[TestFramework, Framework],
|
||||
loader: ClassLoader,
|
||||
groups: Seq[Tests.Group],
|
||||
config: Tests.Execution,
|
||||
cp: Classpath,
|
||||
): Initialize[Task[Tests.Output]] = {
|
||||
allTestGroupsTask(s,
|
||||
frameworks,
|
||||
loader,
|
||||
groups,
|
||||
config,
|
||||
cp,
|
||||
javaHome,
|
||||
forkedParallelExecution = false,
|
||||
javaOptions = Nil)
|
||||
}
|
||||
|
|
@ -881,7 +879,6 @@ object Defaults extends BuildCommon {
|
|||
groups: Seq[Tests.Group],
|
||||
config: Tests.Execution,
|
||||
cp: Classpath,
|
||||
javaHome: Option[File],
|
||||
forkedParallelExecution: Boolean): Initialize[Task[Tests.Output]] = {
|
||||
allTestGroupsTask(s,
|
||||
frameworks,
|
||||
|
|
@ -889,7 +886,6 @@ object Defaults extends BuildCommon {
|
|||
groups,
|
||||
config,
|
||||
cp,
|
||||
javaHome,
|
||||
forkedParallelExecution,
|
||||
javaOptions = Nil)
|
||||
}
|
||||
|
|
@ -900,12 +896,11 @@ object Defaults extends BuildCommon {
|
|||
groups: Seq[Tests.Group],
|
||||
config: Tests.Execution,
|
||||
cp: Classpath,
|
||||
javaHome: Option[File],
|
||||
forkedParallelExecution: Boolean,
|
||||
javaOptions: Seq[String]): Initialize[Task[Tests.Output]] = {
|
||||
val runners = createTestRunners(frameworks, loader, config)
|
||||
val groupTasks = groups map {
|
||||
case Tests.Group(name, tests, runPolicy) =>
|
||||
case Tests.Group(_, tests, runPolicy) =>
|
||||
runPolicy match {
|
||||
case Tests.SubProcess(opts) =>
|
||||
s.log.debug(s"javaOptions: ${opts.runJVMOptions}")
|
||||
|
|
@ -1534,7 +1529,7 @@ object Defaults extends BuildCommon {
|
|||
val cacheStore = s.cacheStoreFactory make "copy-resources"
|
||||
val mappings = (resources.value --- dirs) pair (rebase(dirs, t) | flat(t))
|
||||
s.log.debug("Copy resource mappings: " + mappings.mkString("\n\t", "\n\t", ""))
|
||||
Sync(cacheStore)(mappings)
|
||||
Sync.sync(cacheStore)(mappings)
|
||||
mappings
|
||||
}
|
||||
|
||||
|
|
@ -1607,7 +1602,11 @@ object Defaults extends BuildCommon {
|
|||
val sv = (sbtVersion in pluginCrossBuild).value
|
||||
val scalaV = (scalaVersion in pluginCrossBuild).value
|
||||
val binVersion = (scalaBinaryVersion in pluginCrossBuild).value
|
||||
val cross = if (id.crossVersioned) CrossVersion.binary else Disabled()
|
||||
val cross = id.crossVersionedValue match {
|
||||
case CrossValue.Disabled => Disabled()
|
||||
case CrossValue.Full => CrossVersion.full
|
||||
case CrossValue.Binary => CrossVersion.binary
|
||||
}
|
||||
val base = ModuleID(id.groupID, id.name, sv).withCrossVersion(cross)
|
||||
CrossVersion(scalaV, binVersion)(base).withCrossVersion(Disabled())
|
||||
}
|
||||
|
|
@ -1700,7 +1699,7 @@ object Classpaths {
|
|||
}
|
||||
|
||||
def packaged(pkgTasks: Seq[TaskKey[File]]): Initialize[Task[Map[Artifact, File]]] =
|
||||
enabledOnly(packagedArtifact.task, pkgTasks) apply (_.join.map(_.toMap))
|
||||
enabledOnly(packagedArtifact.toSettingKey, pkgTasks) apply (_.join.map(_.toMap))
|
||||
|
||||
def artifactDefs(pkgTasks: Seq[TaskKey[File]]): Initialize[Seq[Artifact]] =
|
||||
enabledOnly(artifact, pkgTasks)
|
||||
|
|
@ -1710,8 +1709,10 @@ object Classpaths {
|
|||
case (a, true) => a
|
||||
})
|
||||
|
||||
def forallIn[T](key: Scoped.ScopingSetting[SettingKey[T]],
|
||||
pkgTasks: Seq[TaskKey[_]]): Initialize[Seq[T]] =
|
||||
def forallIn[T](
|
||||
key: Scoped.ScopingSetting[SettingKey[T]], // should be just SettingKey[T] (mea culpa)
|
||||
pkgTasks: Seq[TaskKey[_]],
|
||||
): Initialize[Seq[T]] =
|
||||
pkgTasks.map(pkg => key in pkg.scope in pkg).join
|
||||
|
||||
private[this] def publishGlobalDefaults =
|
||||
|
|
@ -1741,9 +1742,9 @@ object Classpaths {
|
|||
deliver := deliverTask(makeIvyXmlConfiguration).value,
|
||||
deliverLocal := deliverTask(makeIvyXmlLocalConfiguration).value,
|
||||
makeIvyXml := deliverTask(makeIvyXmlConfiguration).value,
|
||||
publish := publishTask(publishConfiguration, deliver).value,
|
||||
publishLocal := publishTask(publishLocalConfiguration, deliverLocal).value,
|
||||
publishM2 := publishTask(publishM2Configuration, deliverLocal).value
|
||||
publish := publishTask(publishConfiguration).value,
|
||||
publishLocal := publishTask(publishLocalConfiguration).value,
|
||||
publishM2 := publishTask(publishM2Configuration).value
|
||||
)
|
||||
|
||||
private[this] def baseGlobalDefaults =
|
||||
|
|
@ -1817,7 +1818,7 @@ object Classpaths {
|
|||
appResolvers.value,
|
||||
useJCenter.value) match {
|
||||
case (Some(delegated), Seq(), _, _) => delegated
|
||||
case (_, rs, Some(ars), uj) => ars ++ rs
|
||||
case (_, rs, Some(ars), _) => ars ++ rs
|
||||
case (_, rs, _, uj) => Resolver.combineDefaultResolvers(rs.toVector, uj, mavenCentral = true)
|
||||
}),
|
||||
appResolvers := {
|
||||
|
|
@ -2028,7 +2029,6 @@ object Classpaths {
|
|||
val docTypes = docArtifactTypes.value
|
||||
val out = is.withIvy(s.log)(_.getSettings.getDefaultIvyUserDir)
|
||||
val uwConfig = (unresolvedWarningConfiguration in update).value
|
||||
val scalaModule = scalaModuleInfo.value
|
||||
withExcludes(out, mod.classifiers, lock(app)) { excludes =>
|
||||
lm.updateClassifiers(
|
||||
GetClassifiersConfiguration(
|
||||
|
|
@ -2059,7 +2059,6 @@ object Classpaths {
|
|||
// Override the default to handle mixing in the sbtPlugin + scala dependencies.
|
||||
allDependencies := {
|
||||
val base = projectDependencies.value ++ libraryDependencies.value
|
||||
val dependency = sbtDependency.value
|
||||
val isPlugin = sbtPlugin.value
|
||||
val sbtdeps =
|
||||
(sbtDependency in pluginCrossBuild).value.withConfigurations(Some(Provided.name))
|
||||
|
|
@ -2178,9 +2177,6 @@ object Classpaths {
|
|||
val log = s.log
|
||||
val out = is.withIvy(log)(_.getSettings.getDefaultIvyUserDir)
|
||||
val uwConfig = (unresolvedWarningConfiguration in update).value
|
||||
val depDir = dependencyCacheDirectory.value
|
||||
val ivy = scalaModuleInfo.value
|
||||
val st = state.value
|
||||
withExcludes(out, mod.classifiers, lock(app)) {
|
||||
excludes =>
|
||||
// val noExplicitCheck = ivy.map(_.withCheckExplicit(false))
|
||||
|
|
@ -2197,7 +2193,7 @@ object Classpaths {
|
|||
uwConfig,
|
||||
log
|
||||
) match {
|
||||
case Left(uw) => ???
|
||||
case Left(_) => ???
|
||||
case Right(ur) => ur
|
||||
}
|
||||
}
|
||||
|
|
@ -2228,16 +2224,20 @@ object Classpaths {
|
|||
IvyActions.deliver(ivyModule.value, config.value, streams.value.log)
|
||||
}
|
||||
|
||||
def publishTask(config: TaskKey[PublishConfiguration],
|
||||
deliverKey: TaskKey[_]): Initialize[Task[Unit]] =
|
||||
@deprecated("Use variant without delivery key", "1.1.1")
|
||||
def publishTask(
|
||||
config: TaskKey[PublishConfiguration],
|
||||
deliverKey: TaskKey[_],
|
||||
): Initialize[Task[Unit]] =
|
||||
publishTask(config)
|
||||
|
||||
def publishTask(config: TaskKey[PublishConfiguration]): Initialize[Task[Unit]] =
|
||||
Def.taskDyn {
|
||||
val s = streams.value
|
||||
val skp = (skip in publish).value
|
||||
val ref = thisProjectRef.value
|
||||
if (skp) Def.task { s.log.debug(s"Skipping publish* for ${ref.project}") } else
|
||||
Def.task {
|
||||
IvyActions.publish(ivyModule.value, config.value, s.log)
|
||||
}
|
||||
Def.task { IvyActions.publish(ivyModule.value, config.value, s.log) }
|
||||
} tag (Tags.Publish, Tags.Network)
|
||||
|
||||
val moduleIdJsonKeyFormat: sjsonnew.JsonKeyFormat[ModuleID] =
|
||||
|
|
@ -2404,7 +2404,7 @@ object Classpaths {
|
|||
s.init.evaluate(empty) map { _ -> s.pos }
|
||||
}: _*)
|
||||
} catch {
|
||||
case NonFatal(e) => Map()
|
||||
case NonFatal(_) => Map()
|
||||
}
|
||||
|
||||
val outCacheStore = cacheStoreFactory make "output_dsp"
|
||||
|
|
@ -2709,14 +2709,16 @@ object Classpaths {
|
|||
data: Settings[Scope],
|
||||
deps: BuildDependencies): Initialize[Task[Classpath]] =
|
||||
Def.value {
|
||||
interDependencies(projectRef,
|
||||
deps,
|
||||
conf,
|
||||
conf,
|
||||
data,
|
||||
TrackLevel.TrackAlways,
|
||||
true,
|
||||
unmanagedLibs0)
|
||||
interDependencies(
|
||||
projectRef,
|
||||
deps,
|
||||
conf,
|
||||
conf,
|
||||
data,
|
||||
TrackLevel.TrackAlways,
|
||||
true,
|
||||
(dep, conf, data, _) => unmanagedLibs(dep, conf, data),
|
||||
)
|
||||
}
|
||||
private[sbt] def internalDependenciesImplTask(projectRef: ProjectRef,
|
||||
conf: Configuration,
|
||||
|
|
@ -2821,20 +2823,19 @@ object Classpaths {
|
|||
case TrackLevel.TrackIfMissing => getClasspath(exportedProductJarsIfMissing, dep, conf, data)
|
||||
case TrackLevel.TrackAlways => getClasspath(exportedProductJars, dep, conf, data)
|
||||
}
|
||||
private[sbt] def unmanagedLibs0(dep: ResolvedReference,
|
||||
conf: String,
|
||||
data: Settings[Scope],
|
||||
track: TrackLevel): Task[Classpath] =
|
||||
unmanagedLibs(dep, conf, data)
|
||||
|
||||
def unmanagedLibs(dep: ResolvedReference, conf: String, data: Settings[Scope]): Task[Classpath] =
|
||||
getClasspath(unmanagedJars, dep, conf, data)
|
||||
|
||||
def getClasspath(key: TaskKey[Classpath],
|
||||
dep: ResolvedReference,
|
||||
conf: String,
|
||||
data: Settings[Scope]): Task[Classpath] =
|
||||
(key in (dep, ConfigKey(conf))) get data getOrElse constant(Nil)
|
||||
|
||||
def defaultConfigurationTask(p: ResolvedReference, data: Settings[Scope]): Configuration =
|
||||
flatten(defaultConfiguration in p get data) getOrElse Configurations.Default
|
||||
|
||||
def flatten[T](o: Option[Option[T]]): Option[T] = o flatMap idFun
|
||||
|
||||
val sbtIvySnapshots: URLRepository = Resolver.sbtIvyRepo("snapshots")
|
||||
|
|
@ -2867,7 +2868,7 @@ object Classpaths {
|
|||
up.filter(configurationFilter(config.name) && artifactFilter(`type` = jarTypes))
|
||||
.toSeq
|
||||
.map {
|
||||
case (conf, module, art, file) =>
|
||||
case (_, module, art, file) =>
|
||||
Attributed(file)(
|
||||
AttributeMap.empty
|
||||
.put(artifact.key, art)
|
||||
|
|
@ -3127,13 +3128,16 @@ trait BuildExtra extends BuildCommon with DefExtra {
|
|||
file.value,
|
||||
managedScalaInstance.value)
|
||||
|
||||
def externalPom(file: Initialize[File] = inBase("pom.xml"),
|
||||
iScala: Initialize[Option[ScalaModuleInfo]] = scalaModuleInfo)
|
||||
: Setting[Task[ModuleSettings]] =
|
||||
moduleSettings := PomConfiguration(ivyValidate.value,
|
||||
scalaModuleInfo.value,
|
||||
file.value,
|
||||
managedScalaInstance.value)
|
||||
def externalPom(
|
||||
file: Initialize[File] = inBase("pom.xml"),
|
||||
iScala: Initialize[Option[ScalaModuleInfo]] = scalaModuleInfo,
|
||||
): Setting[Task[ModuleSettings]] =
|
||||
moduleSettings := PomConfiguration(
|
||||
ivyValidate.value,
|
||||
iScala.value,
|
||||
file.value,
|
||||
managedScalaInstance.value,
|
||||
)
|
||||
|
||||
def runInputTask(config: Configuration,
|
||||
mainClass: String,
|
||||
|
|
@ -3162,7 +3166,10 @@ trait BuildExtra extends BuildCommon with DefExtra {
|
|||
config: Configuration,
|
||||
mainClass: String,
|
||||
baseArguments: String*): Vector[Setting[_]] = {
|
||||
// Use Def.inputTask with the `Def.spaceDelimited()` parser
|
||||
// TODO: Re-write to avoid InputTask.apply which is deprecated
|
||||
// I tried "Def.spaceDelimited().parsed" (after importing Def.parserToInput)
|
||||
// but it broke actions/run-task
|
||||
// Maybe it needs to be defined inside a Def.inputTask?
|
||||
def inputTask[T](f: TaskKey[Seq[String]] => Initialize[Task[T]]): Initialize[InputTask[T]] =
|
||||
InputTask.apply(Def.value((s: State) => Def.spaceDelimited()))(f)
|
||||
|
||||
|
|
@ -3217,7 +3224,7 @@ trait BuildExtra extends BuildCommon with DefExtra {
|
|||
|
||||
trait DefExtra {
|
||||
private[this] val ts: TaskSequential = new TaskSequential {}
|
||||
implicit def toTaskSequential(d: Def.type): TaskSequential = ts
|
||||
implicit def toTaskSequential(@deprecated("unused", "") d: Def.type): TaskSequential = ts
|
||||
}
|
||||
|
||||
trait BuildCommon {
|
||||
|
|
@ -3225,7 +3232,7 @@ trait BuildCommon {
|
|||
/**
|
||||
* Allows a String to be used where a `NameFilter` is expected.
|
||||
* Asterisks (`*`) in the string are interpreted as wildcards.
|
||||
* All other characters must match exactly. See [[sbt.GlobFilter]].
|
||||
* All other characters must match exactly. See [[sbt.io.GlobFilter]].
|
||||
*/
|
||||
implicit def globFilter(expression: String): NameFilter = GlobFilter(expression)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
package sbt
|
||||
|
||||
import sbt.internal.{ Load, BuildStructure, TaskTimings, TaskName, GCUtil }
|
||||
import sbt.internal.util.{ Attributed, ErrorHandling, HList, RMap, Signals, Types }
|
||||
import sbt.internal.util.{ Attributed, ConsoleAppender, ErrorHandling, HList, RMap, Signals, Types }
|
||||
import sbt.util.{ Logger, Show }
|
||||
import sbt.librarymanagement.{ Resolver, UpdateReport }
|
||||
|
||||
|
|
@ -247,7 +247,11 @@ object EvaluateTask {
|
|||
(executionRoots in Global) ::= dummyRoots
|
||||
)
|
||||
|
||||
def evalPluginDef(log: Logger)(pluginDef: BuildStructure, state: State): PluginData = {
|
||||
@deprecated("Use variant which doesn't take a logger", "1.1.1")
|
||||
def evalPluginDef(log: Logger)(pluginDef: BuildStructure, state: State): PluginData =
|
||||
evalPluginDef(pluginDef, state)
|
||||
|
||||
def evalPluginDef(pluginDef: BuildStructure, state: State): PluginData = {
|
||||
val root = ProjectRef(pluginDef.root, Load.getRootProject(pluginDef.units)(pluginDef.root))
|
||||
val pluginKey = pluginData
|
||||
val config = extractedTaskConfig(Project.extract(state), pluginDef, state)
|
||||
|
|
@ -256,7 +260,7 @@ object EvaluateTask {
|
|||
val (newS, result) = evaluated getOrElse sys.error(
|
||||
"Plugin data does not exist for plugin definition at " + pluginDef.root)
|
||||
Project.runUnloadHooks(newS) // discard states
|
||||
processResult(result, log)
|
||||
processResult2(result)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -296,8 +300,8 @@ object EvaluateTask {
|
|||
|
||||
def logIncomplete(result: Incomplete, state: State, streams: Streams): Unit = {
|
||||
val all = Incomplete linearize result
|
||||
val keyed = for (Incomplete(Some(key: ScopedKey[_]), _, msg, _, ex) <- all)
|
||||
yield (key, msg, ex)
|
||||
val keyed =
|
||||
all collect { case Incomplete(Some(key: ScopedKey[_]), _, msg, _, ex) => (key, msg, ex) }
|
||||
|
||||
import ExceptionCategory._
|
||||
for ((key, msg, Some(ex)) <- keyed) {
|
||||
|
|
@ -312,7 +316,7 @@ object EvaluateTask {
|
|||
for ((key, msg, ex) <- keyed if (msg.isDefined || ex.isDefined)) {
|
||||
val msgString = (msg.toList ++ ex.toList.map(ErrorHandling.reducedToString)).mkString("\n\t")
|
||||
val log = getStreams(key, streams).log
|
||||
val display = contextDisplay(state, log.ansiCodesSupported)
|
||||
val display = contextDisplay(state, ConsoleAppender.formatEnabledInEnv)
|
||||
log.error("(" + display.show(key) + ") " + msgString)
|
||||
}
|
||||
}
|
||||
|
|
@ -433,12 +437,21 @@ object EvaluateTask {
|
|||
case in @ Incomplete(Some(node: Task[_]), _, _, _, _) => in.copy(node = transformNode(node))
|
||||
case i => i
|
||||
}
|
||||
|
||||
type AnyCyclic = Execute[({ type A[_] <: AnyRef })#A]#CyclicException[_]
|
||||
|
||||
def convertCyclicInc: Incomplete => Incomplete = {
|
||||
case in @ Incomplete(_, _, _, _, Some(c: AnyCyclic)) =>
|
||||
case in @ Incomplete(
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
Some(c: Execute[({ type A[_] <: AnyRef })#A @unchecked]#CyclicException[_])
|
||||
) =>
|
||||
in.copy(directCause = Some(new RuntimeException(convertCyclic(c))))
|
||||
case i => i
|
||||
}
|
||||
|
||||
def convertCyclic(c: AnyCyclic): String =
|
||||
(c.caller, c.target) match {
|
||||
case (caller: Task[_], target: Task[_]) =>
|
||||
|
|
@ -448,7 +461,7 @@ object EvaluateTask {
|
|||
}
|
||||
|
||||
def liftAnonymous: Incomplete => Incomplete = {
|
||||
case i @ Incomplete(node, tpe, None, causes, None) =>
|
||||
case i @ Incomplete(_, _, None, causes, None) =>
|
||||
causes.find(inc => inc.node.isEmpty && (inc.message.isDefined || inc.directCause.isDefined)) match {
|
||||
case Some(lift) => i.copy(directCause = lift.directCause, message = lift.message)
|
||||
case None => i
|
||||
|
|
@ -456,12 +469,19 @@ object EvaluateTask {
|
|||
case i => i
|
||||
}
|
||||
|
||||
@deprecated("Use processResult2 which doesn't take the unused log param", "1.1.1")
|
||||
def processResult[T](result: Result[T], log: Logger, show: Boolean = false): T =
|
||||
onResult(result, log) { v =>
|
||||
processResult2(result, show)
|
||||
|
||||
def processResult2[T](result: Result[T], show: Boolean = false): T =
|
||||
onResult(result) { v =>
|
||||
if (show) println("Result: " + v); v
|
||||
}
|
||||
|
||||
def onResult[T, S](result: Result[T], log: Logger)(f: T => S): S =
|
||||
@deprecated("Use variant that doesn't take log", "1.1.1")
|
||||
def onResult[T, S](result: Result[T], log: Logger)(f: T => S): S = onResult(result)(f)
|
||||
|
||||
def onResult[T, S](result: Result[T])(f: T => S): S =
|
||||
result match {
|
||||
case Value(v) => f(v)
|
||||
case Inc(inc) => throw inc
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@ final case class Extracted(structure: BuildStructure,
|
|||
* See `runAggregated` for that.
|
||||
*/
|
||||
def runTask[T](key: TaskKey[T], state: State): (State, T) = {
|
||||
val rkey = resolve(key.scopedKey)
|
||||
val rkey = resolve(key)
|
||||
val config = extractedTaskConfig(this, structure, state)
|
||||
val value: Option[(State, Result[T])] =
|
||||
EvaluateTask(structure, key.scopedKey, state, currentRef, config)
|
||||
val (newS, result) = getOrError(rkey.scope, rkey.key, value)
|
||||
(newS, EvaluateTask.processResult(result, newS.log))
|
||||
(newS, EvaluateTask.processResult2(result))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -72,22 +72,22 @@ final case class Extracted(structure: BuildStructure,
|
|||
* This method requests execution of only the given task and does not aggregate execution.
|
||||
*/
|
||||
def runInputTask[T](key: InputKey[T], input: String, state: State): (State, T) = {
|
||||
val scopedKey = ScopedKey(
|
||||
val key2 = Scoped.scopedSetting(
|
||||
Scope.resolveScope(Load.projectScope(currentRef), currentRef.build, rootProject)(key.scope),
|
||||
key.key
|
||||
)
|
||||
val rkey = resolve(scopedKey)
|
||||
val inputTask = get(Scoped.scopedSetting(rkey.scope, rkey.key))
|
||||
val rkey = resolve(key2)
|
||||
val inputTask = get(rkey)
|
||||
val task = Parser.parse(input, inputTask.parser(state)) match {
|
||||
case Right(t) => t
|
||||
case Left(msg) => sys.error(s"Invalid programmatic input:\n$msg")
|
||||
}
|
||||
val config = extractedTaskConfig(this, structure, state)
|
||||
EvaluateTask.withStreams(structure, state) { str =>
|
||||
val nv = EvaluateTask.nodeView(state, str, rkey :: Nil)
|
||||
val nv = EvaluateTask.nodeView(state, str, rkey.scopedKey :: Nil)
|
||||
val (newS, result) =
|
||||
EvaluateTask.runTask(task, state, str, structure.index.triggers, config)(nv)
|
||||
(newS, EvaluateTask.processResult(result, newS.log))
|
||||
(newS, EvaluateTask.processResult2(result))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -98,27 +98,29 @@ final case class Extracted(structure: BuildStructure,
|
|||
* Other axes are resolved to `Zero` if unspecified.
|
||||
*/
|
||||
def runAggregated[T](key: TaskKey[T], state: State): State = {
|
||||
val rkey = resolve(key.scopedKey)
|
||||
val rkey = resolve(key)
|
||||
val keys = Aggregation.aggregate(rkey, ScopeMask(), structure.extra)
|
||||
val tasks = Act.keyValues(structure)(keys)
|
||||
Aggregation.runTasks(state,
|
||||
structure,
|
||||
tasks,
|
||||
DummyTaskMap(Nil),
|
||||
show = Aggregation.defaultShow(state, false))(showKey)
|
||||
Aggregation.runTasks(
|
||||
state,
|
||||
tasks,
|
||||
DummyTaskMap(Nil),
|
||||
show = Aggregation.defaultShow(state, false),
|
||||
)(showKey)
|
||||
}
|
||||
|
||||
private[this] def resolve[T](key: ScopedKey[T]): ScopedKey[T] =
|
||||
Project.mapScope(Scope.resolveScope(GlobalScope, currentRef.build, rootProject))(key.scopedKey)
|
||||
private[this] def resolve[K <: Scoped.ScopingSetting[K] with Scoped](key: K): K =
|
||||
key in Scope.resolveScope(GlobalScope, currentRef.build, rootProject)(key.scope)
|
||||
|
||||
private def getOrError[T](scope: Scope, key: AttributeKey[_], value: Option[T])(
|
||||
implicit display: Show[ScopedKey[_]]): T =
|
||||
implicit display: Show[ScopedKey[_]]
|
||||
): T =
|
||||
value getOrElse sys.error(display.show(ScopedKey(scope, key)) + " is undefined.")
|
||||
|
||||
private def getOrError[T](scope: Scope, key: AttributeKey[T])(
|
||||
implicit display: Show[ScopedKey[_]]): T =
|
||||
structure.data.get(scope, key) getOrElse sys.error(
|
||||
display.show(ScopedKey(scope, key)) + " is undefined.")
|
||||
implicit display: Show[ScopedKey[_]]
|
||||
): T =
|
||||
getOrError(scope, key, structure.data.get(scope, key))(display)
|
||||
|
||||
def append(settings: Seq[Setting[_]], state: State): State = {
|
||||
val appendSettings =
|
||||
|
|
|
|||
|
|
@ -270,9 +270,9 @@ object BuiltinCommands {
|
|||
case _ => si.actualVersion
|
||||
}
|
||||
|
||||
private[this] def quiet[T](t: => T): Option[T] = try { Some(t) } catch {
|
||||
case e: Exception => None
|
||||
}
|
||||
private[this] def quiet[T](t: => T): Option[T] =
|
||||
try Some(t)
|
||||
catch { case _: Exception => None }
|
||||
|
||||
def settingsCommand: Command =
|
||||
showSettingLike(SettingsCommand,
|
||||
|
|
@ -397,7 +397,7 @@ object BuiltinCommands {
|
|||
// For correct behavior, we also need to re-inject a settings logger, as we'll be re-evaluating settings
|
||||
val loggerInject = LogManager.settingsLogger(s)
|
||||
val withLogger = newSession.appendRaw(loggerInject :: Nil)
|
||||
val show = Project.showContextKey(newSession, structure)
|
||||
val show = Project.showContextKey2(newSession)
|
||||
val newStructure = Load.reapply(withLogger.mergeSettings, structure)(show)
|
||||
Project.setProject(newSession, newStructure, s)
|
||||
}
|
||||
|
|
@ -421,19 +421,27 @@ object BuiltinCommands {
|
|||
)(cl)
|
||||
val setResult =
|
||||
if (all) SettingCompletions.setAll(extracted, settings)
|
||||
else SettingCompletions.setThis(s, extracted, settings, arg)
|
||||
else SettingCompletions.setThis(extracted, settings, arg)
|
||||
s.log.info(setResult.quietSummary)
|
||||
s.log.debug(setResult.verboseSummary)
|
||||
reapply(setResult.session, structure, s)
|
||||
}
|
||||
|
||||
@deprecated("Use variant that doesn't take a State", "1.1.1")
|
||||
def setThis(
|
||||
s: State,
|
||||
extracted: Extracted,
|
||||
settings: Seq[Def.Setting[_]],
|
||||
arg: String
|
||||
): SetResult =
|
||||
SettingCompletions.setThis(s, extracted, settings, arg)
|
||||
setThis(extracted, settings, arg)
|
||||
|
||||
def setThis(
|
||||
extracted: Extracted,
|
||||
settings: Seq[Def.Setting[_]],
|
||||
arg: String
|
||||
): SetResult =
|
||||
SettingCompletions.setThis(extracted, settings, arg)
|
||||
|
||||
def inspect: Command = Command(InspectCommand, inspectBrief, inspectDetailed)(Inspect.parser) {
|
||||
case (s, (option, sk)) =>
|
||||
|
|
@ -445,10 +453,10 @@ object BuiltinCommands {
|
|||
Command(LastGrepCommand, lastGrepBrief, lastGrepDetailed)(lastGrepParser) {
|
||||
case (s, (pattern, Some(sks))) =>
|
||||
val (str, _, display) = extractLast(s)
|
||||
Output.lastGrep(sks, str.streams(s), pattern, printLast(s))(display)
|
||||
Output.lastGrep(sks, str.streams(s), pattern, printLast)(display)
|
||||
keepLastLog(s)
|
||||
case (s, (pattern, None)) =>
|
||||
for (logFile <- lastLogFile(s)) yield Output.lastGrep(logFile, pattern, printLast(s))
|
||||
for (logFile <- lastLogFile(s)) yield Output.lastGrep(logFile, pattern, printLast)
|
||||
keepLastLog(s)
|
||||
}
|
||||
|
||||
|
|
@ -490,7 +498,7 @@ object BuiltinCommands {
|
|||
lastOnly_keys <- keysParser
|
||||
kvs = Act.keyValues(structure)(lastOnly_keys._2)
|
||||
f <- if (lastOnly_keys._1) success(() => s)
|
||||
else Aggregation.evaluatingParser(s, structure, show)(kvs)
|
||||
else Aggregation.evaluatingParser(s, show)(kvs)
|
||||
} yield
|
||||
() => {
|
||||
def export0(s: State): State = lastImpl(s, kvs, Some(ExportStream))
|
||||
|
|
@ -513,7 +521,7 @@ object BuiltinCommands {
|
|||
def last: Command = Command(LastCommand, lastBrief, lastDetailed)(aggregatedKeyValueParser) {
|
||||
case (s, Some(sks)) => lastImpl(s, sks, None)
|
||||
case (s, None) =>
|
||||
for (logFile <- lastLogFile(s)) yield Output.last(logFile, printLast(s))
|
||||
for (logFile <- lastLogFile(s)) yield Output.last(logFile, printLast)
|
||||
keepLastLog(s)
|
||||
}
|
||||
|
||||
|
|
@ -522,7 +530,7 @@ object BuiltinCommands {
|
|||
|
||||
private[this] def lastImpl(s: State, sks: AnyKeys, sid: Option[String]): State = {
|
||||
val (str, _, display) = extractLast(s)
|
||||
Output.last(sks, str.streams(s), printLast(s), sid)(display)
|
||||
Output.last(sks, str.streams(s), printLast, sid)(display)
|
||||
keepLastLog(s)
|
||||
}
|
||||
|
||||
|
|
@ -547,7 +555,10 @@ object BuiltinCommands {
|
|||
*/
|
||||
def isLastOnly(s: State): Boolean = s.history.previous.forall(_.commandLine == Shell)
|
||||
|
||||
def printLast(s: State): Seq[String] => Unit = _ foreach println
|
||||
@deprecated("Use variant that doesn't take the state", "1.1.1")
|
||||
def printLast(s: State): Seq[String] => Unit = printLast
|
||||
|
||||
def printLast: Seq[String] => Unit = _ foreach println
|
||||
|
||||
def autoImports(extracted: Extracted): EvalImports =
|
||||
new EvalImports(imports(extracted), "<auto-imports>")
|
||||
|
|
@ -617,7 +628,7 @@ object BuiltinCommands {
|
|||
val extraUpdated = Project.updateExtraBuilds(s, f)
|
||||
try doLoadProject(extraUpdated, LoadAction.Current)
|
||||
catch {
|
||||
case e: Exception =>
|
||||
case _: Exception =>
|
||||
s.log.error("Project loading failed: reverting to previous state.")
|
||||
Project.setExtraBuilds(s, original)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import sbt.internal.Load
|
|||
import sbt.internal.CommandStrings._
|
||||
import Cross.{ spacedFirst, requireSession }
|
||||
import sbt.librarymanagement.VersionNumber
|
||||
import Project.{ inScope }
|
||||
import Project.inScope
|
||||
|
||||
/**
|
||||
* Module responsible for plugin cross building.
|
||||
|
|
@ -24,8 +24,7 @@ import Project.{ inScope }
|
|||
private[sbt] object PluginCross {
|
||||
lazy val pluginSwitch: Command = {
|
||||
def switchParser(state: State): Parser[(String, String)] = {
|
||||
val knownVersions = Nil
|
||||
lazy val switchArgs = token(NotSpace.examples(knownVersions: _*)) ~ (token(
|
||||
lazy val switchArgs = token(NotSpace.examples()) ~ (token(
|
||||
Space ~> matched(state.combinedParser)) ?? "")
|
||||
lazy val nextSpaced = spacedFirst(PluginSwitchCommand)
|
||||
token(PluginSwitchCommand ~ OptSpace) flatMap { _ =>
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ abstract class AutoPlugin extends Plugins.Basic with PluginsFunctions {
|
|||
def extraProjects: Seq[Project] = Nil
|
||||
|
||||
/** The [[Project]]s to add to the current build based on an existing project. */
|
||||
def derivedProjects(proj: ProjectDefinition[_]): Seq[Project] = Nil
|
||||
def derivedProjects(@deprecated("unused", "") proj: ProjectDefinition[_]): Seq[Project] = Nil
|
||||
|
||||
private[sbt] def unary_! : Exclude = Exclude(this)
|
||||
|
||||
|
|
@ -224,20 +224,19 @@ object Plugins extends PluginsFunctions {
|
|||
_.label
|
||||
})
|
||||
}
|
||||
val retval = topologicalSort(selectedPlugins, log)
|
||||
val retval = topologicalSort(selectedPlugins)
|
||||
// log.debug(s" :: sorted deduced result: ${retval.toString}")
|
||||
retval
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private[sbt] def topologicalSort(ns: List[AutoPlugin], log: Logger): List[AutoPlugin] = {
|
||||
// log.debug(s"sorting: ns: ${ns.toString}")
|
||||
|
||||
private[sbt] def topologicalSort(ns: List[AutoPlugin]): List[AutoPlugin] = {
|
||||
@tailrec
|
||||
def doSort(found0: List[AutoPlugin],
|
||||
notFound0: List[AutoPlugin],
|
||||
limit0: Int): List[AutoPlugin] = {
|
||||
// log.debug(s" :: sorting:: found: ${found0.toString} not found ${notFound0.toString}")
|
||||
if (limit0 < 0) throw AutoPluginException(s"Failed to sort ${ns} topologically")
|
||||
else if (notFound0.isEmpty) found0
|
||||
else {
|
||||
|
|
@ -250,6 +249,7 @@ object Plugins extends PluginsFunctions {
|
|||
val (roots, nonRoots) = ns partition (_.isRoot)
|
||||
doSort(roots, nonRoots, ns.size * ns.size + 1)
|
||||
}
|
||||
|
||||
private[sbt] def translateMessage(e: LogicException) = e match {
|
||||
case ic: InitialContradictions =>
|
||||
s"Contradiction in selected plugins. These plugins were both included and excluded: ${literalsString(
|
||||
|
|
@ -260,6 +260,7 @@ object Plugins extends PluginsFunctions {
|
|||
case cn: CyclicNegation =>
|
||||
s"Cycles in plugin requirements cannot involve excludes. The problematic cycle is: ${literalsString(cn.cycle)}"
|
||||
}
|
||||
|
||||
private[this] def literalsString(lits: Seq[Literal]): String =
|
||||
lits map { case Atom(l) => l; case Negated(Atom(l)) => l } mkString (", ")
|
||||
|
||||
|
|
@ -271,6 +272,7 @@ object Plugins extends PluginsFunctions {
|
|||
val message = s"Plugin$ns provided by multiple AutoPlugins:$nl${dupStrings.mkString(nl)}"
|
||||
throw AutoPluginException(message)
|
||||
}
|
||||
|
||||
private[this] def exclusionConflictError(requested: Plugins,
|
||||
selected: Seq[AutoPlugin],
|
||||
conflicting: Seq[AutoPlugin]): Unit = {
|
||||
|
|
@ -360,14 +362,14 @@ ${listConflicts(conflicting)}""")
|
|||
// This would handle things like !!p or !(p && z)
|
||||
case Exclude(n) => hasInclude(n, p)
|
||||
case And(ns) => ns.forall(n => hasExclude(n, p))
|
||||
case b: Basic => false
|
||||
case _: Basic => false
|
||||
case Empty => false
|
||||
}
|
||||
private[sbt] def hasInclude(n: Plugins, p: AutoPlugin): Boolean = n match {
|
||||
case `p` => true
|
||||
case Exclude(n) => hasExclude(n, p)
|
||||
case And(ns) => ns.forall(n => hasInclude(n, p))
|
||||
case b: Basic => false
|
||||
case _: Basic => false
|
||||
case Empty => false
|
||||
}
|
||||
private[this] def flattenConvert(n: Plugins): Seq[Literal] = n match {
|
||||
|
|
|
|||
|
|
@ -279,23 +279,29 @@ object Project extends ProjectExtra {
|
|||
showContextKey(state, None)
|
||||
|
||||
def showContextKey(state: State, keyNameColor: Option[String]): Show[ScopedKey[_]] =
|
||||
if (isProjectLoaded(state)) showContextKey(session(state), structure(state), keyNameColor)
|
||||
if (isProjectLoaded(state)) showContextKey2(session(state), keyNameColor)
|
||||
else Def.showFullKey
|
||||
|
||||
@deprecated("Use showContextKey2 which doesn't take the unused structure param", "1.1.1")
|
||||
def showContextKey(
|
||||
session: SessionSettings,
|
||||
structure: BuildStructure,
|
||||
keyNameColor: Option[String] = None
|
||||
): Show[ScopedKey[_]] =
|
||||
Def.showRelativeKey(session.current, structure.allProjects.size > 1, keyNameColor)
|
||||
showContextKey2(session, keyNameColor)
|
||||
|
||||
def showContextKey2(
|
||||
session: SessionSettings,
|
||||
keyNameColor: Option[String] = None
|
||||
): Show[ScopedKey[_]] =
|
||||
Def.showRelativeKey2(session.current, keyNameColor)
|
||||
|
||||
def showLoadingKey(
|
||||
loaded: LoadedBuild,
|
||||
keyNameColor: Option[String] = None
|
||||
): Show[ScopedKey[_]] =
|
||||
Def.showRelativeKey(
|
||||
Def.showRelativeKey2(
|
||||
ProjectRef(loaded.root, loaded.units(loaded.root).rootProjects.head),
|
||||
loaded.allProjectRefs.size > 1,
|
||||
keyNameColor
|
||||
)
|
||||
|
||||
|
|
@ -406,7 +412,7 @@ object Project extends ProjectExtra {
|
|||
def extract(state: State): Extracted = extract(session(state), structure(state))
|
||||
|
||||
private[sbt] def extract(se: SessionSettings, st: BuildStructure): Extracted =
|
||||
Extracted(st, se, se.current)(showContextKey(se, st))
|
||||
Extracted(st, se, se.current)(showContextKey2(se))
|
||||
|
||||
def getProjectForReference(ref: Reference, structure: BuildStructure): Option[ResolvedProject] =
|
||||
ref match { case pr: ProjectRef => getProject(pr, structure); case _ => None }
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ object ScopeFilter {
|
|||
|
||||
/** Selects all scopes that apply to a single project. Zero and build-level scopes are excluded. */
|
||||
def inAnyProject: ProjectFilter =
|
||||
selectAxis(const { case p: ProjectRef => true; case _ => false })
|
||||
selectAxis(const { case _: ProjectRef => true; case _ => false })
|
||||
|
||||
/** Accepts all values for the task axis except Zero. */
|
||||
def inAnyTask: TaskFilter = selectAny[AttributeKey[_]]
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ object SessionVar {
|
|||
|
||||
def read[T](key: ScopedKey[Task[T]], state: State)(implicit f: JsonFormat[T]): Option[T] =
|
||||
Project.structure(state).streams(state).use(key) { s =>
|
||||
try { Some(s.getInput(key, DefaultDataID).read[T]) } catch { case NonFatal(e) => None }
|
||||
try { Some(s.getInput(key, DefaultDataID).read[T]) } catch { case NonFatal(_) => None }
|
||||
}
|
||||
|
||||
def load[T](key: ScopedKey[Task[T]], state: State)(implicit f: JsonFormat[T]): Option[T] =
|
||||
|
|
|
|||
|
|
@ -21,9 +21,10 @@ import BasicCommandStrings._, BasicKeys._
|
|||
|
||||
private[sbt] object TemplateCommandUtil {
|
||||
def templateCommand: Command =
|
||||
Command(TemplateCommand, templateBrief, templateDetailed)(templateCommandParser)(runTemplate)
|
||||
Command(TemplateCommand, templateBrief, templateDetailed)(_ => templateCommandParser)(
|
||||
runTemplate)
|
||||
|
||||
private def templateCommandParser(state: State): Parser[Seq[String]] =
|
||||
private def templateCommandParser: Parser[Seq[String]] =
|
||||
(token(Space) ~> repsep(StringBasic, token(Space))) | (token(EOF) map (_ => Nil))
|
||||
|
||||
private def runTemplate(state: State, inputArg: Seq[String]): State = {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
package sbt
|
||||
package internal
|
||||
|
||||
import Def.{ showRelativeKey, ScopedKey }
|
||||
import Def.{ showRelativeKey2, ScopedKey }
|
||||
import Keys.sessionSettings
|
||||
import sbt.internal.util.complete.{ DefaultParsers, Parser }
|
||||
import Aggregation.{ KeyValue, Values }
|
||||
|
|
@ -56,7 +56,7 @@ object Act {
|
|||
keyMap: Map[String, AttributeKey[_]],
|
||||
data: Settings[Scope]): Parser[ParsedKey] =
|
||||
scopedKeyFull(index, current, defaultConfigs, keyMap) flatMap { choices =>
|
||||
select(choices, data)(showRelativeKey(current, index.buildURIs.size > 1))
|
||||
select(choices, data)(showRelativeKey2(current))
|
||||
}
|
||||
|
||||
def scopedKeyFull(index: KeyIndex,
|
||||
|
|
@ -100,7 +100,7 @@ object Act {
|
|||
conf <- configs(confAmb, defaultConfigs, proj, index)
|
||||
} yield
|
||||
for {
|
||||
taskAmb <- taskAxis(conf, index.tasks(proj, conf), keyMap)
|
||||
taskAmb <- taskAxis(index.tasks(proj, conf), keyMap)
|
||||
task = resolveTask(taskAmb)
|
||||
key <- key(index, proj, conf, task, keyMap)
|
||||
extra <- extraAxis(keyMap, IMap.empty)
|
||||
|
|
@ -161,6 +161,7 @@ object Act {
|
|||
|
||||
def examples(p: Parser[String], exs: Set[String], label: String): Parser[String] =
|
||||
p !!! ("Expected " + label) examples exs
|
||||
|
||||
def examplesStrict(p: Parser[String], exs: Set[String], label: String): Parser[String] =
|
||||
filterStrings(examples(p, exs, label), exs, label)
|
||||
|
||||
|
|
@ -168,6 +169,7 @@ object Act {
|
|||
p.? map { opt =>
|
||||
toAxis(opt, ifNone)
|
||||
}
|
||||
|
||||
def toAxis[T](opt: Option[T], ifNone: ScopeAxis[T]): ScopeAxis[T] =
|
||||
opt match { case Some(t) => Select(t); case None => ifNone }
|
||||
|
||||
|
|
@ -231,8 +233,8 @@ object Act {
|
|||
// This queries the key index so tab completion will list the build-level keys.
|
||||
val buildKeys: Set[String] =
|
||||
proj match {
|
||||
case Some(ProjectRef(uri, id)) => index.keys(Some(BuildRef(uri)), conf, task)
|
||||
case _ => Set()
|
||||
case Some(ProjectRef(uri, _)) => index.keys(Some(BuildRef(uri)), conf, task)
|
||||
case _ => Set()
|
||||
}
|
||||
val keys: Set[String] = index.keys(proj, conf, task) ++ buildKeys
|
||||
keyParser(keys)
|
||||
|
|
@ -255,9 +257,10 @@ object Act {
|
|||
optionalAxis(extras, Zero)
|
||||
}
|
||||
|
||||
def taskAxis(d: Option[String],
|
||||
tasks: Set[AttributeKey[_]],
|
||||
allKnown: Map[String, AttributeKey[_]]): Parser[ParsedAxis[AttributeKey[_]]] = {
|
||||
def taskAxis(
|
||||
tasks: Set[AttributeKey[_]],
|
||||
allKnown: Map[String, AttributeKey[_]],
|
||||
): Parser[ParsedAxis[AttributeKey[_]]] = {
|
||||
val taskSeq = tasks.toSeq
|
||||
def taskKeys(f: AttributeKey[_] => String): Seq[(String, AttributeKey[_])] =
|
||||
taskSeq.map(key => (f(key), key))
|
||||
|
|
@ -380,7 +383,7 @@ object Act {
|
|||
def evaluate(kvs: Seq[ScopedKey[_]]): Parser[() => State] = {
|
||||
val preparedPairs = anyKeyValues(structure, kvs)
|
||||
val showConfig = Aggregation.defaultShow(state, showTasks = action == ShowAction)
|
||||
evaluatingParser(state, structure, showConfig)(preparedPairs) map { evaluate => () =>
|
||||
evaluatingParser(state, showConfig)(preparedPairs) map { evaluate => () =>
|
||||
{
|
||||
val keyStrings = preparedPairs.map(pp => showKey.show(pp.key)).mkString(", ")
|
||||
state.log.debug("Evaluating tasks: " + keyStrings)
|
||||
|
|
|
|||
|
|
@ -61,11 +61,10 @@ object Aggregation {
|
|||
|
||||
def applyTasks[T](
|
||||
s: State,
|
||||
structure: BuildStructure,
|
||||
ps: Values[Parser[Task[T]]],
|
||||
show: ShowConfig
|
||||
)(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
|
||||
Command.applyEffect(seqParser(ps))(ts => runTasks(s, structure, ts, DummyTaskMap(Nil), show))
|
||||
Command.applyEffect(seqParser(ps))(ts => runTasks(s, ts, DummyTaskMap(Nil), show))
|
||||
|
||||
private def showRun[T](complete: Complete[T], show: ShowConfig)(
|
||||
implicit display: Show[ScopedKey[_]]
|
||||
|
|
@ -104,7 +103,6 @@ object Aggregation {
|
|||
}
|
||||
|
||||
def runTasks[HL <: HList, T](s: State,
|
||||
structure: BuildStructure,
|
||||
ts: Values[Task[T]],
|
||||
extra: DummyTaskMap,
|
||||
show: ShowConfig)(implicit display: Show[ScopedKey[_]]): State = {
|
||||
|
|
@ -128,33 +126,26 @@ object Aggregation {
|
|||
key in currentRef get structure.data getOrElse true
|
||||
if (get(showSuccess)) {
|
||||
if (get(showTiming)) {
|
||||
val msg = timingString(start, stop, "", structure.data, currentRef, log)
|
||||
val msg = timingString(start, stop, structure.data, currentRef)
|
||||
if (success) log.success(msg) else log.error(msg)
|
||||
} else if (success)
|
||||
log.success("")
|
||||
}
|
||||
}
|
||||
|
||||
private def timingString(
|
||||
startTime: Long,
|
||||
endTime: Long,
|
||||
s: String,
|
||||
data: Settings[Scope],
|
||||
currentRef: ProjectRef,
|
||||
log: Logger
|
||||
): String = {
|
||||
val format = timingFormat in currentRef get data getOrElse defaultFormat
|
||||
timing(format, startTime, endTime, "", log)
|
||||
timing(format, startTime, endTime)
|
||||
}
|
||||
def timing(
|
||||
format: java.text.DateFormat,
|
||||
startTime: Long,
|
||||
endTime: Long,
|
||||
s: String,
|
||||
log: Logger
|
||||
): String = {
|
||||
val ss = if (s.isEmpty) "" else s + " "
|
||||
|
||||
def timing(format: java.text.DateFormat, startTime: Long, endTime: Long): String = {
|
||||
val nowString = format.format(new java.util.Date(endTime))
|
||||
"Total " + ss + "time: " + (endTime - startTime + 500) / 1000 + " s, completed " + nowString
|
||||
"Total time: " + (endTime - startTime + 500) / 1000 + " s, completed " + nowString
|
||||
}
|
||||
|
||||
def defaultFormat: DateFormat = {
|
||||
|
|
@ -164,20 +155,19 @@ object Aggregation {
|
|||
|
||||
def applyDynamicTasks[I](
|
||||
s: State,
|
||||
structure: BuildStructure,
|
||||
inputs: Values[InputTask[I]],
|
||||
show: ShowConfig
|
||||
)(implicit display: Show[ScopedKey[_]]): Parser[() => State] = {
|
||||
val parsers = for (KeyValue(k, it) <- inputs)
|
||||
yield it.parser(s).map(v => KeyValue(k, v))
|
||||
Command.applyEffect(seq(parsers)) { roots =>
|
||||
runTasks(s, structure, roots, DummyTaskMap(Nil), show)
|
||||
runTasks(s, roots, DummyTaskMap(Nil), show)
|
||||
}
|
||||
}
|
||||
|
||||
def evaluatingParser(s: State, structure: BuildStructure, show: ShowConfig)(
|
||||
keys: Seq[KeyValue[_]]
|
||||
)(implicit display: Show[ScopedKey[_]]): Parser[() => State] = {
|
||||
def evaluatingParser(s: State, show: ShowConfig)(keys: Seq[KeyValue[_]])(
|
||||
implicit display: Show[ScopedKey[_]]
|
||||
): Parser[() => State] = {
|
||||
|
||||
// to make the call sites clearer
|
||||
def separate[L](in: Seq[KeyValue[_]])(
|
||||
|
|
@ -210,12 +200,12 @@ object Aggregation {
|
|||
val otherStrings = other.map(_.key).mkString("Task(s)/setting(s):\n\t", "\n\t", "\n")
|
||||
failure(s"Cannot mix input tasks with plain tasks/settings. $inputStrings $otherStrings")
|
||||
} else
|
||||
applyDynamicTasks(s, structure, maps(inputTasks)(castToAny), show)
|
||||
applyDynamicTasks(s, maps(inputTasks)(castToAny), show)
|
||||
} else {
|
||||
val base =
|
||||
if (tasks.isEmpty) success(() => s)
|
||||
else
|
||||
applyTasks(s, structure, maps(tasks)(x => success(castToAny(x))), show)
|
||||
applyTasks(s, maps(tasks)(x => success(castToAny(x))), show)
|
||||
base.map { res => () =>
|
||||
val newState = res()
|
||||
if (show.settingValues && settings.nonEmpty) printSettings(settings, show.print)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import sbt.internal.util.Attributed
|
|||
import sbt.internal.inc.ReflectUtilities
|
||||
|
||||
trait BuildDef {
|
||||
def projectDefinitions(baseDirectory: File): Seq[Project] = projects
|
||||
def projectDefinitions(@deprecated("unused", "") baseDirectory: File): Seq[Project] = projects
|
||||
def projects: Seq[Project] = ReflectUtilities.allVals[Project](this).values.toSeq
|
||||
// TODO: Should we grab the build core settings here or in a plugin?
|
||||
def settings: Seq[Setting[_]] = Defaults.buildCore
|
||||
|
|
|
|||
|
|
@ -172,9 +172,7 @@ final class DetectedPlugins(val autoPlugins: Seq[DetectedAutoPlugin],
|
|||
private[this] lazy val (autoPluginAutoImports, topLevelAutoPluginAutoImports) =
|
||||
autoPlugins
|
||||
.flatMap {
|
||||
case DetectedAutoPlugin(name, ap, hasAutoImport) =>
|
||||
if (hasAutoImport) Some(name)
|
||||
else None
|
||||
case DetectedAutoPlugin(name, _, hasAutoImport) => if (hasAutoImport) Some(name) else None
|
||||
}
|
||||
.partition(nonTopLevelPlugin)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,9 +43,9 @@ import sbt.util.{ Level, Logger, LogExchange }
|
|||
* this exchange, which could serve command request from either of the channel.
|
||||
*/
|
||||
private[sbt] final class CommandExchange {
|
||||
private val autoStartServer = sys.props.get("sbt.server.autostart") map {
|
||||
_.toLowerCase == "true"
|
||||
} getOrElse true
|
||||
private val autoStartServer =
|
||||
sys.props get "sbt.server.autostart" forall (_.toLowerCase == "true")
|
||||
|
||||
private val lock = new AnyRef {}
|
||||
private var server: Option[ServerInstance] = None
|
||||
private var consoleChannel: Option[ConsoleChannel] = None
|
||||
|
|
@ -90,7 +90,6 @@ private[sbt] final class CommandExchange {
|
|||
else s
|
||||
}
|
||||
|
||||
private def newChannelName: String = s"channel-${nextChannelId.incrementAndGet()}"
|
||||
private def newNetworkName: String = s"network-${nextChannelId.incrementAndGet()}"
|
||||
|
||||
/**
|
||||
|
|
@ -204,42 +203,24 @@ private[sbt] final class CommandExchange {
|
|||
val params = toLogMessageParams(entry)
|
||||
channels collect {
|
||||
case c: ConsoleChannel =>
|
||||
if (broadcastStringMessage) {
|
||||
if (broadcastStringMessage || (entry.channelName forall (_ == c.name)))
|
||||
c.publishEvent(event)
|
||||
} else {
|
||||
if (entry.channelName.isEmpty || entry.channelName == Some(c.name)) {
|
||||
c.publishEvent(event)
|
||||
}
|
||||
}
|
||||
case c: NetworkChannel =>
|
||||
try {
|
||||
// Note that language server's LogMessageParams does not hold the execid,
|
||||
// so this is weaker than the StringMessage. We might want to double-send
|
||||
// in case we have a better client that can utilize the knowledge.
|
||||
import sbt.internal.langserver.codec.JsonProtocol._
|
||||
if (broadcastStringMessage) {
|
||||
if (broadcastStringMessage || (entry.channelName contains c.name))
|
||||
c.langNotify("window/logMessage", params)
|
||||
} else {
|
||||
if (entry.channelName == Some(c.name)) {
|
||||
c.langNotify("window/logMessage", params)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
case _: IOException =>
|
||||
toDel += c
|
||||
}
|
||||
} catch { case _: IOException => toDel += c }
|
||||
}
|
||||
case _ =>
|
||||
channels collect {
|
||||
case c: ConsoleChannel =>
|
||||
c.publishEvent(event)
|
||||
channels foreach {
|
||||
case c: ConsoleChannel => c.publishEvent(event)
|
||||
case c: NetworkChannel =>
|
||||
try {
|
||||
c.publishEvent(event)
|
||||
} catch {
|
||||
case _: IOException =>
|
||||
toDel += c
|
||||
}
|
||||
try c.publishEvent(event)
|
||||
catch { case _: IOException => toDel += c }
|
||||
}
|
||||
}
|
||||
toDel.toList match {
|
||||
|
|
@ -295,6 +276,11 @@ private[sbt] final class CommandExchange {
|
|||
// fanout publishEvent
|
||||
def publishEventMessage(event: EventMessage): Unit = {
|
||||
val toDel: ListBuffer[CommandChannel] = ListBuffer.empty
|
||||
|
||||
def tryTo(x: => Unit, c: CommandChannel): Unit =
|
||||
try x
|
||||
catch { case _: IOException => toDel += c }
|
||||
|
||||
event match {
|
||||
// Special treatment for ConsolePromptEvent since it's hand coded without codec.
|
||||
case entry: ConsolePromptEvent =>
|
||||
|
|
@ -308,32 +294,17 @@ private[sbt] final class CommandExchange {
|
|||
case entry: ExecStatusEvent =>
|
||||
channels collect {
|
||||
case c: ConsoleChannel =>
|
||||
if (entry.channelName.isEmpty || entry.channelName == Some(c.name)) {
|
||||
c.publishEventMessage(event)
|
||||
}
|
||||
if (entry.channelName forall (_ == c.name)) c.publishEventMessage(event)
|
||||
case c: NetworkChannel =>
|
||||
try {
|
||||
if (entry.channelName == Some(c.name)) {
|
||||
c.publishEventMessage(event)
|
||||
}
|
||||
} catch {
|
||||
case e: IOException =>
|
||||
toDel += c
|
||||
}
|
||||
if (entry.channelName contains c.name) tryTo(c.publishEventMessage(event), c)
|
||||
}
|
||||
case _ =>
|
||||
channels collect {
|
||||
case c: ConsoleChannel =>
|
||||
c.publishEventMessage(event)
|
||||
case c: NetworkChannel =>
|
||||
try {
|
||||
c.publishEventMessage(event)
|
||||
} catch {
|
||||
case _: IOException =>
|
||||
toDel += c
|
||||
}
|
||||
case c: ConsoleChannel => c.publishEventMessage(event)
|
||||
case c: NetworkChannel => tryTo(c.publishEventMessage(event), c)
|
||||
}
|
||||
}
|
||||
|
||||
toDel.toList match {
|
||||
case Nil => // do nothing
|
||||
case xs =>
|
||||
|
|
|
|||
|
|
@ -36,12 +36,15 @@ private[sbt] abstract class BackgroundJob {
|
|||
}
|
||||
|
||||
def shutdown(): Unit
|
||||
|
||||
// this should be true on construction and stay true until
|
||||
// the job is complete
|
||||
def isRunning(): Boolean
|
||||
|
||||
// called after stop or on spontaneous exit, closing the result
|
||||
// removes the listener
|
||||
def onStop(listener: () => Unit)(implicit ex: ExecutionContext): Closeable
|
||||
|
||||
// do we need this or is the spawning task good enough?
|
||||
// def tags: SomeType
|
||||
}
|
||||
|
|
@ -57,8 +60,8 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe
|
|||
private val serviceTempDir = IO.createTemporaryDirectory
|
||||
|
||||
// hooks for sending start/stop events
|
||||
protected def onAddJob(job: JobHandle): Unit = {}
|
||||
protected def onRemoveJob(job: JobHandle): Unit = {}
|
||||
protected def onAddJob(@deprecated("unused", "") job: JobHandle): Unit = ()
|
||||
protected def onRemoveJob(@deprecated("unused", "") job: JobHandle): Unit = ()
|
||||
|
||||
// this mutable state could conceptually go on State except
|
||||
// that then every task that runs a background job would have
|
||||
|
|
|
|||
|
|
@ -8,11 +8,18 @@
|
|||
package sbt
|
||||
package internal
|
||||
|
||||
import sbt.internal.util.{ complete, AttributeEntry, AttributeKey, LineRange, MessageOnlyException, RangePosition, Settings }
|
||||
import sbt.internal.util.{
|
||||
AttributeEntry,
|
||||
AttributeKey,
|
||||
LineRange,
|
||||
MessageOnlyException,
|
||||
RangePosition,
|
||||
Settings
|
||||
}
|
||||
|
||||
import java.io.File
|
||||
import compiler.{ Eval, EvalImports }
|
||||
import complete.DefaultParsers.validID
|
||||
import sbt.internal.util.complete.DefaultParsers.validID
|
||||
import Def.{ ScopedKey, Setting }
|
||||
import Scope.GlobalScope
|
||||
import sbt.internal.parser.SbtParser
|
||||
|
|
@ -37,7 +44,9 @@ private[sbt] object EvaluateConfigurations {
|
|||
/**
|
||||
* This represents the parsed expressions in a build sbt, as well as where they were defined.
|
||||
*/
|
||||
private[this] final class ParsedFile(val imports: Seq[(String, Int)], val definitions: Seq[(String, LineRange)], val settings: Seq[(String, LineRange)])
|
||||
private[this] final class ParsedFile(val imports: Seq[(String, Int)],
|
||||
val definitions: Seq[(String, LineRange)],
|
||||
val settings: Seq[(String, LineRange)])
|
||||
|
||||
/** The keywords we look for when classifying a string as a definition. */
|
||||
private[this] val DefinitionKeywords = Seq("lazy val ", "def ", "val ")
|
||||
|
|
@ -48,18 +57,24 @@ private[sbt] object EvaluateConfigurations {
|
|||
* return a parsed, compiled + evaluated [[LoadedSbtFile]]. The result has
|
||||
* raw sbt-types that can be accessed and used.
|
||||
*/
|
||||
def apply(eval: Eval, srcs: Seq[File], imports: Seq[String]): LazyClassLoaded[LoadedSbtFile] =
|
||||
{
|
||||
val loadFiles = srcs.sortBy(_.getName) map { src => evaluateSbtFile(eval, src, IO.readLines(src), imports, 0) }
|
||||
loader => (LoadedSbtFile.empty /: loadFiles) { (loaded, load) => loaded merge load(loader) }
|
||||
def apply(eval: Eval, srcs: Seq[File], imports: Seq[String]): LazyClassLoaded[LoadedSbtFile] = {
|
||||
val loadFiles = srcs.sortBy(_.getName) map { src =>
|
||||
evaluateSbtFile(eval, src, IO.readLines(src), imports, 0)
|
||||
}
|
||||
loader =>
|
||||
(LoadedSbtFile.empty /: loadFiles) { (loaded, load) =>
|
||||
loaded merge load(loader)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a given .sbt file and evaluates it into a sequence of setting values.
|
||||
*
|
||||
* Note: This ignores any non-Setting[_] values in the file.
|
||||
*/
|
||||
def evaluateConfiguration(eval: Eval, src: File, imports: Seq[String]): LazyClassLoaded[Seq[Setting[_]]] =
|
||||
def evaluateConfiguration(eval: Eval,
|
||||
src: File,
|
||||
imports: Seq[String]): LazyClassLoaded[Seq[Setting[_]]] =
|
||||
evaluateConfiguration(eval, src, IO.readLines(src), imports, 0)
|
||||
|
||||
/**
|
||||
|
|
@ -68,13 +83,16 @@ private[sbt] object EvaluateConfigurations {
|
|||
*
|
||||
* @param builtinImports The set of import statements to add to those parsed in the .sbt file.
|
||||
*/
|
||||
private[this] def parseConfiguration(file: File, lines: Seq[String], builtinImports: Seq[String], offset: Int): ParsedFile =
|
||||
{
|
||||
val (importStatements, settingsAndDefinitions) = splitExpressions(file, lines)
|
||||
val allImports = builtinImports.map(s => (s, -1)) ++ addOffset(offset, importStatements)
|
||||
val (definitions, settings) = splitSettingsDefinitions(addOffsetToRange(offset, settingsAndDefinitions))
|
||||
new ParsedFile(allImports, definitions, settings)
|
||||
}
|
||||
private[this] def parseConfiguration(file: File,
|
||||
lines: Seq[String],
|
||||
builtinImports: Seq[String],
|
||||
offset: Int): ParsedFile = {
|
||||
val (importStatements, settingsAndDefinitions) = splitExpressions(file, lines)
|
||||
val allImports = builtinImports.map(s => (s, -1)) ++ addOffset(offset, importStatements)
|
||||
val (definitions, settings) = splitSettingsDefinitions(
|
||||
addOffsetToRange(offset, settingsAndDefinitions))
|
||||
new ParsedFile(allImports, definitions, settings)
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a parsed sbt configuration file.
|
||||
|
|
@ -86,11 +104,15 @@ private[sbt] object EvaluateConfigurations {
|
|||
*
|
||||
* @return Just the Setting[_] instances defined in the .sbt file.
|
||||
*/
|
||||
def evaluateConfiguration(eval: Eval, file: File, lines: Seq[String], imports: Seq[String], offset: Int): LazyClassLoaded[Seq[Setting[_]]] =
|
||||
{
|
||||
val l = evaluateSbtFile(eval, file, lines, imports, offset)
|
||||
loader => l(loader).settings
|
||||
}
|
||||
def evaluateConfiguration(eval: Eval,
|
||||
file: File,
|
||||
lines: Seq[String],
|
||||
imports: Seq[String],
|
||||
offset: Int): LazyClassLoaded[Seq[Setting[_]]] = {
|
||||
val l = evaluateSbtFile(eval, file, lines, imports, offset)
|
||||
loader =>
|
||||
l(loader).settings
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a parsed sbt configuration file.
|
||||
|
|
@ -102,27 +124,33 @@ private[sbt] object EvaluateConfigurations {
|
|||
* @return A function which can take an sbt classloader and return the raw types/configuration
|
||||
* which was compiled/parsed for the given file.
|
||||
*/
|
||||
private[sbt] def evaluateSbtFile(eval: Eval, file: File, lines: Seq[String], imports: Seq[String], offset: Int): LazyClassLoaded[LoadedSbtFile] =
|
||||
{
|
||||
// TODO - Store the file on the LoadedSbtFile (or the parent dir) so we can accurately do
|
||||
// detection for which project project manipulations should be applied.
|
||||
val name = file.getPath
|
||||
val parsed = parseConfiguration(file, lines, imports, offset)
|
||||
val (importDefs, definitions) =
|
||||
if (parsed.definitions.isEmpty) (Nil, DefinedSbtValues.empty) else {
|
||||
val definitions = evaluateDefinitions(eval, name, parsed.imports, parsed.definitions, Some(file))
|
||||
val imp = BuildUtil.importAllRoot(definitions.enclosingModule :: Nil)
|
||||
(imp, DefinedSbtValues(definitions))
|
||||
}
|
||||
val allImports = importDefs.map(s => (s, -1)) ++ parsed.imports
|
||||
val dslEntries = parsed.settings map {
|
||||
case (dslExpression, range) =>
|
||||
evaluateDslEntry(eval, name, allImports, dslExpression, range)
|
||||
private[sbt] def evaluateSbtFile(eval: Eval,
|
||||
file: File,
|
||||
lines: Seq[String],
|
||||
imports: Seq[String],
|
||||
offset: Int): LazyClassLoaded[LoadedSbtFile] = {
|
||||
// TODO - Store the file on the LoadedSbtFile (or the parent dir) so we can accurately do
|
||||
// detection for which project project manipulations should be applied.
|
||||
val name = file.getPath
|
||||
val parsed = parseConfiguration(file, lines, imports, offset)
|
||||
val (importDefs, definitions) =
|
||||
if (parsed.definitions.isEmpty) (Nil, DefinedSbtValues.empty)
|
||||
else {
|
||||
val definitions =
|
||||
evaluateDefinitions(eval, name, parsed.imports, parsed.definitions, Some(file))
|
||||
val imp = BuildUtil.importAllRoot(definitions.enclosingModule :: Nil)
|
||||
(imp, DefinedSbtValues(definitions))
|
||||
}
|
||||
eval.unlinkDeferred()
|
||||
// Tracks all the files we generated from evaluating the sbt file.
|
||||
val allGeneratedFiles = (definitions.generated ++ dslEntries.flatMap(_.generated))
|
||||
loader => {
|
||||
val allImports = importDefs.map(s => (s, -1)) ++ parsed.imports
|
||||
val dslEntries = parsed.settings map {
|
||||
case (dslExpression, range) =>
|
||||
evaluateDslEntry(eval, name, allImports, dslExpression, range)
|
||||
}
|
||||
eval.unlinkDeferred()
|
||||
// Tracks all the files we generated from evaluating the sbt file.
|
||||
val allGeneratedFiles = (definitions.generated ++ dslEntries.flatMap(_.generated))
|
||||
loader =>
|
||||
{
|
||||
val projects =
|
||||
definitions.values(loader).collect {
|
||||
case p: Project => resolveBase(file.getParentFile, p)
|
||||
|
|
@ -140,9 +168,14 @@ private[sbt] object EvaluateConfigurations {
|
|||
case DslEntry.ProjectManipulation(f) => f
|
||||
}
|
||||
// TODO -get project manipulations.
|
||||
new LoadedSbtFile(settings, projects, importDefs, manipulations, definitions, allGeneratedFiles)
|
||||
new LoadedSbtFile(settings,
|
||||
projects,
|
||||
importDefs,
|
||||
manipulations,
|
||||
definitions,
|
||||
allGeneratedFiles)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** move a project to be relative to this file after we've evaluated it. */
|
||||
private[this] def resolveBase(f: File, p: Project) = p.copy(base = IO.resolve(f, p.base))
|
||||
|
|
@ -173,11 +206,19 @@ private[sbt] object EvaluateConfigurations {
|
|||
* @return A method that given an sbt classloader, can return the actual [[sbt.internal.DslEntry]] defined by
|
||||
* the expression, and the sequence of .class files generated.
|
||||
*/
|
||||
private[sbt] def evaluateDslEntry(eval: Eval, name: String, imports: Seq[(String, Int)], expression: String, range: LineRange): TrackedEvalResult[DslEntry] = {
|
||||
private[sbt] def evaluateDslEntry(eval: Eval,
|
||||
name: String,
|
||||
imports: Seq[(String, Int)],
|
||||
expression: String,
|
||||
range: LineRange): TrackedEvalResult[DslEntry] = {
|
||||
// TODO - Should we try to namespace these between.sbt files? IF they hash to the same value, they may actually be
|
||||
// exactly the same setting, so perhaps we don't care?
|
||||
val result = try {
|
||||
eval.eval(expression, imports = new EvalImports(imports, name), srcName = name, tpeName = Some(SettingsDefinitionName), line = range.start)
|
||||
eval.eval(expression,
|
||||
imports = new EvalImports(imports, name),
|
||||
srcName = name,
|
||||
tpeName = Some(SettingsDefinitionName),
|
||||
line = range.start)
|
||||
} catch {
|
||||
case e: sbt.compiler.EvalException => throw new MessageOnlyException(e.getMessage)
|
||||
}
|
||||
|
|
@ -206,7 +247,11 @@ private[sbt] object EvaluateConfigurations {
|
|||
*/
|
||||
// Build DSL now includes non-Setting[_] type settings.
|
||||
// Note: This method is used by the SET command, so we may want to evaluate that sucker a bit.
|
||||
def evaluateSetting(eval: Eval, name: String, imports: Seq[(String, Int)], expression: String, range: LineRange): LazyClassLoaded[Seq[Setting[_]]] =
|
||||
def evaluateSetting(eval: Eval,
|
||||
name: String,
|
||||
imports: Seq[(String, Int)],
|
||||
expression: String,
|
||||
range: LineRange): LazyClassLoaded[Seq[Setting[_]]] =
|
||||
evaluateDslEntry(eval, name, imports, expression, range).result andThen {
|
||||
case DslEntry.ProjectSettings(values) => values
|
||||
case _ => Nil
|
||||
|
|
@ -216,44 +261,59 @@ private[sbt] object EvaluateConfigurations {
|
|||
* Splits a set of lines into (imports, expressions). That is,
|
||||
* anything on the right of the tuple is a scala expression (definition or setting).
|
||||
*/
|
||||
private[sbt] def splitExpressions(file: File, lines: Seq[String]): (Seq[(String, Int)], Seq[(String, LineRange)]) =
|
||||
{
|
||||
val split = SbtParser(file, lines)
|
||||
// TODO - Look at pulling the parsed expression trees from the SbtParser and stitch them back into a different
|
||||
// scala compiler rather than re-parsing.
|
||||
(split.imports, split.settings)
|
||||
}
|
||||
private[sbt] def splitExpressions(
|
||||
file: File,
|
||||
lines: Seq[String]): (Seq[(String, Int)], Seq[(String, LineRange)]) = {
|
||||
val split = SbtParser(file, lines)
|
||||
// TODO - Look at pulling the parsed expression trees from the SbtParser and stitch them back into a different
|
||||
// scala compiler rather than re-parsing.
|
||||
(split.imports, split.settings)
|
||||
}
|
||||
|
||||
private[this] def splitSettingsDefinitions(lines: Seq[(String, LineRange)]): (Seq[(String, LineRange)], Seq[(String, LineRange)]) =
|
||||
lines partition { case (line, range) => isDefinition(line) }
|
||||
private[this] def splitSettingsDefinitions(
|
||||
lines: Seq[(String, LineRange)]): (Seq[(String, LineRange)], Seq[(String, LineRange)]) =
|
||||
lines partition { case (line, _) => isDefinition(line) }
|
||||
|
||||
private[this] def isDefinition(line: String): Boolean =
|
||||
{
|
||||
val trimmed = line.trim
|
||||
DefinitionKeywords.exists(trimmed startsWith _)
|
||||
}
|
||||
private[this] def isDefinition(line: String): Boolean = {
|
||||
val trimmed = line.trim
|
||||
DefinitionKeywords.exists(trimmed startsWith _)
|
||||
}
|
||||
|
||||
private[this] def extractedValTypes: Seq[String] =
|
||||
Seq(classOf[Project], classOf[InputKey[_]], classOf[TaskKey[_]], classOf[SettingKey[_]]).map(_.getName)
|
||||
Seq(classOf[Project], classOf[InputKey[_]], classOf[TaskKey[_]], classOf[SettingKey[_]])
|
||||
.map(_.getName)
|
||||
|
||||
private[this] def evaluateDefinitions(eval: Eval, name: String, imports: Seq[(String, Int)], definitions: Seq[(String, LineRange)], file: Option[File]): compiler.EvalDefinitions =
|
||||
{
|
||||
val convertedRanges = definitions.map { case (s, r) => (s, r.start to r.end) }
|
||||
eval.evalDefinitions(convertedRanges, new EvalImports(imports, name), name, file, extractedValTypes)
|
||||
}
|
||||
private[this] def evaluateDefinitions(eval: Eval,
|
||||
name: String,
|
||||
imports: Seq[(String, Int)],
|
||||
definitions: Seq[(String, LineRange)],
|
||||
file: Option[File]): compiler.EvalDefinitions = {
|
||||
val convertedRanges = definitions.map { case (s, r) => (s, r.start to r.end) }
|
||||
eval.evalDefinitions(convertedRanges,
|
||||
new EvalImports(imports, name),
|
||||
name,
|
||||
file,
|
||||
extractedValTypes)
|
||||
}
|
||||
}
|
||||
|
||||
object Index {
|
||||
def taskToKeyMap(data: Settings[Scope]): Map[Task[_], ScopedKey[Task[_]]] =
|
||||
{
|
||||
// AttributeEntry + the checked type test 'value: Task[_]' ensures that the cast is correct.
|
||||
// (scalac couldn't determine that 'key' is of type AttributeKey[Task[_]] on its own and a type match still required the cast)
|
||||
val pairs = for (scope <- data.scopes; AttributeEntry(key, value: Task[_]) <- data.data(scope).entries) yield (value, ScopedKey(scope, key.asInstanceOf[AttributeKey[Task[_]]])) // unclear why this cast is needed even with a type test in the above filter
|
||||
pairs.toMap[Task[_], ScopedKey[Task[_]]]
|
||||
}
|
||||
def taskToKeyMap(data: Settings[Scope]): Map[Task[_], ScopedKey[Task[_]]] = {
|
||||
|
||||
val pairs = data.scopes flatMap (scope =>
|
||||
data.data(scope).entries collect {
|
||||
case AttributeEntry(key, value: Task[_]) =>
|
||||
(value, ScopedKey(scope, key.asInstanceOf[AttributeKey[Task[_]]]))
|
||||
})
|
||||
|
||||
pairs.toMap[Task[_], ScopedKey[Task[_]]]
|
||||
}
|
||||
|
||||
def allKeys(settings: Seq[Setting[_]]): Set[ScopedKey[_]] =
|
||||
settings.flatMap(s => if (s.key.key.isLocal) Nil else s.key +: s.dependencies).filter(!_.key.isLocal).toSet
|
||||
settings
|
||||
.flatMap(s => if (s.key.key.isLocal) Nil else s.key +: s.dependencies)
|
||||
.filter(!_.key.isLocal)
|
||||
.toSet
|
||||
|
||||
def attributeKeys(settings: Settings[Scope]): Set[AttributeKey[_]] =
|
||||
settings.data.values.flatMap(_.keys).toSet[AttributeKey[_]]
|
||||
|
|
@ -261,30 +321,36 @@ object Index {
|
|||
def stringToKeyMap(settings: Set[AttributeKey[_]]): Map[String, AttributeKey[_]] =
|
||||
stringToKeyMap0(settings)(_.label)
|
||||
|
||||
private[this] def stringToKeyMap0(settings: Set[AttributeKey[_]])(label: AttributeKey[_] => String): Map[String, AttributeKey[_]] =
|
||||
{
|
||||
val multiMap = settings.groupBy(label)
|
||||
val duplicates = multiMap collect { case (k, xs) if xs.size > 1 => (k, xs.map(_.manifest)) } collect { case (k, xs) if xs.size > 1 => (k, xs) }
|
||||
if (duplicates.isEmpty)
|
||||
multiMap.collect { case (k, v) if validID(k) => (k, v.head) } toMap
|
||||
else
|
||||
sys.error(duplicates map { case (k, tps) => "'" + k + "' (" + tps.mkString(", ") + ")" } mkString ("Some keys were defined with the same name but different types: ", ", ", ""))
|
||||
private[this] def stringToKeyMap0(settings: Set[AttributeKey[_]])(
|
||||
label: AttributeKey[_] => String): Map[String, AttributeKey[_]] = {
|
||||
val multiMap = settings.groupBy(label)
|
||||
val duplicates = multiMap collect { case (k, xs) if xs.size > 1 => (k, xs.map(_.manifest)) } collect {
|
||||
case (k, xs) if xs.size > 1 => (k, xs)
|
||||
}
|
||||
if (duplicates.isEmpty)
|
||||
multiMap.collect { case (k, v) if validID(k) => (k, v.head) } toMap
|
||||
else
|
||||
sys.error(
|
||||
duplicates map { case (k, tps) => "'" + k + "' (" + tps.mkString(", ") + ")" } mkString ("Some keys were defined with the same name but different types: ", ", ", ""))
|
||||
}
|
||||
|
||||
private[this]type TriggerMap = collection.mutable.HashMap[Task[_], Seq[Task[_]]]
|
||||
private[this] type TriggerMap = collection.mutable.HashMap[Task[_], Seq[Task[_]]]
|
||||
|
||||
def triggers(ss: Settings[Scope]): Triggers[Task] =
|
||||
{
|
||||
val runBefore = new TriggerMap
|
||||
val triggeredBy = new TriggerMap
|
||||
for ((_, amap) <- ss.data; AttributeEntry(_, value: Task[_]) <- amap.entries) {
|
||||
val as = value.info.attributes
|
||||
update(runBefore, value, as get Keys.runBefore)
|
||||
update(triggeredBy, value, as get Keys.triggeredBy)
|
||||
def triggers(ss: Settings[Scope]): Triggers[Task] = {
|
||||
val runBefore = new TriggerMap
|
||||
val triggeredBy = new TriggerMap
|
||||
ss.data.values foreach (
|
||||
_.entries foreach {
|
||||
case AttributeEntry(_, value: Task[_]) =>
|
||||
val as = value.info.attributes
|
||||
update(runBefore, value, as get Keys.runBefore)
|
||||
update(triggeredBy, value, as get Keys.triggeredBy)
|
||||
case _ => ()
|
||||
}
|
||||
val onComplete = Keys.onComplete in GlobalScope get ss getOrElse { () => () }
|
||||
new Triggers[Task](runBefore, triggeredBy, map => { onComplete(); map })
|
||||
}
|
||||
)
|
||||
val onComplete = Keys.onComplete in GlobalScope get ss getOrElse (() => ())
|
||||
new Triggers[Task](runBefore, triggeredBy, map => { onComplete(); map })
|
||||
}
|
||||
|
||||
private[this] def update(map: TriggerMap, base: Task[_], tasksOpt: Option[Seq[Task[_]]]): Unit =
|
||||
for (tasks <- tasksOpt; task <- tasks)
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ object GlobalPlugin {
|
|||
val nv = nodeView(state, str, roots)
|
||||
val config = EvaluateTask.extractedTaskConfig(Project.extract(state), structure, state)
|
||||
val (newS, result) = runTask(t, state, str, structure.index.triggers, config)(nv)
|
||||
(newS, processResult(result, newS.log))
|
||||
(newS, processResult2(result))
|
||||
}
|
||||
}
|
||||
val globalPluginSettings = Project.inScope(Scope.GlobalScope in LocalRootProject)(
|
||||
|
|
|
|||
|
|
@ -37,18 +37,12 @@ private[sbt] object LibraryManagement {
|
|||
): UpdateReport = {
|
||||
|
||||
/* Resolve the module settings from the inputs. */
|
||||
def resolve(inputs: UpdateInputs): UpdateReport = {
|
||||
def resolve: UpdateReport = {
|
||||
import sbt.util.ShowLines._
|
||||
|
||||
log.info(s"Updating $label...")
|
||||
val reportOrUnresolved: Either[UnresolvedWarning, UpdateReport] =
|
||||
//try {
|
||||
lm.update(module, updateConfig, uwConfig, log)
|
||||
// } catch {
|
||||
// case e: Throwable =>
|
||||
// e.printStackTrace
|
||||
// throw e
|
||||
// }
|
||||
val report = reportOrUnresolved match {
|
||||
case Right(report0) => report0
|
||||
case Left(unresolvedWarning) =>
|
||||
|
|
@ -96,12 +90,12 @@ private[sbt] object LibraryManagement {
|
|||
import sbt.librarymanagement.LibraryManagementCodec._
|
||||
val cachedResolve = Tracked.lastOutput[UpdateInputs, UpdateReport](cache) {
|
||||
case (_, Some(out)) if upToDate(inChanged, out) => markAsCached(out)
|
||||
case _ => resolve(updateInputs)
|
||||
case _ => resolve
|
||||
}
|
||||
import scala.util.control.Exception.catching
|
||||
catching(classOf[NullPointerException], classOf[OutOfMemoryError])
|
||||
.withApply { t =>
|
||||
val resolvedAgain = resolve(updateInputs)
|
||||
val resolvedAgain = resolve
|
||||
val culprit = t.getClass.getSimpleName
|
||||
log.warn(s"Update task caching failed due to $culprit.")
|
||||
log.warn("Report the following output to sbt:")
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ private[sbt] object Load {
|
|||
val globalBase = getGlobalBase(state)
|
||||
val base = baseDirectory.getCanonicalFile
|
||||
val rawConfig = defaultPreGlobal(state, base, globalBase, log)
|
||||
val config0 = defaultWithGlobal(state, base, rawConfig, globalBase, log)
|
||||
val config0 = defaultWithGlobal(state, base, rawConfig, globalBase)
|
||||
val config =
|
||||
if (isPlugin) enableSbtPlugin(config0) else config0.copy(extraBuilds = topLevelExtras)
|
||||
(base, config)
|
||||
|
|
@ -109,7 +109,7 @@ private[sbt] object Load {
|
|||
javaHome = None,
|
||||
scalac
|
||||
)
|
||||
val evalPluginDef = EvaluateTask.evalPluginDef(log) _
|
||||
val evalPluginDef: (BuildStructure, State) => PluginData = EvaluateTask.evalPluginDef _
|
||||
val delegates = defaultDelegates
|
||||
val pluginMgmt = PluginManagement(loader)
|
||||
val inject = InjectSettings(injectGlobal(state), Nil, const(Nil))
|
||||
|
|
@ -145,7 +145,6 @@ private[sbt] object Load {
|
|||
base: File,
|
||||
rawConfig: LoadBuildConfiguration,
|
||||
globalBase: File,
|
||||
log: Logger
|
||||
): LoadBuildConfiguration = {
|
||||
val globalPluginsDir = getGlobalPluginsDirectory(state, globalBase)
|
||||
val withGlobal = loadGlobal(state, base, globalPluginsDir, rawConfig)
|
||||
|
|
@ -208,7 +207,6 @@ private[sbt] object Load {
|
|||
project => projectInherit(lb, project),
|
||||
(project, config) => configInherit(lb, project, config, rootProject),
|
||||
task => task.extend,
|
||||
(project, extra) => Nil
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import Keys.{ logLevel, logManager, persistLogLevel, persistTraceLevel, sLog, tr
|
|||
import scala.Console.{ BLUE, RESET }
|
||||
import sbt.internal.util.{
|
||||
AttributeKey,
|
||||
ConsoleAppender,
|
||||
ConsoleOut,
|
||||
Settings,
|
||||
SuppressedTraceContext,
|
||||
|
|
@ -105,7 +106,7 @@ object LogManager {
|
|||
|
||||
def backgroundLog(data: Settings[Scope], state: State, task: ScopedKey[_]): ManagedLogger = {
|
||||
val console = screen(task, state)
|
||||
LogManager.backgroundLog(data, state, task, console, relay(()), extra(task).toList)
|
||||
LogManager.backgroundLog(data, state, task, console, relay(()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -191,7 +192,6 @@ object LogManager {
|
|||
console: Appender,
|
||||
/* TODO: backed: Appender,*/
|
||||
relay: Appender,
|
||||
extra: List[Appender]
|
||||
): ManagedLogger = {
|
||||
val scope = task.scope
|
||||
val screenLevel = getOr(logLevel.key, data, scope, state, Level.Info)
|
||||
|
|
@ -253,7 +253,7 @@ object LogManager {
|
|||
private[this] def slog: Logger =
|
||||
Option(ref.get) getOrElse sys.error("Settings logger used after project was loaded.")
|
||||
|
||||
override val ansiCodesSupported = slog.ansiCodesSupported
|
||||
override val ansiCodesSupported = ConsoleAppender.formatEnabledInEnv
|
||||
override def trace(t: => Throwable) = slog.trace(t)
|
||||
override def success(message: => String) = slog.success(message)
|
||||
override def log(level: Level.Value, message: => String) = slog.log(level, message)
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ private[sbt] class PluginsDebug(
|
|||
if (possible.nonEmpty) {
|
||||
val explained = possible.map(explainPluginEnable)
|
||||
val possibleString =
|
||||
if (explained.size > 1)
|
||||
if (explained.lengthCompare(1) > 0)
|
||||
explained.zipWithIndex
|
||||
.map { case (s, i) => s"$i. $s" }
|
||||
.mkString(s"Multiple plugins are available that can provide $notFoundKey:\n", "\n", "")
|
||||
|
|
@ -111,7 +111,7 @@ private[sbt] class PluginsDebug(
|
|||
}
|
||||
|
||||
private[this] def multi(strs: Seq[String]): String =
|
||||
strs.mkString(if (strs.size > 4) "\n\t" else ", ")
|
||||
strs.mkString(if (strs.lengthCompare(4) > 0) "\n\t" else ", ")
|
||||
}
|
||||
|
||||
private[sbt] object PluginsDebug {
|
||||
|
|
@ -377,7 +377,7 @@ private[sbt] object PluginsDebug {
|
|||
def explainPluginEnable(ps: PluginEnable): String =
|
||||
ps match {
|
||||
case PluginRequirements(plugin,
|
||||
context,
|
||||
_,
|
||||
blockingExcludes,
|
||||
enablingPlugins,
|
||||
extraEnabledPlugins,
|
||||
|
|
@ -393,9 +393,8 @@ private[sbt] object PluginsDebug {
|
|||
note(willRemove(plugin, toBeRemoved.toList)) ::
|
||||
Nil
|
||||
parts.filterNot(_.isEmpty).mkString("\n")
|
||||
case PluginImpossible(plugin, context, contradictions) =>
|
||||
pluginImpossible(plugin, contradictions)
|
||||
case PluginActivated(plugin, context) => s"Plugin ${plugin.label} already activated."
|
||||
case PluginImpossible(plugin, _, contradictions) => pluginImpossible(plugin, contradictions)
|
||||
case PluginActivated(plugin, _) => s"Plugin ${plugin.label} already activated."
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class RelayAppender(name: String)
|
|||
val level = ConsoleAppender.toLevel(event.getLevel)
|
||||
val message = event.getMessage
|
||||
message match {
|
||||
case o: ObjectMessage => appendEvent(level, o.getParameter)
|
||||
case o: ObjectMessage => appendEvent(o.getParameter)
|
||||
case p: ParameterizedMessage => appendLog(level, p.getFormattedMessage)
|
||||
case r: RingBufferLogEvent => appendLog(level, r.getFormattedMessage)
|
||||
case _ => appendLog(level, message.toString)
|
||||
|
|
@ -35,7 +35,7 @@ class RelayAppender(name: String)
|
|||
def appendLog(level: Level.Value, message: => String): Unit = {
|
||||
exchange.publishEventMessage(LogEvent(level.toString, message))
|
||||
}
|
||||
def appendEvent(level: Level.Value, event: AnyRef): Unit =
|
||||
def appendEvent(event: AnyRef): Unit =
|
||||
event match {
|
||||
case x: StringEvent => {
|
||||
import JsonProtocol._
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import sbt.librarymanagement.Configuration
|
|||
import Project._
|
||||
import Def.{ ScopedKey, Setting }
|
||||
import Scope.Global
|
||||
import Types.{ const, idFun }
|
||||
import Types.idFun
|
||||
import complete._
|
||||
import DefaultParsers._
|
||||
|
||||
|
|
@ -64,11 +64,10 @@ private[sbt] object SettingCompletions {
|
|||
setResult(session, r, redefined)
|
||||
}
|
||||
|
||||
/** Implementation of the `set` command that will reload the current project with `settings` appended to the current settings. */
|
||||
def setThis(s: State,
|
||||
extracted: Extracted,
|
||||
settings: Seq[Def.Setting[_]],
|
||||
arg: String): SetResult = {
|
||||
/** Implementation of the `set` command that will reload the current project with `settings`
|
||||
* appended to the current settings.
|
||||
*/
|
||||
def setThis(extracted: Extracted, settings: Seq[Def.Setting[_]], arg: String): SetResult = {
|
||||
import extracted._
|
||||
val append =
|
||||
Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, settings)
|
||||
|
|
@ -82,16 +81,19 @@ private[sbt] object SettingCompletions {
|
|||
private[this] def setResult(
|
||||
session: SessionSettings,
|
||||
r: Relation[ScopedKey[_], ScopedKey[_]],
|
||||
redefined: Seq[Setting[_]])(implicit show: Show[ScopedKey[_]]): SetResult = {
|
||||
redefined: Seq[Setting[_]],
|
||||
)(implicit show: Show[ScopedKey[_]]): SetResult = {
|
||||
val redefinedKeys = redefined.map(_.key).toSet
|
||||
val affectedKeys = redefinedKeys.flatMap(r.reverse)
|
||||
def summary(verbose: Boolean): String = setSummary(redefinedKeys, affectedKeys, verbose)
|
||||
new SetResult(session, summary(true), summary(false))
|
||||
}
|
||||
|
||||
private[this] def setSummary(redefined: Set[ScopedKey[_]],
|
||||
affected: Set[ScopedKey[_]],
|
||||
verbose: Boolean)(implicit display: Show[ScopedKey[_]]): String = {
|
||||
private[this] def setSummary(
|
||||
redefined: Set[ScopedKey[_]],
|
||||
affected: Set[ScopedKey[_]],
|
||||
verbose: Boolean,
|
||||
)(implicit display: Show[ScopedKey[_]]): String = {
|
||||
val QuietLimit = 3
|
||||
def strings(in: Set[ScopedKey[_]]): Seq[String] = in.toSeq.map(sk => display.show(sk)).sorted
|
||||
def lines(in: Seq[String]): (String, Boolean) =
|
||||
|
|
@ -129,17 +131,17 @@ private[sbt] object SettingCompletions {
|
|||
* when there are fewer choices or tab is pressed multiple times.
|
||||
* The last part of the completion will generate a template for the value or function literal that will initialize the setting or task.
|
||||
*/
|
||||
def settingParser(settings: Settings[Scope],
|
||||
rawKeyMap: Map[String, AttributeKey[_]],
|
||||
context: ResolvedProject): Parser[String] = {
|
||||
val keyMap
|
||||
: Map[String, AttributeKey[_]] = rawKeyMap.map { case (k, v) => (keyScalaID(k), v) }.toMap
|
||||
def inputScopedKey(pred: AttributeKey[_] => Boolean): Parser[ScopedKey[_]] =
|
||||
scopedKeyParser(keyMap.filter { case (_, k) => pred(k) }, settings, context)
|
||||
def settingParser(
|
||||
settings: Settings[Scope],
|
||||
rawKeyMap: Map[String, AttributeKey[_]],
|
||||
context: ResolvedProject,
|
||||
): Parser[String] = {
|
||||
val keyMap: Map[String, AttributeKey[_]] =
|
||||
rawKeyMap.map { case (k, v) => (keyScalaID(k), v) }.toMap
|
||||
val full = for {
|
||||
defineKey <- scopedKeyParser(keyMap, settings, context)
|
||||
a <- assign(defineKey)
|
||||
_ <- valueParser(defineKey, a, inputScopedKey(keyFilter(defineKey.key)))
|
||||
_ <- valueParser(defineKey, a)
|
||||
} yield
|
||||
() // parser is currently only for completion and the parsed data structures are not used
|
||||
|
||||
|
|
@ -167,9 +169,7 @@ private[sbt] object SettingCompletions {
|
|||
* Parser for the initialization expression for the assignment method `assign` on the key `sk`.
|
||||
* `scopedKeyP` is used to parse and complete the input keys for an initialization that depends on other keys.
|
||||
*/
|
||||
def valueParser(sk: ScopedKey[_],
|
||||
assign: Assign.Value,
|
||||
scopedKeyP: Parser[ScopedKey[_]]): Parser[Seq[ScopedKey[_]]] = {
|
||||
def valueParser(sk: ScopedKey[_], assign: Assign.Value): Parser[Seq[ScopedKey[_]]] = {
|
||||
val fullTypeString = keyTypeString(sk.key)
|
||||
val typeString = if (assignNoAppend(assign)) fullTypeString else "..."
|
||||
if (assign == Assign.Update) {
|
||||
|
|
@ -181,14 +181,6 @@ private[sbt] object SettingCompletions {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For a setting definition `definingKey <<= (..., in, ...) { ... }`,
|
||||
* `keyFilter(definingKey)(in)` returns true when `in` is an allowed input for `definingKey` based on whether they are settings or not.
|
||||
* For example, if `definingKey` is for a setting, `in` may only be a setting itself.
|
||||
*/
|
||||
def keyFilter(definingKey: AttributeKey[_]): AttributeKey[_] => Boolean =
|
||||
if (isSetting(definingKey)) isSetting _ else isTaskOrSetting _
|
||||
|
||||
/**
|
||||
* Parser for a Scope for a `key` given the current project `context` and evaluated `settings`.
|
||||
* The completions are restricted to be more useful. Currently, this parser will suggest
|
||||
|
|
@ -202,17 +194,20 @@ private[sbt] object SettingCompletions {
|
|||
val definedScopes = data.toSeq flatMap {
|
||||
case (scope, attrs) => if (attrs contains key) scope :: Nil else Nil
|
||||
}
|
||||
scope(key, allScopes, definedScopes, context)
|
||||
scope(allScopes, definedScopes, context)
|
||||
}
|
||||
|
||||
private[this] def scope(key: AttributeKey[_],
|
||||
allScopes: Seq[Scope],
|
||||
definedScopes: Seq[Scope],
|
||||
context: ResolvedProject): Parser[Scope] = {
|
||||
def axisParser[T](axis: Scope => ScopeAxis[T],
|
||||
name: T => String,
|
||||
description: T => Option[String],
|
||||
label: String): Parser[ScopeAxis[T]] = {
|
||||
private[this] def scope(
|
||||
allScopes: Seq[Scope],
|
||||
definedScopes: Seq[Scope],
|
||||
context: ResolvedProject,
|
||||
): Parser[Scope] = {
|
||||
def axisParser[T](
|
||||
axis: Scope => ScopeAxis[T],
|
||||
name: T => String,
|
||||
description: T => Option[String],
|
||||
label: String,
|
||||
): Parser[ScopeAxis[T]] = {
|
||||
def getChoice(s: Scope): Seq[(String, T)] = axis(s) match {
|
||||
case Select(t) => (name(t), t) :: Nil
|
||||
case _ => Nil
|
||||
|
|
@ -220,19 +215,23 @@ private[sbt] object SettingCompletions {
|
|||
def getChoices(scopes: Seq[Scope]): Map[String, T] = scopes.flatMap(getChoice).toMap
|
||||
val definedChoices: Set[String] =
|
||||
definedScopes.flatMap(s => axis(s).toOption.map(name)).toSet
|
||||
val fullChoices: Map[String, T] = getChoices(allScopes.toSeq)
|
||||
val fullChoices: Map[String, T] = getChoices(allScopes)
|
||||
val completions = fixedCompletions { (seen, level) =>
|
||||
completeScope(seen, level, definedChoices, fullChoices)(description).toSet
|
||||
}
|
||||
Act.optionalAxis(inParser ~> token(Space) ~> token(scalaID(fullChoices, label), completions),
|
||||
This)
|
||||
Act.optionalAxis(
|
||||
inParser ~> token(Space) ~> token(scalaID(fullChoices, label), completions),
|
||||
This,
|
||||
)
|
||||
}
|
||||
val configurations: Map[String, Configuration] =
|
||||
context.configurations.map(c => (configScalaID(c.name), c)).toMap
|
||||
val configParser = axisParser[ConfigKey](_.config,
|
||||
c => configScalaID(c.name),
|
||||
ck => configurations.get(ck.name).map(_.description),
|
||||
"configuration")
|
||||
val configParser = axisParser[ConfigKey](
|
||||
_.config,
|
||||
c => configScalaID(c.name),
|
||||
ck => configurations.get(ck.name).map(_.description),
|
||||
"configuration",
|
||||
)
|
||||
val taskParser =
|
||||
axisParser[AttributeKey[_]](_.task, k => keyScalaID(k.label), _.description, "task")
|
||||
val nonGlobal = (configParser ~ taskParser) map { case (c, t) => Scope(This, c, t, Zero) }
|
||||
|
|
@ -242,8 +241,8 @@ private[sbt] object SettingCompletions {
|
|||
|
||||
/** Parser for the assignment method (such as `:=`) for defining `key`. */
|
||||
def assign(key: ScopedKey[_]): Parser[Assign.Value] = {
|
||||
val completions = fixedCompletions { (seen, level) =>
|
||||
completeAssign(seen, level, key).toSet
|
||||
val completions = fixedCompletions { (seen, _) =>
|
||||
completeAssign(seen, key).toSet
|
||||
}
|
||||
val identifier = Act.filterStrings(Op, Assign.values.map(_.toString), "assignment method") map Assign.withName
|
||||
token(Space) ~> token(optionallyQuoted(identifier), completions)
|
||||
|
|
@ -267,7 +266,7 @@ private[sbt] object SettingCompletions {
|
|||
* Completions for an assignment method for `key` given the tab completion `level` and existing partial string `seen`.
|
||||
* This will filter possible assignment methods based on the underlying type of `key`, so that only `<<=` is shown for input tasks, for example.
|
||||
*/
|
||||
def completeAssign(seen: String, level: Int, key: ScopedKey[_]): Seq[Completion] = {
|
||||
def completeAssign(seen: String, key: ScopedKey[_]): Seq[Completion] = {
|
||||
val allowed: Iterable[Assign.Value] =
|
||||
if (appendable(key.key)) Assign.values
|
||||
else assignNoAppend
|
||||
|
|
@ -284,7 +283,7 @@ private[sbt] object SettingCompletions {
|
|||
prominentCutoff: Int,
|
||||
detailLimit: Int): Seq[Completion] =
|
||||
completeSelectDescribed(seen, level, keys, detailLimit)(_.description) {
|
||||
case (k, v) => v.rank <= prominentCutoff
|
||||
case (_, v) => v.rank <= prominentCutoff
|
||||
}
|
||||
|
||||
def completeScope[T](
|
||||
|
|
@ -293,17 +292,17 @@ private[sbt] object SettingCompletions {
|
|||
definedChoices: Set[String],
|
||||
allChoices: Map[String, T])(description: T => Option[String]): Seq[Completion] =
|
||||
completeSelectDescribed(seen, level, allChoices, 10)(description) {
|
||||
case (k, v) => definedChoices(k)
|
||||
case (k, _) => definedChoices(k)
|
||||
}
|
||||
|
||||
def completeSelectDescribed[T](seen: String, level: Int, all: Map[String, T], detailLimit: Int)(
|
||||
description: T => Option[String])(prominent: (String, T) => Boolean): Seq[Completion] = {
|
||||
val applicable = all.toSeq.filter { case (k, v) => k startsWith seen }
|
||||
val applicable = all.toSeq.filter { case (k, _) => k startsWith seen }
|
||||
val prominentOnly = applicable filter { case (k, v) => prominent(k, v) }
|
||||
|
||||
val showAll = (level >= 3) || (level == 2 && prominentOnly.size <= detailLimit) || prominentOnly.isEmpty
|
||||
val showAll = (level >= 3) || (level == 2 && prominentOnly.lengthCompare(detailLimit) <= 0) || prominentOnly.isEmpty
|
||||
val showKeys = if (showAll) applicable else prominentOnly
|
||||
val showDescriptions = (level >= 2) || (showKeys.size <= detailLimit)
|
||||
val showDescriptions = (level >= 2) || showKeys.lengthCompare(detailLimit) <= 0
|
||||
completeDescribed(seen, showDescriptions, showKeys)(s => description(s).toList.mkString)
|
||||
}
|
||||
def completeDescribed[T](seen: String, showDescriptions: Boolean, in: Seq[(String, T)])(
|
||||
|
|
@ -315,14 +314,11 @@ private[sbt] object SettingCompletions {
|
|||
val withDescriptions = in map { case (id, key) => (id, description(key)) }
|
||||
val padded = CommandUtil.aligned("", " ", withDescriptions)
|
||||
(padded, in).zipped.map {
|
||||
case (line, (id, key)) =>
|
||||
case (line, (id, _)) =>
|
||||
Completion.tokenDisplay(append = appendString(id), display = line + "\n")
|
||||
}
|
||||
} else
|
||||
in map {
|
||||
case (id, key) =>
|
||||
Completion.tokenDisplay(display = id, append = appendString(id))
|
||||
}
|
||||
in map { case (id, _) => Completion.tokenDisplay(display = id, append = appendString(id)) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -364,18 +360,6 @@ private[sbt] object SettingCompletions {
|
|||
keyType(key)(mfToString, mfToString, mfToString)
|
||||
}
|
||||
|
||||
/** True if the `key` represents an input task, false if it represents a task or setting. */
|
||||
def isInputTask(key: AttributeKey[_]): Boolean =
|
||||
keyType(key)(const(false), const(false), const(true))
|
||||
|
||||
/** True if the `key` represents a setting, false if it represents a task or an input task.*/
|
||||
def isSetting(key: AttributeKey[_]): Boolean =
|
||||
keyType(key)(const(true), const(false), const(false))
|
||||
|
||||
/** True if the `key` represents a setting or task, false if it is for an input task. */
|
||||
def isTaskOrSetting(key: AttributeKey[_]): Boolean =
|
||||
keyType(key)(const(true), const(true), const(false))
|
||||
|
||||
/** True if the `key` represents a setting or task that may be appended using an assignment method such as `+=`. */
|
||||
def appendable(key: AttributeKey[_]): Boolean = {
|
||||
val underlying = keyUnderlyingType(key).runtimeClass
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ object Graph {
|
|||
val withBar = childLines.zipWithIndex flatMap {
|
||||
case ((line, withBar), pos) if pos < (cs.size - 1) =>
|
||||
(line +: withBar) map { insertBar(_, 2 * (level + 1)) }
|
||||
case ((line, withBar), pos) if withBar.lastOption.getOrElse(line).trim != "" =>
|
||||
case ((line, withBar), _) if withBar.lastOption.getOrElse(line).trim != "" =>
|
||||
(line +: withBar) ++ Vector(twoSpaces * (level + 1))
|
||||
case ((line, withBar), _) => line +: withBar
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ private[sbt] final class TaskTimings(shutdown: Boolean) extends ExecuteProgress[
|
|||
println(s"Total time: $total $unit")
|
||||
import collection.JavaConverters._
|
||||
def sumTimes(in: Seq[(Task[_], Long)]) = in.map(_._2).sum
|
||||
val timingsByName = timings.asScala.toSeq.groupBy { case (t, time) => mappedName(t) } mapValues (sumTimes)
|
||||
val timingsByName = timings.asScala.toSeq.groupBy { case (t, _) => mappedName(t) } mapValues (sumTimes)
|
||||
val times = timingsByName.toSeq
|
||||
.sortBy(_._2)
|
||||
.reverse
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ private[sbt] case class SbtParser(file: File, lines: Seq[String]) extends Parsed
|
|||
modifiedContent: String,
|
||||
imports: Seq[Tree]
|
||||
): Seq[(String, Int)] = {
|
||||
val toLineRange = imports map convertImport(modifiedContent)
|
||||
val toLineRange = imports map convertImport
|
||||
val groupedByLineNumber = toLineRange.groupBy { case (_, lineNumber) => lineNumber }
|
||||
val mergedImports = groupedByLineNumber.map {
|
||||
case (l, seq) => (l, extractLine(modifiedContent, seq))
|
||||
|
|
@ -286,12 +286,10 @@ private[sbt] case class SbtParser(file: File, lines: Seq[String]) extends Parsed
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param modifiedContent - modifiedContent
|
||||
* @param t - tree
|
||||
* @return ((start,end),lineNumber)
|
||||
* @return ((start, end), lineNumber)
|
||||
*/
|
||||
private def convertImport(modifiedContent: String)(t: Tree): ((Int, Int), Int) = {
|
||||
private def convertImport(t: Tree): ((Int, Int), Int) = {
|
||||
val lineNumber = t.pos.line - 1
|
||||
((t.pos.start, t.pos.end), lineNumber)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,10 +57,7 @@ private[sbt] object SbtRefactorings {
|
|||
commands.flatMap {
|
||||
case (_, command) =>
|
||||
val map = toTreeStringMap(command)
|
||||
map.flatMap {
|
||||
case (name, statement) =>
|
||||
treesToReplacements(split, name, command)
|
||||
}
|
||||
map.flatMap { case (name, _) => treesToReplacements(split, name, command) }
|
||||
}
|
||||
|
||||
private def treesToReplacements(split: SbtParser, name: String, command: Seq[String]) =
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ private[sbt] object Definition {
|
|||
updateCache(StandardMain.cache)(cacheFile, useBinary)
|
||||
}
|
||||
|
||||
private[sbt] def getAnalyses(log: Logger): Future[Seq[Analysis]] = {
|
||||
private[sbt] def getAnalyses: Future[Seq[Analysis]] = {
|
||||
import scalacache.modes.scalaFuture._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
StandardMain.cache
|
||||
|
|
@ -261,7 +261,7 @@ private[sbt] object Definition {
|
|||
val LspDefinitionLogHead = "lsp-definition"
|
||||
import sjsonnew.support.scalajson.unsafe.CompactPrinter
|
||||
log.debug(s"$LspDefinitionLogHead json request: ${CompactPrinter(jsonDefinition)}")
|
||||
lazy val analyses = getAnalyses(log)
|
||||
lazy val analyses = getAnalyses
|
||||
val definition = getDefinition(jsonDefinition)
|
||||
definition
|
||||
.flatMap { definition =>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import sjsonnew.support.scalajson.unsafe._
|
|||
object SettingQuery {
|
||||
import sbt.internal.util.{ AttributeKey, Settings }
|
||||
import sbt.internal.util.complete.{ DefaultParsers, Parser }, DefaultParsers._
|
||||
import sbt.Def.{ showBuildRelativeKey, ScopedKey }
|
||||
import sbt.Def.{ showBuildRelativeKey2, ScopedKey }
|
||||
|
||||
// Similar to Act.ParsedAxis / Act.projectRef / Act.resolveProject except you can't omit the project reference
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ object SettingQuery {
|
|||
data: Settings[Scope]
|
||||
): Parser[ParsedKey] =
|
||||
scopedKeyFull(index, currentBuild, defaultConfigs, keyMap) flatMap { choices =>
|
||||
Act.select(choices, data)(showBuildRelativeKey(currentBuild, index.buildURIs.size > 1))
|
||||
Act.select(choices, data)(showBuildRelativeKey2(currentBuild))
|
||||
}
|
||||
|
||||
def scopedKey(
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ object Delegates extends Properties("delegates") {
|
|||
}
|
||||
}
|
||||
property("Initial scope present with all combinations of Global axes") = allAxes(
|
||||
globalCombinations)
|
||||
(s, ds, _) => globalCombinations(s, ds))
|
||||
|
||||
property("initial scope first") = forAll { (keys: Keys) =>
|
||||
allDelegates(keys) { (scope, ds) =>
|
||||
|
|
@ -66,6 +66,7 @@ object Delegates extends Properties("delegates") {
|
|||
all(f(s, ds, _.project), f(s, ds, _.config), f(s, ds, _.task), f(s, ds, _.extra))
|
||||
}
|
||||
}
|
||||
|
||||
def allDelegates(keys: Keys)(f: (Scope, Seq[Scope]) => Prop): Prop =
|
||||
all(keys.scopes map { scope =>
|
||||
val delegates = keys.env.delegates(scope)
|
||||
|
|
@ -73,16 +74,20 @@ object Delegates extends Properties("delegates") {
|
|||
("Delegates:\n\t" + delegates.map(scope => Scope.display(scope, "_")).mkString("\n\t")) |:
|
||||
f(scope, delegates)
|
||||
}: _*)
|
||||
|
||||
def alwaysZero(s: Scope, ds: Seq[Scope], axis: Scope => ScopeAxis[_]): Prop =
|
||||
(axis(s) != Zero) ||
|
||||
all(ds map { d =>
|
||||
(axis(d) == Zero): Prop
|
||||
}: _*)
|
||||
def globalCombinations(s: Scope, ds: Seq[Scope], axis: Scope => ScopeAxis[_]): Prop = {
|
||||
val mods = List[Scope => Scope](_.copy(project = Zero),
|
||||
_.copy(config = Zero),
|
||||
_.copy(task = Zero),
|
||||
_.copy(extra = Zero))
|
||||
|
||||
def globalCombinations(s: Scope, ds: Seq[Scope]): Prop = {
|
||||
val mods = List[Scope => Scope](
|
||||
_.copy(project = Zero),
|
||||
_.copy(config = Zero),
|
||||
_.copy(task = Zero),
|
||||
_.copy(extra = Zero),
|
||||
)
|
||||
val modAndIdent = mods.map(_ :: idFun[Scope] :: Nil)
|
||||
|
||||
def loop(cur: Scope, acc: List[Scope], rem: List[Seq[Scope => Scope]]): Seq[Scope] =
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@ object ParseKey extends Properties("Key parser test") {
|
|||
("Mask: " + mask) |:
|
||||
("Current: " + structure.current) |:
|
||||
parse(structure, string) {
|
||||
case Left(err) => false
|
||||
case Right(sk) if hasZeroConfig => true
|
||||
case Right(sk) => sk.scope.project == Select(structure.current)
|
||||
case Left(_) => false
|
||||
case Right(_) if hasZeroConfig => true
|
||||
case Right(sk) => sk.scope.project == Select(structure.current)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ object ParseKey extends Properties("Key parser test") {
|
|||
("Key: " + displayPedantic(key)) |:
|
||||
("Mask: " + mask) |:
|
||||
parse(structure, string) {
|
||||
case Left(err) => false
|
||||
case Left(_) => false
|
||||
case Right(sk) => sk.scope.task == Zero
|
||||
}
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ object ParseKey extends Properties("Key parser test") {
|
|||
("Expected configuration: " + resolvedConfig.map(_.name)) |:
|
||||
parse(structure, string) {
|
||||
case Right(sk) => (sk.scope.config == resolvedConfig) || (sk.scope == Scope.GlobalScope)
|
||||
case Left(err) => false
|
||||
case Left(_) => false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ object ParseKey extends Properties("Key parser test") {
|
|||
("Expected: " + displayFull(expected)) |:
|
||||
("Mask: " + mask) |:
|
||||
parse(structure, s) {
|
||||
case Left(err) => false
|
||||
case Left(_) => false
|
||||
case Right(sk) =>
|
||||
(s"${sk}.key == ${expected}.key: ${sk.key == expected.key}") |:
|
||||
(s"${sk.scope} == ${expected.scope}: ${Scope.equal(sk.scope, expected.scope, mask)}") |:
|
||||
|
|
|
|||
|
|
@ -39,18 +39,18 @@ object PluginsTest extends Specification {
|
|||
}
|
||||
"throw an AutoPluginException on conflicting requirements" in {
|
||||
deducePlugin(S, log) must throwAn[AutoPluginException](
|
||||
message = """Contradiction in enabled plugins:
|
||||
- requested: sbt.AI\$S
|
||||
- enabled: sbt.AI\$S, sbt.AI\$Q, sbt.AI\$R, sbt.AI\$B, sbt.AI\$A
|
||||
- conflict: sbt.AI\$R is enabled by sbt.AI\$Q; excluded by sbt.AI\$S""")
|
||||
message = s"""Contradiction in enabled plugins:
|
||||
- requested: sbt.AI\\$$S
|
||||
- enabled: sbt.AI\\$$S, sbt.AI\\$$Q, sbt.AI\\$$R, sbt.AI\\$$B, sbt.AI\\$$A
|
||||
- conflict: sbt.AI\\$$R is enabled by sbt.AI\\$$Q; excluded by sbt.AI\\$$S""")
|
||||
}
|
||||
"generates a detailed report on conflicting requirements" in {
|
||||
deducePlugin(T && U, log) must throwAn[AutoPluginException](message =
|
||||
"""Contradiction in enabled plugins:
|
||||
- requested: sbt.AI\$T && sbt.AI\$U
|
||||
- enabled: sbt.AI\$U, sbt.AI\$T, sbt.AI\$A, sbt.AI\$Q, sbt.AI\$R, sbt.AI\$B
|
||||
- conflict: sbt.AI\$Q is enabled by sbt.AI\$A && sbt.AI\$B; required by sbt.AI\$T, sbt.AI\$R; excluded by sbt.AI\$U
|
||||
- conflict: sbt.AI\$R is enabled by sbt.AI\$Q; excluded by sbt.AI\$T""")
|
||||
deducePlugin(T && U, log) must throwAn[AutoPluginException](
|
||||
message = s"""Contradiction in enabled plugins:
|
||||
- requested: sbt.AI\\$$T && sbt.AI\\$$U
|
||||
- enabled: sbt.AI\\$$U, sbt.AI\\$$T, sbt.AI\\$$A, sbt.AI\\$$Q, sbt.AI\\$$R, sbt.AI\\$$B
|
||||
- conflict: sbt.AI\\$$Q is enabled by sbt.AI\\$$A && sbt.AI\\$$B; required by sbt.AI\\$$T, sbt.AI\\$$R; excluded by sbt.AI\\$$U
|
||||
- conflict: sbt.AI\\$$R is enabled by sbt.AI\\$$Q; excluded by sbt.AI\\$$T""")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,7 +142,6 @@ abstract class TestBuild {
|
|||
inheritProject,
|
||||
inheritConfig,
|
||||
inheritTask,
|
||||
(ref, mp) => Nil
|
||||
)
|
||||
lazy val allFullScopes: Seq[Scope] =
|
||||
for {
|
||||
|
|
@ -213,7 +212,7 @@ abstract class TestBuild {
|
|||
}
|
||||
|
||||
def structure(env: Env, settings: Seq[Setting[_]], current: ProjectRef): Structure = {
|
||||
implicit val display = Def.showRelativeKey(current, env.allProjects.size > 1)
|
||||
implicit val display = Def.showRelativeKey2(current)
|
||||
if (settings.isEmpty) {
|
||||
try {
|
||||
sys.error("settings is empty")
|
||||
|
|
|
|||
|
|
@ -77,8 +77,7 @@ class ErrorSpec extends AbstractSpec {
|
|||
case exception: MessageOnlyException =>
|
||||
val error = exception.getMessage
|
||||
"""(\d+)""".r.findFirstIn(error) match {
|
||||
case Some(x) =>
|
||||
true
|
||||
case Some(_) => true
|
||||
case None =>
|
||||
println(s"Number not found in $error")
|
||||
false
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ object SettingQueryTest extends org.specs2.mutable.Specification {
|
|||
.put(globalBaseDirectory, globalDirFile)
|
||||
|
||||
val config0 = defaultPreGlobal(state, baseFile, globalDirFile, state.log)
|
||||
val config = defaultWithGlobal(state, baseFile, config0, globalDirFile, state.log)
|
||||
val config = defaultWithGlobal(state, baseFile, config0, globalDirFile)
|
||||
|
||||
val buildUnit: BuildUnit = {
|
||||
val loadedPlugins: LoadedPlugins =
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ object Util {
|
|||
"-Yno-adapted-args",
|
||||
"-Ywarn-dead-code",
|
||||
"-Ywarn-numeric-widen",
|
||||
"-Ywarn-unused:-patvars,-params,-implicits,_",
|
||||
//"-Ywarn-value-discard",
|
||||
"-Ywarn-unused",
|
||||
"-Ywarn-unused-import"
|
||||
)
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
scalaVersion := "2.12.3"
|
||||
scalaVersion := "2.12.4"
|
||||
scalacOptions ++= Seq("-feature", "-language:postfixOps")
|
||||
|
||||
addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.4")
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ trait Import {
|
|||
type Cache[I, O] = sbt.util.Cache[I, O]
|
||||
val Cache = sbt.util.Cache
|
||||
val CacheImplicits = sbt.util.CacheImplicits
|
||||
@deprecated("Use Tracked.inputChanged and Tracked.outputChanged instead", "1.0.1")
|
||||
type Changed[O] = sbt.util.Changed[O]
|
||||
type ChangeReport[T] = sbt.util.ChangeReport[T]
|
||||
val ChangeReport = sbt.util.ChangeReport
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
object A {
|
||||
def main(args: Array[String]) =
|
||||
{
|
||||
assert(args(0).toInt == args(1).toInt)
|
||||
assert(java.lang.Boolean.getBoolean("sbt.check.forked"))
|
||||
}
|
||||
def main(args: Array[String]) = {
|
||||
assert(args(0).toInt == args(1).toInt)
|
||||
assert(java.lang.Boolean.getBoolean("sbt.check.forked"))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ object Common {
|
|||
val UpdateK1 = Command.command("UpdateK1") { st: State =>
|
||||
val ex = Project extract st
|
||||
import ex._
|
||||
val session2 = BuiltinCommands.setThis(st, ex, Seq(k1 := {}), """k1 := {
|
||||
val session2 = BuiltinCommands.setThis(ex, Seq(k1 := {}), """k1 := {
|
||||
|//
|
||||
|//
|
||||
|}""".stripMargin).session
|
||||
|
|
@ -24,7 +24,7 @@ object Common {
|
|||
val UpdateK3 = Command.command("UpdateK3") { st: State =>
|
||||
val ex = Project extract st
|
||||
import ex._
|
||||
val session2 = BuiltinCommands.setThis(st, ex, Seq(k3 := {}), """k3 := {
|
||||
val session2 = BuiltinCommands.setThis(ex, Seq(k3 := {}), """k3 := {
|
||||
|//
|
||||
|//
|
||||
|}""".stripMargin).session
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import sbt.internal.util.complete.{ Parser, DefaultParsers }
|
|||
import sbt.internal.inc.classpath.ClasspathUtilities
|
||||
import sbt.internal.inc.ModuleUtilities
|
||||
import java.lang.reflect.Method
|
||||
import sbt.librarymanagement.CrossVersion.partialVersion
|
||||
|
||||
object ScriptedPlugin extends AutoPlugin {
|
||||
override def requires = plugins.JvmPlugin
|
||||
|
|
@ -40,7 +39,7 @@ object ScriptedPlugin extends AutoPlugin {
|
|||
scriptedSbt := (sbtVersion in pluginCrossBuild).value,
|
||||
sbtLauncher := getJars(ScriptedLaunchConf).map(_.get.head).value,
|
||||
sbtTestDirectory := sourceDirectory.value / "sbt-test",
|
||||
libraryDependencies ++= (partialVersion(scriptedSbt.value) match {
|
||||
libraryDependencies ++= (CrossVersion.partialVersion(scriptedSbt.value) match {
|
||||
case Some((0, 13)) =>
|
||||
Seq(
|
||||
"org.scala-sbt" % "scripted-sbt" % scriptedSbt.value % ScriptedConf,
|
||||
|
|
@ -51,13 +50,15 @@ object ScriptedPlugin extends AutoPlugin {
|
|||
"org.scala-sbt" %% "scripted-sbt" % scriptedSbt.value % ScriptedConf,
|
||||
"org.scala-sbt" % "sbt-launch" % scriptedSbt.value % ScriptedLaunchConf
|
||||
)
|
||||
case Some((x, y)) => sys error s"Unknown sbt version ${scriptedSbt.value} ($x.$y)"
|
||||
case None => sys error s"Unknown sbt version ${scriptedSbt.value}"
|
||||
}),
|
||||
scriptedBufferLog := true,
|
||||
scriptedClasspath := getJars(ScriptedConf).value,
|
||||
scriptedTests := scriptedTestsTask.value,
|
||||
scriptedRun := scriptedRunTask.value,
|
||||
scriptedDependencies := {
|
||||
def use[A](x: A*): Unit = () // avoid unused warnings
|
||||
def use[A](@deprecated("unused", "") x: A*): Unit = () // avoid unused warnings
|
||||
val analysis = (compile in Test).value
|
||||
val pub = (publishLocal).value
|
||||
use(analysis, pub)
|
||||
|
|
|
|||
|
|
@ -385,8 +385,11 @@ class ScriptedRunner {
|
|||
instances: Int
|
||||
): Unit = {
|
||||
val runner = new ScriptedTests(resourceBaseDirectory, bufferLog, bootProperties, launchOpts)
|
||||
val sbtVersion = bootProperties.getName.dropWhile(!_.isDigit).dropRight(".jar".length)
|
||||
val accept = isTestCompatible(resourceBaseDirectory, sbtVersion) _
|
||||
// The scripted tests mapped to the inputs that the user wrote after `scripted`.
|
||||
val scriptedTests = get(tests, resourceBaseDirectory, logger).map(st => (st.group, st.name))
|
||||
val scriptedTests =
|
||||
get(tests, resourceBaseDirectory, accept, logger).map(st => (st.group, st.name))
|
||||
val scriptedRunners = runner.batchScriptedRunner(scriptedTests, prescripted, instances, logger)
|
||||
val parallelRunners = scriptedRunners.toParArray
|
||||
val pool = new java.util.concurrent.ForkJoinPool(instances)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ sealed trait Action[T] {
|
|||
* If `inline` is true, `f` will be evaluated on the scheduler thread without the overhead of normal scheduling when possible.
|
||||
* This is intended as an optimization for already evaluated values or very short pure computations.
|
||||
*/
|
||||
final case class Pure[T](f: () => T, inline: Boolean) extends Action[T] {
|
||||
final case class Pure[T](f: () => T, `inline`: Boolean) extends Action[T] {
|
||||
private[sbt] def mapTask(f: Task ~> Task) = this
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,9 @@ object TaskRunnerCircularTest extends Properties("TaskRunner Circular") {
|
|||
}
|
||||
try { tryRun(top, true, workers); false } catch { case i: Incomplete => cyclic(i) }
|
||||
}
|
||||
|
||||
def cyclic(i: Incomplete) =
|
||||
Incomplete
|
||||
.allExceptions(i)
|
||||
.exists(_.isInstanceOf[Execute[({ type A[_] <: AnyRef })#A]#CyclicException[_]])
|
||||
.exists(_.isInstanceOf[Execute[({ type A[_] <: AnyRef })#A @unchecked]#CyclicException[_]])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ object TaskRunnerForkTest extends Properties("TaskRunner Fork") {
|
|||
true
|
||||
}
|
||||
def runDoubleJoin(a: Int, b: Int, workers: Int): Unit = {
|
||||
def inner(i: Int) = List.range(0, b).map(j => task(j).named(j.toString)).join
|
||||
tryRun(List.range(0, a).map(inner).join, false, workers)
|
||||
def inner = List.range(0, b).map(j => task(j).named(j.toString)).join
|
||||
tryRun(List.range(0, a).map(_ => inner).join, false, workers)
|
||||
}
|
||||
property("fork and reduce") = forAll(TaskListGen, MaxWorkersGen) { (m: List[Int], workers: Int) =>
|
||||
m.nonEmpty ==> {
|
||||
|
|
|
|||
|
|
@ -34,12 +34,12 @@ object Test extends std.TaskExtra {
|
|||
val d2 = t3(a, b2, c) mapR f
|
||||
val f2: Values => Task[Any] = {
|
||||
case (Value(aa), Value(bb), Value(cc)) => task(aa + " " + bb + " " + cc)
|
||||
case x => d3
|
||||
case _ => d3
|
||||
}
|
||||
lazy val d = t3(a, b, c) flatMapR f2
|
||||
val f3: Values => Task[Any] = {
|
||||
case (Value(aa), Value(bb), Value(cc)) => task(aa + " " + bb + " " + cc)
|
||||
case x => d2
|
||||
case _ => d2
|
||||
}
|
||||
lazy val d3 = t3(a, b, c) flatMapR f3
|
||||
|
||||
|
|
|
|||
|
|
@ -360,8 +360,11 @@ private[sbt] final class Execute[A[_] <: AnyRef](
|
|||
// cyclic reference checking
|
||||
|
||||
def snapshotCycleCheck(): Unit =
|
||||
for ((called: A[c], callers) <- callers.toSeq; caller <- callers)
|
||||
cycleCheck(caller.asInstanceOf[A[c]], called)
|
||||
callers.toSeq foreach {
|
||||
case (called: A[c], callers) =>
|
||||
for (caller <- callers) cycleCheck(caller.asInstanceOf[A[c]], called)
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
def cycleCheck[T](node: A[T], target: A[T]): Unit = {
|
||||
if (node eq target) cyclic(node, target, "Cannot call self")
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ final class TestFramework(val implClassNames: String*) extends Serializable {
|
|||
case oldFramework: OldFramework => new FrameworkWrapper(oldFramework)
|
||||
})
|
||||
} catch {
|
||||
case e: ClassNotFoundException =>
|
||||
log.debug("Framework implementation '" + head + "' not present.");
|
||||
case _: ClassNotFoundException =>
|
||||
log.debug("Framework implementation '" + head + "' not present.")
|
||||
createFramework(loader, log, tail)
|
||||
}
|
||||
case Nil =>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ trait TestReportListener {
|
|||
def endGroup(name: String, result: TestResult): Unit
|
||||
|
||||
/** Used by the test framework for logging test results */
|
||||
def contentLogger(test: TestDefinition): Option[ContentLogger] = None
|
||||
def contentLogger(@deprecated("unused", "") test: TestDefinition): Option[ContentLogger] = None
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ package sbt
|
|||
package internal.testing
|
||||
|
||||
import testing.{ Logger => TLogger }
|
||||
import sbt.internal.util.{ ManagedLogger, BufferedAppender }
|
||||
import sbt.internal.util.{ BufferedAppender, ConsoleAppender, ManagedLogger }
|
||||
import sbt.util.{ Level, LogExchange, ShowLines }
|
||||
import sbt.protocol.testing._
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
|
@ -89,7 +89,7 @@ object TestLogger {
|
|||
def debug(s: String) = log(Level.Debug, TestStringEvent(s))
|
||||
def trace(t: Throwable) = logger.trace(t)
|
||||
private def log(level: Level.Value, event: TestStringEvent) = logger.logEvent(level, event)
|
||||
def ansiCodesSupported() = logger.ansiCodesSupported
|
||||
def ansiCodesSupported() = ConsoleAppender.formatEnabledInEnv
|
||||
}
|
||||
|
||||
private[sbt] def toTestItemEvent(event: TestEvent): TestItemEvent =
|
||||
|
|
|
|||
Loading…
Reference in New Issue