Gradle Tasks Difference - gradle

What's the difference between the following two code snippets?
First:
task copyFiles(type: Copy) << {
from "folder/from"
into "dest/folder"
}
Second:
task copyFiles(type: Copy) {
from "folder/from"
into "dest/folder"
}

In short, the first snippet is getting it wrong, and the second one is getting it right.
A Gradle build proceeds in three phases: initialization, configuration, and execution. Methods like from and into configure a task, hence they need to be invoked in the configuration phase. However, << (which is a shortcut for doLast) adds a task action - it instructs the task what to do if and when it gets executed. In other words, the first snippet configures the task in the execution phase, and even worse, after its main (copy) action has been executed. Hence the configuration won't have any effect.
Typically, a task has either a type (which already brings along a task action) or a << (for an ad-hoc task). There are legitimate uses cases for having both (doing a bit of custom work after the task's "main" work), but more often that not, it's a mistake where the task gets configured too late.
I generally recommend to use doLast instead of <<, because it's less cryptic and makes it easier to spot such mistakes. (Once you understand the concepts, it's kind of obvious that task copyFiles(type: Copy) { doLast { from ... } } is wrong.)

The first block of code create a task and append an Action to it. A task is composed of actions which are instructions blocks run sequentially when the task is called
The second block create a task and configure it. These instructions are run in the gradle "configuration" lifecycle phase.
here you find a clear explanation of the differences
here you can find an in depth explanation of gradle tasks
here is the gradle guide about lifecycle

Related

How to write output from Task Scheduling in Laravel?

I have read the documentation, but I don't understand how to write the output if the task fails? I deliberately made a mistake in my task and copied it to the controller so that you can see the execution result.
The result is an error that is displayed. But when the task is executed through Task Scheduling, I get empty output to my email.
How to write the error output so that it would be present in the letter?
My kernel.php:
$schedule->call(new Load())->everyTenMinutes()->emailOutputOnFailure('myemail');
The emailOutputTo, emailOutputOnFailure, sendOutputTo, and
appendOutputTo methods are exclusive to the command and exec methods.
https://laravel.com/docs/8.x/scheduling#task-output

what is the best way to get notified when a task finishes, in F#?

I have a pool of tasks and I am trying to figure out the best way to be notified, through an event, when one is finished.
Since the tasks are quite varied, I don't want to add a piece of code inside the task itself since that would mean putting it in several places. These are long running tasks, I'm not waiting for them to complete anywhere, they're just getting started, do their work (minutes to days) and then they finish.
The ugly-but-could-work solution is to wrap each work task into another task that awaits for the work task to be complete and then sends an event, but I'm hoping there would be something more elegant.
In a comment you explained that you're starting your tasks like this:
Async.StartAsTask (runner.Start(), TaskCreationOptions.LongRunning, cancellationSource.Token)
Instead of doing that, start them like this:
startMyTask runner cancellationSource (fun() -> printfn "Task completed!")
Where:
let startMyTask (runner: RunnerType) (s: CancellationTokenSource) onDone =
let wrapper = async {
do! runner.Start()
onDone()
}
Async.StartAsTask (wrapper, TaskCreationOptions.LongRunning, s.Token)

Can Gradle task dependencies be set up to exclude a task?

We have in our build a lifecycle task which is supposed to run everything to do a quick check of the code. It looks like this:
task minimalBuild(dependsOn: [jar, testJar, javadoc])
Someone said it should also run checks, which seems reasonable, except that if I depend on check itself, check depends on test, so all the tests will be run and it's no longer a quick build.
I could manually list the individual checks of course, and that is my best idea right now, but every time someone installs a new checking tool, they will have to update this list, and they might not know they have to.
Is there a way to do this programmatically at least? Can I make minimalBuild depend on "everything check depends on except for test"?
You can onfigure it via taskGraph, like so:
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(minimalBuild)) {
tasks.withType(Test){
enabled = false
}
}
}
This configuration should be added to root of the script. It waits untill the execution graph is ready (it contains all the task, which should be really executed), after that it checks, whether minimalBuild task will be executed and if yes, then it disables all the tasks wit Test type.

Gradle - Capturing output written to out / err on a per task basis

I'm trying to capture output written from each task as it is executed. The code below works as expected when running Gradle with --max-workers 1, but when multiple tasks are running in parallel this code below picks up output written from other tasks running simultaneously.
The API documentation states the following about the "getLogging" method on Task. From what it says I judge that it should support capturing output from single tasks regardless of any other tasks running at the same time.
getLogging()
Returns the LoggingManager which can be used to control the logging level and standard output/error capture for this task. https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html
graph.allTasks.forEach { Task task ->
task.ext.capturedOutput = [ ]
def listener = { task.capturedOutput << it } as StandardOutputListener
task.logging.addStandardErrorListener(listener)
task.logging.addStandardOutputListener(listener)
task.doLast {
task.logging.removeStandardOutputListener(listener)
task.logging.removeStandardErrorListener(listener)
}
}
Have I messed up something in the code above or should I report this as a bug?
It looks like every LoggingManager instance shares an OutputLevelRenderer, which is what your listeners eventually get added to. This did make me wonder why you weren't getting duplicate messages because you're attaching the same listeners to the same renderer over and over again. But it seems the magic is in BroadcastDispatch, which keeps the listeners in a map, keyed by the listener object itself. So you can't have duplicate listeners.
Mind you, for that to hold, the hash code of each listener must be the same, which seems surprising. Anyway, perhaps this is working as intended, perhaps it isn't. It's certainly worth an issue to get some clarity on whether Gradle should support listeners per task. Alternatively raise it on the dev mailing list.

Troubles trying to start two asynchronous tasks.

I want to start two Async Tasks but the second will not start until the first has completed.
From what I've googled, people usually suggest this approach:
new MyAsyncTask().execute(params);
new MyAsyncTask().execute(params);
However, I need to instantiate them separately and also keep the handles of the task's (to pass messages for example). Therefore, I SORT OF do this:
onStart()
{
taskA = new MyAsyncTask(paramsA);
taskB = new MyAsyncTask(paramsB);
}
onButtonPress()
{
taskA.execute();
taskB.execute();
}
Edit:
I've noticed that taskB does not actually start executing until taskA completes (which runs a tcp/ip server so it takes a long time). I cannot figure out why. Any thoughts or comments ?
The short answer is that, depending on your version of Android, all AsyncTask subclasses may be using the same thread, so you can only do one at a time. There are two ways around this:
Use Runnable instead of AsyncTask
Replace one call to execute with executeOnExecutor(Executor.THREAD_POOL_EXECUTOR, params)
Clearly, try #2 first - it's less of a code change. But if that doesn't work pretty quickly, I'd switch to #1. In that case, you don't have to worry about how Android might change in the future.
If you want more details about the threading model for AsyncTask, have a look at the Android doc entry.

Resources