Chained Gradle task cannot read file generated by previous task - gradle

I have gradle task, taskA, which when run will generate a html file. Then taskB will try opening that file. When I chain these like:
./gradlew taskA taskB
Then taskB cannot see the generated file. Incidentally IntelliJ is open and does not see the file at the same time.
However if I run the commands separately, e.g.
./gradlew taskA
./gradlew taskB
Then taskB can see the file fine. Do you know how I might chain the commands with the effect of running them separately? I have tried using clean at the start of taskB but it does not help.

The way you chain task in Gradle is by making taskA depend on taskB.
You can do it as follows:
apply plugin: 'base'
def file = project.file('shared-file.txt')
task taskA {
outputs.file(file)
doLast {
// Create the file
file.text = "Hello world!"
}
}
task taskB(dependsOn: taskA) {
inputs.file(file)
doLast {
// Print file content
println file.text
}
}
To clean up the file you can run cleanTaskA which will cleanup all outputs that taskA has defined. Or if you want to add the cleanup to the generic clean task then add clean.dependsOn(cleanTaskA, cleanTaskB).

The way I got it to work was by cd'ing back into the current directory.
This can be achieved with the following command, when you are in the correct directory:
cd .
This forces gradle to pick up any new files immediately.

Related

How to run custom task after gradle assemble command

Actually I have these lines as part of my build.gradle file (using gradle 7.3.3)
processResources {
dependsOn "buildAngular"
}
task buildAngular(type: Exec) {
...
my task "buildAngular" runs automaticly on ./gradlew assemble its perfect and exactly what I want. But it runs on ./gradlew test too.
How I can make it run only on ./gradlew assemble?
As already mentioned in my comment on the question:
Since tests require a complete runtime classpath and since processResources produces parts of that classpath, it wouldn’t make sense to not run it when test is run.
If you only want to run buildAngular as part of assemble, then simply make the former a dependency of the latter:
assemble {
dependsOn 'buildAngular'
}

gradle - cleanup after task complete with dependsOn

I have two custom tasks like --
task taskA(type: SomeTaskA) {
....
}
task taskB(type: SomeTaskB, dependsOn: 'taskA') {
....
}
taskA generates a file and performs some operations on it.
taskB also performs some operations on the file that is generated by taskA.
I can run both the tasks individually.
I need to delete this file when gradle command complete, ie., if I run gradle taskA then the file will delete when taskA completed and if I run gradle taskB then the file will delete when taskB completed.
I can achieve first part by adding doLast block and add delete logic there but when I run taskB then I have no file to perform operation (because taskA doLast already deleted the file).
Is then anyway to stop taskA doLast when I run taskB, or any other way to achieve this?
You could create a dedicated "cleanup" task to handle the file deletion, and make both tasks taskA and taskB be finalized by this task cleanup:
task cleanup{
doLast{
// DELETE the file
}
}
taskA.finalizedBy cleanup
taskB.finalizedBy cleanup
This way, the file will always be deleted, either you run taks A or B. And this will ensure that taskB is executed before the file is deleted by task cleanup as well.

gradle copy file task not working in build

I am new to gradle, I want copy the jar file generated by gradlew build to another dir.
task myCopyTask(type: Copy) {
from "build/libs/gs.jar"
into "D:/bin/gs"
}
I add above task to the build.gradle which belong to gs module which will generate gs.jar.
The problem is the command gradlew build will not do the copy and this task indeed executed(I add println in myCopyTask). However, the command gradlew myCopyTask works.
First I thought maybe the copy task running too early, so I change it to
task myCopyTask(type: Copy) {
doLast {
from "build/libs/gs.jar"
into "D:/bin/gs"
}
}
This is not working even by gradlew myCopyTask. Only first version can work by command gradlew myCopyTask, the terminal will show: 1 actionable task: 1 executed
What is the problem?
You haven't wired the task into Gradle's DAG so currently it will only executed when you do gradlew myCopyTask
You'll probably do something like
apply plugin: 'base' // adds build and assemble lifecycle tasks
task myJarTask(type:Jar) {...}
task myCopyTask(type: Copy) {
dependsOn myJarTask
...
}
assemble.dependsOn myCopyTask
See https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:task_dependencies

Gradle: execute tasks sequentially in some task

I have a library, which contains 3 lib modules and 1 example module. Before deploy task I want to execute some other tasks. In command line it looks like this: ./gradlew -x:example:clean -x:example:check -x:example:uploadArchives clean check :androidLib:assembleRelease uploadArchives.
I want to write gradle task to execute all tasks sequentially for all modules besides example module. That I can do: ./gradlew deployAll. How can i do it?
I try do this:
task deployAll {
doLast {
subprojects {
if(it.plugins.withType(com.android.build.gradle.AppPlugin)) return
it.tasks.getByName('clean').execute()
it.tasks.getByName('check').execute()
...
}
}
}
But execute() is deprecated and it execute only first task and ignore any.
You can use dependsOn inside of your gradle tasks to make sure your tasks run in the correct order
task task1{
dependsOn task2
//Task one code
}
task2{
dependsOn task3
//task 3 code
}
task3{
//task3 code
}
so in this example if you call task1, first task 3 will be executed, then task2 and then finally task one, but you need only call task1.
You can make another task and set other tasks its dependencies
task deployAll {
dependsOn tasks.getByName('clean')
dependsOn(tasks.getByName('check'))
}
To ensure the order add put this somewhere
tasks.getByName('check').mustRunAfter(tasks.getByName('clean'))

Why does gradle run every task in gradle.build

I'm very new to gradle and have a basic question.
When I add a custom task to my gradle.build file and call "gradlw build" or "gradle clean" or any other gradle command,
it automatically runs my custom task.
Is that how things work in gradle? run every task in the build file?
Is there way to run a task only when I want it manually?
task foo {
println 'hello'
}
That creates a task, and during the configuration of the task, it tells gradle to execute println 'hello'. Every task is configured at each build, because gradle needs to know what its configuration is to know if the task must be executed or not.
task foo << {
println 'hello'
}
That creates a task, and during the execution of the task, it tells gradle to execute println 'hello'. So the code will only be executed if you explicitly chose to run the task foo, or a task that depends on foo.
It's equivalent to
task foo {
doLast {
println 'hello'
}
}
You chose not to post your code, probably assuming that gradle was acting bizarrely, and that your code had nothing to do with the problem. So this is just a guess, but you probably used the first incorrect code rather than the second, correct one.

Resources