Gradle task dependsOn does not work - gradle

I want to setup simple dependency between tasks.
My build.gradle
apply plugin: 'java'
sourceCompatibility = 1.8
version = '1.0'
repositories {
mavenCentral()
}
task('Second', dependsOn: 'First') {
println "Second"
}
task('First') {
println "First"
}
As a result I expect First and than Second.
But I've got:
$ gradle build
Second
First
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build UP-TO-DATE
What am I doing wrong?
Thanks for help.

Still the same error.. You're at configuration phase. Add actions to task and everything will be fine. This will work:
apply plugin: 'java'
sourceCompatibility = 1.8
version = '1.0'
repositories {
mavenCentral()
}
task('Second', dependsOn: 'First') << {
println "Second"
}
task('First') << {
println "First"
}
This is a configuration phase:
task t1 {
println "t1"
}
Code in configuration phase is executed before action. Adding action is done with << (leftShift) operator.
task t1 << {
println "t1"
}
Here are the docs.
<< is just overridden operator do doLast method. Without it it will be:
apply plugin: 'java'
sourceCompatibility = 1.8
version = '1.0'
repositories {
mavenCentral()
}
task('Second', dependsOn: 'First') {
doLast {
println "Second"
}
}
task('First') {
doLast {
println "First"
}
}
I also encourage you to read this blog post.

Related

How does IntelliJ gradle resolve task name from build.gradle

I am a bit puzzle about how gradle in IntelliJ resolve the task name
For example, build.gradle has following content:
plugins {
id 'java'
id 'org.gauge' version '1.8.1'
}
group 'com.example'
version '0.0.1-SNAPSHOT'
sourceCompatibility = 1.11
targetCompatibility = 1.11
repositories {...}
dependencies {...}
task gaugeTestLocal(type: GaugeTask) {
doFirst {
gauge {
specsDir = 'specs'
inParallel = false
nodes = 3
env = 'stg'
additionalFlags = '--verbose'
}
}
}
task downloadDependencies {...}
Using IntelliJ Gradle with command gradle gaugeTe, it somehow knows to run gaugeTestLocal instead.
How is this made possible behind the scene?
Run output
> Task :compileJava NO-SOURCE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :compileTestJava UP-TO-DATE
> Task :processTestResources UP-TO-DATE
> Task :testClasses UP-TO-DATE
> Task :gaugeTestLocal

Run Task in Gradle Plugin after check

