mirror of https://github.com/sbt/sbt.git
Remove thunk for slash syntax
Ref #3606, #3611, and #3613 This removes unnecessary thunk for slash syntax. The semantics using this approach is strictly better than the previous `in (ref, config, task)`. By removing the thunk, we retain `(a / b) / c == a / b / c`. See the following example: ```scala scala> import sbt._, Keys._ scala> val t: TaskKey[Unit] = (test in Test) t: sbt.TaskKey[Unit] = TaskKey(This / Select(ConfigKey(test)) / This / test) scala> ThisBuild / t ThisBuild / t res1: sbt.TaskKey[Unit] = TaskKey(Select(ThisBuild) / Select(ConfigKey(test)) / This / test) scala> ThisBuild / t / name ThisBuild / t / name res2: sbt.SettingKey[String] = SettingKey(Select(ThisBuild) / Select(ConfigKey(test)) / Select(test) / name) ``` so far so good? Now look at this: ``` scala> scala> name in (ThisBuild, t) name in (ThisBuild, t) res3: sbt.SettingKey[String] = SettingKey(Select(ThisBuild) / This / Select(test) / name) ``` `Test` configuration knowledge is lost! For `in (..)` maybe it was ok because mostly we don't use unscoped keys, but that's the difference between `in (..)` and `/`. Fixes #3605
This commit is contained in:
parent
48a990b34f
commit
2a6385fd94
|
|
@ -39,23 +39,31 @@ trait SlashSyntax {
|
||||||
|
|
||||||
implicit def sbtSlashSyntaxRichConfigKey(c: ConfigKey): RichConfiguration =
|
implicit def sbtSlashSyntaxRichConfigKey(c: ConfigKey): RichConfiguration =
|
||||||
new RichConfiguration(Scope(This, Select(c), This, This))
|
new RichConfiguration(Scope(This, Select(c), This, This))
|
||||||
|
implicit def sbtSlashSyntaxRichConfiguration(c: Configuration): RichConfiguration =
|
||||||
implicit def sbtSlashSyntaxRichConfiguration(c: Configuration): RichConfiguration = (c: ConfigKey)
|
sbtSlashSyntaxRichConfigKey(c: ConfigKey)
|
||||||
|
|
||||||
implicit def sbtSlashSyntaxRichScopeFromScoped(t: Scoped): RichScope =
|
|
||||||
new RichScope(Scope(This, This, Select(t.key), This))
|
|
||||||
|
|
||||||
implicit def sbtSlashSyntaxRichScope(s: Scope): RichScope = new RichScope(s)
|
implicit def sbtSlashSyntaxRichScope(s: Scope): RichScope = new RichScope(s)
|
||||||
|
|
||||||
implicit def sbtSlashSyntaxScopeAndKeyRescope(scopeAndKey: ScopeAndKey[_]): TerminalScope =
|
/**
|
||||||
scopeAndKey.rescope
|
* This handles task scoping an existing scoped key (such as `Compile / test`)
|
||||||
|
* into a task scoping in `(Compile / test) / name`.
|
||||||
|
*/
|
||||||
|
implicit def sbtSlashSyntaxRichScopeFromScoped(t: Scoped): RichScope =
|
||||||
|
new RichScope(t.scope.copy(task = Select(t.key)))
|
||||||
|
|
||||||
implicit def sbtSlashSyntaxScopeAndKeyMaterialize[K <: Key[K]](scopeAndKey: ScopeAndKey[K]): K =
|
implicit val sbtSlashSyntaxSettingKeyCanScope: CanScope[SettingKey] = new SettingKeyCanScope()
|
||||||
scopeAndKey.materialize
|
implicit val sbtSlashSyntaxTaskKeyCanScope: CanScope[TaskKey] = new TaskKeyCanScope()
|
||||||
|
implicit val sbtSlashSyntaxInputKeyCanScope: CanScope[InputKey] = new InputKeyCanScope()
|
||||||
}
|
}
|
||||||
|
|
||||||
object SlashSyntax {
|
object SlashSyntax {
|
||||||
|
|
||||||
|
/** RichScopeLike wraps a general scope to provide the `/` operator for key scoping. */
|
||||||
|
sealed trait RichScopeLike {
|
||||||
|
protected def scope: Scope
|
||||||
|
def /[A, F[_]: CanScope](key: F[A]): F[A] = implicitly[CanScope[F]].inScope(key, scope)
|
||||||
|
}
|
||||||
|
|
||||||
/** RichReference wraps a reference to provide the `/` operator for scoping. */
|
/** RichReference wraps a reference to provide the `/` operator for scoping. */
|
||||||
final class RichReference(protected val scope: Scope) extends RichScopeLike {
|
final class RichReference(protected val scope: Scope) extends RichScopeLike {
|
||||||
def /(c: ConfigKey): RichConfiguration = new RichConfiguration(scope in c)
|
def /(c: ConfigKey): RichConfiguration = new RichConfiguration(scope in c)
|
||||||
|
|
@ -68,46 +76,28 @@ object SlashSyntax {
|
||||||
|
|
||||||
/** RichConfiguration wraps a configuration to provide the `/` operator for scoping. */
|
/** RichConfiguration wraps a configuration to provide the `/` operator for scoping. */
|
||||||
final class RichConfiguration(protected val scope: Scope) extends RichScopeLike {
|
final class RichConfiguration(protected val scope: Scope) extends RichScopeLike {
|
||||||
|
|
||||||
// This is for handling `Zero / Zero / Zero / name`.
|
// This is for handling `Zero / Zero / Zero / name`.
|
||||||
def /(taskAxis: ScopeAxis[AttributeKey[_]]): RichScope =
|
def /(taskAxis: ScopeAxis[AttributeKey[_]]): RichScope =
|
||||||
new RichScope(scope.copy(task = taskAxis))
|
new RichScope(scope.copy(task = taskAxis))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Both `Scoped.ScopingSetting` and `Scoped` are parents of `SettingKey`, `TaskKey` and
|
|
||||||
* `InputKey`. We'll need both, so this is a convenient type alias. */
|
|
||||||
type Key[K] = Scoped.ScopingSetting[K] with Scoped
|
|
||||||
|
|
||||||
sealed trait RichScopeLike {
|
|
||||||
protected def scope: Scope
|
|
||||||
|
|
||||||
// We don't know what the key is for yet, so just capture for now.
|
|
||||||
def /[K <: Key[K]](key: K): ScopeAndKey[K] = new ScopeAndKey(scope, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** RichScope wraps a general scope to provide the `/` operator for scoping. */
|
/** RichScope wraps a general scope to provide the `/` operator for scoping. */
|
||||||
final class RichScope(protected val scope: Scope) extends RichScopeLike
|
final class RichScope(protected val scope: Scope) extends RichScopeLike {}
|
||||||
|
|
||||||
/** TerminalScope provides the last `/` for scoping. */
|
|
||||||
final class TerminalScope(scope: Scope) {
|
|
||||||
def /[K <: Key[K]](key: K): K = key in scope
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ScopeAndKey is a synthetic DSL construct necessary to capture both the built-up scope with a
|
* A typeclass that represents scoping.
|
||||||
* given key, while we're not sure if the given key is terminal or task-scoping. The "materialize"
|
|
||||||
* method will be used if it's terminal, returning the scoped key, while "rescope" will be used
|
|
||||||
* if we're task-scoping.
|
|
||||||
*
|
|
||||||
* @param scope the built-up scope
|
|
||||||
* @param key a given key
|
|
||||||
* @tparam K the type of the given key, necessary to type "materialize"
|
|
||||||
*/
|
*/
|
||||||
final class ScopeAndKey[K <: Key[K]](scope: Scope, key: K) {
|
sealed trait CanScope[F[A]] {
|
||||||
private[sbt] def materialize: K = key in scope
|
def inScope[A](key: F[A], scope: Scope): F[A]
|
||||||
private[sbt] def rescope: TerminalScope = new TerminalScope(scope in key.key)
|
|
||||||
|
|
||||||
override def toString: String = s"$scope / ${key.key}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class SettingKeyCanScope extends CanScope[SettingKey] {
|
||||||
|
def inScope[A](key: SettingKey[A], scope: Scope): SettingKey[A] = key in scope
|
||||||
|
}
|
||||||
|
final class TaskKeyCanScope extends CanScope[TaskKey] {
|
||||||
|
def inScope[A](key: TaskKey[A], scope: Scope): TaskKey[A] = key in scope
|
||||||
|
}
|
||||||
|
final class InputKeyCanScope extends CanScope[InputKey] {
|
||||||
|
def inScope[A](key: InputKey[A], scope: Scope): InputKey[A] = key in scope
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import org.scalacheck.{ Test => _, _ }, Arbitrary.arbitrary, Gen._, Prop._
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import sbt.io.IO
|
import sbt.io.IO
|
||||||
import sbt.SlashSyntax, SlashSyntax.Key
|
import sbt.SlashSyntax
|
||||||
import sbt.{ Scope, ScopeAxis, Scoped, Select, This, Zero }, Scope.{ Global, ThisScope }
|
import sbt.{ Scope, ScopeAxis, Scoped, Select, This, Zero }, Scope.{ Global, ThisScope }
|
||||||
import sbt.{ BuildRef, LocalProject, LocalRootProject, ProjectRef, Reference, RootProject, ThisBuild, ThisProject }
|
import sbt.{ BuildRef, LocalProject, LocalRootProject, ProjectRef, Reference, RootProject, ThisBuild, ThisProject }
|
||||||
import sbt.ConfigKey
|
import sbt.ConfigKey
|
||||||
|
|
@ -63,21 +63,26 @@ object BuildDSLInstances {
|
||||||
1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope)
|
1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope)
|
||||||
))
|
))
|
||||||
|
|
||||||
implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] =
|
object WithScope {
|
||||||
withScope(Gen.identifier map (InputKey[A](_)))
|
implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] =
|
||||||
|
withScope(Gen.identifier map (InputKey[A](_)))
|
||||||
|
|
||||||
implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] =
|
implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] =
|
||||||
withScope(Gen.identifier map (SettingKey[A](_)))
|
withScope(Gen.identifier map (SettingKey[A](_)))
|
||||||
|
|
||||||
implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] =
|
implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] =
|
||||||
withScope(Gen.identifier map (TaskKey[A](_)))
|
withScope(Gen.identifier map (TaskKey[A](_)))
|
||||||
|
}
|
||||||
|
|
||||||
implicit def arbKey[A: Manifest]: Arbitrary[Key[_]] = Arbitrary {
|
object WithoutScope {
|
||||||
Gen.frequency[Key[_]](
|
implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] =
|
||||||
15 -> arbitrary[InputKey[A]], // 15,431
|
Arbitrary(Gen.identifier map (InputKey[A](_)))
|
||||||
20 -> arbitrary[SettingKey[A]], // 19,645
|
|
||||||
23 -> arbitrary[TaskKey[A]], // 22,867
|
implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] =
|
||||||
)
|
Arbitrary(Gen.identifier map (SettingKey[A](_)))
|
||||||
|
|
||||||
|
implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] =
|
||||||
|
Arbitrary(Gen.identifier map (TaskKey[A](_)))
|
||||||
}
|
}
|
||||||
|
|
||||||
implicit def arbScopeAxis[A: Arbitrary]: Arbitrary[ScopeAxis[A]] =
|
implicit def arbScopeAxis[A: Arbitrary]: Arbitrary[ScopeAxis[A]] =
|
||||||
|
|
@ -134,111 +139,105 @@ import CustomEquality._
|
||||||
|
|
||||||
object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax {
|
object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax {
|
||||||
property("Global / key == key in Global") = {
|
property("Global / key == key in Global") = {
|
||||||
def check[K <: Key[K]: Arbitrary] = forAll((k: K) => expectValue(k in Global)(Global / k))
|
import WithScope._
|
||||||
check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]]
|
(forAll { (k: SettingKey[String]) => expectValue(k in Global)(Global / k) }
|
||||||
|
&& forAll { (k: TaskKey[String]) => expectValue(k in Global)(Global / k) }
|
||||||
|
&& forAll { (k: InputKey[String]) => expectValue(k in Global)(Global / k) })
|
||||||
}
|
}
|
||||||
|
|
||||||
property("Reference / key == key in Reference") = {
|
property("Reference / key == key in Reference") = {
|
||||||
def check[K <: Key[K]: Arbitrary] = forAll((r: Reference, k: K) => expectValue(k in r)(r / k))
|
import WithScope._
|
||||||
check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]]
|
(forAll { (r: Reference, k: SettingKey[String]) => expectValue(k in r)(r / k) }
|
||||||
|
&& forAll { (r: Reference, k: TaskKey[String]) => expectValue(k in r)(r / k) }
|
||||||
|
&& forAll { (r: Reference, k: InputKey[String]) => expectValue(k in r)(r / k) })
|
||||||
}
|
}
|
||||||
|
|
||||||
property("Reference / Config / key == key in Reference in Config") = {
|
property("Reference / Config / key == key in Reference in Config") = {
|
||||||
def check[K <: Key[K]: Arbitrary] =
|
import WithScope._
|
||||||
forAll((r: Reference, c: ConfigKey, k: K) => expectValue(k in r in c)(r / c / k))
|
(forAll { (r: Reference, c: ConfigKey, k: SettingKey[String]) => expectValue(k in r in c)(r / c / k) }
|
||||||
check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]]
|
&& forAll { (r: Reference, c: ConfigKey, k: TaskKey[String]) => expectValue(k in r in c)(r / c / k) }
|
||||||
|
&& forAll { (r: Reference, c: ConfigKey, k: InputKey[String]) => expectValue(k in r in c)(r / c / k) })
|
||||||
}
|
}
|
||||||
|
|
||||||
property("Reference / task / key == key in Reference in task") = {
|
property("Reference / task / key == key in Reference in task") = {
|
||||||
def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] =
|
import WithoutScope._
|
||||||
forAll((r: Reference, t: K, k: K) => expectValue(k in (r, t))(r / t / k))
|
(forAll { (r: Reference, t: TaskKey[String], k: SettingKey[String]) => expectValue(k in (r, t))(r / t / k) }
|
||||||
(true
|
&& forAll { (r: Reference, t: TaskKey[String], k: TaskKey[String]) => expectValue(k in (r, t))(r / t / k) }
|
||||||
&& check[InputKey[String], InputKey[String]]
|
&& forAll { (r: Reference, t: TaskKey[String], k: InputKey[String]) => expectValue(k in (r, t))(r / t / k) })
|
||||||
&& check[InputKey[String], SettingKey[String]]
|
|
||||||
&& check[InputKey[String], TaskKey[String]]
|
|
||||||
&& check[SettingKey[String], InputKey[String]]
|
|
||||||
&& check[SettingKey[String], SettingKey[String]]
|
|
||||||
&& check[SettingKey[String], TaskKey[String]]
|
|
||||||
&& check[TaskKey[String], InputKey[String]]
|
|
||||||
&& check[TaskKey[String], SettingKey[String]]
|
|
||||||
&& check[TaskKey[String], TaskKey[String]]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
property("Reference / Config / task / key == key in Reference in Config in task") = {
|
property("Reference / Config / task / key == key in Reference in Config in task") = {
|
||||||
def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] =
|
import WithoutScope._
|
||||||
forAll((r: Reference, c: ConfigKey, t: K, k: K) => expectValue(k in (r, c, t))(r / c / t / k))
|
(forAll { (r: Reference, c: ConfigKey, t: TaskKey[String], k: SettingKey[String]) => expectValue(k in (r, c, t))(r / c / t / k) }
|
||||||
(true
|
&& forAll { (r: Reference, c: ConfigKey, t: TaskKey[String], k: TaskKey[String]) => expectValue(k in (r, c, t))(r / c / t / k) }
|
||||||
&& check[InputKey[String], InputKey[String]]
|
&& forAll { (r: Reference, c: ConfigKey, t: TaskKey[String], k: InputKey[String]) => expectValue(k in (r, c, t))(r / c / t / k) })
|
||||||
&& check[InputKey[String], SettingKey[String]]
|
|
||||||
&& check[InputKey[String], TaskKey[String]]
|
|
||||||
&& check[SettingKey[String], InputKey[String]]
|
|
||||||
&& check[SettingKey[String], SettingKey[String]]
|
|
||||||
&& check[SettingKey[String], TaskKey[String]]
|
|
||||||
&& check[TaskKey[String], InputKey[String]]
|
|
||||||
&& check[TaskKey[String], SettingKey[String]]
|
|
||||||
&& check[TaskKey[String], TaskKey[String]]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
property("Config / key == key in Config") = {
|
property("Config / key == key in Config") = {
|
||||||
def check[K <: Key[K]: Arbitrary] =
|
import WithScope._
|
||||||
forAll((c: ConfigKey, k: K) => expectValue(k in c)(c / k))
|
(forAll { (c: ConfigKey, k: SettingKey[String]) => expectValue(k in c)(c / k) }
|
||||||
check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]]
|
&& forAll { (c: ConfigKey, k: TaskKey[String]) => expectValue(k in c)(c / k) }
|
||||||
|
&& forAll { (c: ConfigKey, k: InputKey[String]) => expectValue(k in c)(c / k) })
|
||||||
}
|
}
|
||||||
|
|
||||||
property("Config / task / key == key in Config in task") = {
|
property("Config / task / key == key in Config in task") = {
|
||||||
def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] =
|
import WithoutScope._
|
||||||
forAll((c: ConfigKey, t: K, k: K) => expectValue(k in c in t)(c / t / k))
|
(forAll { (c: ConfigKey, t: TaskKey[String], k: SettingKey[String]) => expectValue(k in c in t)(c / t / k) }
|
||||||
(true
|
&& forAll { (c: ConfigKey, t: TaskKey[String], k: TaskKey[String]) => expectValue(k in c in t)(c / t / k) }
|
||||||
&& check[InputKey[String], InputKey[String]]
|
&& forAll { (c: ConfigKey, t: TaskKey[String], k: InputKey[String]) => expectValue(k in c in t)(c / t / k) })
|
||||||
&& check[InputKey[String], SettingKey[String]]
|
|
||||||
&& check[InputKey[String], TaskKey[String]]
|
|
||||||
&& check[SettingKey[String], InputKey[String]]
|
|
||||||
&& check[SettingKey[String], SettingKey[String]]
|
|
||||||
&& check[SettingKey[String], TaskKey[String]]
|
|
||||||
&& check[TaskKey[String], InputKey[String]]
|
|
||||||
&& check[TaskKey[String], SettingKey[String]]
|
|
||||||
&& check[TaskKey[String], TaskKey[String]]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
property("task / key == key in task") = {
|
property("task / key == key in task") = {
|
||||||
def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] =
|
import WithoutScope._
|
||||||
forAll((t: K, k: K) => expectValue(k in t)(t / k))
|
(forAll { (t: TaskKey[String], k: SettingKey[String]) => expectValue(k in t)(t / k) }
|
||||||
(true
|
&& forAll { (t: TaskKey[String], k: TaskKey[String]) => expectValue(k in t)(t / k) }
|
||||||
&& check[InputKey[String], InputKey[String]]
|
&& forAll { (t: TaskKey[String], k: InputKey[String]) => expectValue(k in t)(t / k) })
|
||||||
&& check[InputKey[String], SettingKey[String]]
|
|
||||||
&& check[InputKey[String], TaskKey[String]]
|
|
||||||
&& check[SettingKey[String], InputKey[String]]
|
|
||||||
&& check[SettingKey[String], SettingKey[String]]
|
|
||||||
&& check[SettingKey[String], TaskKey[String]]
|
|
||||||
&& check[TaskKey[String], InputKey[String]]
|
|
||||||
&& check[TaskKey[String], SettingKey[String]]
|
|
||||||
&& check[TaskKey[String], TaskKey[String]]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
property("Scope / key == key in Scope") = {
|
property("Scope / key == key in Scope") = {
|
||||||
def check[K <: Key[K]: Arbitrary] = forAll((s: Scope, k: K) => expectValue(k in s)(s / k))
|
import WithScope._
|
||||||
check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]]
|
(forAll { (s: Scope, k: SettingKey[String]) => expectValue(k in s)(s / k) }
|
||||||
|
&& forAll { (s: Scope, k: TaskKey[String]) => expectValue(k in s)(s / k) }
|
||||||
|
&& forAll { (s: Scope, k: InputKey[String]) => expectValue(k in s)(s / k) })
|
||||||
}
|
}
|
||||||
|
|
||||||
property("Reference? / key == key in ThisScope.copy(..)") = {
|
property("Reference? / key == key in ThisScope.copy(..)") = {
|
||||||
def check[K <: Key[K]: Arbitrary] =
|
import WithScope._
|
||||||
forAll((r: ScopeAxis[Reference], k: K) =>
|
(forAll { (r: ScopeAxis[Reference], k: SettingKey[String]) =>
|
||||||
expectValue(k in ThisScope.copy(project = r))(r / k))
|
expectValue(k in ThisScope.copy(project = r))(r / k) } &&
|
||||||
check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]]
|
forAll { (r: ScopeAxis[Reference], k: TaskKey[String]) =>
|
||||||
|
expectValue(k in ThisScope.copy(project = r))(r / k) } &&
|
||||||
|
forAll { (r: ScopeAxis[Reference], k: InputKey[String]) =>
|
||||||
|
expectValue(k in ThisScope.copy(project = r))(r / k) })
|
||||||
}
|
}
|
||||||
|
|
||||||
property("Reference? / ConfigKey? / key == key in ThisScope.copy(..)") = {
|
property("Reference? / ConfigKey? / key == key in ThisScope.copy(..)") = {
|
||||||
def check[K <: Key[K]: Arbitrary] =
|
import WithScope._
|
||||||
forAll((r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: K) =>
|
(forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: SettingKey[String]) =>
|
||||||
expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k))
|
expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) } &&
|
||||||
check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]]
|
forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: TaskKey[String]) =>
|
||||||
|
expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) } &&
|
||||||
|
forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: InputKey[String]) =>
|
||||||
|
expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) })
|
||||||
}
|
}
|
||||||
// property("Reference? / AttributeKey? / key == key in ThisScope.copy(..)") = {
|
|
||||||
// def check[K <: Key[K]: Arbitrary] =
|
// property("Reference? / AttributeKey? / key == key in ThisScope.copy(..)") = {
|
||||||
// forAll(
|
// import WithScope._
|
||||||
// (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: K) =>
|
// (forAll { (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: SettingKey[String]) =>
|
||||||
// expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k))
|
// expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k) } &&
|
||||||
// check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]]
|
// forAll { (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: TaskKey[String]) =>
|
||||||
// }
|
// expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k) } &&
|
||||||
|
// forAll { (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: InputKey[String]) =>
|
||||||
|
// expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k) }
|
||||||
|
// }
|
||||||
|
|
||||||
property("Reference? / ConfigKey? / AttributeKey? / key == key in ThisScope.copy(..)") = {
|
property("Reference? / ConfigKey? / AttributeKey? / key == key in ThisScope.copy(..)") = {
|
||||||
def check[K <: Key[K]: Arbitrary] =
|
import WithScope._
|
||||||
forAll(
|
(forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: SettingKey[String]) =>
|
||||||
(r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: K) =>
|
expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k) } &&
|
||||||
expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k))
|
forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: TaskKey[String]) =>
|
||||||
check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]]
|
expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k) } &&
|
||||||
|
forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: InputKey[String]) =>
|
||||||
|
expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
import sbt.internal.CommandStrings.{ inspectBrief, inspectDetailed }
|
import sbt.internal.CommandStrings.{ inspectBrief, inspectDetailed }
|
||||||
import sbt.internal.Inspect
|
import sbt.internal.Inspect
|
||||||
|
import sjsonnew._, BasicJsonProtocol._
|
||||||
|
|
||||||
val uTest = "com.lihaoyi" %% "utest" % "0.5.3"
|
val uTest = "com.lihaoyi" %% "utest" % "0.5.3"
|
||||||
|
|
||||||
|
val foo = taskKey[Int]("")
|
||||||
|
val bar = taskKey[Int]("")
|
||||||
|
val baz = inputKey[Unit]("")
|
||||||
|
val buildInfo = taskKey[Seq[File]]("The task that generates the build info.")
|
||||||
|
|
||||||
lazy val root = (project in file("."))
|
lazy val root = (project in file("."))
|
||||||
.settings(
|
.settings(
|
||||||
Global / cancelable := true,
|
Global / cancelable := true,
|
||||||
|
|
@ -10,9 +16,24 @@ lazy val root = (project in file("."))
|
||||||
console / scalacOptions += "-deprecation",
|
console / scalacOptions += "-deprecation",
|
||||||
Compile / console / scalacOptions += "-Ywarn-numeric-widen",
|
Compile / console / scalacOptions += "-Ywarn-numeric-widen",
|
||||||
projA / Compile / console / scalacOptions += "-feature",
|
projA / Compile / console / scalacOptions += "-feature",
|
||||||
|
Zero / name := "foo",
|
||||||
Zero / Zero / name := "foo",
|
Zero / Zero / name := "foo",
|
||||||
Zero / Zero / Zero / name := "foo",
|
Zero / Zero / Zero / name := "foo",
|
||||||
|
|
||||||
|
Test / bar := 1,
|
||||||
|
Test / foo := (Test / bar).value + 1,
|
||||||
|
Compile / foo := {
|
||||||
|
(Compile / bar).previous.getOrElse(1)
|
||||||
|
},
|
||||||
|
Compile / bar := {
|
||||||
|
(Compile / foo).previous.getOrElse(2)
|
||||||
|
},
|
||||||
|
Test / buildInfo := Nil,
|
||||||
|
baz := {
|
||||||
|
val x = (Test / buildInfo).taskValue
|
||||||
|
(Compile / run).evaluated
|
||||||
|
},
|
||||||
|
|
||||||
libraryDependencies += uTest % Test,
|
libraryDependencies += uTest % Test,
|
||||||
testFrameworks += new TestFramework("utest.runner.Framework"),
|
testFrameworks += new TestFramework("utest.runner.Framework"),
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue