project name in gradle must be a directory? - gradle

Is it mandatory to have a directory with same name as project in gradle ? My code is like this:
.
|-- build.gradle
`-- suites
`-- lrgabc.gradle
1 directory, 2 files
content of suites/lrgabc.gradle
$ cat suites/lrgabc.gradle
project(':lrgabc') {
task block1 << {
println "Hello from lrgabc.block1"
}
}
Content of build.gradle
apply from: 'suites/lrgabc.gradle'
When I run, gradle -q :lrgabc:block1 I get
* Where:
Script '/home/skgupta/gradle-examples/multiproject/suites/lrgabc.gradle' line: 1
* What went wrong:
A problem occurred evaluating script.
> Project with path ':lrgabc' could not be found in root project 'multiproject'.
Is it mandatory to have 'lrgabc' as a directory under 'multiproject' ?
What I'm trying is under one single project, create multiple test suites using gradle. Each test suite is one gradle file, where each task in that gradle represent one test [These are non java tests, like perl, python..etc]
How do I solve this ?

Each subproject in a multi-project Gradle build needs to have a separate project directory. However, directory names do not have to correspond to project names (this is configurable in settings.gradle).

You really want to take a look at the documentation for multi-project builds - http://www.gradle.org/docs/current/userguide/multi_project_builds.html There are also samples in Gradle distribution that can help you.
You don't need to create new projects to create more test tasks. You can have these tests in one project. It is quite common to define multiple test suite like unit and functional tests this way. http://blog.safaribooksonline.com/2013/08/22/gradle-test-organization/ shows a possible implementation.

Related

Manage generated resources for project in Gradle

I have a Gradle project which has a lot of resources in the /src/main/resources folder. For performance reasons, some resources have to be generated from other resources at build time. So I split everything up into sub-projects:
/MainProj/src/main/java - The application
/MainProj/src/main/resources
/InternalProj/src/main/java - Code for generating additional resources for MainProj
/InternalProj/src/main/resources
When I run InternalProj using a special Gradle task, it generates some files to /InternalProj/output which I then copy to /MainProj/src/main/resources. Needless to say, this is really ugly and I'd like to know how to do this in a better way. Should I put it somewhere into build or directly into /MainProj/src/main/resources? Maybe use a symlink?
Edit
I now use a relative symlink from /src/main/generated-resources to /build/something and so far it works fine. But now I have a different problem: I have task A that generates some resources and task B that depends on those resources and thus on A. If I run gradle B or gradle A B, B will still fail since the resources generated by A didn't get updated into its build folder. How can I force Gradle to update the resources?
You can add the output file to the main source set of the InternalProj:
Example Groovy Code:
sourceSets {
main {
resources {
srcDirs "src/main/resources", "output"
}
}
}
Related answer: https://stackoverflow.com/a/38982006/3708426

Understanding gradle multi project build.gradle execution order

I'm doing some experiments on below gradle multi project structure
I have added println in all the build.gradle & settings.gradle files to see in what order they execute. I'm seeing that projectA -> build.gradle file is executing after its subproject pA1->build.gradle as seen in the output below
I'm not understanding why projectA->build.gradle is executing after its sub projects ? Should it not execute before its subproject, just like the build.gradle file on root.
location on project Multi project sample
First off, putting a naked println line in your build.gradle files does not give you execution order. The println will be invoked in the configuration phase, so if anything you're looking at the configuration order.
If you want to investigate execution order add a task with the same name to all your build.gradle files, maybe something like this:
task action << {
println("In project: ${project.name}")
}
and then run gradle action from the root folder.

How do I prevent Gradle from building a non-project directory?

