I originally had a single Github repository with a Gradle multi-project setup for a number of libraries.
I had been thinking of breaking out some of the libraries anyway, but Bintray really needs a Github repository per library, so with some regret, I broke up the multi-project into single projects. The regret was because I thought I needed a directory hierarchy to support a Gradle multi-project.
Now I didn't really want to maintain several build files, all very similar, and just as I expected, a pain to keep up to date.
So I went back to the excellent Gradle documentation looking for inspiration, but it still took a while to work out what I needed to do.
I read the Multi-Project Java build and Multi-Build Projects sections again, but still couldn't find an answer to making the build work across a flat directory structure, with the root project at the same directory level as its subprojects.
Eventually I stumbled on the answers, and they are in the documentation - just that I didn't find them the easy way. So if you are Gradle, Github and Bintray together, for a multi-project build, this is what you need:
Settings.gradle
In the settings.gradle file, which must be in your root project directory, you define your sub-projects with include statements ... but you are not limited to a hierarchical structure. You can code any structure you like (coding in a settings file is a bit unusual, too). Ironically, the first example I found was in the Gradle repository on Github (not in the structure I wanted, but it demonstrates the feature).My own example looks like this:
include 'krail'include 'krail-jpa'include 'krail-demo'include 'krail-testApp'include
'krail-testUtil'include 'krail-quartz'include 'krail-bench'include 'q3c-testUtil'
rootProject.children.each {project ->
String fileBaseName = project.name String projectDirName = '../'+fileBaseName
project.projectDir = new File(projectDirName)
// for example, makes it krail.gradle project.buildFileName = "${fileBaseName}.gradle"
//make sure it exists assert project.projectDir.isDirectory()
assert project.buildFile.isFile()
}
All this does is map each of the sub-projects at the same directory level as the root project - it also points to *.gradle files which are named the same as their projects (so krail-jpa.gradle for the krail-jpa project). This is to avoid having multiple "build.gradle" files in the IDE, which can be confusing.
Now this almost worked, except I couldn't run the sub-projects from their own directories, I had to call grade from the root project directory.
There must be a master
This time I did find the answer in the documentation, but in the Build Lifecycle section, when I was looking for something else!
....if you execute Gradle from within a project with nosettings.gradle
file, Gradle looks for asettings.gradle
file in the following way:
- It looks in a directory called
master
which has the same nesting level as the current dir.- If not found yet, it searches parent directories.
- If not found yet, the build is executed as a single project build.
- If a
settings.gradle
file is found, Gradle checks if the current project is part of the multiproject hierarchy defined in the foundsettings.gradle
file. If not, the build is executed as a single project build. Otherwise a multiproject build is executed.
For my scenario, all I needed to do was to rename my root project directory as master ... and now I can execute tasks sub-projects from their own directories.
No comments:
Post a Comment