How do I reuse task configuration in Gradle? - gradle

I have task war configuration with many from/include/exclude:
task war {
exclude
exclude
...
into ... from ...
into ... from ...
}
I have another task war configuration which is the same except one exclude.
I don't want to duplicate those configurations. How can I reuse the first configuration?

Try:
ext.sharedCopyConf = { task, to ->
configure(task) {
into to
from 'a'
}
}
task copy1(type: Copy) { t ->
sharedCopyConf(t, 'b')
}
task copy2(type: Copy) { t ->
sharedCopyConf(t, 'c')
}
Have a look at the demo.

ext.sharedWarConfig = { task->
configure(task) {
from ... include ...
}}
task warWithoutFile(type: War) { task ->
sharedWarConfig(task)
exclude ...
}
task warWithFile(type: War) { task -> sharedWarConfig(task) }
jettyRunWar {
dependsOn warWithFile
dependsOn.remove("war")
webApp = warWithFile.archivePath
}

Related

Is there a way to configure multiple gradle tasks at once?

I have the following snippet in a build.gradle file for a project I work on:
tasks.named('test').configure {
dependsOn customTask
}
tasks.named('compileTestJava').configure {
dependsOn customTask
}
tasks.named('jar').configure {
dependsOn customTask
}
tasks.named('build').configure {
dependsOn customTask
}
It seems redundant to have to specify the the same configuration for 4 tasks separately. Is there a way to select and configure multiple tasks at once? Perhaps something like:
tasks.named('test', 'compileTestJava', 'jar', 'build').configure {
dependsOn customTask
}
(I tried this code, but it does not work.)
You can do
['a', 'b', 'c'].each {
tasks.named(it).configure {
dependsOn 'customTask'
}
}

How to ignore dependsOn failure because some subprojects don't have the defined task

I have a multi-project gradle build where not all of the subprojects have the same plugin, but I would like to define tasks in the root build.gradle file like this:
subprojects {
task continuousBuild(dependsOn: ["clean", "check", "jacocoTestReport", "integrationTests"]
}
Not all subprojects have "jacocoTestReport" or "integrationTests" defined, but this task will fail because of that fact. How do I configure this to work, and frankly, why is the default behavior so strict?
This is what ended up working for me:
task continuousBuild(dependsOn: ['clean', 'check']) {
def uncommonTasks = ['jacocoTestReport', 'integrationTests']
dependsOn += tasks
.findAll { uncommonTasks.contains(name) }
}
And I forgot that I actually needed to run integrationTests in a doLast, which looks like this:
task continuousBuild(dependsOn: ['clean', 'check']) {
dependsOn += tasks
.findAll { 'jacocoTestReport' == name) }
if (tasks.findByName('integrationTests')) {
doLast {
integrationTests
}
}
}

What is the best way to parameterize a task on Gradle?

I need to create two different .properties files from two different .properties.dist if they don't exist, so I'm using a Copy task and I'm specifying the from and the into accordingly.
At the moment I had to create two different tasks, each of which is creating a file like this:
task copyAndRenameDialling(type: Copy){
if(!file("./properties/dialling.properties").exists()){
from './dist/dialling.properties.dist'
into './properties/'
rename{ String fileName ->
fileName.replace('.dist','')
}
}
}
task copyAndRenameFiles(type: Copy){
if(!file("./properties/file.properties").exists()){
from './dist/files.properties.dist'
into './properties/'
rename{ String fileName ->
fileName.replace('.dist','')
}
}
}
task copyAndRenameProperties {
dependsOn << copyAndRenameDialling
dependsOn << copyAndRenameFiles
}
and I run the task with gradle copyAndRenameProperties.
Is it possible to make the two Copy tasks parameterized based on the name of the file, so that I have only one generic copyAndRename?
If so, how can I pass the parameter to the task?
I'd do it like this:
task copyAndRenameProperties(type: Copy) {
from 'dist'
include '*.properties.dist'
into 'properties'
rename { it - ~/\.dist$/ }
eachFile { if (file("properties/$it.name").file) it.exclude() }
}
or if you really only want those two specific files
task copyAndRenameProperties(type: Copy) {
from 'dist/dialling.properties.dist'
from 'dist/file.properties.dist'
into 'properties'
rename { it - ~/\.dist$/ }
eachFile { if (file("properties/$it.name").file) it.exclude() }
}
or
task copyAndRenameProperties(type: Copy) {
from 'dist'
include 'dialling.properties.dist', 'file.properties.dist'
into 'properties'
rename { it - ~/\.dist$/ }
eachFile { if (file("properties/$it.name").file) it.exclude() }
}

