mirror of https://github.com/sbt/sbt.git
commit
6b26b709f1
|
|
@ -1 +1 @@
|
|||
1.7
|
||||
1.8
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
language: scala
|
||||
|
||||
scala: 2.11.8
|
||||
scala:
|
||||
- 2.11.8
|
||||
- 2.12.1
|
||||
|
||||
script:
|
||||
- sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M "so test"
|
||||
- sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M "plz $TRAVIS_SCALA_VERSION test"
|
||||
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
|
|
|
|||
13
build.sbt
13
build.sbt
|
|
@ -13,14 +13,14 @@ def commonSettings: Seq[Setting[_]] = Seq(
|
|||
resolvers += Resolver.mavenLocal,
|
||||
// concurrentRestrictions in Global += Util.testExclusiveRestriction,
|
||||
testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"),
|
||||
javacOptions in compile ++= Seq("-target", "6", "-source", "6", "-Xlint", "-Xlint:-serial"),
|
||||
crossScalaVersions := Seq(scala211),
|
||||
javacOptions in compile ++= Seq("-Xlint", "-Xlint:-serial"),
|
||||
crossScalaVersions := Seq(scala211, scala212),
|
||||
scalacOptions ++= Seq("-Ywarn-unused", "-Ywarn-unused-import"),
|
||||
scalacOptions --= // scalac 2.10 rejects some HK types under -Xfuture it seems..
|
||||
(CrossVersion partialVersion scalaVersion.value collect { case (2, 10) => List("-Xfuture", "-Ywarn-unused", "-Ywarn-unused-import") }).toList.flatten,
|
||||
scalacOptions in console in Compile -= "-Ywarn-unused-import",
|
||||
scalacOptions in console in Test -= "-Ywarn-unused-import",
|
||||
previousArtifact := None, // Some(organization.value %% moduleName.value % "1.0.0"),
|
||||
mimaPreviousArtifacts := Set(), // Some(organization.value %% moduleName.value % "1.0.0"),
|
||||
publishArtifact in Compile := true,
|
||||
publishArtifact in Test := false
|
||||
)
|
||||
|
|
@ -154,8 +154,11 @@ lazy val utilScripted = (project in internalPath / "util-scripted").
|
|||
commonSettings,
|
||||
name := "Util Scripted",
|
||||
libraryDependencies ++= {
|
||||
if (scalaVersion.value startsWith "2.11") Seq(parserCombinator211)
|
||||
else Seq()
|
||||
scalaVersion.value match {
|
||||
case sv if sv startsWith "2.11" => Seq(parserCombinator211)
|
||||
case sv if sv startsWith "2.12" => Seq(parserCombinator211)
|
||||
case _ => Seq()
|
||||
}
|
||||
}
|
||||
).
|
||||
configure(addSbtIO)
|
||||
|
|
|
|||
|
|
@ -5,9 +5,37 @@ import scala.annotation.tailrec
|
|||
// Copied from Cats (MIT license)
|
||||
|
||||
/**
|
||||
* Eval is a datatype, which controls evaluation.
|
||||
* Eval is a monad which controls evaluation.
|
||||
*
|
||||
* This type wraps a value (or a computation that produces a value)
|
||||
* and can produce it on command via the `.value` method.
|
||||
*
|
||||
* There are three basic evaluation strategies:
|
||||
*
|
||||
* - Now: evaluated immediately
|
||||
* - Later: evaluated once when value is needed
|
||||
* - Always: evaluated every time value is needed
|
||||
*
|
||||
* The Later and Always are both lazy strategies while Now is eager.
|
||||
* Later and Always are distinguished from each other only by
|
||||
* memoization: once evaluated Later will save the value to be returned
|
||||
* immediately if it is needed again. Always will run its computation
|
||||
* every time.
|
||||
*
|
||||
* Eval supports stack-safe lazy computation via the .map and .flatMap
|
||||
* methods, which use an internal trampoline to avoid stack overflows.
|
||||
* Computation done within .map and .flatMap is always done lazily,
|
||||
* even when applied to a Now instance.
|
||||
*
|
||||
* It is not generally good style to pattern-match on Eval instances.
|
||||
* Rather, use .map and .flatMap to chain computation, and use .value
|
||||
* to get the result when needed. It is also not good style to create
|
||||
* Eval instances whose computation involves calling .value on another
|
||||
* Eval instance -- this can defeat the trampolining and lead to stack
|
||||
* overflows.
|
||||
*/
|
||||
sealed abstract class Eval[A] extends Serializable { self =>
|
||||
sealed abstract class Eval[+A] extends Serializable { self =>
|
||||
|
||||
/**
|
||||
* Evaluate the computation and return an A value.
|
||||
*
|
||||
|
|
@ -15,7 +43,7 @@ sealed abstract class Eval[A] extends Serializable { self =>
|
|||
* will be performed at this point. For eager instances (Now), a
|
||||
* value will be immediately returned.
|
||||
*/
|
||||
def get: A
|
||||
def value: A
|
||||
|
||||
/**
|
||||
* Transform an Eval[A] into an Eval[B] given the transformation
|
||||
|
|
@ -47,8 +75,11 @@ sealed abstract class Eval[A] extends Serializable { self =>
|
|||
case c: Eval.Compute[A] =>
|
||||
new Eval.Compute[B] {
|
||||
type Start = c.Start
|
||||
val start = c.start
|
||||
val run = (s: c.Start) =>
|
||||
// See https://issues.scala-lang.org/browse/SI-9931 for an explanation
|
||||
// of why the type annotations are necessary in these two lines on
|
||||
// Scala 2.12.0.
|
||||
val start: () => Eval[Start] = c.start
|
||||
val run: Start => Eval[B] = (s: c.Start) =>
|
||||
new Eval.Compute[B] {
|
||||
type Start = A
|
||||
val start = () => c.run(s)
|
||||
|
|
@ -87,7 +118,7 @@ sealed abstract class Eval[A] extends Serializable { self =>
|
|||
* This type should be used when an A value is already in hand, or
|
||||
* when the computation to produce an A value is pure and very fast.
|
||||
*/
|
||||
final case class Now[A](get: A) extends Eval[A] {
|
||||
final case class Now[A](value: A) extends Eval[A] {
|
||||
def memoize: Eval[A] = this
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +146,7 @@ final class Later[A](f: () => A) extends Eval[A] {
|
|||
//
|
||||
// (For situations where `f` is small, but the output will be very
|
||||
// expensive to store, consider using `Always`.)
|
||||
lazy val get: A = {
|
||||
lazy val value: A = {
|
||||
val result = thunk()
|
||||
thunk = null // scalastyle:off
|
||||
result
|
||||
|
|
@ -139,7 +170,7 @@ object Later {
|
|||
* caching must be avoided. Generally, prefer Later.
|
||||
*/
|
||||
final class Always[A](f: () => A) extends Eval[A] {
|
||||
def get: A = f()
|
||||
def value: A = f()
|
||||
def memoize: Eval[A] = new Later(f)
|
||||
}
|
||||
|
||||
|
|
@ -193,8 +224,8 @@ object Eval {
|
|||
* they will be automatically created when needed.
|
||||
*/
|
||||
sealed abstract class Call[A](val thunk: () => Eval[A]) extends Eval[A] {
|
||||
def memoize: Eval[A] = new Later(() => get)
|
||||
def get: A = Call.loop(this).get
|
||||
def memoize: Eval[A] = new Later(() => value)
|
||||
def value: A = Call.loop(this).value
|
||||
}
|
||||
|
||||
object Call {
|
||||
|
|
@ -229,16 +260,16 @@ object Eval {
|
|||
*
|
||||
* Unlike a traditional trampoline, the internal workings of the
|
||||
* trampoline are not exposed. This allows a slightly more efficient
|
||||
* implementation of the .get method.
|
||||
* implementation of the .value method.
|
||||
*/
|
||||
sealed abstract class Compute[A] extends Eval[A] {
|
||||
type Start
|
||||
val start: () => Eval[Start]
|
||||
val run: Start => Eval[A]
|
||||
|
||||
def memoize: Eval[A] = Later(get)
|
||||
def memoize: Eval[A] = Later(value)
|
||||
|
||||
def get: A = {
|
||||
def value: A = {
|
||||
type L = Eval[Any]
|
||||
type C = Any => Eval[Any]
|
||||
@tailrec def loop(curr: L, fs: List[C]): Any =
|
||||
|
|
@ -251,12 +282,12 @@ object Eval {
|
|||
cc.run.asInstanceOf[C] :: c.run.asInstanceOf[C] :: fs
|
||||
)
|
||||
case xx =>
|
||||
loop(c.run(xx.get).asInstanceOf[L], fs)
|
||||
loop(c.run(xx.value), fs)
|
||||
}
|
||||
case x =>
|
||||
fs match {
|
||||
case f :: fs => loop(f(x.get), fs)
|
||||
case Nil => x.get
|
||||
case f :: fs => loop(f(x.value), fs)
|
||||
case Nil => x.value
|
||||
}
|
||||
}
|
||||
loop(this.asInstanceOf[L], Nil).asInstanceOf[A]
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ final case class Scope(nestIndex: Int, idAtIndex: Int = 0)
|
|||
// Lots of type constructors would become binary, which as you may know requires lots of type lambdas
|
||||
// when you want a type function with only one parameter.
|
||||
// That would be a general pain.)
|
||||
object SettingsExample extends Init[Scope] {
|
||||
case class SettingsExample() extends Init[Scope] {
|
||||
// Provides a way of showing a Scope+AttributeKey[_]
|
||||
val showFullKey: Show[ScopedKey[_]] = new Show[ScopedKey[_]] {
|
||||
def apply(key: ScopedKey[_]) = s"${key.scope.nestIndex}(${key.scope.idAtIndex})/${key.key.label}"
|
||||
|
|
@ -30,8 +30,8 @@ object SettingsExample extends Init[Scope] {
|
|||
|
||||
/** Usage Example **/
|
||||
|
||||
object SettingsUsage {
|
||||
import SettingsExample._
|
||||
case class SettingsUsage(val settingsExample: SettingsExample) {
|
||||
import settingsExample._
|
||||
|
||||
// Define some keys
|
||||
val a = AttributeKey[Int]("a")
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ package sbt.internal.util
|
|||
|
||||
import org.scalacheck._
|
||||
import Prop._
|
||||
import SettingsUsage._
|
||||
import SettingsExample._
|
||||
|
||||
object SettingsTest extends Properties("settings") {
|
||||
val settingsExample: SettingsExample = SettingsExample()
|
||||
import settingsExample._
|
||||
val settingsUsage = SettingsUsage(settingsExample)
|
||||
import settingsUsage._
|
||||
|
||||
import scala.reflect.Manifest
|
||||
|
||||
|
|
@ -126,7 +128,7 @@ object SettingsTest extends Properties("settings") {
|
|||
// Each project defines an initial value, but the update is defined in globalKey.
|
||||
// However, the derived Settings that come from this should be scoped in each project.
|
||||
val settings: Seq[Setting[_]] =
|
||||
derive(setting(globalDerivedKey, SettingsExample.map(globalKey)(_ + 1))) +: projectKeys.map(pk => setting(pk, value(0)))
|
||||
derive(setting(globalDerivedKey, settingsExample.map(globalKey)(_ + 1))) +: projectKeys.map(pk => setting(pk, value(0)))
|
||||
val ev = evaluate(settings)
|
||||
// Also check that the key has no value at the "global" scope
|
||||
val props = for { pk <- projectDerivedKeys } yield checkKey(pk, Some(1), ev)
|
||||
|
|
@ -184,6 +186,7 @@ object SettingsTest extends Properties("settings") {
|
|||
}
|
||||
// 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] =
|
||||
bind(init) { t =>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import Keys._
|
|||
object Dependencies {
|
||||
val scala210 = "2.10.6"
|
||||
val scala211 = "2.11.8"
|
||||
val scala212 = "2.12.0"
|
||||
val scala212 = "2.12.1"
|
||||
|
||||
private val sbtIO = "org.scala-sbt" %% "io" % "1.0.0-M7"
|
||||
|
||||
|
|
@ -31,8 +31,8 @@ object Dependencies {
|
|||
val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value }
|
||||
val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value }
|
||||
|
||||
val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.13.1"
|
||||
val scalatest = "org.scalatest" %% "scalatest" % "2.2.6"
|
||||
val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.13.4"
|
||||
val scalatest = "org.scalatest" %% "scalatest" % "3.0.1"
|
||||
|
||||
val parserCombinator211 = "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.4"
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.1")
|
||||
addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.2")
|
||||
|
|
|
|||
Loading…
Reference in New Issue