Now that we can declare tasks,
it's time to start thinking about the relationships between tasks.
For example,
in a Java build we can't jar up our library before compiling our sources.
We model these relationships by task dependencies and order.
We'll discuss three ways to configure the relationships between tasks.
Depends on, finalize by, and must run after.
Task A depends on Task B,
if Task A can't do its work without Task B having done its work.
To take a familiar example, when you're getting up in the morning,
you can't put on your shoes without putting on your socks first.
Let's declare and configure some tasks.
So here's our tasks that represent getting ready in the morning.
We've got put on socks, just prints a message,
put on shoes also just prints out that we're putting on our shoes.
The new thing is we've got this depends on function.
And we just passed the task name that put on shoes depends on.
In this case, put on socks.
So, let's give put on shoes a try.
And we are running Gradle on quiet mode, so
that we don't see all those diagnostic output.
We just see the printed messages.
There we go, when we try to put on our shoes Gradle realized we can't put on
our shoes without putting on our socks, so we ran that first.
The next type of task dependency we're going to talk about is finalized by.
We say task A is finalized by task B.
If every time task A runs, task B should be run afterwards.
To continue our example,
every time you eat breakfast, you really should brush your teeth afterwards.
We have those tasks here.
We've got the eat breakfast task, and the brush your teeth task.
And we note that eat breakfast is finalized by brush your teeth.
So, let's see what happens when we try to tell Gradle to
just run the eat breakfast task.
Looks like Gradle It was keeping us honest and
made us brush our teeth after we ate breakfast.
The use case for must run after is slightly less obvious.
Say we have a long running process that's unlikely to fail,
like deploying some artifact to a continuous integration server.
And we also have a short running task that is likely to fail,
like running unit tests.
Those two tasks don't have any dependency relationship, but
if we're running both we would really like the unit test to be run before
the integration tests.
To continue our morning routine example, let's continue showering and
putting on a fragrance like perfume or cologne.
Putting on a fragrance doesn't require showering, and showering doesn't
require putting on a fragrance, but if we're going to both take a shower and
also put on a fragrance, we should really take the shower first.
Let's create those tasks and relationship between them.
All right, so we've got our take shower task, and we've got our put on fragrance
task along with the should run after take shower.
So now if we go back to Gradle, and we say hey Gradle, run put on fragrance and
take shower.
Well, let's see what order they run in.
Looks like they run in the order that makes sense.
First we take a shower, then we put on the fragrance.
Let's check out a few other things we can do with task dependencies.
We can depend on multiple tasks, note this is one of those situations where
you do need to use the equal sign when you're assigning to a property.
Let's give this one a try.
So since get ready depends on taking shower, eating breakfast, and
putting on shoes, looks like we eat breakfast, and
since breakfast is finalized by brushing your teeth, we do that.
We're going to put on our shoes, but first we have to put on our socks.
And then we take a shower? Whoops.
Something's not right here.
I think we need one more ordering constraint.
There's no dependency relationship between taking a shower and putting on
shoes, but it certainly looks like if we're going to both take a shower and
put on shoes, we should probably take the shower first.
Let's change that out.
And there we go.
We say to put on shoes,
you must run after take shower, and now if we run this again,
looks like we're doing things in a more sensible order this time.
One more advanced thing we can do is look at all the tasks in a project and
decide which ones we want to depend on.
Let's make a task called getEquipped that depends on
every task that starts with putOn.
So here's our get equipped task.
And you'll see it depends on, and then this is actually a list that was
created by looking at all the other tasks in the project.
You don't need to understand how this works right now.
The point is just to show off something that would be extremely difficult or
impossible to do in other build tools.
Let's give it a try.
And we run get equipped, looks like we put on a fragrance, we put on our socks,
we put on our shoes.
As always there's more information to be found on task dependencies
in the course code.
Check it out!