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