Gradle plugin task ordering - gradle

What I have?
Java source file with Main class (MainApp)
gradle build script
apply plugin: 'application'
mainClassName = "MainApp"
sourceSets.main.java.srcDirs = ['.']
So when I do gradle run, it executes main method and everything works just perfectly.
C:\tmp\gradle-fun>gradle run
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello MainApp !!
BUILD SUCCESSFUL
What I want to do?
Now I was wondering about clean task (common build tasks) to clean the build directory before run task executes.
There is reason behind that, I want to make sure that every time gradle should compile the java files and all .class file should be refreshed (its some requirement)
What I have tried?
Added a wrapper task which executes clean task and run task in order.
apply plugin: 'application'
mainClassName = "MainApp"
sourceSets.main.java.srcDirs = ['.']
task exec(dependsOn: ['clean', 'run'])
So when I run gradle exec, it does it job properly. However I feel that its patch work when you have extra tasks just for ordering execution.
C:\tmp\gradle-fun>gradle run
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello MainApp !!
:exec
BUILD SUCCESSFUL
What I would like to know?
Is there any way to avoid writing wrapper task and do some Gradle magic to achieve the requirement?

Just have the run task depend on clean. This will ensure your project is cleaned before every run. If you want to be more specific in regards to your use case, you can simply clean the compileJava task.
run.dependsOn 'cleanCompileJava'
Edit: To avoid deleting your classes before the run add:
classes.mustRunAfter 'cleanCompileJava'

You could create your own task, with clean and run as dependencies:
task cleanRun(dependsOn: [clean, run])
Or, you could follow Mark Vieira's answer and change the wiring:
run.dependsOn 'clean'
classes.mustRunAfter 'clean'
The second line makes sure that it doesn't clean the compiled classes.
Hope this helps =)

Related

how to execute 'gradle build' command from gradle.build script

I want to execute a gradle build command from build.gradle file.
build.gradle file
apply plugin: 'java'
apply plugin: 'application'
task me{
//Can we perform gradle build command here.
}
Question:
Can we perform gradle build command inside task me, similarly like we do from command prompt(screenshot attached)..?
Note : I am using windows env, please assume I am providing all other statements in build.gradle file.
I am able to build from command prompt by executing
.
I want to execute this task me from command prompt and it should be responsible to call gradle build command.(attached screenshot)
Yes, if you make the task me to a task of type GradleBuild
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.GradleBuild.html
E.g.
task me(type: GradleBuild){
buildFile 'mybuild.gradle' //defaults to build.gradle so not needed
dir 'someDir'
tasks 'clean', 'build'
}
You cannot "call" a Gradle task in a Gradle build.
You might stumble upon the method execute() that each Gradle task has, but this is a purely internal method that must not be used by any build script. Using it will not work properly. It will not ensure the task is run only once, it will not ensure dependency tasks are run before and so on and so on, just don't use it.
Your code snippet is too big for me wanting to interpret it right now to understand what you want to do exactly, but if you want to "call" a Gradle task from another Gradle task, your logic is bogus and should be changed. If you want to run a Gradle task before or after another Gradle task is run, the only supported way is to use dependsOn (before) or finalizedBy (after) and you can not set these properties during execution phase of a task but only during configuration phase.
Well, there is one other way to call a Gradle task from a build script, but this is by using a task of type GradleBuild which would start a complete new and separate build of the project you specify which is most often not the action you really want to do.

How to run JavaExec with out compile

I run a gradle javaexec in build.gradle
task main(type: JavaExec) {
main = 'com.gtan.Application'
classpath = sourceSets.main.runtimeClasspath
}
this is the output result:
:compileJava UP-TO-DATE
:compileScala UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:main
i want run this javaexec without compile tasks. like:
:main
what should i do ?
When you set up the classpath as the runtime classpath from the main sourceSet, you're telling Gradle that your task depends on the output from the main sourceSet. So, it will compile the main source set first, in order to ensure that the classpath is correctly set up for your JavaExec task.
The answer to your question depends on where the com.gtan.Application class is, and what classpath the application is expecting. If this class resides in the local project, under src/main/java, you won't be able to get rid of compilation, because Gradle must compile this class in order to execute it.
If the class lives in a JAR that your build depends on, for example:
dependencies {
runtime 'com.gtan:this-example-has-what-to-run:1.0.0'
}
Then, you can change your task definition to:
task main(type: JavaExec) {
main = 'com.gtan.Application'
classpath = configurations.runtime
}
By setting the classpath to a configuration, Gradle does not need to perform any compilation, and you get:
$ ./gradlew main
:main