In the Gradle samples (included with version 2.2.1) there is a java/multiproject project.
The settings.gradle file defines the following projects:
include "shared", "api", "services:webservice", "services:shared"
Note that services is not itself a project, merely a directory which contains the webservice and shared projects.
When I run the command gradle build from the root directory, I notice that after gradle successfully builds it creates inside the /services directory a /build directory containing /lib and a /tmp directories.
Inside of /services/build/lib is a jar: services-1.0.jar which contains very little; specifically just a META-INF/MANIFEST.MF file containing:
Manifest-Version: 1.0
provider: gradle
So what is causing Gradle to build a jar for this non-project? And how can I prevent this behavior in my similarly structured multiproject project?
/services isn't a project, I don't want to create anything inside /build folder at all. Yes I could just delete it, but I would like to avoid the unnecessary work of building this jar/running any tasks on this non-project in the first place.
To be honest I've no reasonable idea why gradle builds this folder. I guess that because it's a kind of a transient folder. However it can be excluded by adding the following piece of code to main build.gradle script:
project(':services').jar { onlyIf { false } }
Desired effect (services.jar elimination) can be also obtained with the following settings.gradle content:
include "shared", "api", "services/webservice", "services/shared"
File instead of project paths are included.
My guess would be that this is a combination of the next 2 gradle rules:
When you're including subprojects in the build.settings file using the include keyword according to Gradle Documentation here:
the inclusion of the path 'services:hotels:api' will result in
creating 3 projects: 'services', 'services:hotels' and
'services:hotels:api'.
In simple words, this means that the inclusion of services::webservice will also build the services project
The bulid.gradle file in your root that applies the 'java' plugin. According to Gradle Documentation here every configuration defined in the root.gradle takes effect for all sub projects. This means that it will also hold as the default configuration for the services project. As the 'java' plugin was applied a jar will be created, but as there is no src/main folder under the services directory nothing will be compiled and the jar will include only a META-INF/MANIFEST.MF file.

Executing integration tests in gradle

Me and my team are working on a project with a lot of modules. We are using gradle for the project and everyone is new to gradle. We have a Main parent project i.e, parent build with the details of project dependencies. We want to add the integration_test task configuration to all the modules so that we can call the command gradle integration_test. So is there any way or concept of writing the configuration in the main module and make the child projects import the same configuration.
FYI: I tried it by directly adding it to the main project but got an error saying the classpath for the files which I specified does not exists. Any help or thought would be appreciated. Thanks in advance.
Is there a particular reason to split "integration tests" from the standard test task?
If so, you can run the same script for all subprojects from the main project's build file: https://docs.gradle.org/current/userguide/multi_project_builds.html#sec:subproject_configuration
For instance:
subprojects {
task integrationTest {
// whatever you need
}
}
I am note sure if this is what you talk about in the last paragraph. If so, please attache the error message you get.
It is also possible to "import" some configuration by subprojects, but the above definition is better in most scenarios.

Gradle-built project structure

I see a lot of examples of Gradle-built Java/Groovy projects that have the following structure:
some-app/
src/
main/
test/
docs/
README.md
build.gradle
gradlew
gradlew.bat
settings.gradle
gradle.properties
gradle/
*.gradle
I understand that build.gradle is the main buildscript and that gradle.properties is its properties file. But settings.gradle really throws me. Inside it I see:
rootProject.name = "someApp"
But this seems like it belongs in gradle.properties. I'm also wondering where the gradlew and gradlew.bat files come from, they seem to be generated.
Finally, I'm wondering why there are so many *.gradle files under the gradle/ dir: are these plugins, or extension scripts of some sort. They are all pulled in from the main build.gradle like so:
apply "gradle/fizz.gradle"
apply "gradle/buzz.gradle"
etc.
So:
What properties are supposed to go in settings.gradle that are not supposed to go in gradle.properties?
How are the gradlew/gradlew.bat files generated?
Why would someone have so many disparate *.gradle files? Why not just 1 big build.gradle buildscript?
1) gradle.properties is normal properties file, while settings.gradle is also a build script. You can add there some code that will be executed during build. Typically this file is needed when You have a multi-module project.
2) When You type gradle tasks in project build directory (empty build.gradle is enough to see it) You'll see wrapper task. This task is used to generate scripts You're asking about. More info.
3) The reason is that all these files have different responsibilities that are cleanly separated.

Resources