Is there a way to "merge" gradle tasks to avoid many dependsOn declarations

Suppose this gradle script:
task copyGroovyScript(dependsOn: prepare, type: Copy) {
from "${scriptSrcLocation}/${scriptSrcName}"
into buildFolderZipSource
}
task copyDependenciesForGroovyScript(dependsOn: copyGroovyScript, type: Copy) {
from configurations.groovyScript.resolve()
into "${buildFolderZipSource}/groovy-plugin-lib"
}
task copyTestScripts(dependsOn: copyDependenciesForGroovyScript, type: Copy ) {
from "${scriptSrcLocation}/ReadClient.groovy"
into "${buildFolderZipSource}/test"
}
task copyTestScriptsBin(dependsOn: copyTestScripts, type: Copy ) {
from "${scriptSrcLocation}/bin"
into "${buildFolderZipSource}/test/bin"
}
task copyDependenciesForTestScripts(dependsOn: copyTestScriptsBin, type: Copy) {
from configurations.testScripts.resolve()
into "${buildFolderZipSource}/test/lib"
}
task packageAll(dependsOn: copyDependenciesForTestScripts, type:Zip) {
archiveName "output-${buildTime()}.zip"
excludes ['*.zip']
destinationDir buildFolder
from buildFolder
}
I need different Copy tasks before they have different output folders.
Is there a way to avoid having to have all those dependsOn statements and just have gradle execute things in order of declaration in the file somehow?
There's no way to execute in the way it's declared. But why don't you go this way:
task packageAll(dependsOn: copyDependenciesForTestScripts, type:Zip) {
doFirst {
copy {
from "${scriptSrcLocation}/${scriptSrcName}"
into buildFolderZipSource
}
}
//following doFirst and so on..
archiveName "output-${buildTime()}.zip"
excludes ['*.zip']
destinationDir buildFolder
from buildFolder
}
EDIT
After discussion in comments it turned out that the following piece of code should do the job
task prepare {
doFirst {
copy {
from "${scriptSrcLocation}/${scriptSrcName}"
into buildFolderZipSource
}
}
//following doFirst and so on..
}
task packageAll(dependsOn: prepare, type:Zip) {
archiveName "output-${buildTime()}.zip"
excludes ['*.zip']
destinationDir buildFolder
from buildFolder
}

Change copy task destination

I would like to change the destination dir for file copy depending on the chosen build.
This does not work since the task graph is executed in execution phase but the copyTask is set in configuration phase.
How can I achieve this?
gradle.taskGraph.whenReady { taskGraph ->
println('taskGraph')
if (taskGraph.hasTask(buildRelease)){
File toDir=file('test/r')
println('Copy to: ' + toDir.getName())
}else if (taskGraph.hasTask(buildDevel)) {
File toDir=file('test/d')
println('Copy to: ' + toDir.getName())
}
}
task buildDevel (dependsOn: ['copyTask']){}
task buildRelease (dependsOn: ['copyTask']){}
task copyTask(type: Copy) {
from "test"
into toDir
include 'a.txt'
}
This may help You (You need to create a.txt file on the same level as build.gradle is located:
gradle.taskGraph.whenReady { taskGraph ->
def cp = project.copyTask
if (taskGraph.hasTask(buildRelease)){
cp.into 'lol1'
} else if (taskGraph.hasTask(buildDevel)) {
cp.into 'lol2'
}
}
task buildDevel (dependsOn: ['copyTask']){}
task buildRelease (dependsOn: ['copyTask']){}
task copyTask(type: Copy) {
from file('.')
include 'a.txt'
}
This will also work:
task buildDevel
task buildRelease
buildDevel.doFirst {
cp('lol1')
}
buildRelease.doFirst {
cp('lol2')
}
def cp(to) {
copy {
from file('.')
into to
include 'a.txt'
}
}

Resources