On 07/05/2013, at 7:50 AM, Adam Murdoch <adam.murd...@gradleware.com> wrote:
> Hi, > > For the C++ support, I'd like to make use of the deferred configuration > stuff. This will mean growing it to make it more usable. > > There are 2 use cases I'd like to use deferred configuration for: > > 1. Defer creation of tasks until we know which binaries to build. This allows > the creation of tool chain specific task implementations. We might also use > this to skip creation of tasks for binaries that cannot be built locally. > > 2. Add default variants when none defined. This allows us to select a tool > chain based on whatever's available and add a variant for this. > > For use case #1, this means being able to register some logic that runs after > a domain object has been configured. For use case #2, this means being able > to register some logic that runs just before a domain object is made > available for consumption, but after all other configuration logic. > > One simple option is to allow the plugin that defines an extension (and only > that plugin) to register an action to run once the extension is configured. > This action can take care of both #1 and #2: > > project.extensions.createDeferred('libraries', NativeLibraries.class, { > … define defaults and then create tasks ... }) > > A couple of downsides: The main one is that there's no way to configure the > domain object without creating the tasks for that domain object and we want > to move away from this. The other is that there's no way to override the > 'infer the defaults' logic or the 'create the tasks' logic - it's baked into > the definition of the domain object. > > A similar option is to allow logic to be registered that fires at various > points in the domain object's lifecycle: > > // Define a delayed extension (replaces @DeferredConfigurable) and > return a promise for the result > Delayed<NativeLibraries> extension = > project.extensions.define('libraries', NativeLibraries.class) > > extension.beforeConfigured { … called before any configure actions are > executed … } > extension.configure { … called to configure the object … } > extension.finishConfiguration { … called after all configure actions > are executed … } > extension.whenConfigured { … called once the object is configured … } > > // Force configuration, if you really need to > NativeLibraries libraries = extension.get() > > Anything with access to the project would be able to do stuff with the > delayed object: > > Delayed<NativeLibraries> extension = > project.extensions.getDelayed(NativeLibraries.class); > extension.whenConfigured { … } > > And via the DSL: > > Delayed<NativeLibraries> extension = > project.extensions.delayed.libraries > project.extensions.delayed.libraries.whenConfigured { … } > > To infer default values, we might instead of `finishConfiguration` have a > single `addDefaults` action to be registered, and you can replace this action > with whatever logic you like. > > To create tasks, we might add another lifecycle event, so that a single > action `createTasksFor` action can be registered. This is called somewhere > after configuring the domain object and building the task graph, and only > when we need the tasks for the domain object. My gut feel is that this is going to make things incomprehensible. Trying to reason through when all these callbacks are firing for a complex model seems like it will be difficult. It might be better to try and give these actions identity… which I guess is getting into (somewhat) what Hans is talking about with configuration actions. I'm think that the more info we have on these actions the more space we have going forward. For example, do we need to know that a configuration action of a domain object needs another domain object to be in a certain state? That is, it depends on this other object in this other state? -- Luke Daley Principal Engineer, Gradleware http://gradleware.com Join me at the Gradle Summit 2013, June 13th and 14th in Santa Clara, CA: http://www.gradlesummit.com --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email