Execute task with build task

I have a traditional java project using gradle build system.
I would like to add jacoco code coverage report generation. So I applied jacoco plugin and everything works as expected when I call gradle build jacocoTestReport
I was wondering how can I define in my build.gradle script that jacocoTestReport task should run automatically after buildtask has been finished.
The goal is to only run gradle build from command line and this will automatically execute test and jacocoTestReport (so that I don't have to pass jacocoTestReport as commandline parameter explicitly).
I would suggest
build.finalizedBy(jacocoTestReport)
This way, the jacocoTestReport task is only executed after the build task, as you specified. In the accepted answer, the build task depends on the test report task, which means build will be executed after your custom task.
Add this to the end of your buildscript
build.dependsOn jacocoTestReport

Run my task before a plugin's task?

We're using a gradle file to build a Java WAR file. I know very little about gradle. At the top of build.gradle:
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'war'
We run the gradle with gradle clean install. I'm not sure where these tasks are defined but I assume they're in one of the plugins (I'd guess war).
When I run gradle clean install it seems to print the tasks that it are run:
:clean
:compileJava
:processResources
:classes
:war
:install
Correct me if I'm wrong, but it seems that the task install dependsOn compileJava, processResources, classes, and war.
I need a task I've written to run sometime after clean but sometime before war. Preferably without modifying the plugin.
I've tried indicating that my task mustRunAfter processResources but it doesn't work that way.
How can I inject my task as a dependency on install before the dependency war?
You can declare task dependencies explicitly.
Add following code to your build.gradle file
tasks.war.dependsOn("yourTaskNameHere")
tasks["yourTaskNameHere"].dependsOn("clean")

Gradle task at the end of build with a multiproject build

I am attempting to create my own task, that will create a package of all the artifacts generated during my multi-project build.
Currently what I do right is now just:
gradle build createPackage
Which gives output like the following:
:test-utility:compileJava UP-TO-DATE
:test-utility:processResources UP-TO-DATE
...
:test-utility:check UP-TO-DATE
:test-utility:build UP-TO-DATE
Creating Package...
Created.
BUILD SUCCESSFUL
Total time: 4.654 secs
With the createPackage task being:
task createPackage {
println "Creating Package..."
println "Created."
}
However, I would like to simply it by running just one command, so what would the best way to do this and ensure the order stays maintained?
Ideally I would like to call build within the createPackage task or append to the build task with my task.
Ok reading between the lines there are a few things to clear up
1) Your printlns are being run in the configuration phase, not the execution phase. See http://www.gradle.org/docs/current/userguide/build_lifecycle.html for more info.
2) You do not have a single 'build' task. gradle build on the command line will run the 'build' task of each of your subprojects. Your package task would need to depend on all of them. Something like..
apply plugin: 'java'
evaluationDependsOnChildren()
task createPackage(type:Zip) {
dependsOn subprojects*.build
}
3) You can be more declarative with gradle - just tell it what you want to package up and it will figure out what it needs to run. For example, you can say that you want to zip up all the jars from your subprojects.
apply plugin: 'java'
evaluationDependsOnChildren()
task createPackage(type:Zip) {
from subprojects*.jar
}
There are plenty of ways. One suggestion is to modify build to depend on createPackage to make sure you can call just gradle build. Then you want to enhance your task and tell what are its inputs (probably those are outputs of some other tasks like jar). Gradle will add these tasks to execution when you run the build and can re-run them based on up-to-date status of each task. This is documented in userguide - http://www.gradle.org/docs/current/userguide/more_about_tasks.html#sec:up_to_date_checks and later in a chapter on custom tasks.

Resources