On Dec 28, 2008, at 10:49 PM, Adam Murdoch wrote:



Hans Dockter wrote:
In Gradle we have the necessity that some information is provided _before_ the build script is compiled (for example if you want to add additional jars to the build script classpath). At the moment we solve this with a settings.gradle file. Tom and I have talked about this during Devoxx. We both would love to get rid of this additional build file 'settings.gradle'.

I would love to see it go as well.

What we would like to do instead, is to have a two phase processing of the build.gradle file. The first parsing would extract information for example about the build script classpath or about project naming. The second step would be the actual compile.


I'm not sure about this approach. The build file stops being a groovy script and turns into something else, where some bits of the code are executed differently to other bits (or not executed at all). This doesn't feel right to me. Can you describe how this would work?

But our build scripts are anyway no Groovy scripts which can be executed on its own. They need the Gradle runtime. And we do already some Groovy metamagic to let the scripts run (e.g. delegation to the project object). So I think this proposed approach would not necessarily be conceptually different to what we do now.

With Groovy 1.5.x what we could do is to have a hand crafted solution. First run some regex matching over the build script and extract the necessary information. Then do a normal compile. For the first phase directives we could provide empty implementations in the project object to make the compile work.

With Groovy 1.6 you can customize the Groovy compilation. I have never done this, but Peter Niederwieser has done this for Spock and he would give us a hand for this. As 1.6-rc1 is already out this is I guess that would be the preferred approach. I don't know about the details. But Peter said that our use case can be solved by that.


I think there might be some alternative approaches which don't require execution magic. Currently, we use the settings file for a few different use cases. We don't need to solve each the same way, and we can potentially move some of the more common use cases to the build file, and leave the settings file for more exotic usages.

The less magic the better.

Here's what we use the settings file for, with some potential options for replacement:

1. Locating the root project.

Currently, we scan up the directory hierarchy from the current directory looking for a settings file.

A simple option here is to scan up the hierarchy for .gradle files, and use the file from the highest location we find.

Good idea. We have already the strategy pattern implemented for finding the root. Right now there is the ParentDirSettingsFinderStrategy and the MasterDirSettingsFinderStrategy. So it would be easy to implement and use strategies suitable for a certain settings.

2. Naming the root project.

Currently, the only way to give the root project a name other than the default is via the settings file.

As discussed in another email, one option is to use the build file's name as the default project name.

As said before, I like this.

Another option is to allow the project name to be specified in the build file. I think there could be a window early in the execution of the build file where the name can be changed. One possibility is to allow the name to be changed only before any other modification is made to the project.

The problem here are multi-project builds. The name of the project is part of the path of the project. For example if you access 'someProject' from 'otherProject' via project(':someProject'). If the someProject build script has not been evaluated but contains a name change (which means also a path change), things won't work out. As then the path of a project will change during the multi-project build evaluation.

3. Defining subprojects.

Currently, the only way to add projects to a build is via the settings file.

One option is to allow subprojects to be added to a project, pretty much the same way we allow tasks to be added to the project. Or configurations added to the dependency manager.

We would run into a similar problem as described above (without using magic). Depending on the build script evaluation order of the multi- project build, those projects would be accessible or unaccessible from other projects.

4. Making external plugins available for use.

Currently, you can use an external plugin by adding it as a dependency in the settings file.

Some options:
- Allow the build file a way to add stuff to its classloader

- Use a special configuration which defines the classpath for loading plugins
- Allow dependencies to be specified when calling usePlugin()

Let's assume you want to use classes provide by the plugin jar (we are talking about our future plugin system). Then those classes must be available to the Groovy compiler before the build script is evaluated. Which is only possible if you have two phases (either with the help of settings.gradle or with 1.6 compiler magic).

- Add a definePlugin() method, which would take a bunch of dependencies, the plugin classname, and the desired plugin name. These definitions would be inherited by subprojects.

5. Making classes available for use in the build file.

Interestingly, we have 2 places where you can declare extra classes you want to make available to the build file: in the settings file, and in the runtime configuration for the buildSrc project.

Perhaps we could just use buildSrc as the replacement for this use case.

This is a good idea. Definitely better than the settings.gradle option. On the other hand, if people don't need build sources we would impose indirections onto them, more or less the same way as we do now. From a user perspective I think the most natural way to define libraries for the build script would be within the build script.

- Hans

--
Hans Dockter
Gradle Project lead
http://www.gradle.org





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email


Reply via email to