I've written a Gradle Plugin in Groovy under buildSrc as:
package test
import org.gradle.api.Plugin
import org.gradle.api.Project
class SamplePlugin implements Plugin<Project> {
#Override
void apply(Project project) {
println "This line prints" //Just for Configuration. This prints
def sample = project.tasks.create("sample") {
doLast {
println "This line does not print"
}
}
project.configure(project) {
sample.mustRunAfter('check')
}
}
}
Here, I'm trying to run the sample task at the end of my build, so I have it run after check
I now try to call it in my projects build.gradle file that looks like:
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
}
apply plugin: 'java'
apply plugin:'application'
apply plugin: test.SamplePlugin
repositories {
mavenLocal()
mavenCentral()
}
mainClassName = "test.Widget"
Unfortunately, I don't see that it runs i.e. the code in the doLast does not appear in the output, but the configuration code does:
:buildSrc:compileJava NO-SOURCE
:buildSrc:compileGroovy
:buildSrc:processResources UP-TO-DATE
:buildSrc:classes
:buildSrc:jar
:buildSrc:assemble
:buildSrc:compileTestJava NO-SOURCE
:buildSrc:compileTestGroovy NO-SOURCE
:buildSrc:processTestResources NO-SOURCE
:buildSrc:testClasses UP-TO-DATE
:buildSrc:test NO-SOURCE
:buildSrc:check UP-TO-DATE
:buildSrc:build
This line prints
:compileJava UP-TO-DATE
:processResources NO-SOURCE
:classes UP-TO-DATE
:jar UP-TO-DATE
:startScripts UP-TO-DATE
:distTar UP-TO-DATE
:distZip UP-TO-DATE
:assemble UP-TO-DATE
:compileTestJava NO-SOURCE
:processTestResources NO-SOURCE
:testClasses UP-TO-DATE
:test NO-SOURCE
:check UP-TO-DATE
:build UP-TO-DATE
BUILD SUCCESSFUL in 1s
5 actionable tasks: 5 up-to-date
I'd be grateful for any help or pointers
Edit: As M.Ricciuti commented below order matters, so I have moved the test.SamplePlugin after the plugin java. Otherwise, please follow lu.koerfers solution of using the pluginManager.
In your plugin you are creating a new task 'sample' and set a constraint "sample must run after check": but this does not include the sample task in the task graph . It just says: "if sample and check tasks are both executed , then check task must be executed first". So if you just execute 'gradle build', this will not trigger execution of task "sample".
Try to execute directly "gradle sample" : you will see it will trigger its execution, and make the execution of "check" task first in respect of the contraint you have defined in plugin.
If you want to make "sample" task execute each time you execute "build" task, then just set a "dependsOn" constraint between "build" and "sample" tasks, in your plugin:
class SamplePlugin implements Plugin<Project> {
#Override
void apply(Project project) {
println "This line prints" //Just for Configuration. This prints
def sample = project.tasks.create("sample") {
doLast {
println "This line does not print"
}
}
project.configure(project) {
sample.mustRunAfter('check')
project.getTasks().findByName('build').dependsOn(sample) // <== set this contraint
}
}
}
EDIT : to avoid having to rely on plugin apply order, the task dependency declaration could be wrapped in a "afterEvaluate" block:
void apply(Project project) {
// task 'sample' def ...
// ...
project.configure(project) {
project.afterEvaluate {
sample.mustRunAfter('check')
project.getTasks().findByName('build').dependsOn(sample)
}
}
The methods mustRunAfter and shouldRunAfter only define execution order, not causality. That means that they won't cause a task to be executed. But if both tasks are executed, the specified order will be taken into account.
To specify a task dependency, use dependsOn or finalizedBy:
project.pluginManager.withPlugin('java') {
project.tasks.getByName('check').finalizedBy('sample');
}
This would cause sample to run everytime check runs and it ensures that it runs after check.

gradle-release build and publish non-snapshot artifacts

I have a multi-module project. And, I want to be able do just do gradle release and get all artifacts of all modules released.
One of the problems is that when I include the plugins, I get
Task with name 'build' not found in root project '
So, following some advice on the internet I created a build task and added a bunch of dependencies on it:
plugins {
id "net.researchgate.release" version "2.6.0"
}
defaultTasks 'clean', 'assemble'
def repoUrl = System.env.REPO ?: "https://company.jfrog.io/company/maven"
allprojects {
repositories {
mavenCentral()
jcenter()
maven {
url 'https://dl.bintray.com/palantir/releases'
}
maven {
credentials {
username System.env.REPO_USER
password System.env.REPO_PASS
}
url repoUrl
name 'company'
}
}
}
task build{}
subprojects { thisProject ->
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'checkstyle'
apply plugin: 'maven-publish'
apply plugin: 'findbugs'
build.dependsOn "${thisProject}:build"
publishing {
repositories {
maven {
credentials {
username System.env.REPO_USER
password System.env.REPO_PASS
}
url repoUrl
name 'company'
}
}
publications {
"-$thisProject.name-"(MavenPublication) {
from components.java
}
}
}
sourceCompatibility = 1.8 // java 8
targetCompatibility = 1.8
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar
archives javadocJar
}
}
tasks.each {println(it)}
afterReleaseBuild.dependsOn tasks.publish
when I run gradle tasks --all I get
task ':afterReleaseBuild'
task ':beforeReleaseBuild'
task ':build'
task ':checkCommitNeeded'
task ':checkSnapshotDependencies'
task ':checkUpdateNeeded'
task ':commitNewVersion'
task ':confirmReleaseVersion'
task ':createReleaseTag'
task ':createScmAdapter'
task ':initScmAdapter'
task ':preTagCommit'
task ':release'
task ':runBuildTasks'
task ':unSnapshotVersion'
task ':updateVersion'
"release" works. That is to say it bumps versions, tags, strips the "-SNAPSHOT" off, etc. But, there is a step missing here (and it could totally be my ignorance), but upon stripping the "-SNAPSHOT" from the version I need it to build the artifacts and publish them. This is like the maven release process but without the artifact upload. I am currently using gradle publish and not maven upload.
Caveats: Very new to gradle but not java
Can someone tell me what I am missing?
_
You just can try to remove build task from the relesae plugin configuration.
buildTasks = [] works fine for me.
release {
...
tagTemplate = '${version}'
versionPropertyFile = 'gradle.properties'
buildTasks = []
...
}

