Gradle short task - gradle

For fust build project I use such command
gradle clean build -x checkstyleMain -x checkstyleTest -x findbugsMain -x findbugsTest -x test
How I can create short task for this?
Something like this
task short {
clean
// build-x checkstyleMain -x checkstyleTest -x findbugsMain -x findbugsTest -x test
}
I have error with -x
UPDATE
I add such
gradle.taskGraph.whenReady {
if (gradle.taskGraph.hasTask(":fastRun")) {
checkstyleMain.enabled = false
checkstyleTest.enabled = false
findbugsMain = fasle
findbugsTest = false
test = false
}
}
task fastRun {
// clean
// build
}
And run
gradle clean build fastRun
But all tasks run =(

Gradle is not lifecycle based the way Maven is. Instead of asking for a task that includes all these other tasks you do not want to do, you are better off finding a task that does what you want without including all these others.
For example, assuming you are using the java plugin:
assemble: will create all archives in the project, but not run any tests or checks
compileTestJava: will compile all main and test Java classes but will not run tests or create binaries. Unless their creation is required by a different project in a multi-project build.
???: some task that maybe does exactly what you want
And if point 3 has no answer for you, you can define a new task that will depend only on what you want to achieve and not the rest.
See the Java plugin documentation for an exhaustive list of the tasks added, including the high level ones.

Unfortunately, usual ways of skipping tasks won't work in your case just out of the box.
But you can use a TaskGraph to check whether your custom task will be executed and if it'll be, disable all the tasks you don't want to be executed. For that, you need to add such a configuration snippet:
gradle.taskGraph.whenReady {
if (gradle.taskGraph.hasTask(":short")) {
checkstyleMain.enabled = false
checkstyleTest.enabled = false
// any other task you want to skip...
}
}
This snippet should be placed into the root of the build skript. Just note, that task names could differ depending on the project structure you have.
It's waiting until the task graph is ready and if it has a task named short (that means, that this task will be executed), then it disables some other tasks.

You can add the following codes to skip the tasks,
gradle.startParameter.excludedTaskNames += "testClasses"
gradle.startParameter.excludedTaskNames += "test"

Related

gradle custom task that depends on build task without testing

I am using gradle 6.0.1
I am trying to write my on task, but I want first the the build task is executed but without tests.
I tried (from build.gradle):
task startEnv(type: GradleBuild) {
tasks = ['build']
doLast {
// START ENV CODE
}
}
However, I don't manage to find a way to call build without running tests, as I would run
gradle build -x test
Is it possible to achieve this functionality?
Another option I can use, is to check inside my startEnv task whether build already exists and run this task only if build exists - Is there a way to query whether build exists? (this is a multi module projects, so I am not sure it is enough to check whether build directory exists on the root project).
I followed the comments and tried the solution mentioned at Skip a task when running another task
I added to build.gradle:
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(startEnv)) {
println("DEBUG1")
test.enabled = false
}
}
task startEnv(type: GradleBuild) {
tasks = ['build']
doLast {
// START ENV CODE
}
}
But when I run ./gradlew startEnv - it still fails with some tests that in current phase I know they should fail.
I can see the DEBUG1 print when I execute this command but the build fails with tests that are failing.
Thank you,

Determine if a task is defined in an external build.gradle file

