On Tue, 22 May 2012 11:57:17 -0700
Lee Mighdoll <
l...@underneath.ca> wrote:
> My use case is for integration tests. Here's an example:
>
> vanillaIntegration <<= (startServers, waitForServers, externalTests,
> stopServers) {(start,wait,tests,stop) =>
> start && wait && tests doFinally stop
> }
>
>
> I think the && on RichInitializeTask would win the following pithier
> version: (well, assuming there's a way way to get andFinally to work with
> TaskKey...)
>
> vanillaIntegration <<= startServers && waitForServers && externalTests
> andFinally stopServers
The problem is that strict sequencing and tasks are not really compatible. A task defines the inputs it needs to run and doesn't enforce an order beyond that.
All 'b && c' does is delay introducing 'c' into the run until after 'a' completes. It doesn't force c to run after b. If 'b' depends on 'c' somehow (and I don't think this is an unreasonable situation), 'c' will get introduced. To prevent this, c would have to declare 'b' as a dependency. In fact, if you really wanted to stick with tasks, you'd define stopServers to depend on externalTests, externalTests to depend on waitForServers and define waitForServers to depend on startServers.
I haven't made && easy to use because I don't think its semantics are intuitive and users will expect to use them like sequencing as in this thread. If what you want is sequencing (and it looks like you do), use a command like you show below, or sequence within a task. Conceptually, you want a task that does:
externalTests = {
startServers()
waitForServers()
try runExternalTests()
finally stopServers()
}
all in one task within the task. (These are plain methods.) The difference here is that execution order is explicit and nothing else can interfere, such as by causing stopServers to run earlier than runExternalTests or whatever.
(I seem to remember someone else explaining this more succinctly/clearly on this mailing list, but I couldn't find it. Hopefully it gets the right idea across.)
>
>
> I had tried writing this with Command, but didn't find anything clean, e.g.:
>
> Command.command("vanilla-integration") {state =>
> val extracted = Project.extract(state)
> try {
> extracted.runTask(startServersTask, state)
> extracted.runTask(waitForServersTask, state)
> runExternalTests()
> } finally {
> extracted.runTask(stopServers, state)
> }
> state
> }
Is this what you want, what you have but don't like, or what?
> Suggestions welcome. Hopefully the concrete example helps.
Yes, thanks.
-Mark