Gradle skipping jacoco coverage plugin

I know there are a lot of similar questions for this on stackexchange but this is driving me crazy and nothing from any other answers have helped me. I've used just about every force flag for gradle I can find.
My Gradle version is 2.2.1
My build.gradle
buildscript {
ext {
springBootVersion = '1.5.3.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("se.transmode.gradle:gradle-docker:1.2")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'application'
apply plugin: 'docker'
apply plugin: 'jacoco'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
ext {
springCloudVersion = 'Dalston.RELEASE'
}
test {
include 'src/test/java'
finalizedBy jacocoTestReport
}
jacocoTestReport {
reports {
xml.enabled true
csv.enabled false
html.enabled false
xml.destination "${buildDir}/jacoco"
}
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
When I run gradle test or gradle clean test jacocoTestReport or gradle clean --re-run etc etc I get the same results.
gradle test
:compileJava
:processResources
:classes
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test UP-TO-DATE
:jacocoTestReport SKIPPED
I have only 1 test in the src/test/java location.
Why will it not generate the reports and run? I'm at a loss.
Remove the wrong include statement in your test configuration.
That seems to cause the test task to always be up-to-date (not executing any test as the include pattern isn't matched)
The jacocoTestReport will be skipped if there's no execution data available that is needed to generate the report. This execution data should be generated while the test task is executed. In your example we see that the test task is always marked as up-to-date (because of the invalid include statement) causing the build to never produce any input for the jacocoTestReport task.
For Spring 2.5 Users, who got stuck with it for hours -just like myself.
I was not having the exec file generated.
And because of that ,
I found that the jacocoTestReport was simply "skipped".
I got it fixed by adding :
test {
useJUnitPlatform()
finalizedBy jacocoTestReport // report is always generated after tests run
}
That's because I'm using Junit5 with spring boot 2.X
It was a bit tricky to find that JaCoCo by default skips every jacocoTestCoverageVerification task in case if tests are run trough a custom named task (not just test).
For example, tests were run via unitTest in my project, JaCoCo did create build/jacoco/unitTest.exec during their execution, yet it kept searching for test.exec during verification. ¯\_(ツ)_/¯
The workaround is to override executionData path for JaCoCo gradle tasks:
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.8.8"
}
def coverageFile = layout -> layout.buildDirectory.file('jacoco/coverage.exec').get()
tasks.named('jacocoTestCoverageVerification') {
getExecutionData().setFrom(files(coverageFile(layout)))
violationRules {
rule {
limit {
minimum = project.properties['testCoverageThreshold'] ?: 0.5
}
}
}
}
tasks.named('jacocoTestReport') {
getExecutionData().setFrom(files(coverageFile(layout)))
}
tasks.named('unitTest') {
jacoco {
destinationFile = coverageFile(layout).asFile
}
finalizedBy jacocoTestReport, jacocoTestCoverageVerification
}

Error pushing docker image to dockerhub using gradle

I am trying this Spring boot with docket example using Gradle, but getting the following error on running the task gradle build buildDocker
C:\Users\zeeshan\Workspace\MyWorkspace\SpringBootDocker>gradle build buildDocker
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:findMainClass
:jar
:bootRepackage
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build
:buildDocker FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':buildDocker'.
> java.io.IOException: Cannot run program "docker": CreateProcess error=2, The system cannot find the file specified
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 10.092 secs
The Docketfile exists in src\main\docker in my windows machine.
My build.gradle file:
buildscript {
repositories {
maven { url "${nexusUrl}/content/groups/public" }
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.5.RELEASE")
classpath('se.transmode.gradle:gradle-docker:1.2')
}
}
group = 'mydockergroup'
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'docker'
jar {
baseName = 'gs-spring-boot-docker'
version = '0.1.0'
}
repositories {
maven { url "${nexusUrl}/content/groups/public" }
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
task wrapper(type: Wrapper) {
gradleVersion = '2.3'
}
task buildDocker(type: Docker, dependsOn: build) {
push = true
applicationName = jar.baseName
dockerfile = file('src/main/docker/Dockerfile')
doFirst {
copy {
from jar
into stageDir
}
}
}
Note: I copied my workspace in a Ubuntu system and it worked fine. Is there a problem setting the file path for dockerfile in my build.gradle for Windows system?
We are specifying dockerDirectory in docker-maven-plugin. I think you may required to setup similar in gradle.
<dockerDirectory>${basedir}/docker</dockerDirectory>

Resources