My project structure is look like
Root + subproj1
+ subproj2
in each sub project defined his own task run(){}.
What i'm trying to do is run :subproj1:run, :subproj2:run in parallel from Root project's run task.
I tried in root project's build.gradle
task run(){
def threads = 2
def tasks = [ ":subproj1:run", ":subproj2:run" ]
tasks.each {
new Thread(){
public void run(){
dependsOn it
}
}.start();
}
}
but it makes an exception like
Exception in thread "Thread-12" org.gradle.api.UnknownProjectException:
Project with path ':subproj1:run' could not be found in root project 'ROOT'
How i can run sub project's task in parallel from root project?
With gradle 2.1 it should work out of the box. One solution is --parallel like Perryn said or you set org.gradle.parallel:true into your gradle.properties. And then you should be able to run "gradle run" in the root project and both should be executed parallel.
I also put undeclared-project-coupling=fail into gradle.properties to know if they are coupled and can't be executed in parallel.
have you tried looking at the --parallel command line option?
Related
im trying to run test task before android's assembleRelease
App has multiple modules.
In single module app I used to do it via
afterEvaluate {
println tasks
}
in app/build.gradle
This does not work anymore for multimodule, i.e. it only runs tests on app module. So I need that block inside every module's build file, which is error prone
So I tried globally in root build file
allprojects {
afterEvaluate {
tasks.findByName("assembleRelease").dependsOn tasks.findByName("test")
}
}
This however fails that those tasks cannot be find, i.e. they're not present in println tasks anyways.
Anybody have idea where to get reference to them? Or better, how to run root test task before root assembleRelease?
Thanks
I have a multi-project Gradle build and I customised the "run" task to do something a bit different in the root project.
However, I don't want it to call the "run" task of each sub-project after completion, as it does now. But this behaviour should only be for this task, I want every other task to be recursively executed as is the default, but the run task not. I also cannot disable the run task globally for every subproject, because it does have a purpose in each subproject when executed on its own.
In the root build.gradle, consider the following (full example here):
gradle.taskGraph.whenReady { graph ->
def hasRootRunTask = graph.hasTask(':run')
if (hasRootRunTask) {
graph.getAllTasks().each { task ->
// look for :abc:run, :def:run etc
def subRunTask = (task.path =~ /:.+:run/)
if (subRunTask) {
println "TRACER skipping ${task.path} because ':run' was specified"
task.enabled = false
}
}
}
}
This will check the task graph for :run. When it exists, then :abc:run (that is, a subproject task) will be disabled.
Example output for root run task:
$ gradle -q run
TRACER skipping :abc:run because ':run' was specified
TRACER skipping :def:run because ':run' was specified
TRACER executing run for path :
Example output for run task in abc subproject on its own:
$ gradle -q :abc:run
TRACER executing run for path :abc
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
In my root build.gradle, I've defined a GradleBuild task like this:
project.task('distribute', type : GradleBuild) {
startParameter = gradle.startParameter.newInstance()
tasks = [":subprojectA:displayInfo"]
}
Given that my root project directory called root,
when I run the distribute task, the task that is executed is
:root:subProjectA:displayInfo
How is it that root becomes what looks like a subproject and why does the gradle build task not execute the correct task like this:
:subProjectA:displayInfo
This is actually not an issue. Even though the gradle output indicates that root is a subproject, the correct task is still executed.
I have a gradle sync task:
task updateSharedCode {
group = 'build'
}
updateSharedCode << {
sync {
from '../employee_shared/src'
into 'src/shared'
}
}
If I paste this task in the root's subprojects object everything runs fine But I only want to run this on a small subsection of my subprojects. But when I copy this task into one of the subprojects and remove it from the root I get the error
Execution failed for task ':employee_app:updateSharedCode'.
Could not find method from() for arguments [../employee_shared/src] on project ':employee_app'.
I have no clue why this is happening so any help would be helpfull.