Gradle exclude resources for one task but not for second - gradle

Is it possible to exclude resources for a task, but do not exclude them for a second task? Both are triggered from a third task like this:
task createBoth {
dependsOn = [createFirst, createSecond]
}
task createFirst {
sourceSets.main.resources.excludes = ['**/images']
}
task createSecond {
sourceSets.main.resources.excludes = []
}
I tried to exclude in doFirst{} method, but it did not work. If run as a single task then it works fine. Both results are the same version of my Java project. Except they have a different main class and one does not need all images. So I want to create both files in a single run. Is it even possible?
Attempt 2:
task createSystemcheckJar(type: OneJar) {
exclude('**/images/ads/images') // And some ohter combinations with stars
}
Same problem.

Related

How to include/exclude junit5 tags in gradle cmd?

I want to execute tagged JUnit 5 tests, eg. only slow tests, with gradle.
I want to do the same like this in maven:
mvn test -Dgroups="slow"
But what is the equivalent in gradle? Or is there anything at all?
To execute all JUnit 5 tests which are marked with #Tag("slow"). I know it's quite simple to create a dedicated task like this:
tasks.withType(Test::class.java).configureEach {
useJUnitPlatform() {
includeTags("slow")
}
}
But I have a lot of different tags and I don't want to have a task for each single tag. Or worse, having one task for all permutations.
Another possibility would be to pass self defined properties to the task like this
tasks.withType(Test::class.java).configureEach {
val includeTagsList = System.getProperty("includeTags", "")!!.split(",")
.map { it.trim() }
.filter { it.isNotBlank() }
if (includeTagsList.isNotEmpty()) {
includeTags(*includeTagsList.toTypedArray())
}
}
The last time I checked, Gradle didn't have built-in support for configuring JUnit Platform include and exclude tags via the command line, so you'll have to go with your second approach.
But... there's no need to split, map, and filter the tags: just use a tag expression instead: https://junit.org/junit5/docs/current/user-guide/#running-tests-tag-expressions
You can create a separate task and to choose do you want to run the task or to skip it.
For example add this code in build.gradle:
def slowTests= tasks.register("slowTests", Test) {
useJUnitPlatform {
includeTags "slow"
}
}
Now if you want to run only slow tests:
./gradlew clean build -x test slowTests

Set the properties in the configuration phase of a task in another task

I have spent the last few hours trying to find a solution for my requirement, without luck:
I have a task that has to run some logic in a certain path:
task run(type: MyPlugin) {
pathForPlugin = myPath //Defined as a property in another gradle file
}
I want to set the "pathForPlugin" property dynamically in another task because it has to be read from some configuration file.
task initPaths(type: PathFinder) {
configurationFile = 'C:\\myConfig.conf'
}
The myConfig.conf would look like this:
pathForPlugin = 'C:\\Correct\\Path'
The problem is that "initPaths" has to run before the configuration phase of "run".
I have tried several approaches for this (GradleBuild task, dependsOn, Using Properties in the Plugin for "Lazy Configuration") but every approach only takes effect in the Execution phase leading to the "pathForPlugin" always staying at its default value.
Is there some way i can realize this or should i look for another solution outside of the gradle build?
I found a solution for the problem:
Instead of defining a task "initPaths" i directly used the java class "Pathfinder" in the build script:
import mypackage.PathFinder;
new PathFinder(project).run()
You only have to make sure that this part is above the definition of the task where the properties are used.
I admit this is a bit of a "hacky" solution but it works fine for my requirement.
you can do like this:
ext {
myPath //use it as a global variable that you can set and get from different gradle tasks and files
}
task firstTask {
doLast {
ext.myPath = "your path"
}
}
task run(type: MyPlugin) {
doFirst { //executed on runtime not on task definition
pathForPlugin = ext.myPath //Defined as a property in another gradle file
}
}
//example 2 - create run task dynamic
task initPath {
doLast {
tasks.create(name: "run", type: MyPlugin) {
pathForPlugin = ext.myPath
}
}
}

Gradle Sync task with doLast doesn't work

