Gradle up-to-date check and doLast - gradle

task myJar(type: Jar) {
doLast {
// process jar, e.g. proguard jar, override the same jar
tasks.proguardJar.execute()
}
}
Gradle creates hash for task inputs and outputs for UP_TO_DATE check. When will they be created? before doFirst and after doLast?

Before doFirst and after doLast sounds right.
Recent gradle versions are stricter when it comes to changes in the file containing doFirst and doLast blocks, though. Any textual change will now cause the task to be out-of-date.

Related

Gradle, shadowJar: use relocate inside task

I have the following task:
task myJar(type: Jar) {
archiveName = 'myJar.jar'
includeEmptyDirs = false
destinationDir = rootProject.libsDir
dependsOn compileJava
manifest.attributes('Class-Path': '../lib/commons-lang-2.5.jar')
into '/', {
from compileJava.destinationDir
include 'com/myCompany/project/util/order/**',
'com/myCompany/project/event/**',
}
}
and I would like to relocate all classes from com/myCompany/project/event/** to com/myCompany/relocated/project/event/** (so that some apps using my jar and having com.myCompany.project.event package defined will avoid any possible conflicts)
I discovered that it can be done using shadow plugin and I tried to add
relocate 'com.myCompany.project.event.', 'com.myCompany.relocated.project.event.'
under this task but it doesn't seem to work.
Does anybody know where I should add this line?
You can achieve this by adding below plugin to your build.gradle
apply plugin: 'com.github.johnrengelman.shadow'
After adding this plugin add below code to your build.gradle file
shadowJar {
relocate 'com.myCompany.project.event', 'com.myCompany.relocated.project.event'
}
After adding this, to ensure your ShadowJar task runs before build, add this line at the end
assemble.dependsOn shadowJar
This will ensure that shadow jar task is triggered before assemble/build task during gradle build.
On doing the Gradle build, you should see all your packages and their corresponding dependencies relocated from 'com.myCompany.project.event' to 'com.myCompany.relocated.project.event'.
For more info you can refer to ShadowJarUserGuide

How to extend gradle war task with dofirst/dolast

I need to extend the gradle war task with some doFirst and doLast commands to compile my sencha frontend in production state.
I know to extend a task I need to add task.doFirst {} but this is not working with war. I did some tests using other tasks like
clean {
doFirst {
println "test"
}
}
This is working ... but with war it isn't
war {
doFirst {
println "test"
}
}
My main idea was to remove src/main/webapp from the from list and execute sencha-cmd sencha app build -c --destination $war/ production
You should create a separate task for the sencha compilation with it's own inputs/outputs so Gradle can perform up-to-date checking (so it can be skipped if not necessary). You can then wire the task into the gradle DAG via Task.dependsOn(...)
task compileSencha(type:Exec) {
inputs.dir 'src/main/sencha'
outputs.dir "$buildDir/sencha"
commandLine 'sencha', 'app', 'build', file('src/main/sencha').absolutePath, file("$buildDir/sencha").absolutePath
}
war {
from "$buildDir/sencha"
dependsOn compileSencha
}

How to execute a gradle task before any distributions are built

I've got a gradle build with source and javadoc jars and I'd like these tasks to be executed before distZip and distTar, is there a dependency that captures both of those for use with shouldRunAfter.
Right now I've got:
task javadocJar(type: Jar) {
classifier 'javadoc'
from javadoc
}
task sourcesJar(type: Jar) {
classifier 'sources'
from sourceSets.main.allSource
}
tasks.distZip.shouldRunAfter tasks.javadocJar
tasks.distTar.shouldRunAfter tasks.javadocJar
tasks.distZip.shouldRunAfter tasks.sourcesJar
tasks.distTar.shouldRunAfter tasks.sourcesJar
I'd like to condense down those four shouldRunAfter to two which captures both distZip and distTar.
You can use groovy syntax to make this shorter
[distZip, distTar]*.shouldRunAfter javadocJar, sourcesJar
Probably you also want dependsOn instead of shouldRunAfter so that the jars are built whenever one of the dist tasks is enabled.

Prevent Gradle Zip task from downloading dependencies before task execution

I have a simple gradle task that zips a maven jar (for an example). How do you get this task to not download the jar until the task is executed?
apply plugin:'base'
repositories { mavenCentral() }
configurations.create 'myDep'
dependencies {
myDep 'commons-io:commons-io:1.0'
}
task zip(type:Zip) {
from { configurations.myDep.collect { zipTree(it) } }
}
If I run 'gradle tasks', it will download the jar unexpectedly:
$ gradle tasks
Download http://repo1.maven.org/maven2/commons-io/commons-io/1.0/commons-io-1.0.pom
Download http://repo1.maven.org/maven2/commons-io/commons-io/1.0/commons-io-1.0.jar
:tasks
I think that gradle tasks is a special case, as it needs to evaluate inputs of all tasks to determine (and display) their task dependencies. In general, the zip task's inputs will only be evaluated (and therefore the Jar downloaded) once Gradle has decided to execute the zip task. This will happen during building of the task execution graph (again to determine task dependencies), that is before any task is executed (but only if Gradle has decided to execute zip).
If you absolutely must prevent downloading of the Jar in case of gradle tasks, you can defer configuring the from until zip.doFirst {}, but this is not a general solution and can cause other problems (up-to-date checks not working correctly, task dependencies not being inferred automatically).

Gradle Release System Task - Calling uploadArchives on subprojects

In order to release my system, I am creating a releaser project that calls uploadArchives for a number of other projects.
In my project I have the following files:
settings.gradle
include '../proj-a', '../proj-b'
build.gradle
task releaseSystem() {
// what goes here?
}
What should the contents of the releaseSystem task be such that I can call gradle releaseSystem and have it run uploadArchives for each of my sub projects?
I've tried a number of options, but none have been successful thus far.
Thank you for any insights you can provide.
ANSWER
I'm continually impressed with the graceful solutions gradle provides to my problems. Here's my final solution (as Peter pointed out below):
settings.gradle
include 'proj-a', 'proj-b'
project (':proj-a').projectDir = new File(settingsDir, '../proj-a')
project (':proj-b').projectDir = new File(settingsDir, '../proj-b')
build.gradle
task releaseSystem() {
dependsOn {
[
subprojects.build,
subprojects.uploadArchives
]
}
}
Note, that since my repository is a maven repository, when I originally included '../proj-a' in my settings.gradle, it produced poms with artifactId ../proj-a which was invalid. I had to change my settings.gradle to the format above for the system to put the poms together correctly and for the uploadArchives task to complete successfully.
Assuming all subprojects have an uploadArchives task:
task releaseSystem {
dependsOn { subprojects.uploadArchives }
}
Note that this won't run the subprojects' tests.

Resources