Gradle task at the end of build with a multiproject build - gradle

I am attempting to create my own task, that will create a package of all the artifacts generated during my multi-project build.
Currently what I do right is now just:
gradle build createPackage
Which gives output like the following:
:test-utility:compileJava UP-TO-DATE
:test-utility:processResources UP-TO-DATE
...
:test-utility:check UP-TO-DATE
:test-utility:build UP-TO-DATE
Creating Package...
Created.
BUILD SUCCESSFUL
Total time: 4.654 secs
With the createPackage task being:
task createPackage {
println "Creating Package..."
println "Created."
}
However, I would like to simply it by running just one command, so what would the best way to do this and ensure the order stays maintained?
Ideally I would like to call build within the createPackage task or append to the build task with my task.

Ok reading between the lines there are a few things to clear up
1) Your printlns are being run in the configuration phase, not the execution phase. See http://www.gradle.org/docs/current/userguide/build_lifecycle.html for more info.
2) You do not have a single 'build' task. gradle build on the command line will run the 'build' task of each of your subprojects. Your package task would need to depend on all of them. Something like..
apply plugin: 'java'
evaluationDependsOnChildren()
task createPackage(type:Zip) {
dependsOn subprojects*.build
}
3) You can be more declarative with gradle - just tell it what you want to package up and it will figure out what it needs to run. For example, you can say that you want to zip up all the jars from your subprojects.
apply plugin: 'java'
evaluationDependsOnChildren()
task createPackage(type:Zip) {
from subprojects*.jar
}

There are plenty of ways. One suggestion is to modify build to depend on createPackage to make sure you can call just gradle build. Then you want to enhance your task and tell what are its inputs (probably those are outputs of some other tasks like jar). Gradle will add these tasks to execution when you run the build and can re-run them based on up-to-date status of each task. This is documented in userguide - http://www.gradle.org/docs/current/userguide/more_about_tasks.html#sec:up_to_date_checks and later in a chapter on custom tasks.

Related

how to execute 'gradle build' command from gradle.build script

I want to execute a gradle build command from build.gradle file.
build.gradle file
apply plugin: 'java'
apply plugin: 'application'
task me{
//Can we perform gradle build command here.
}
Question:
Can we perform gradle build command inside task me, similarly like we do from command prompt(screenshot attached)..?
Note : I am using windows env, please assume I am providing all other statements in build.gradle file.
I am able to build from command prompt by executing
.
I want to execute this task me from command prompt and it should be responsible to call gradle build command.(attached screenshot)
Yes, if you make the task me to a task of type GradleBuild
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.GradleBuild.html
E.g.
task me(type: GradleBuild){
buildFile 'mybuild.gradle' //defaults to build.gradle so not needed
dir 'someDir'
tasks 'clean', 'build'
}
You cannot "call" a Gradle task in a Gradle build.
You might stumble upon the method execute() that each Gradle task has, but this is a purely internal method that must not be used by any build script. Using it will not work properly. It will not ensure the task is run only once, it will not ensure dependency tasks are run before and so on and so on, just don't use it.
Your code snippet is too big for me wanting to interpret it right now to understand what you want to do exactly, but if you want to "call" a Gradle task from another Gradle task, your logic is bogus and should be changed. If you want to run a Gradle task before or after another Gradle task is run, the only supported way is to use dependsOn (before) or finalizedBy (after) and you can not set these properties during execution phase of a task but only during configuration phase.
Well, there is one other way to call a Gradle task from a build script, but this is by using a task of type GradleBuild which would start a complete new and separate build of the project you specify which is most often not the action you really want to do.

Gradle plugin task ordering

