Merge pull request #5439 from dwijnand/introduce-Taskable

Introduce Taskable & toTaskable
This commit is contained in:
eugene yokota 2020-02-28 10:43:16 -05:00 committed by GitHub
commit 0b12862caf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 150 additions and 27 deletions

View File

@ -805,6 +805,9 @@ lazy val mainSettingsProj = (project in file("main-settings"))
// added a method to a sealed trait
exclude[InheritedNewAbstractMethodProblem]("sbt.Scoped.canEqual"),
exclude[InheritedNewAbstractMethodProblem]("sbt.ScopedTaskable.canEqual"),
// widened ScopedTaskable parameter to (new) supertype Taskable
exclude[IncompatibleSignatureProblem]("sbt.Scoped#RichTaskable*.this"),
exclude[IncompatibleSignatureProblem]("sbt.TupleSyntax.t*ToTable*"),
),
)
.configure(

View File

@ -20,7 +20,7 @@ import Util._
import sbt.util.Show
/** A concrete settings system that uses `sbt.Scope` for the scope type. */
object Def extends Init[Scope] with TaskMacroExtra {
object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
type Classpath = Seq[Attributed[File]]
def settings(ss: SettingsDefinition*): Seq[Setting[_]] = ss.flatMap(_.settings)
@ -268,6 +268,14 @@ object Def extends Init[Scope] with TaskMacroExtra {
def taskKey[T](description: String): TaskKey[T] = macro std.KeyMacro.taskKeyImpl[T]
def inputKey[T](description: String): InputKey[T] = macro std.KeyMacro.inputKeyImpl[T]
class InitOps[T](private val x: Initialize[T]) extends AnyVal {
def toTaskable: Taskable[T] = x
}
class InitTaskOps[T](private val x: Initialize[Task[T]]) extends AnyVal {
def toTaskable: Taskable[T] = x
}
private[sbt] def dummy[T: Manifest](name: String, description: String): (TaskKey[T], Task[T]) =
(TaskKey[T](name, description, DTask), dummyTask(name))
@ -310,3 +318,12 @@ trait TaskMacroExtra {
@deprecated("unused", "") in: State => Parser[T]
): std.ParserInput[T] = ???
}
sealed trait InitializeImplicits0 { self: Def.type =>
implicit def initOps[T](x: Def.Initialize[T]): Def.InitOps[T] = new Def.InitOps(x)
}
sealed trait InitializeImplicits extends InitializeImplicits0 { self: Def.type =>
implicit def initTaskOps[T](x: Def.Initialize[Task[T]]): Def.InitTaskOps[T] =
new Def.InitTaskOps(x)
}

View File

@ -30,11 +30,24 @@ sealed trait Scoped extends Equals {
override def hashCode() = (scope, key).##
}
/** A common type for SettingKey and TaskKey so that both can be used as inputs to tasks.*/
sealed trait ScopedTaskable[T] extends Scoped {
/** A SettingKey, TaskKey or `Initialize[Task]` that can be converted into an `Initialize[Task]`. */
sealed trait Taskable[T] {
def toTask: Initialize[Task[T]]
}
sealed trait TaskableImplicits { self: Taskable.type =>
implicit def fromInit[T](x: Initialize[T]): Taskable[T] =
new Taskable[T] { def toTask = Def.toITask(x) }
}
object Taskable extends TaskableImplicits {
implicit def fromITask[T](x: Initialize[Task[T]]): Taskable[T] =
new Taskable[T] { def toTask = x }
}
/** A common type for SettingKey and TaskKey so that both can be used as inputs to tasks.*/
sealed trait ScopedTaskable[T] extends Scoped with Taskable[T]
/**
* Identifies a setting. It consists of three parts: the scope, the name, and the type of a value associated with this key.
* The scope is represented by a value of type Scope.
@ -457,7 +470,7 @@ object Scoped {
Initialize.joinAny[Task](keys).apply(deps => nop.dependsOn(deps: _*))
}
sealed abstract class RichTaskables[K[L[x]]](final val keys: K[ScopedTaskable])(
sealed abstract class RichTaskables[K[L[x]]](final val keys: K[Taskable])(
implicit a: AList[K]
) {
@ -469,7 +482,7 @@ object Scoped {
/** Convert the higher-kinded function to a Function1. For tuples that means call `.tupled`. */
protected def convert[M[_], Ret](f: Fun[M, Ret]): K[M] => Ret
private[this] val inputs: K[App] = a.transform(keys, λ[ScopedTaskable ~> App](_.toTask))
private[this] val inputs: K[App] = a.transform(keys, λ[Taskable ~> App](_.toTask))
private[this] def onTasks[T](f: K[Task] => Task[T]): App[T] =
Def.app[AList.SplitK[K, Task]#l, Task[T]](inputs)(f)(AList.asplit[K, Task](a))
@ -484,7 +497,7 @@ object Scoped {
// format: off
type ST[X] = ScopedTaskable[X]
type ST[X] = Taskable[X]
final class RichTaskable2[A, B](t2: (ST[A], ST[B])) extends RichTaskables[AList.T2K[A, B]#l](t2)(AList.tuple2[A, B]) {
type Fun[M[_], Ret] = (M[A], M[B]) => Ret
def identityMap = map(mkTuple2)
@ -608,16 +621,17 @@ trait TupleSyntax {
// format: off
// this is the least painful arrangement I came up with
implicit def t2ToTable2[A, B](t2: (ScopedTaskable[A], ScopedTaskable[B])): RichTaskable2[A, B] = new RichTaskable2(t2)
implicit def t3ToTable3[A, B, C](t3: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C])): RichTaskable3[A, B, C] = new RichTaskable3(t3)
implicit def t4ToTable4[A, B, C, D](t4: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D])): RichTaskable4[A, B, C, D] = new RichTaskable4(t4)
implicit def t5ToTable5[A, B, C, D, E](t5: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E])): RichTaskable5[A, B, C, D, E] = new RichTaskable5(t5)
implicit def t6ToTable6[A, B, C, D, E, F](t6: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F])): RichTaskable6[A, B, C, D, E, F] = new RichTaskable6(t6)
implicit def t7ToTable7[A, B, C, D, E, F, G](t7: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G])): RichTaskable7[A, B, C, D, E, F, G] = new RichTaskable7(t7)
implicit def t8ToTable8[A, B, C, D, E, F, G, H](t8: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H])): RichTaskable8[A, B, C, D, E, F, G, H] = new RichTaskable8(t8)
implicit def t9ToTable9[A, B, C, D, E, F, G, H, I](t9: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I])): RichTaskable9[A, B, C, D, E, F, G, H, I] = new RichTaskable9(t9)
implicit def t10ToTable10[A, B, C, D, E, F, G, H, I, J](t10: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J])): RichTaskable10[A, B, C, D, E, F, G, H, I, J] = new RichTaskable10(t10)
implicit def t11ToTable11[A, B, C, D, E, F, G, H, I, J, K](t11: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K])): RichTaskable11[A, B, C, D, E, F, G, H, I, J, K] = new RichTaskable11(t11)
type ST[T] = Taskable[T]
implicit def t2ToTable2[A, B](t2: (ST[A], ST[B])): RichTaskable2[A, B] = new RichTaskable2(t2)
implicit def t3ToTable3[A, B, C](t3: (ST[A], ST[B], ST[C])): RichTaskable3[A, B, C] = new RichTaskable3(t3)
implicit def t4ToTable4[A, B, C, D](t4: (ST[A], ST[B], ST[C], ST[D])): RichTaskable4[A, B, C, D] = new RichTaskable4(t4)
implicit def t5ToTable5[A, B, C, D, E](t5: (ST[A], ST[B], ST[C], ST[D], ST[E])): RichTaskable5[A, B, C, D, E] = new RichTaskable5(t5)
implicit def t6ToTable6[A, B, C, D, E, F](t6: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F])): RichTaskable6[A, B, C, D, E, F] = new RichTaskable6(t6)
implicit def t7ToTable7[A, B, C, D, E, F, G](t7: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G])): RichTaskable7[A, B, C, D, E, F, G] = new RichTaskable7(t7)
implicit def t8ToTable8[A, B, C, D, E, F, G, H](t8: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H])): RichTaskable8[A, B, C, D, E, F, G, H] = new RichTaskable8(t8)
implicit def t9ToTable9[A, B, C, D, E, F, G, H, I](t9: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I])): RichTaskable9[A, B, C, D, E, F, G, H, I] = new RichTaskable9(t9)
implicit def t10ToTable10[A, B, C, D, E, F, G, H, I, J](t10: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J])): RichTaskable10[A, B, C, D, E, F, G, H, I, J] = new RichTaskable10(t10)
implicit def t11ToTable11[A, B, C, D, E, F, G, H, I, J, K](t11: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K])): RichTaskable11[A, B, C, D, E, F, G, H, I, J, K] = new RichTaskable11(t11)
implicit def t2ToApp2[A, B](t2: (Initialize[A], Initialize[B])): Apply2[A, B] = new Apply2(t2)
implicit def t3ToApp3[A, B, C](t3: (Initialize[A], Initialize[B], Initialize[C])): Apply3[A, B, C] = new Apply3(t3)

