Gradle JAR files in a folder recursively - gradle

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.

Related

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: 'dependsOn' to task in other subproject

I have a hierarchical gradle 3.1 project, which looks like this:
root
- build.gradle
- settings.gradle
- server (Java + WAR plugin)
- build.gradle
- client (Node plugin)
- build.gradle
The settings.gradle therefore looks like this:
include ':server', ':client'
What I would like to do now is to bundle the output of the :client:build task in the *.war file produced by the :server:war task. To do so, I need a dependency from :server:war to :client:build in order to ensure that the output files of :client:build are always present when I need to copy them in the :server:war task.
The question is: how does this work?
What I want to achieve here: whenever :server:war is executed, :client:build gets executed first.
Things I tried so far (none of them worked):
// in server/build.gradle
task war {
dependsOn ':client:build'
}
I also tried:
// in server/build.gradle
war.dependsOn = ':client:build'
... and also:
// in server/build.gradle
task war(dependsOn: ':client:build') {
}
None of the attempts above works. Any idea what I am doing wrong?
Please try just:
war.dependsOn ':client:build'
and:
task war {
dependsOn ':client:build'
}
defines a new task called war
and:
war.dependsOn = ':client:build'
theoretically calls this method but the argument has wrong type
and:
task war(dependsOn: ':client:build') {
}
here you define a new task as well.

Access project build variables in init.gradle task

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.

Gradle: Common Zip task for every subproject

I have a multi-project gradle build, where all subprojects of root project have common zip task. They should zip some source, depending of the subproject's settings.
First, I configured it in parent build.gradle:
subprojects { subproject ->
apply plugin: 'java'
...
task submission(type: Zip) {
destinationDir = subproject.buildDir
archiveName = subproject.name
from subproject.ext.submissionFiles
}
}
But this does not work with Cannot get property 'submissionFiles' on extra properties extension as it does not exist. So i moved the task in each subproject's build.gradle, which breaks DRY principle.
I think the problem is that the configuration phase takes place before subprojects are configured. How can I "defer" configuration of this task, so that I only configure ext.submissionFiles in subprojects?
I think you're saying that submissionFiles is set in the subproject's build.gradle?
There are a few ways of doing it.
Option 1. You could defer the evaluation of subproject.ext.submissionFiles by wrapping it in a closure:
task submission(type: Zip) {
destinationDir = subproject.buildDir
archiveName = subproject.name
from ({ subproject.ext.submissionFiles })
}
Option 2. I think it could be better if you didn't use the intermediate variable (submissionFiles) and directly configured the submission task in the children:
// In root
task submission(type: Zip) {
destinationDir = subproject.buildDir
archiveName = subproject.name
}
// In child
submission {
from("path/to/files")
}
Using an intermediate variable like that to move configuration around can make your builds harder to understand connections between tasks.
Option 3. In some cases, it makes sense to use evaluationDependsOnChildren(), but I would generally not recommend it.

How to execute another task from a task with dependencies

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.

Resources