What I have?
Java source file with Main class (MainApp)
gradle build script
apply plugin: 'application'
mainClassName = "MainApp"
sourceSets.main.java.srcDirs = ['.']
So when I do gradle run, it executes main method and everything works just perfectly.
C:\tmp\gradle-fun>gradle run
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello MainApp !!
BUILD SUCCESSFUL
What I want to do?
Now I was wondering about clean task (common build tasks) to clean the build directory before run task executes.
There is reason behind that, I want to make sure that every time gradle should compile the java files and all .class file should be refreshed (its some requirement)
What I have tried?
Added a wrapper task which executes clean task and run task in order.
apply plugin: 'application'
mainClassName = "MainApp"
sourceSets.main.java.srcDirs = ['.']
task exec(dependsOn: ['clean', 'run'])
So when I run gradle exec, it does it job properly. However I feel that its patch work when you have extra tasks just for ordering execution.
C:\tmp\gradle-fun>gradle run
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello MainApp !!
:exec
BUILD SUCCESSFUL
What I would like to know?
Is there any way to avoid writing wrapper task and do some Gradle magic to achieve the requirement?
Just have the run task depend on clean. This will ensure your project is cleaned before every run. If you want to be more specific in regards to your use case, you can simply clean the compileJava task.
run.dependsOn 'cleanCompileJava'
Edit: To avoid deleting your classes before the run add:
classes.mustRunAfter 'cleanCompileJava'
You could create your own task, with clean and run as dependencies:
task cleanRun(dependsOn: [clean, run])
Or, you could follow Mark Vieira's answer and change the wiring:
run.dependsOn 'clean'
classes.mustRunAfter 'clean'
The second line makes sure that it doesn't clean the compiled classes.
Hope this helps =)

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 batch task that invokes subproject and other tasks in order

I am writing gradle 1.4 build file for multimodule project. So there is root build.gradle that defines something like:
subprojects {
apply plugin: 'java'
...
which defines build task for all submodules. Submodules are included in settings.gradle and each module has its build file with defined dependencies.
Everything by-the-book, so far:) Now, in the main build file I've added some additional project-scope tasks, like: aggregateJavadoc (collects all javadocs into one) or bundleJar (creates bundle jar from all classes), etc. Each on works when invoked manually.
Now I need a task release that will
build all submodules (as invoked from command line - meaning, i dont want to manually write execute() for each submodule)
invoke additional tasks (using execute() I presume).
I tried dependsOn but the order of listed tasks is not followed. Also, dependent modules seems to be executed after release task execution. I tried several other ideas and failed.
Question: what would be the best way to create such batch task, that has to invoke something on all submodules and additionally to perform some more tasks? What would be the best gradle-friendly solution? Thanx!
It happened that this can be solved with simple dependency management.
So, we have many modules. Now, lets create additional tasks that depends on modules being build:
task aggregateJavadoc(type: Javadoc) {
dependsOn subprojects.build
task bundleJar(type: Jar) {
dependsOn subprojects.build
Finally, our release task would simply look like this:
task release() {
dependsOn subprojects.build
dependsOn aggregateJavadoc
dependsOn bundleJar
...
}
This will build subprojects first; not because it is listed first, but because additional tasks depends on building. Order of additional task is not important. This make sense the most to me.
EDIT
if one of your subprojects (i.e. modules) is non-java module, then you will have a problem building this project. What I do is to group submodules, like this:
def javaModules() {
subprojects.findAll {it.name.contains('jodd-')}
}
and then instead to refer to subprojects, use javaModules everywhere! For example:
configure(javaModules()) {
apply plugin: 'java'
...
and
task prj {
dependsOn javaModules().build
}
btw, I am using this 'dummy' task prj for dependsOn on all those additional projects that depends on building, to prevent repeating.

Why is uploadArchives not listed at the tasks list?

i thought uploadArchives is a task which is provided by the java plugin.
In my build.gradle i use the java plugin:
apply plugin: 'java'
But if i invoke gradle tasks on command line, i can't see the uploadArchives task.
Even not with gradle gradle tasks --all
The uploadArchives task is listed in the gradle java plugin documentation
see http://www.gradle.org/java_plugin (table 11).
I use gradle version 1.0-milestone-6.
I can invoke gradle uploadArchives without error, but the task is not listed.
The uploadArchives task is added as a Rule to your build script and not explicitly by name. In the output of "gradle tasks" you should see this line:
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.
This means, that for each configuration in your build file, an according uploadTask exist. The java plugin adds an configuration named archives to your build script. By adding the configuration "archives" to your build script explicitly by the java plugin, the uploadArchives task is added implicitly too.
There are scenarios, where gradle can't know what tasks need to be materialized by a rule.
E.g.
tasks.addRule("Pattern: ping<ID>") { String taskName ->
if (taskName.startsWith("ping")) {
task(taskName) << {
println "Pinging: " + (taskName - 'ping')
}
}
}
There is no way to figure out which ping tasks should be shown as they are just materialized when triggered from commandline via 'gradle pingServer1 pingServer2 pingServer3'
regards,
René
The uploadArchives task is a part of the maven-plugin. You have to add:
apply plugin: 'maven'

Resources