I would like to have in animalSniffer plugin one task to depend on compilation of all production classes (Java, Groovy, Scala) in all sourceSets and the second to depend on compilation of all test classes in all sourceSets (possibly separate test and integrationTest).
I wouldn't like to depend on *classes tasks as *classes tasks should depend animalSniffer tasks (which detects Java version API incompatibilities after the compilation and can stop the build).
Is there a better way in Gradle to achieve that than checking if an instance of AbstractCompile task name starts with "compileTest"?
You can use tasks.withType(AbstractCompile) which returns all compile tasks for all source sets (which includes Java, Groovy, Scala). You can then filter on this by eliminating all tasks that have test in them as suggested in the other answer.
For a specific task to depend on all these, you can do the following:
myTask.dependsOn tasks.withType(AbstractCompile).matching {
!it.name.toLowerCase().contains("test")
}
If you need to differentiate between production and test compile tasks/source sets, checking whether the name contains test (case-insensitive) is the best solution that's available.
Related
Suppose I have one set of Java sources in the standard repository layout (ie. src/main/java). Now suppose I want to create two jars from this set of sources - one each using the classes produced from two different JavaCompile tasks that are configured differently. For example, I might have something like this:
tasks.named('compileA', JavaCompile).configure {
// one set of toolchain and options settings here
}
tasks.named('compileB', JavaCompile).configure {
// a different set of toolchain and options settings here
}
The question is, is it better to just have the main source set (supplying the compileA equivalent, and thus the jarA equivalent, for free) and commission compileB (and jarB) separately, or have two separate source sets, one each for compileA/jarA and compileB/jarB? What if I needed something like a war, where I need the source set's runtime classpath? Is there a way that I can make a warA and warB, where they each only have the classes from one or the other compile task?
Additionally, suppose that I have a multi-project build, where multiple projects have this compileA/compileB setup, and there are project dependencies between the subprojects. What else would I need to do in order to make it so that we end up with a jar that only consists of classes compiled using the various compileA tasks, and a different jar that only consists of classes compiled using the various compileB tasks?
gradle newbie here,
I have began to implement a small gradle plugin. The goal of the plugin is to create a release zip for projects, with the intention of using across a couple of different projects.
Each project has a yaml file with a zipping structure loosely as such;
---
zip:
task:
- name:
zip:
task:
- name:
- name:
- name:
zip denotes that a given working directory should be zipped at this point
task denotes the name of a gradle task that should be executed preparing a particular directory in preparation of being zipped
The best pro that comes to mind is, with this approach I can reuse gradle tasks between projects and if needed include custom gradle tasks at a per project level and reference them here in the yml. Using a yaml also assists with creating release zips making them easy to build and read..
I have a manager gradle task that is called at runtime from cli ./gradlew myReleaseZipTask ( I think I achieve this by making it an exec task and putting the logic into the exec action). This manager task is responsible for parsing the yaml file into DTOs. Traversing from the lowest task I traverse up the graph executing each gradle task as defined preparing files into a specified directory and then once all tasks are completed zip the current workspace. Continue up the graph
Im halfway through my implementation and Im a little bit worried im abusing gradle in a way that its not intended. Some of my main concerns are;
I have one task that is orchestrating many other gradle tasks, I either find or create a task on the fly, then retrieve its actions and execute them from inside my manager task, this isnt something I see often in gradle examples. Everyone seems to have very static linear task dependencies and dont "reflectively" create or find tasks to execute..
When dealing with a task entry from the yml my manager task tries to lookup the gradle task by name, if it doesnt exist, it tries to create the task. Given a task is created/found I set the properties from the YmlTaskDTO onto the task and then call the task to execute. Will I run into issues with reusing the same tasks with different properties? For example if I have something like;
zip:
task:
- name: taskA
argA: A
argB: B
- name: taskA
argA: A
argB: C
Could anyone give me some feedback on my design and if its inline with correct standards of gradle use? Please raise any concerns you may have!
I think you have realised some of the answers your self.
The one guidance here is that 'plugins' are to create a new functionalities, that are not available in native gradle.
What you are doing here is composition of existing tasks in a specific order for your use case. Plugin for this is an overkill.
What you are looking for can be achieved with simple tasks and task chaining.
As a part of a TDD workflow, I want to be able to check if my Java codebase compiles, but not if the tests pass.
Currently, if I run gradle build it runs the compile tasks (for source and tests) and then also executes the test task (and returns a non-zero exit code since the tests fail).
So I find that I have to run gradle build -x test to exclude the test task, and get a successful zero exit code.
What do I add to my build.gradle to define a new task, say compile that is an alias for build x test?
So far I have this, but it doesn't seem like dependsOn takes any arguments to customize the build task I want to execute:
task compile {
dependsOn build
}
I've been reading the docs here, I see different kinds of dependency chaining mechanisms, but not to disable/exclude a particular task. How does the -x flag even work then? I assumed there would be a way to control it programmatically too.
Thanks to Bjørn Vester's answer and reading the docs, I have implemented my task as follows:
task compile {
dependsOn classes
dependsOn testClasses
}
There are lots of different tasks you can run individually. For instance:
gradle classes: Will compile your "main" code.
gradle testClasses: Will compile your "main" code as well as test code.
gradle jar: Will compile your "main" code and assemble it into a jar.
None of the above will run your unit tests. On the other hand, the build task depends on all of the above, as well as the test task and more.
In general, if you like to run a particular set of tasks, you do that by defining a new task and then make dependencies to those other tasks you like to run with it. You tried that already, but instead of build you should have used something like compileJava or classes whatever other tasks you need. But always check if there isn't one already that satisfies your needs, like there are in this case. You can read about what tasks are available in Java projects in the documentation for the Gradle java plugin.
I'm using the shadowJar plugin for Gradle (4.2.1) to build the so-called fatJar or uberJar. This works as expected but I would like to to add some actions after the building is done. More precisely, I'd like to make the resulting file executable (in Unix terms, i.e. chmod +x) and then copy it to a certain directory. I've googled a lot and I know that both task are possible. I'd like to know whether I should write a script (task) that runs shadowJar and then does what I want, or I should change the shadowJar itself to embed the operations I need.
I think a good criteria to decide about such situation is to ask yourself if the new features are really part of the responsibility of the shoadowJar. If the answer is no, then it would be better to (as you mentioned) have another task that runs on top of that. By doing so you can reuse the shadowJar in much more different scenarios by combining it to other tasks. If you define the new one to be dependent on the shadowJar, then you would be sure that you can still call shadowJar task individually while calling the new task would always trigger the shadowJar. Your new task would be something like this:
task afterShadowJar (dependesOn: 'shadowJar') {
// manipulate file permissions, etc.
}
I am a gmake user transitioning to Gradle. I have a multi-project structure, where one sub-project is a Java project and the other a home-brewed language. The home-brewed language does not use any Gradle plugins. Now I want to add a task that runs a Java program to generate XML when any of my home-brewed source files have been modified. In make, I would just declare a dependency on inputFile.mine or *.mine next to the target name, but I could not easily find how to do this basic thing with Gradle. Currently, I force the task to always execute using the potentially ugly work-around below. I want to replace this with some dependsOn *.mine . The Gradle user guide has a whole chapter dedicated to explaining different ways of specifying files, but I did not see how to declare a dependency.
task generateXML(type: Exec) {
generateXML.getOutputs().upToDateWhen({false}) // Force it to execute always
executable("java.exe")
args("-jar", "resources/generateXml.jar", "src/inputFile.mine")
}
Thanks for helping a newbie out.
You can define task inputs and outputs in Gradle.
For example:
task generateXML(type: Exec) {
inputs.file ("src/inputFile.mine")
executable("java.exe")
args("-jar", "resources/generateXml.jar", "src/inputFile.mine")
}
See https://docs.gradle.org/current/userguide/more_about_tasks.html and https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskInputs.html for more information.
Side note: When you run your build with -i, Gradle will tell you what has happened during the up-to-date check.