Multiproject build


(m m) #1

In the manual it is mentioned that for a multiproject build , the settings need to be specified as include ‘project1’, ‘project2’, ‘project2:child1’. This means that the inclusion of path ‘services:hotels:api’ will result in creating 3 projects: ‘services’, ‘services:hotels’ and ‘services:hotels:api’.

In my case , I do not want a project to be created for the intermediate folder

for eg : Folder1 -> Folder2 -> Folder3

The actual components are in the folder3 which is the project folder. They are grouped under folder2 , which is simply a folder and not a project. I am trying to run the multiproject with the settings.gradle under Fodler1 as the project root.

Gradle treats folder2 as a project and creates the build folders which I want to avoid.

Is there any way to achieve this ? I run from the project root ( folder 1 ) , but I want only folder3 to be treated as a project.


(Matias Bjarland) #2

Not sure if I read your problem correctly, but let’s give it a whirl.

Given the following directory structure:

$ tree .
gradle-multiproject
├── build.gradle
├── one
│   └── two
│  
   └── three
└── settings.gradle

(only a root level build.gradle and a settings.gradle file with some empty directories)

and the following file contents:

//settings.gradle
include ":one"
  def p = project(":one")
p.name = "two"
p.projectDir = file("$settingsDir/one/two")
  //root build.gradle
 allprojects {
  task hello << {
    println "My path is ${project.path} and i am at $projectDir"
  }
}

we get the following execution log from executing the task hello (which in turn executes the task ‘hello’ for all subprojects):

$ gradle hello
:hello
My path is : and i am at ~/gradle-multiproject
:two:hello
My path is :two and i am at ~/gradle-multiproject/one/two
  BUILD SUCCESSFUL
  Total time: 0.884 secs

As you can see from the settings.gradle file, we do something quite ugly here. The code executed in the settings file deals with objects of type ProjectDescriptor. Thus the variable ‘p’ in my example above is of type ProjectDescriptor. In the example above, we include a project from a directory (any directory) directly under the root and then reconfigure the project descriptor for that project to point at a different directory and have a different name.

The idea behind the project descriptor objects is that they describe “how the projects will be configured once they are created”, but they give you the opportunity to change the configuration before gradle goes ahead and actually creates the project objects (of type Project).

I strongly suspect that doing this works against the grain of the gradle philosophy and might not be the best of ideas. Might I ask why you mind having the intermediate project object created?

Gradle gurus, if there is a clean way of accommodating this, I would be interested in finding out also.


(Peter Niederwieser) #3

The easiest way to only add a ‘folder3’ subproject is ‘include “folder2/folder3”’.


(Matias Bjarland) #4

Nice! Did not know this existed. So much for my long and ugly hack : )

Was this introduced in some near or post 1.0 release or has it been there for long? Just asking as I jumped through quite a number of hoops at some point to get this to work in some early milestone release.


(Peter Niederwieser) #5

I can’t tell for sure, but I think it has always worked like this.


(m m) #6

Thanks Peter . Thats really nice.


(m m) #7

Thanks Matias. That was informative.

The intermediate folder is just for grouping the sub folders and having a build folder under the intermediate folder might confuse the development team

And since I am migrating an existing project from maven to gradle its the all the more important to avoid any unwanted folders.

Thanks . I am impresssed by the suppot that I am getting for gradle.


(m m) #8

The uploadArchives task works only if we user folder2:folder3 . The POM validation fails if we specify folder2/folder3

Execution failed for task ‘:common-sub/common-utilities-comp:uploadArchives’. > Could not publish configuration ‘:common-sub/common-utilities-comp:archives’.

Unable to initialize POM pom-default.xml: Failed to validate POM for projec t framework-app:common-sub/common-utilities-comp at D:\framework-app\common-sub\common-utilities-comp\build\poms\pom-default.xml


(Peter Niederwieser) #9

Probably need to go with Matias’ solution then. It’s fine, and I wouldn’t consider it a hack.


(m m) #10

The problem is because the name of the project is folder2/folder3 which is getting confiugured as the artifactId in the generated pom.xml .


(m m) #11

I am new to groovy . Just a temporary workaround below to solve the above problem

uploadArchives {

repositories {

mavenDeployer {

repository(url: “file:D:\gradle-repo”)

pom.artifactId=project.name.substring(project.name.lastIndexOf(’/’)+1)

}

}

}


(Peter Niederwieser) #12

You probably don’t want the project to be named ‘project2/project3’ anyway. Hence I’d go with Matias’ solution.


(Matias Bjarland) #13

You could always use Peter’s method for the include and then mine to reset the name. Saves you a line of code in settings.gradle.


(m m) #14

Thanks Matias and Peter . I have used both your solution to address the concern