I am trying to figure out, how to set variables in build.gradle and access that varible in init.gradle script.
Please find below sample build script :-
gradle.allprojects{
task CommonTasks{
println "CommonTasks - loaded"
}
CommonTasks.doFirst{
println "CommonTasks - doFirst : here i want to use variable, that is declared in project build"
}
CommonTasks.doLast{
println "CommonTasks - doLast"
}
}
Also find below sample project build :-
apply plugin : 'java'
//some-where here i want to pass a variable in CommonTasks
clean.dependsOn CommonTasks
Please suggest, how to access project build.gradle variables(say, String or File type for example) on init.gradle page.
Largely, you just need to be careful about which phases all of the code runs in. Gradle has 3 phases when you run a gradle <some task> command.
Initialization - processes init.gradle scripts, settings.gradle scripts, and generally just gets the project structure defined
Configuration - processes build.gradle scripts for all projects
Execution - executes the requested tasks
Importantly you can delay execution of code in your init.gradle script into later phases. I included print statements in the example below to help illustrate when this code executes.
One option for what you want is to declare the property in the init phase on the task or project (my example shows it on the task). This way you are sure that the property is defined by the time you reference it in your doFirst. Your build.gradle just needs to set that variable at configuration time.
init.gradle
println 'init.gradle: In initialization phase'
gradle.allprojects {
task CommonTasks {
println 'init.gradle: In configuration phase'
ext.myVar = null
println "Value of myVar=${myVar}"
doFirst {
println 'init.gradle: In execution phase - doFirst'
println "Value of myVar=${myVar}"
}
doLast {
println 'init.gradle: In execution phase - doLast'
}
}
}
build.gradle
apply plugin: 'java'
// set the value
CommonTasks.myVar = 'buildValue'
clean.dependsOn CommonTasks
This should print out myVar=buildValue upon execution.
Related
build.gradle is:
task copy(type: Copy, group: "Custom", description: "Copies sources to the dest directory") {
from "src"
into "dest"
println "copy"
}
task hello {
println "hello"
}
And when I try with ./gradlew copy, both copy and hello are executed. Output like below:
> Configure project :
copy
hello
How can I only execute copy?
In your example, only the copy task is executed. However, both are configured.
A Gradle build has three distinct phases in the build lifecycles:
An initialization phase
A configuration phase
An execution phase
By default, Gradle configures all tasks at start-up, though many types of configurations can be deferred (lazy configuration).
The println statement you have in the hello task is part of the configuration and this is why you see it no matter what task you intend to execute. You can also see in the output that is under the > Configure project : header.
If you want to only print "hello" when it actually executes, move it into a doLast block like this:
task hello {
doLast {
println "hello"
}
}
How can I JAR a folder and all of it's sub directories and files in a simple JAR?
I tried something like this and it does not work.
task jarVrCore(type: Jar, description: 'JARs core part of the project') {
doLast {
archiveName = "vasasdasasdasd"
from "${projectDir}"
println "${vrCoreSourceDir}"
destinationDir = file("${dirTmpLibsVr4}")
}
}
I always get an empty JAR with only the manifest.
The problem is that all of your task configurations are applied too late. You are using a doLast closure, which is executed after the actual task action (for a Jar task: the creation of the .jar file).
Normally, all task configuration is done directly inside the task configuration closure:
task jarVrCore(type: Jar, description: 'JARs core part of the project') {
archiveName = "vasasdasasdasd"
from "${projectDir}"
println "${vrCoreSourceDir}"
destinationDir = file("${dirTmpLibsVr4}")
}
If you need to apply configuration after other tasks have been executed, use a doFirst closure.
Please note, that using the example above, the println statement will be executed during configuration phase and therefore on each Gradle invocation, whether the task jarVrCore is executed or not.
This is what i am trying inside the gradle task
task parse(type: Exec) {
standardOutput = new ByteArrayOutputStream()
executable 'make'
args "print_JDBC_CURRENT_JDK_OPT_JAR"
doLast {
project.ext.jdkver=standardOutput.toString()
}
}
println project.jdkver
Error: Could not get unknown property 'jdkver' for root project 'xyz'
of type org.gradle.api.Project.
Task actions, doFirst and doLast closures are executed during execution phase, but everything else in your build script, including your println statement is executed before that, during the so-called configuration phase.
Since the extension property is used before it's defined, the build fails.
If the value you determine is only required in another task, you can keep your approach and use the value in the tasks, if they are executed after this task (which you can ensure via dependsOn).
If you need the value in your configuration phase and independent from any task (or how you call Gradle), do not use an Exec task, but the exec method of your Project object, which will be executed immediately.
Please find below init.gradle file that has a common task for all my projects :-
rootProject { apply plugin: "eclipse" }
gradle.allprojects{
ext.commonTaskForEveryBuild = {
println "Common task for every build starts here..."
println "Common task for every build ends here..."
}
}
Also find below sample build.gradle for one of my project :-
apply plugin : 'java'
clean.doFirst{
println "Before invoking commonTaskForEveryBuild"
//This is invocation of commonTaskForEveryBuild
commonTaskForEveryBuild
println "After invoking commonTaskForEveryBuild"
}
Below are the logs for the execution of "gradle clean" task for the sample build.gradle file :-
:clean
Before invoking commonTaskForEveryBuild
After invoking
commonTaskForEveryBuild
:clean UP-TO-DATE
BUILD SUCCESSFUL
Total time: 3.722 secs
Looks like clean.doFirst is called, but it's not invoking definition of commonTaskForEveryBuild. Although, there is no compile time or runtime error.
Please suggest.
It's all right, that your task is not invoked, since your script doesn't attempt to do it and it's not even a task. You just getting your commonTaskForEveryBuild instance, but do nothing with it.
You may need to read the official user guide to find out, how to call one task from another. In short - this is usually done via task dependencies. You have to make your clean task depending on commonTaskForEveryBuild task to run it before the clean task execution. This could be done like so:
clean.dependsOn commonTaskForEveryBuild
Furthermore, it's all about tasks, but in your case ext.commonTaskForEveryBuild = {...} is not even a task, but just a closure and it must be executed as commonTaskForEveryBuild()
I have multiple gradle files to run test suites. Each gradle file has multiple tasks with dependencies defined. And there will be a task with same name as file name to run all those tasks.
Example
foo_test.gradle
task testBlockA << {
// do some tests here
}
task testBlockB(dependsOn: testBlockC) << {
// do some tests here
}
task testBlockC << {
// do some stuff here
}
task foo_test(dependsOn: testBlockA, testBlockB)
Now I want to write a common test.gradle file which, based on argument provided, loads the given test gradle file and runs the task
gradle -b test.gradle -Ptest_to_run=foo_test
How to I create a task in test.gradle, which will run foo_test task of foo_test.gradle, along with its dependencies (testBlockA-C)
As I read tasks['foo_test'].execute() will not work as it does not execute the dependsOn tasks.
In your main build.gradle file, you can read the provided -P attribute in your build.gradle file:
if(project.hasProperty("test_to_run")){
apply from:test_to_run
defaultTasks test_to_run
}
this snippet applies a buildscript based on the input property and also declares a defaultTask to run.