On May 23, 2009, at 11:32 PM, Adam Murdoch wrote:
Hi,
I'd like to come up with a plan for removing the settings.gradle file.
(apologies for the essay - I think this stuff needs to be considered
as a whole)
There's 5 things we use settings.gradle for, which we will need
replacements for:
1. Defining the project heirarchy. That is, which projects are
included in thie build?
2. Defining the project descriptor for each project in the build.
That is, what is the project name, build file, project dir and build
dir for each project?
3. Defining the build script classpath(s). That is, which classes
are available at compilation time and execution time for each build
script.
And right now there is the additional constraint, that there is only
one build script classpath for all of the build scripts of a multi-
project build.
4. Defining the classpath(s) for custom plugins to be used in the
build script. Currently we use the build script classpath for the
custom plugin classpath, but I think they really are separate use
cases.
5. Locating the root project of the build when running from the
command-line.
Plus, the solution should allow us to later add better ways of
composing the build and plugin classpaths, such as by using project
dependencies.
I have some suggestions, but they're really just a starting point
for discussion.
* Defining the heirarchy
It would be useful, I think, for any project to be able to define
its own subprojects. This allows for better build encapsulation, and
would allow small builds to be more easily composed into multiple
larger builds. Perhaps something like this in the build file:
projects {
subProject {
buildFile = 'sub-project.gradle'
}
anotherSubProjectUsingDefaults
aSubProjectConfiguredUsingAMap(projectDir: 'sub', buildFile:
'sub.gradle')
}
This could be nested to allow a project tree to be specified:
projects {
subProject {
anotherProject { ... }
}
}
I think a builder syntax is a natural way to express and configure a
project hierarchy.
I think having aggregate multi-project builds are very important. I
see two types of multiproject builds. One is a strongly coupled one,
where the subprojects depend on the configuration of the parent
project and where artifact project dependencies are used. This is well
supported in Gradle at the moment. The other type of multi-project
build is much more loosely coupled. The subprojects don't know of each
other and can be build independently. Artifacts dependencies are
realized as external dependencies. An aggregate multi-project build
will often contain both types of multi-project builds. Those aggregate
builds are an important requirement on our way to become a good build
integration tool.
Right now we have the behavior that only the root and the leafs of the
project hierarchy need to be specified. The nodes in between are
automatically created. I don't think this makes a lot of sense. I just
want to mention it.
I think we should do away with the processing stage which figures
out which projects are included in the build, and simply allow them
to be added at any point during the evaluation stage. That is,
projects are just regular domain objects, not anything special. I
think this consistency important. In addition, this would mean you
can use plugins or classes in buildSrc to define or influence the
project hierarchy without us doing anything special to support it.
The same would be true of any future capability we add to let you
compose the build logic. To me, this approach seems more flexible
and more likely to handle use-cases we haven't anticipated, than
would special-casing assembly of the project hierarchy.
I'm trying to understand the lifecycle we would have then. Let's say
we have a non aggregate multi-project build. All subprojects are
declared in the root project. During the evaluation phase of the root
project we hit the projects closure. After a declaration of each
subproject, we would create an empty project instance for this
subproject. After the projects closure is evaluated the root project
can configure the sub projects. After the root project is evaluated,
the subprojects are evaluated (let's say by default in alphabetical
order). The evaluation order can be customized by calling the
subproject.evaluate() method or by creating a dependsOn relation (for
example because subproject1 needs an evaluated subproject2).
Does this makes sense? I need to understand this before commenting on
the other issues.
- Hans
--
Hans Dockter
Gradle Project Manager
http://www.gradle.org
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email