The gradle task is working well:
task mySync1(type: Sync) {
from "source-dir1"
from "source-dir2"
into "target-dir"
}
But if I add doLast, it doesn't nothing(and no errors):
task mySyncNotWorking(type: Sync) {
doLast {
from "source-dir1"
from "source-dir2"
into "target-dir-z"
}
}
The correct one is:
task mySyncFixed() {
doLast {
project.sync {
from "source-dir1"
from "source-dir2"
into "target-dir-z"
}
}
}
My question is the task mySyncNotWorking, the from and into methods are still belong to Sync if they are inside doLast? Why do they not work?
Why do they not work?
They do work, but after the task was executed. And you can't configure something after it was executed.
If you really need to configure your task during execution phase, maybe because you need to use the results of other tasks (but can't use task outputs for some reason), just use a doFirst closure.
The reason why nothing happens in your second example is the nothing-to-do check of the implemented task action. It is perfectly fine for a task to do nothing, this is not a reason for an error.

Call Zip Task Multiple Times In Gradle

I need to update 9 zip files and the code to do it is about 15 lines.
I'd rather not have to repeat the same 15 lines 9 times in the build script with just different variable names.
Is it possible to call a Zip task in a loop from another task?
Using dynamic tasks seems to be one way but it requires me to list the array of tasks twice which I can see causing an error in future when an extra item is added.
[war1, war2, war3, war4, war5, war6, war7, war8, war9].each { warName ->
task "task$warName"(type: Zip) {
archiveName = "${warName}.war"
//etc etc
}
}
task all(dependsOn: [taskwar1, taskwar2, taskwar3, taskwar4, taskwar5, taskwar6, taskwar7, taskwar8, taskwar9]) {
}
Is there any alternative?
Firs of all your code might be simplified just to:
task allWars
(1..9).each { id ->
task "taskwar${id}"(type: Zip) {
archiveName = "war${id}.war"
}
allWars.dependsOn "taskwar${id}"
}
And a solution with task rules:
tasks.addRule('Pattern: taskwar<ID>') { String taskName ->
if (taskName.startsWith('taskwar')) {
task(taskName, type: Zip) {
archiveName = "${taskName - 'task'}.war"
}
}
}
task allWars {
dependsOn << (1..9).collect { "taskwar$it" }
}
There are almost no obvious pros and cons - when it comes to functionality. Basically solution without rules is shorter as you can see, so if you represent attitude less code is better that's the way to go. However task rules were created in gradle for this kind of situations - where there are lots of predefined tasks. First solution is more groovier while the second one is more gradler ;)
One way is to store the list of 'war' names in a ext property and then iterate over it to create the tasks and use a mapping function for defining the dependencies for the all task.
// Define the variables here
ext.warTaskPrefix = "task"
ext.warNames = ["war1", "war2", "war3", "war4", "war5", "war6", "war7", "war8", "war9"]
// Define the war task dynamically
warNames.each { warName ->
task "${warTaskPrefix}${warName}"(type: Zip) {
archiveName = "${warName}.war"
//etc etc
}
}
// Define the task that depends on all war tasks
task all(dependsOn: warNames.collect{ warName -> "${warTaskPrefix}${warName}" }) {
}

Moving built-in gradle tasks work to doLast/built-in tasks shourtcuts

I want to create a simple sync task that slightly change it behaviour depending on build type (e.g. debug/release) and I use boolean variable 'dummy' decrared in gradle.taskGraph.whenReady:
gradle.taskGraph.whenReady {taskGraph ->
dummy = false
if (taskGraph.hasTask(':dummybuild')) {
dummy = true
}
}
The problem is that task configured by the following way has configuration scope, i.e. before whenReady so it doesn't have access to the 'dummy' variable:
task copySkins(type: Sync) {
from skinsFrom
into skinsInto
rename skinsRename
exclude symbianExclude
if (!dummy) exclude dummyExclude
}
Right now I'm using this workaround
task copySkins {
inputs.dir skinsFrom
outputs.dir skinsInto
doLast {
task skins(type: Sync) {
from skinsFrom
into skinsInto
rename skinsRename
exclude symbianExclude
if (!dummy) exclude dummyExclude
}
skins.execute()
}
}
Is it possible to
detect/setup some build properties in some other place except whenReady
move sync task work to doLast
or at least have some shortcut for sync task (.execute() looks quite ugly)
1) whenReady event allows user to access fully-initialized task graph: all initialization is finished and tasks are ready to run. The only situation, when you need to detect/setup build properties here, is when you need to introspect current build setup.
If you do not need this information, you can place your initialization anywhere in your build script. At the very end, it is nothing but groovy script.
apply plugin: 'java'
def now = new Date()
compileJava.doFirst {
println "It is ${now}. We are starting to compile"
}
2) You can not move sync task work to doLast. But you can always add your actions to doFirst ;) I think, this should work:
task copySkins(type: Sync) {
from skinsFrom
into skinsInto
rename skinsRename
exclude symbianExclude
doFirst {
if (!dummy) exclude dummyExclude
}
}
3) With all said before, missing sync task shortcut should not be that painfull

Resources