On 03/02/2013, at 10:02, Hans Dockter <[email protected]> wrote:
> > > On Sat, Feb 2, 2013 at 11:50 PM, Adam Murdoch <[email protected]> > wrote: >> Hi, >> >> Something I'd like to try to achieve as part of the work to introduce >> multiple outputs for JVM based projects, is to create fewer task instances >> at configuration time. There are 2 main parts to this: >> >> 1. Don't create tasks that will never be required. For example, if there is >> no src/main/resources directory, and nothing generates it, then don't create >> a processResources task. >> 2. Don't create tasks that are not required for the current build. For >> example, if I'm generating the javadoc, don't create the test task or any of >> its dependencies. >> >> Ignore for the moment how we might do this. Let's just say its possible to >> infer both #1 and #2. > > Which would be awesome. But doesn't it leave the door open for certain > undetectable(?) configuration time dependencies? I would say if we are able > to reliably solve that problem, reliable parallel task execution isn't far > away either (if we want to go for it). >> >> Let's also say that if such as task is directly referenced in the build >> logic, then it's "required". For example, if I execute >> `myTask.dependsOn(processResources)` in my build script, then >> processResources is required and must be created. Possibly also for the >> command-line, so that if I run `gradle processResources`, then it is >> required. >> >> The question is whether we consider it backwards compatible or not that we >> don't create certain tasks that used to always be created. >> >> At first glance, it looks not too bad. The tasks don't do anything and >> nothing references them from code, so it's fine to leave them out. There are >> a few important benefits to doing this: >> >> - There's less work to do at configuration time. This doesn't seem certain to me. The calculation on whether something is really needed may not be "free". Depends on how efficient the inference is. >> - There's less heap required to maintain the model through the whole build. >> - We wouldn't log the execution of tasks that don't do anything. For >> example, if there is no test source, you wouldn't see 'testClasses', >> 'compileTestJava', 'processTestResources' etc. > > Which is a strong indicator that we are doing something right here. > >> - It pushes the decoupling of 'what' and 'how', which means the 'how' can >> vary across different executions of the same build. For example, when >> generated source must be downloaded when building on one platform but can be >> generated when building on some other platform. Or when I'm running the >> tests against a distribution built by CI. I don't quite see the relationship here. It seems to me like you could this without what you're talking about. >> >> Unfortunately, there are a few places where the tasks leak out and are not >> referenced by name or path: >> >> - Via the events on TaskContainer, such as tasks.all { } or tasks.whenAdded >> { } >> - Iterating over the various collections of tasks, such as >> project.getTasks(name), or tasks.withType(type). >> - Via the execution events, such as gradle.taskGraph.beforeTask { } >> >> Strictly speaking, we'd still be following the contract for these things. In >> practice, though, I think there's an implicit contract that says that we >> must continue to create all possible tasks. > > I think this would be a breaking change for not even exotic use cases. I agree with Hans and about the implicit contract. This just feels like too big a change to consider backwards compatible. > > >> >> Some options: >> >> 1. Don't create the tasks, and simply document this as a potential breaking >> change (or, more likely, as series of changes). >> 2. Create alternatives to the above leakage points, but with stronger >> contracts. If you use one of the above, then we always create every possible >> task. > > This is an interesting one. > >> 3. Toggle the strategy based on whether you're using the Gradle 2.0 >> configuration model or not. > > My preferred option I think. After all Gradle 2.0 is about scalability and > this is another milestone in that direction. It is possibly also cheaper than > the second option. > > Hans > >> >> We might also choose a different option for tasks that are never required vs >> task that are required only for this build. I'd rather not do this, as I >> think it's important that we move towards the situation where we guarantee >> that we create only the tasks that are required, and don't care about the >> distinction between 'sometimes' and 'never' for tasks. >> >> >> Thoughts? >> >> >> -- >> Adam Murdoch >> Gradle Co-founder >> http://www.gradle.org >> VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting >> http://www.gradleware.com >
