i would like to run the build-task from the gradle war plugin inside one of my own defined tasks. I tried various things, but nothing worked.
This is how my task looks at the moment:
task deploy << {
build.execute()
copy {
from '/build/libs/app.war'
into tomcat_webapps
}
}
When i run
gradle deploy
the build task will not be executed. Does anyone of you know how i can do this?
Thank you!
Calling tasks manually should be your very last resort. The gradle way would be to define a dependency between your task and the build task. This way gradle can determine a proper order for the tasks that need to be executed.
Setting up the dependency can be done in several ways. One way would be this:
task deploy(type: Copy) {
dependsOn build
from '/build/libs/app.war'
into tomcat_webapps
}
Related
I am using some static analysis plugins (spotbugs, pmd) attached to my gradle build. They run automatically when you run gradlew check or something that depends on check.
I am trying to find a way to run JUST the parts of check, but exclude unit tests, in a command. Since check depends on test, I am not sure how to do this, if it's possible.
I have a large number of java / android modules and it takes a long time to do a full build with tests and static analysis, so I want to break them up as separate tasks on separate CI systems.
You should be able to do:
./gradlew check --exclude-task test
See the docs here
Instead of calling the task check with excluded task test as proposed by Dave, you can simply create a new task and add dependencies on all tasks that perform static analysis:
task staticAnalysis {
dependsOn 'spotbugsMain'
dependsOn 'pmdMain'
}
You may then call ./gradle staticAnalysis.
I am writing a custom Gradle plugin in Java and it seems to work as I expect when I call explicitly the task it creates.
Now, the task is highly related to tests, so I would like it to execute automatically when the tests are executed (ideally, before the tests actually), but I am having 2 issues. Below is my plugin :
public class MyCustomGradlePlugin implements Plugin<Project> {
public void apply(Project project) {
MyCustomGradleConfig myCustomGradleConfig = project.getExtensions().create("myCustomGradleExtension", MyCustomGradleConfig.class, project);
Task myCustomTask=project.getTasks().create("checkRules", MyCustomRulesTask.class, myCustomGradleConfig);
archUnitTask.setGroup("verification");
project.getTasks().findByName("test").dependsOn(myCustomTask);
}
}
I build and deploy locally this plugin. When I declare and configure it in the build.gradle at the root of a multi-module project :
if I forget to apply java plugin in the project, then the ´test´ task doesn't exist and myCustomTask can't be "attached" to it : is there a way to make sure the java plugin is declared when MyCustomGradlePlugin executes ?
´myCustomTask´executes, but only at the root of the project, where there's nothing interesting : if the project is a multi-module project, I need it to execute for all the modules. Ideally, I would like that the plugin takes care of it, to simplify to the maximum the config in the projects that will use it. How do I achieve that ?
is there a way to make sure the java plugin is declared when MyCustomGradlePlugin executes ?
Yes. You can either apply the Java plugin in your own plugin like this:
project.getPlugins().apply(JavaPlugin.class)
Or you can conditionally add your task if the Java plugin exists like this:
project.getPlugins().withType(JavaPlugin.class) {
MyCustomGradleConfig myCustomGradleConfig = ...
}
if theproject is amulti-module project, I need it to execute for all the modules.
You can achieve that by simply applying your plugin to each individual sub-project, e.g. through the allprojects method:
allprojects {
apply plugin: "your.plugin.id"
myCustomGradleExtension {
// ...
}
}
Alternatively, you can also wrap all your plugin code in an allprojects block. In that case, from the user perspective, they apply your own plugin to the root and it will configure itself for all sub-projects.
I have gradle project with 4 subprojects. I have current root gradle.build with checkstyle:
allprojects {
apply plugin: "checkstyle"
checkstyle {
...
}
}
so when I run ./gradlew build in the main folder, I get next:
checkstyle for 1st subproject, then tests. Then it runs checkstyle for 2nd subproject and then tests for 2nd, etc.
The problem is: if I have long tests in 1st subproject, I can wait a lot of time, and then discover that I have 2 spaces in the 4th project, so checkstyle fails, but I was waiting so much time for it.
What I really want:
run all checks (checkstyle, and I have pmd too) for all subprojects, and then run all tests in all subprojects. It will save a lot of time for everybody in the team.
Can I do it except, make 2 different pipelines, and run them separately? like: ./gradlew allMyCheckstyles && ./gradlew build.
I would love to use just ./gradlew build
Thanks!
I tried many dependsOn, runAfter, but it didn't work out.
Apologies, a previous version of this answer misinterpreted the requirements of this question.
Here's a solution that should do what you want:
// Create a lifecycle task in the root project.
// We'll make this depend on all checkstyle tasks from subprojects (see below)
def checkstyleAllTask = task("checkstyleAll")
// Make 'check' task depend on our new lifecycle task
check.dependsOn(checkstyleAllTask)
allProjects {
// Ensure all checkstyle tasks are a dependency of the "checkstyleAll" task
checkstyleAllTask.dependsOn(tasks.withType(Checkstyle))
tasks.withType(Test) {
// Indicate that testing tasks should run after the "checkstyleAll" task
shouldRunAfter(checkstyleAllTask)
// Indicate that testing tasks should run after any checksytle tasks.
// This is useful for when you only want to run an individual
// subproject's checks (e.g. ./gradlew ::subprojA::check)
shouldRunAfter(tasks.withType(Checkstyle))
}
}
Documentation here and here
I have a multi-project dependency in my gradle build, but there's a feature that's somewhat in my way. Whenever I call a task name that exists in both projects, it calls them both. I don't like that.
My directory structure is as follows:
[Root]
---->[projA]
----------->build.gradle
---->[projB]
----------->build.gradle
So I have projB dependent on projA in my code.
Say I have a task run in projB:
task run << {
println 'projB running'
}
And I also have a task run in projA:
task run << {
println 'projA running'
}
By calling gradle run, I would get
:run
projB running
:projA:run
projA running
Is there any way to prevent some of the tasks from having this dependency? Some of them, say clean is fine, but I'd prefer to have specific tasks separate (without having to change the naming scheme).
The equivalent of what I want can be achieved by doing either:
gradle run -x :projA:run
or
gradle :run
I want a solution that is within the build file, though.
Thanks!
That fact that projB declares a project dependency on projA is irrelevant for the behavior you are seeing. If you execute a task from the root project of a multi-project build Gradle will try to find the task in any of its subprojects with the requested name and execute it. This feature is called task execution matching. Given this default behavior there's no way Gradle could know which run task you mean when executing gradle run from the root project. I'd suggest you define what you want to execute on the command line as mentioned in my previous comment.
If you really wanted to add logic to your build script, then you could achieve it with the following code:
def taskRequests = gradle.startParameter.taskRequests
def runTaskRequest = taskRequests.find { it.args.contains('run') }
if (runTaskRequest) {
gradle.startParameter.excludedTaskNames = [':projA:run']
}
The code provided would prevent the execution of the run task for the subproject projA if you execute the command gradle run. Keep in mind that it would also exclude :projA:run if you navigate to the projA subdirectory and run the same command. If you still want to be able to execute the run task from the subdirectory, then you'll have to build in additional logic.
I can't tell if this is a bug with Gradle 1.0m7, or if we are just doing this wrong.
We have some classes that get compiled as apart of a project, that we want to individually jar into it's own artifact. These are for example standalone domain model objects, that we want to share with another project.
I'd prefer not to go the multi-project build route, so how do we tell Gradle to create another jar for these?
Currently we are doing this:
task modelJar(type: Jar) {
classifier = 'model'
from fileTree(dir: sourceSets.main.classesDir).matching { include 'com/foo/bar/model/**' }
}
artifacts {
archives modeljar
}
The issue here, is the modeljar task runs before the classes are compiled. At first we didn't realise this and thought this was working. Turns out, the artifact was picking up classes from the previous run, not the current run. Doing clean before the build results in a jar with no classes in it, and reveals the problem.
I was looking at custom configuration, but it seems pretty complex and I didn't want to overly complicate the build file.
Appreciate any advice.
Thanks.
the most convenient way to do this is
task modelJar(type: Jar) {
classifier = 'model'
from sourceSets.main.output
include 'com/foo/bar/model/**'
}
Some background:
sourceSets.main.output is a buildable filecollection. This means that if a task works with this file collection, gradle knows that this file collection must be created before another task can use it. in this particular case, sourcesets.main.classes is wired to the classes task of the java plugin. Therefore you your modelJar task does not need to depend on the classes task explicitly.
How about making modelJar task depend on classes (built-in) task? This should make sure compilation is done before modelJar task.
task modelJar(dependsOn: classes, type: Jar){
...