2009/5/23 Adam Murdoch <[email protected]>

> 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.
>
> 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 like this.

>
> 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.

I agree.

> 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.

That would be cool :)

> 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.
>
> There are some down-sides, but I think we can come up with simple solutions
> to those (or already have, in the Task model).
>
>
> * Project Descriptor
>
> It makes sense that a build script should be able to define the name of the
> project, something like:
>
> project {
>   name = 'myProject'
>   // maybe some other properties as well
> }
>
> Given that the name is fundamental to the identity of the project, this
> closure would have to be executed as soon as the project is included in the
> build (regardless of how that might happen). We would need to do some magic
> to extract just this closure. I think it should be possible.
>
> It's a closure so that 1) we can find it easily, 2) you can use statements
> to configure the descriptor, and 3) so we can add more properties or methods
> to the descriptor later.
>
> Some issues:
>
> - There is the potential for 2 different names to be specified for the
> project: one in the ancestor project, and one in the project itself. Not
> sure how to resolve this.

I would only allow the name to be set once and fail when the second time it
is a different value. I think this is very likely to happen a lot. When the
module is not yet part of a larger build it will need the name in a local
build script. When it is incorporated in the larger build it will be defined
in the larger build hierarchy with it's name to make the larger build
independent of changes to the lower module build files (like removing the
name because it is no longer needed).

>
> - Which properties should be available for configuring in the descriptor?
> For example, do we let you specify the project or build dirs? Let you apply
> plugins? Define tasks/configurations/repositories? Set arbitrary project
> properties? Are you simply configuring a Project object, where the name
> property is mutable while the closure executes?
>
> - Which properties can only be specified in the descriptor? Certainly the
> name is one. If we let you specify the project or build dirs, should we make
> them immutable after the descriptor has been configured?

I would make them immutable after configuration.

>
>
> - What about the ancestor parent which includes the project? What can it
> configure?

I wouldn't make a distinction between the two location where a project can
be configured. Everything can be configured in both locations, but only once
(and ignoring multiple configurations of the same thing that are trying to
configure it in the same way - like I'm suggested with the possible names
issue).

>
>
>
> * Build Script Classpath
>
> Again, it makes sense that each project can specify its own classpath.
> Perhaps, something like:
>
> buildclasspath {
>   repositories { .... }     dependencies {
>       build name: 'somelib', version: '..'
>       build group: '..' ...
>   }
> }
>
> That is, a mini project which allows you specify repositories and
> dependencies (but maybe not configurations). Like the project descriptor,
> this closure would be executed as a special step before compiling the build
> script proper.
>
> Some issues:
>
> - Do we configure the project descriptor before the build classpath? Or the
> other way around? That is, can you use the project name in the
> buildclasspath { } closure, or can you use the classpath in the project { }
> closure?

I'd go for the classpath in the project { } closure, I can imagine some
custom build logic wanting to add some custom properties to project.

>
>
> - Do we continue with a single classloader for all projects? I'd be tempted
> to create a classloader per project.

I agree we should have separate classloaders per project.

>
>
>
> * Custom plugins
>
> Some possibilities:
>
> - Continue to use the build script classpath for locating plugins.
> - Use a separate configuration for plugins in the buildclasspath { }
> closure.

I'd opt for something like this, allow configurations to be defined in the
buildclasspath, and when you say usePlugin(SomeClass,
somePluginConfiguration) this does imply that we need separate classloaders
for plugins aswell.

>
> - Allow dependencies for a plugin to be declared closer to where the plugin
> is applied, something like:
>
> usePlugin(SomeClass) {
>   dependencies group: 'myOrg', name: 'myBuildInfrastructureProject',
> version: '1.0+'
> }
>
> By teasing apart the build script and plugin classpaths, particularly if we
> end up with a classpath per plugin, we are taking a big step towards Gradle
> modularisation. In addition, if we add file dependencies and project
> dependencies to the mix, we end up with a really flexible solution for
> composing build logic - in particular sharing this stuff across the
> organisation.
>
>
> * Finding the root project.
>
> When settings.gradle disappears, we lose the marker file which helps us
> find the root project.
>
> A simple replacement is to scan up the directory hierarchy and treat the
> highest *.gradle file we find as the root project's build file. We would
> replace the --settings-file command-line option with a --root-project
> command-line option in those cases where this doesn't work.
>
> Alternatively, we could allow the project descriptor to point to the parent
> project. Or combine these two options.

If the *.gradle file scan doesn't work it would indeed be nice to be able to
specify the parent project in the build file, you wouldn't want to specify
it every time you want to execute a gradle command. So allowing them both is
indeed a good idea.

>
>
>
> Adam
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>   http://xircles.codehaus.org/manage_email
>
>
>

Reply via email to