Hi Adam,

this mail is written from my mobile. I hope the formatting is OK.

Finally I get your point. I like the idea of a conf producing task. An 
alternative would be to pass to a project dependency a specific 
artifactProductionTask. But I prefer your proposal, as it removes the smell of 
'inappropriate intimacy' between projects. 
Right now we have two use cases for a n:n mapping between conf and tasks. We 
have a taskUsesConf use case. For example the compile task may use a couple of 
configurations to get its classpath from. We have also a 
confIsAssociatedWithTask use case. When we establish a project dependency right 
now we create a task dependency between the tasks associated with the conf and 
the artifactProductionTask of the other projects. In fact this use case was the 
very reason why we have introduced task-conf mappings. Without project 
dependencies we would not need such a mapping. Instead we could add an 
additional confs property to the respective tasks (e.g. compile). But as we 
needed such a mapping anyway I thought it is less redundant to let the tasks 
use this mapping as well to get its dependencies.

To implement your proposal we could modify the confIsAssociatedWithTask 
behavior. Instead of linking the tasks with an artifactProductionTask we could 
link the tasks with something like 
otherProject.dependencies.publishTaskForConf('someconf').

Just to point it out. An alternative approach would be not to use the task-conf 
mapping as described above. Instead we would execute at build execution time 
the publishTaskForConf when the resolve takes place. The advantage would be 
that it is easier and more flexible. For example if you say in an init action: 
dependencies.resolve('compile'). Let's say also the compile conf has a project 
dependency. The jars of the project dependency wouldn't be available as only 
the execution of the compile task triggers the generation of the artifacts of 
the other project. The disadvantage is that the graph of tasks to be executed 
wouldn't be complete after configuration time.

One more point we need to think about. If we do a partial build of project A 
which has a project dependency on project B. Let's say we execute 'gradle clean 
libs'. Project A is cleaned before its libs are created, not so project B. Only 
the publish task is executed. We could declare an additional 
dependsOn('projectB') in project A. Such a dependsOn establishes task 
dependencies between tasks with similar names of both projects. Now the clean 
is done for both projects but also the libs task is executed for project B 
which would neutralize our effort to become more fine-grained regarding project 
dependencies artifacts.

- Hans

____________ Ursprüngliche Mitteilung ____________
Betreff:        Re: [gradle-dev] dependency layer refactoring
Autor:  "Adam Murdoch" <[EMAIL PROTECTED]>
Datum:          3. August 2008 12.27.53



Hans Dockter wrote:
>
> On Jul 30, 2008, at 12:08 PM, Adam Murdoch wrote:
>
>>
>>
>> Hans Dockter wrote:
>>> Hi Adam,
>>>
>>> On Jul 30, 2008, at 5:17 AM, Adam Murdoch wrote:
>>>
>>>> the other is the relationship between a configuration and a task 
>>>> which *produces* it.
>>>
>>> I don't see a use case relationship. Any examples?
>>>
>> One example is a project which uses the artifacts of another project 
>> in a multi-project build. Currently we use 
>> DependencyManager.artifactProductionTaskName to model this, which 
>> ProjectDependency uses to add a task dependency from the consuming 
>> project to the producing task of the project. This is fine when all 
>> public configurations of a project are produced by a single task and 
>> are cheap to build. A problem I ran into porting a multi-project ant 
>> build to gradle is that some configurations were very expensive to 
>> build and were not needed by most of the other projects. However, in 
>> order to use any of them in another project, I was forced to build 
>> all of them whether required or not.
>
> I'm not sure if I understand the example above correctly. As I 
> understand it, 'configuration project dependencies' as described at 
> the end of section 14.6 in the UG might help (e.g. new 
> ProjectDependency(project(':api'), 'spi')).
>
Say I have a multi-project build (not neccessarily using the java 
plugin), where each project has 2 tasks: a 'libs' task, which assembles 
some jars for the project, and a 'dists' task, which assembles the 
project into some kind of distribution. The 'libs' task publishes a 
'libs' configuration, and depends on the 'libs' configuration of other 
projects. Similarly, the 'dists' task publishes a 'dists' configuration, 
and depends on the 'dists' configuration of other projects.  Say that 
the 'dists' task is really slow, so that we don't want to execute it if 
we're only building the jars for a project.

The ProjectDependency lets me declare that the 'libs' task for a project 
depends on the 'libs' config for some other project, and that the 
'dists' task depends on the 'dists' config. This is good.  What I can't 
do is declare that the 'libs' task publishes the 'libs' config and that 
the 'dists' task publishes the 'dists' config.  All I can do is set 
DependencyManager.artifactProductionTaskName, which I would have to set 
to 'dists' in this case. Which means that when I only want to build the 
jars for a project, I have to build the jars and dists for all the 
projects which the project depends on, whereas I only really want to 
build the jars for the other projects.

Given that we have a way to tell DependencyManager that a given task 
uses a given config, it would be good to also tell DependencyManager 
that a given task produces a given config.  That is, rename 
linkConfWithTask() to something like taskUsesConf(task, conf) and add 
something like taskPublishesConf(task, conf)

>>
>> I also think some consistency between modelling the consumers of a 
>> configuration and the producers of a configuration would help 
>> understandability.
>>
>
> Configurations in Ivy have two aspects. One is internal for a project, 
> like compile, testCompile, etc which are needed for building the 
> project. The other aspect is an external one. You use configurations 
> to bundle artifacts produced by a project (like 'spi' in the example 
> above). When you talk about a producer of configurations, is this 
> equivalent to a producer of artifacts?
>
Good question. I'm talking about the task which publishes the artifacts 
for the configuration.  I guess this isn't strictly the same as the 
task(s) that produce the artifacts themselves.


Adam


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

    http://xircles.codehaus.org/manage_email

Reply via email to