Gradle task not executed if added as a dependency - gradle

I have two gradle tasks in my build.gradle file, one to archive a folder and another to push it to a remote server.
task tarTask(type: Exec) {
commandLine 'tar', '-czf', 'javadocs.tgz', 'javadocs/'
}
If I execute tarTask alone with gradle tarTask and with the publish task commented out, the build succeeds.
I am using this task as a dependency in the publish task.
task publish(dependsOn: tarTask) {
ssh.run {
settings {
knownHosts = allowAnyHosts
fileTransfer = 'scp'
}
session(remotes.webServer) {
from: 'javadocs.tgz', into: 'publishingHouse/'
}
}
}
But when i execute gradle publish it fails saying that it is not able to find the tgz file which should have been created if the previous task is executed.
java.io.FileNotFoundException: javadocs.tgz
Being new to gradle i am not really sure what I am missing here. Any ideas on what I can do?

I suppose the reason is within the phase when tasks are executed. tarTask is configured at the configuration phase and will be executed at the execution phase.
And at the same time publish task doesn't have any behavior to execute at the execution phase, but has ssh.run to be executed during configuration.
This mean, that when you run gradle publish your logic to copy tar-archive is executed at the configuration phase, while tar-archive is not yet exists (it will be created later at the execution phase).
To make a copy execution at the execution phase you can simply add << to the publish task declaration as follows:
task publish(dependsOn: tarTask) << {
ssh.run {
settings {
knownHosts = allowAnyHosts
fileTransfer = 'scp'
}
session(remotes.webServer) {
from: 'javadocs.tgz', into: 'publishingHouse/'
}
}
}
Note, that << is the same as doLast and the closure will be excuted at the execution phase. You can read about Gradle build lifecycle here

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,

Wrong order of task execution in gradle 3.3

I want to define methods inside my script file, and use them to define build tasks for each project individual (custom library).
ext.buildDockerImage = { imageName ->
def distDir = "${getProject().getBuildDir()}/docker"
copy {
from "${project.getProjectDir()}/src/docker/"
into distDir
}
println 'Build docker image'
}
In my project build.gradle I have created a task:
apply plugin: "war"
apply plugin: "jacoco"
dependency {
// all dependencies
}
task buildDocker() {
apply from: "${project.getRootDir()}/docker/scripts.gradle"
buildDockerImage("admin")
}
The problem is that whenever I am running gradle build, this tasks executes also:
$ gradle build -xtest
Build docker image
# rest of build
As you can see , all I want is to create a custom library that will hold methods, used to create tasks for each project. But currently I cannot import those methods without breaking the build. Method buildDockerImage will work only after war file is added to build directory, so this task must be executed on demand only, I don't want to be included in the process all the time.
My questions:
how make my task to only run when I execute task manually
why, when I execute my build, script executes as first?
Your task buildDocker() defines everything in configuration phase. So when you run your gradle build this will always run.
task buildDocker() {
apply from: "${project.getRootDir()}/docker/scripts.gradle"
buildDockerImage("admin")
}
If you want to run this task as a standalone task, define your stuff in execution phase of the task. something like below
task buildDocker() {
apply from: "${project.getRootDir()}/docker/scripts.gradle"
doLast{
buildDockerImage("admin")
}
}
Read This article
This might help

How to install/run a watch task in Gradle

I'd like to run a given task, every time a file in the folder src changes.
It seems that Gradle does not have a task like that, but there is the gradle-watch-plugin on github. Following the installation guide, I tried:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.bluepapa32:gradle-watch-plugin:0.1.5'
}
}
apply plugin: 'com.bluepapa32.watch'
task "sometask" << {
println "My Own task."
}
watch {
somename {
files files('src')
tasks 'sometask'
}
}
Unfortunately this results in an error:
Starting:watch FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':watch'.
> org.gradle.tooling.BuildLauncher.withArguments([Ljava/lang/String;)Lorg/gradle/tooling/BuildLauncher;
So what's wrong with my build.gradle?
This can be done without a plugin by enabling continuous mode in your build via the --continuous or -t command line argument. For example, given the following build script running gradle -t myTask will automatically watch for changes in the folder src and reexecute the task when those files change.
task myTask {
inputs.files 'src'
doLast {
// do some stuff with files in 'src' folder
}
}

Why gradle clean task starts all other non-default tasks?

I have gradle set up and running. My build.gradle has 2 tasks defined inside:
task setVersion() {
println('setVersion')
//...
}
task setIntegrationEnv() {
println('setIntegrationEnv')
//...
}
When I run
./gradlew clean
gradle runs both tasks setVersion and setIntegrationEnv and then it runs clean for all my modules (app, cloud_module) in that project, output:
Relying on packaging to define the extension of the main artifact has been deprecated and is scheduled to be removed in Gradle 2.0
setVersion
setIntegrationEnv
:cloud_module:clean
:app:clean
BUILD SUCCESSFUL
Total time: 14.18 secs
Why this happens, where this behavior is defined?
Could You please provide full build.gradle script? I'd be much easier to help You. You've probably mistaken gradle build phase with configuration phase - it's a common topic here.
General rule is that code You'd like to be run at build phase should be added as an action:
task someTask << {
println 'runtime'
}
while code You'd like to run at configuration phase should be added in task body:
task someTask {
println 'configuration
}
or all together:
task someTask {
println 'configuration'
doLast {
println 'runtime'
}
}
Additional info can be found here, here and here.

how to override a task making it depend on one of mine in gradle

I tried following the gradle manual with their example like this but copyJars is not run at all before the eclipse task. (the eclipse task comes from the eclipse plugin)
task('copyJars') {
ext.collection = files { genLibDir.listFiles() }
delete ext.collection
copy { from configurations.compile into genLibDir }
copy { from fixedLibDir into genLibDir }
}
eclipse.dependsOn = copyJars
task('setupAll', dependsOn: 'eclipse') {
description = 'Update jars from remote repositories and then fix eclipse classpath for stbldfiles project'
}
There are some problems with this build script:
eclipse doesn't refer to the task but to the equally named model object. (Don't you get an exception for eclipse.dependsOn?)
Task copyJars does its work in the configuration phase rather than the execution phase (i.e for every build, even if the task isn't executed)
To fix that, use tasks.eclipse.dependsOn(copyJars) and task copyJars << { ... }.
Another question is if there isn't a simpler way than copying things around with copyJars and fixing up the Eclipse class path after the fact, but I'd need more information to be able to tell.

Resources