From b0a10815a641e0a11bb0b92c65dfbcacfd5bc8a6 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 20 Jan 2015 01:21:33 -0500 Subject: [PATCH 1/3] Implementes `Def.sequential`. Fixes #1001 Adds Def.sequential based on Mark's implementation provided in #1001. --- main/src/main/scala/sbt/Defaults.scala | 6 +- main/src/main/scala/sbt/TaskSequential.scala | 104 ++++++++++++++++++ notes/0.13.8/sequential-task.markdown | 40 +++++++ sbt/src/sbt-test/project/sequential/build.sbt | 36 ++++++ sbt/src/sbt-test/project/sequential/test | 1 + 5 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 main/src/main/scala/sbt/TaskSequential.scala create mode 100644 notes/0.13.8/sequential-task.markdown create mode 100644 sbt/src/sbt-test/project/sequential/build.sbt create mode 100644 sbt/src/sbt-test/project/sequential/test diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index dbe40f3e0..5c66c1c1c 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1760,7 +1760,7 @@ object Classpaths { } } -trait BuildExtra extends BuildCommon { +trait BuildExtra extends BuildCommon with DefExtra { import Defaults._ /** @@ -1890,6 +1890,10 @@ trait BuildExtra extends BuildCommon { def filterKeys(ss: Seq[Setting[_]], transitive: Boolean = false)(f: ScopedKey[_] => Boolean): Seq[Setting[_]] = ss filter (s => f(s.key) && (!transitive || s.dependencies.forall(f))) } +trait DefExtra { + private[this] val ts: TaskSequential = new TaskSequential {} + implicit def toTaskSequential(d: Def.type): TaskSequential = ts +} trait BuildCommon { @deprecated("Use Def.inputTask with the `Def.spaceDelimited()` parser.", "0.13.0") def inputTask[T](f: TaskKey[Seq[String]] => Initialize[Task[T]]): Initialize[InputTask[T]] = diff --git a/main/src/main/scala/sbt/TaskSequential.scala b/main/src/main/scala/sbt/TaskSequential.scala new file mode 100644 index 000000000..58c998215 --- /dev/null +++ b/main/src/main/scala/sbt/TaskSequential.scala @@ -0,0 +1,104 @@ +package sbt + +import Def._ + +/** + * This trait injected to `Def` object to provide `sequential` functions for tasks. + */ +trait TaskSequential { + def sequential[B](last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(Nil, last) + def sequential[A0, B](task0: Initialize[Task[A0]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0)), last) + def sequential[A0, A1, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1)), last) + def sequential[A0, A1, A2, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2)), last) + def sequential[A0, A1, A2, A3, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3)), last) + def sequential[A0, A1, A2, A3, A4, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4)), last) + def sequential[A0, A1, A2, A3, A4, A5, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], task11: Initialize[Task[A11]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10), unitTask(task11)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], task11: Initialize[Task[A11]], task12: Initialize[Task[A12]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10), unitTask(task11), unitTask(task12)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], task11: Initialize[Task[A11]], task12: Initialize[Task[A12]], task13: Initialize[Task[A13]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10), unitTask(task11), unitTask(task12), unitTask(task13)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], task11: Initialize[Task[A11]], task12: Initialize[Task[A12]], task13: Initialize[Task[A13]], task14: Initialize[Task[A14]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10), unitTask(task11), unitTask(task12), unitTask(task13), unitTask(task14)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], task11: Initialize[Task[A11]], task12: Initialize[Task[A12]], task13: Initialize[Task[A13]], task14: Initialize[Task[A14]], task15: Initialize[Task[A15]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10), unitTask(task11), unitTask(task12), unitTask(task13), unitTask(task14), unitTask(task15)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], task11: Initialize[Task[A11]], task12: Initialize[Task[A12]], task13: Initialize[Task[A13]], task14: Initialize[Task[A14]], task15: Initialize[Task[A15]], task16: Initialize[Task[A16]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10), unitTask(task11), unitTask(task12), unitTask(task13), unitTask(task14), unitTask(task15), unitTask(task16)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], task11: Initialize[Task[A11]], task12: Initialize[Task[A12]], task13: Initialize[Task[A13]], task14: Initialize[Task[A14]], task15: Initialize[Task[A15]], task16: Initialize[Task[A16]], task17: Initialize[Task[A17]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10), unitTask(task11), unitTask(task12), unitTask(task13), unitTask(task14), unitTask(task15), unitTask(task16), unitTask(task17)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], task11: Initialize[Task[A11]], task12: Initialize[Task[A12]], task13: Initialize[Task[A13]], task14: Initialize[Task[A14]], task15: Initialize[Task[A15]], task16: Initialize[Task[A16]], task17: Initialize[Task[A17]], task18: Initialize[Task[A18]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10), unitTask(task11), unitTask(task12), unitTask(task13), unitTask(task14), unitTask(task15), unitTask(task16), unitTask(task17), unitTask(task18)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], task11: Initialize[Task[A11]], task12: Initialize[Task[A12]], task13: Initialize[Task[A13]], task14: Initialize[Task[A14]], task15: Initialize[Task[A15]], task16: Initialize[Task[A16]], task17: Initialize[Task[A17]], task18: Initialize[Task[A18]], task19: Initialize[Task[A19]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10), unitTask(task11), unitTask(task12), unitTask(task13), unitTask(task14), unitTask(task15), unitTask(task16), unitTask(task17), unitTask(task18), unitTask(task19)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], task11: Initialize[Task[A11]], task12: Initialize[Task[A12]], task13: Initialize[Task[A13]], task14: Initialize[Task[A14]], task15: Initialize[Task[A15]], task16: Initialize[Task[A16]], task17: Initialize[Task[A17]], task18: Initialize[Task[A18]], task19: Initialize[Task[A19]], task20: Initialize[Task[A20]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10), unitTask(task11), unitTask(task12), unitTask(task13), unitTask(task14), unitTask(task15), unitTask(task16), unitTask(task17), unitTask(task18), unitTask(task19), unitTask(task20)), last) + def sequential[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, B](task0: Initialize[Task[A0]], task1: Initialize[Task[A1]], task2: Initialize[Task[A2]], task3: Initialize[Task[A3]], task4: Initialize[Task[A4]], task5: Initialize[Task[A5]], task6: Initialize[Task[A6]], task7: Initialize[Task[A7]], task8: Initialize[Task[A8]], task9: Initialize[Task[A9]], task10: Initialize[Task[A10]], task11: Initialize[Task[A11]], task12: Initialize[Task[A12]], task13: Initialize[Task[A13]], task14: Initialize[Task[A14]], task15: Initialize[Task[A15]], task16: Initialize[Task[A16]], task17: Initialize[Task[A17]], task18: Initialize[Task[A18]], task19: Initialize[Task[A19]], task20: Initialize[Task[A20]], task21: Initialize[Task[A21]], + last: Initialize[Task[B]]): Initialize[Task[B]] = + sequential(List(unitTask(task0), unitTask(task1), unitTask(task2), unitTask(task3), unitTask(task4), unitTask(task5), unitTask(task6), unitTask(task7), unitTask(task8), unitTask(task9), unitTask(task10), unitTask(task11), unitTask(task12), unitTask(task13), unitTask(task14), unitTask(task15), unitTask(task16), unitTask(task17), unitTask(task18), unitTask(task19), unitTask(task20), unitTask(task21)), last) + + def sequential[B](tasks: Seq[Initialize[Task[Unit]]], last: Initialize[Task[B]]): Initialize[Task[B]] = + tasks.toList match { + case Nil => Def.task { last.value } + case x :: xs => + Def.taskDyn { + val _ = x.value + sequential(xs, last) + } + } + private def unitTask[A](task: Initialize[Task[A]]): Initialize[Task[Unit]] = + Def.task { + task.value + () + } +} + +// for { +// i <- 0 to 21 +// } { +// val idx = 0 to i +// val tparams = (idx map { "A" + _ }).mkString(", ") +// val params = (idx map { j => s"task$j: Initialize[Task[A$j]]" }).mkString(", ") +// val args = (idx map { j => s"unitTask(task$j)" }).mkString(", ") +// println(s""" def sequential[$tparams, B]($params, +// | last: Initialize[Task[B]]): Initialize[Task[B]] = +// | sequential(List($args), last)""".stripMargin) +// } diff --git a/notes/0.13.8/sequential-task.markdown b/notes/0.13.8/sequential-task.markdown new file mode 100644 index 000000000..aeeecab91 --- /dev/null +++ b/notes/0.13.8/sequential-task.markdown @@ -0,0 +1,40 @@ + [@cunei]: https://github.com/cunei + [@eed3si9n]: https://github.com/eed3si9n + [@gkossakowski]: https://github.com/gkossakowski + [@jsuereth]: https://github.com/jsuereth + [1817]: https://github.com/sbt/sbt/pull/1817 + [1001]: https://github.com/sbt/sbt/issues/1001 + [Custom-Settings0]: http://www.scala-sbt.org/0.13/tutorial/Custom-Settings.html + +### Fixes with compatibility implications + +### Improvements + +### Bug fixes + +### Sequential tasks + +sbt 0.13.8 adds a new `Def.sequential` function to run tasks under semi-sequential semantics. +Here's an example usage: + + lazy val root = project. + settings( + testFile := target.value / "test.txt", + sideEffect0 := { + val t = testFile.value + IO.append(t, "0") + t + }, + sideEffect1 := { + val t = testFile.value + IO.append(t, "1") + t + }, + foo := Def.sequential(compile in Compile, sideEffect0, sideEffect1, test in Test).value + ) + +Normally sbt's task engine will reorder tasks based on the dependencies among the tasks, +and run as many tasks in parallel (See [Custom settings and tasks][Custom-Settings0] for more details on this). +`Def.sequential` instead tries to run the tasks in the specified order. +However, the task engine will still deduplicate tasks. For instance, when `foo` is executed, it will only compile once, +even though `test in Test` depends on compile. [#1817][1817]/[#1001][1001] by [@eed3si9n][@eed3si9n] diff --git a/sbt/src/sbt-test/project/sequential/build.sbt b/sbt/src/sbt-test/project/sequential/build.sbt new file mode 100644 index 000000000..1cc79681e --- /dev/null +++ b/sbt/src/sbt-test/project/sequential/build.sbt @@ -0,0 +1,36 @@ +lazy val foo = taskKey[Int]("foo") +lazy val bar = taskKey[Int]("bar") +lazy val sideEffect0 = taskKey[Unit]("side effect 0") +lazy val sideEffect1 = taskKey[Unit]("side effect 1") +lazy val sideEffect2 = taskKey[Unit]("side effect 2") +lazy val testFile = settingKey[File]("test file") +lazy val check = taskKey[Unit]("check") + +lazy val root = project. + settings( + check := { + val x = foo.value + if (x == 1) () + else sys.error("foo did not return 1") + val t = testFile.value + val s = IO.read(t) + val expected = "012" + if (s == expected) () + else sys.error(s"""test.txt expected '$expected' but was '$s'.""") + }, + testFile := target.value / "test.txt", + sideEffect0 := { + val t = testFile.value + IO.append(t, "0") + }, + sideEffect1 := { + val t = testFile.value + IO.append(t, "1") + }, + sideEffect2 := { + val t = testFile.value + IO.append(t, "2") + }, + foo := Def.sequential(compile in Compile, sideEffect0, sideEffect1, sideEffect2, test in Test, bar).value, + bar := 1 + ) diff --git a/sbt/src/sbt-test/project/sequential/test b/sbt/src/sbt-test/project/sequential/test new file mode 100644 index 000000000..15675b169 --- /dev/null +++ b/sbt/src/sbt-test/project/sequential/test @@ -0,0 +1 @@ +> check From eca9321d221cb57b3e1df0d50af29a79e334390d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 20 Jan 2015 09:48:56 -0500 Subject: [PATCH 2/3] Add sleep in sequential test per review --- sbt/src/sbt-test/project/sequential/build.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/sbt/src/sbt-test/project/sequential/build.sbt b/sbt/src/sbt-test/project/sequential/build.sbt index 1cc79681e..f3b423d13 100644 --- a/sbt/src/sbt-test/project/sequential/build.sbt +++ b/sbt/src/sbt-test/project/sequential/build.sbt @@ -20,6 +20,7 @@ lazy val root = project. }, testFile := target.value / "test.txt", sideEffect0 := { + Thread.sleep(100) val t = testFile.value IO.append(t, "0") }, From e94ccfd72bc6f0ba8f18238156f36409d167f264 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 20 Jan 2015 18:05:03 -0500 Subject: [PATCH 3/3] Check for deduplication of tasks --- sbt/src/sbt-test/project/sequential/build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sbt/src/sbt-test/project/sequential/build.sbt b/sbt/src/sbt-test/project/sequential/build.sbt index f3b423d13..cd4cb1eac 100644 --- a/sbt/src/sbt-test/project/sequential/build.sbt +++ b/sbt/src/sbt-test/project/sequential/build.sbt @@ -29,6 +29,8 @@ lazy val root = project. IO.append(t, "1") }, sideEffect2 := { + // check for deduplication of tasks + val _ = sideEffect1.value val t = testFile.value IO.append(t, "2") },