I have a gradle task that is created at runtime to call another task ("myOtherTask") which is in a separate gradle file. The problem is if that other task doesn't exist an exception will be thrown. Is it possible to check that a task exists in an external gradle file before attempting to call it?
Example:
task mainTaskBlah(dependsOn: ':setupThings')
task setupThings(){
//...
createMyOtherTask(/*...*/)
//...
}
def createMyOtherTask(projName, appGradleDir) {
def taskName = projName + 'blahTest'
task "$taskName"(type: GradleBuild) {
buildFile = appGradleDir + '/build.gradle'
dir = appGradleDir
tasks = ['myOtherTask']
}
mainTaskBlah.dependsOn "$taskName"
}
You can check if the tasks exists. For example if we wanted to simulate this we could make the task creation triggered by a command line property
apply plugin: "groovy"
group = 'com.jbirdvegas.q41227870'
version = '0.1'
repositories {
jcenter()
}
dependencies {
compile localGroovy()
}
// if user supplied our parameter (superman) then add the task
// simulates if the project has or doesn't have the task
if (project.hasProperty('superman')) {
// create task like normal
project.tasks.create('superman', GradleBuild) {
println "SUPERMAN!!!!"
buildFile = project.projectDir.absolutePath + '/build.gradle'
dir = project.projectDir.absolutePath
tasks = ['myOtherTask']
}
}
// check if the task we are interested in exists on the current project
if (project.tasks.findByName('superman')) {
// task superman exists here we do whatever work we need to do
// when the task is present
def supermanTask = project.tasks.findByName('superman')
project.tasks.findByName('classes').dependsOn supermanTask
} else {
// here we do the work needed if the task is missing
println "Superman not yet added"
}
Then we can see both uses cases rather easily
$ ./gradlew -q build -Psuperman
SUPERMAN!!!!
$ ./gradlew -q build
Superman not yet added
This won't help you find if the task is in a specific external file, but if you just want to determine if a task is defined in any of your imported gradle files...
From gradlew help I see there is a tasks task.
Sadly, gradlew tasks doesn't always show all taks. Some of my projects have an integrationTest task while others do not, in which case I can only go as far as build. However, the default tasks command lists integrationTestClasses but not integrationTest.
From gradlew help --task tasks I can see there is a report expanding --all parameter that we can use.
Now, I can see all tasks via gradlew tasks --all, so a simple grep can tell me whether or not the task I want exists. In bash, this might look like:
TASK="integrationTest"
if gradlew tasks --all | grep -qw "^$TASK"
then
gradlew clean integrationTest
else
gradlew clean build
fi
FYI --
Personally, I needed something to tell me in a git pre-commit hook whether the integrationTest task existed or not, so I know whether I can run gradlew integrationTest or if I have to stop at gradlew build. Not finding an answer here, I kept looking, and this is what I came up with to solve my problem. Hopefully, this is of use to others as well.
I made a little "tool" for stuff like that - maybe it comes in handy for some of you...
$ cat if_gradle_task_exists
#!/bin/sh
TASKS=$(./gradlew tasks --all)
BUILD="./gradlew "
for COMMAND in $#; do
echo "$TASKS" | grep -q "$COMMAND" && BUILD="$BUILD $COMMAND"
done
$BUILD
You can append as many tasks as you like and only the existing ones are executed.
I use it in combination with alias as a kind of super api wrapper for tasks I want to be done in different projects (and I don't want to have to care if any of the specific tasks really do exist):
alias ge='~/.config/bin/if_gradle_task_exists eclipse initDb createTestUsers startLdapServerMock startBrokerMock'
That allows me to be as lazy as ge
stumpf#HV000408:/c/devel/workspace/myproject $> ge
to set up the project for eclipse and prepare all needed servers for local development.
The list of tasks produced will need some time to be set-up, so I wouldn't recommend to use it as a full gradlew wrapper though.
Regards

Gradle: Custom task with parameter set programmatically

I have the following scenario where I wish to disable JOOQ Schema generation unless explicitly called for:
gradle.taskGraph.beforeTask {
task ->
if (!rootProject.hasProperty("generate") && task.name.equals("generateSampleJooqSchemaSource")) {
task.enabled = false
}
}
Now I can always manually generate the schema when passing "generate" as a parameter as follows:
$ gradle build -Pgenerate
Whereas a normal
$ gradle build
would not regenerate all my schema classes.
However, I do not like this approach very much. You have to remember the parameter name, and also prepend it with -P which does not look as clean.
I would ideally like to be able to make a custom task as follows:
task generate {
tasks[build].executeWithParameter("generate")
}
So that it would also show up as an actual task.
How can I accomplish this?
You can create a task that dependsOn build task and disable jooq task from it. This requires the task declaration to be put after jooq task declaration.
task generate (dependsOn: build) {
tasks['generateSampleJooqSchemaSource'].enabled = false
}
to set project property from task
task generate (dependsOn: build) {
project.ext.generate = "true"
}

Skip a task when running another task

I added a task to my gradle project:
task deploy() {
dependsOn "build"
// excludeTask "test" <-- something like this
doFirst {
// ...
}
}
Now the build task always runs before the deploy task. This is fine because the build task has many steps included. Now I want to explicitly disable one of these included tasks.
Usually I disable it from command line with
gradle deploy -x test
How can I exclude the test task programmatically?
You need to configure tasks graph rather than configure the deploy task itself. Here's the piece of code you need:
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(deploy)) {
test.enabled = false
}
}
WARNING: this will skip the actions defined by the test task, it will NOT skip tasks that test depends on. Thus this is not the same behavior as passing -x test on the command line
I don't know what your deploy task does, but it probably just shouldn't depend on the 'build' task. The 'build' task is a very coarse grained lifecycle task that includes tons of stuff you probably don't want.
Instead it should correctly define its inputs (probably the artifacts that you wanna deploy) and then Gradle will only run the necessary tasks to build those inputs. Then you no longer need any excludes.
I ran into a similar problem. Here is how I prevent "test" from running when I run "intTest" and want the ITs to run alone:
test {
onlyIf { !gradle.startParameter.taskNames.contains("intTest") }
}
An alternative that doesn't depend on certain tasks being run explicitly:
test {
onlyIf { !gradle.taskGraph.hasTask(":intTest") || gradle.taskGraph.hasTask(":check") }
}

How to prevent gradle build from executing test task

I know that I can use the -x test option to prevent the test task from getting called. I also have something like this in my gradle script to prevent tests from being executed in certain cases:
plugins.withType(JavaPlugin).whenPluginAdded {
test {
doFirst {
if (env.equals('prod')) {
throw new StopExecutionException("DON'T RUN TESTS IN PROD!!!!")
}
}
}
}
but is there a way to configure the java plugin to removed the dependency between build -> test?
build depends on test via check. You probably don't want to remove the dependency on check as it may do other things, so you could try:
check.dependsOn.remove(test)
Do you mind if I ask why you want to do this?
You can skip tasks via the command line with the -x option:
./gradlew assembleDebug -x taskToSkip
I don't know if it is possible to remove such a dependency.
You can however skip the execution of tasks, eg: skipping all test tasks (in production) goes like this.
tasks.withType(Test).each { task ->
task.enabled = !env.equals('prod')
}

Resources