Hans Dockter wrote:
* 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 should be possible with Groovy 1.6 in any case.
A minor point. For single project builds this looks a bit unintuitive.
Any thoughts on what would be more intuitive? I wonder if we even need
this, if we use the build file name as the default project name.
Anyway, compared to 0.6 where you would need your settings.gradle file
to change the name, this is still a big improvement.
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.
My first thought is that this is legal and that ancestor should win.
The use case I have in mind is a loosely coupled multi-project build.
The subprojects are not aware that they take part in such a build.
They might set their names, possibly even using equal ones.
This is a good option.
- 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?
- What about the ancestor parent which includes the project? What can
it configure?
As said in the other email. We might remove the ProjectDescriptor.
That would expose the whole API (also for the ancestor). This might
raise some issues. For example what to do with
projects {
subproject {
println name // name is not defined in the subproject
either
}
}
The name would default to 'subproject'. But it might change at some
point (soon) after the println statement.
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 would say we should configure first the project closure. Then the
buildclasspath can make use of the information. Project stuff that
needs the buildclasspath can always be added later. Unless you need
the buildclasspath to figure out the project name. But this latter,
rather uncommon, problem could always be solved with a multi-project I
think.
Right. Alternatively, the classes from buildSrc runtime would be
available in the project { } closure. Which means you could add stuff to
the buildSrc runtime config to make it available.
- Do we continue with a single classloader for all projects? I'd be
tempted to create a classloader per project.
We need one per project I'd say. Otherwise we will bump into issues.
It would be easy to come up with use cases.
Should a project's classloader extend it's parent's classloader?
* Custom plugins
Some possibilities:
- Continue to use the build script classpath for locating plugins.
- Use a separate configuration for plugins in the buildclasspath { }
closure.
- 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.
I think plugins should be able to contribute two things. One is
manipulating the project object. The other is providing a library to
the project. Let's look at the Java plugin. You might want to apply
the Java plugin but you also want to use the Jar class in a custom
way. What would we gain by a separate configuration? What I think is
important are the transitive dependencies. It would be cool if every
buildclasspath dependency would not expose its transitive dependencies
to the build script. As far as I understand, the Spring Bundlor
project for example, can create OSGi manifest files from ivy.xml and
pom.xml. Of course this would require the big leap to OSGi.
I wonder if it has to be such a big leap. For example, we could use it
to wire up Gradle itself to start with, and only later use it to wire up
plugins and projects. Or the other way around (which might be a better
option). In addition, I imagine we could build the OSGi plugin system to
sit alongside the old plugin system, so that we can port the plugins (if
that is needed) one at a time.
I can't really think of any general solution to this problem that
doesn't involve a ClassLoader DAG + some declarative meta-data + a
packaging format, ie what OSGi provides. So I think a plan might be to
leave the plugin + build script classpaths together for now, and look at
using OSGi to wire plugins into projects (and only that) soon.
Adam
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email