View File

@ -0,0 +1,18 @@
/*
* sbt
* Copyright 2011 - 2018, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt.test
import sbt._
import sbt.Def.Initialize
import sbt.TupleSyntax._
object TupleSyntaxTest {
def t1[T](a: SettingKey[T], b: TaskKey[T], c: Initialize[T], d: Initialize[Task[T]]) = {
(a, b, c.toTaskable, d.toTaskable).map((x: T, y: T, z: T, w: T) => "" + x + y + z + w)
}
}

View File

@ -1327,10 +1327,12 @@ object Defaults extends BuildCommon {
case _ => None
}
}
def resourceMappings = relativeMappings(unmanagedResources, unmanagedResourceDirectories)
def relativeMappings(
files: ScopedTaskable[Seq[File]],
dirs: ScopedTaskable[Seq[File]]
files: Taskable[Seq[File]],
dirs: Taskable[Seq[File]]
): Initialize[Task[Seq[(File, String)]]] =
Def.task {
val rdirs = dirs.toTask.value.toSet
@ -1340,14 +1342,27 @@ object Defaults extends BuildCommon {
case _ => None
}
}
def collectFiles(
dirs: ScopedTaskable[Seq[File]],
filter: ScopedTaskable[FileFilter],
excludes: ScopedTaskable[FileFilter]
dirs: Taskable[Seq[File]],
filter: Taskable[FileFilter],
excludes: Taskable[FileFilter]
): Initialize[Task[Seq[File]]] =
Def.task {
dirs.toTask.value.descendantsExcept(filter.toTask.value, excludes.toTask.value).get
}
def relativeMappings( // forward to widened variant
files: ScopedTaskable[Seq[File]],
dirs: ScopedTaskable[Seq[File]]
): Initialize[Task[Seq[(File, String)]]] = relativeMappings(files: Taskable[Seq[File]], dirs)
def collectFiles( // forward to widened variant
dirs: ScopedTaskable[Seq[File]],
filter: ScopedTaskable[FileFilter],
excludes: ScopedTaskable[FileFilter]
): Initialize[Task[Seq[File]]] = collectFiles(dirs: Taskable[Seq[File]], filter, excludes)
def artifactPathSetting(art: SettingKey[Artifact]): Initialize[File] =
Def.setting {
val f = artifactName.value
@ -2021,20 +2036,30 @@ object Defaults extends BuildCommon {
}
}
}
object Classpaths {
import Defaults._
import Keys._
def concatDistinct[T](
def concatDistinct[T](a: Taskable[Seq[T]], b: Taskable[Seq[T]]): Initialize[Task[Seq[T]]] =
Def.task((a.toTask.value ++ b.toTask.value).distinct)
def concat[T](a: Taskable[Seq[T]], b: Taskable[Seq[T]]): Initialize[Task[Seq[T]]] =
Def.task(a.toTask.value ++ b.toTask.value)
def concatSettings[T](a: Initialize[Seq[T]], b: Initialize[Seq[T]]): Initialize[Seq[T]] =
Def.setting { a.value ++ b.value }
def concatDistinct[T]( // forward to widened variant
a: ScopedTaskable[Seq[T]],
b: ScopedTaskable[Seq[T]]
): Initialize[Task[Seq[T]]] = Def.task {
(a.toTask.value ++ b.toTask.value).distinct
}
): Initialize[Task[Seq[T]]] = concatDistinct(a: Taskable[Seq[T]], b)
def concat[T](a: ScopedTaskable[Seq[T]], b: ScopedTaskable[Seq[T]]): Initialize[Task[Seq[T]]] =
Def.task { a.toTask.value ++ b.toTask.value }
concat(a: Taskable[Seq[T]], b) // forward to widened variant
def concatSettings[T](a: SettingKey[Seq[T]], b: SettingKey[Seq[T]]): Initialize[Seq[T]] =
Def.setting { a.value ++ b.value }
concatSettings(a: Initialize[Seq[T]], b) // forward to widened variant
lazy val configSettings: Seq[Setting[_]] = classpaths ++ Seq(
products := makeProducts.value,

View File

@ -0,0 +1,46 @@
/*
* sbt
* Copyright 2011 - 2018, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt.test
import sbt._
import sbt.Classpaths._
import sbt.Def.Initialize
class ClasspathsTest[T](
settKey: SettingKey[Seq[T]],
taskKey: TaskKey[Seq[T]],
initVal: Initialize[Seq[T]],
taskVal: Initialize[Task[Seq[T]]],
) {
def testConcat() = {
concat(settKey, settKey)
concat(settKey, taskKey)
concat(settKey, initVal)
concat(settKey, taskVal)
concat(taskKey, settKey)
concat(taskKey, taskKey)
concat(taskKey, initVal)
concat(taskKey, taskVal)
concat(initVal, settKey)
concat(initVal, taskKey)
concat(initVal, initVal)
concat(initVal, taskVal)
concat(taskVal, settKey)
concat(taskVal, taskKey)
concat(taskVal, initVal)
concat(taskVal, taskVal)
}
def testConcatSettings() = {
concatSettings(settKey, settKey)
concatSettings(settKey, initVal)
concatSettings(initVal, settKey)
concatSettings(initVal, initVal)
}
}