On 01/05/2012, at 11:06 AM, Adam Murdoch wrote:

> Hi,
> 
> Something we want to do soon is to replace the buildSrc project with a 
> regular project. There are a few motivations for this:
> 
> * To improve the user experience for those builds that need dedicated build 
> logic. For example, currently the buildSrc project's 'build' target is used. 
> But this runs all the tests and checks, whereas for 95% of the time, the user 
> is only interested in compiling the classes. Or, currently we need to clean 
> the buildSrc project when the Gradle version changes, whereas for regular 
> projects we don't need to do this. Or, currently the buildSrc project does 
> not end up in the IDE model, but would be included if it were a regular 
> project.
> 
> * To allow build logic to both be published and used in the same build (but 
> not in the same project, for now). This will mean that you can use your 
> enterprise plugins in the same build that produces them. For example, you can 
> use your custom release plugin to release your custom release plugin. We may 
> use this in Gradle, too, when we add a plugin dev plugin.
> 
> * To detangle project configuration from the project hierarchy. In 
> particular, this required for parallel execution, so that projects can be 
> configured in an arbitrary order, and across multiple JVMs and/or threads.
> 
> DSL-wise, there are 3 main use cases:
> 1. Declare that a given script depends on the build logic from some a project.
> 2. Declare that every script depends on the build logic from some project. Or 
> there might be a convention for this, so that you give a project a particular 
> name or put it in a particular directory, and it is automatically picked up 
> as a build logic project.
> 3. Inject configuration to all projects, including those projects that are 
> built during configuration time.
> 
> Use case 1
> -------------
> 
> I think this is as simple as being able to add project dependencies to the 
> build script's classpath configuration:
> 
> buildscript {
>     dependencies { classpath project(':buildLogic') }
> }
> 
> When we simplify the DSL for applying plugins, this might become something 
> like:
> 
> apply project: ':buildLogic', plugin: 'my-custom-plugin'
> 
> Implementation-wise, the configuration phase would look something like this:
> 
> 1. Queue up the configuration of each project, in parent-first order (like we 
> do now).
> 2. For each project, if not already configured, then execute the project's 
> build script.
> 3. For each script that is executed:
>     * Execute the buildscript { } section of the build script.
>     * For each project dependency in the build script classpath, recursively 
> configure and build the target project. Fail if the target project is 
> currently being configured.
>     * Resolve the build script classpath and execute the script.
>     * For each call to evaluationDependsOn(), recursively configure the 
> target project. Fail if the target project is currently being configured.
> 4. For each project that is built during configuration:
>     * Configure the project as above
>     * For each project dependency required to build the project, recursively 
> configure the target project. Fail if the target project is currently being 
> configured.
>     * Add the tasks that build the runtime class path for the project to the 
> DAG.
>     * Execute the tasks.
> 
> I think this boils down to some changes to dependency resolution:
> 
> During the configuration of a project:
> 1. When a Configuration is resolved, for each project dependency we trigger 
> configuration of the target project and building of its artefacts.

One implication of this is that an accidental resolve during configuration time 
(which is easy enough to do) will trigger the building of other projects. While 
this is much, much better than the current behaviour of just silently ignoring 
the projects that haven't been configured (and caching the result, no less), 
it's possibly a little surprising.

So, we might only allow the implicit build of project dependencies between 
running the buildscript { } block and running the script body. You'd have to 
declare in the buildscript { } block, any project dependencies that you may 
need to resolve in the script body. Resolving a project dependency that was not 
declared in buildscript { } would be an error (or a deprecation warning to 
start with).


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com

Reply via email to