On Jan 8, 2009, at 8:11 PM, Adam Murdoch wrote:
Hans Dockter wrote:
I have the following plan for refactoring inter-project dependencies.
- For the project other projects depend on:
For every configuration that contains artifacts to be published,
Gradle creates a 'publish<ConfigurationName>Artifacts' task (just a
working name) belonging to this configuration. This task published
the project artifacts (i.e. the archives _produced_ by this
project) to the internal repository.
- For the projects dependent on other projects
Configuration objects will also be tasks. Executing such a task has
one and only one purpose: To make sure that all artifacts of the
configuration exists. For external artifacts we have to assume that
they exists. For internal artifacts (i.e. project dependencies) we
have to build them. If a configuration task has only external
dependencies, executing the task does nothing. If a project
dependency is added to a configuration, this will create a
dependsOn relation between the configuration task and the
'publish<ConfigurationName>Artifacts' task of the other project.
The existing configuration API works as before.
Generally, I think this would be an excellent thing to do. I have a
couple of concerns with the details:
- I don't think Configuration should be a Task (ie Configuration
extends Task). I think it would be much better if Configuration has-
a resolve Task (ie compose rather than inherit). This keeps it
consistent with the fact that Configuration also has-a publish task.
Also, this would allow me to more easily swap in my own
implementation for either the configuration or the resolve task.
- Currently in our plugins we have, for example, a 'compile'
configuration and a 'compile' task. We're going to have to choose a
different name for one of these if we add a resolve task. Perhaps
the resolve task should be called something like
'resolve<ConfigName>Artifacts'.
I wonder if we even need the resolve task. Provided that
Configuration has an associated TaskDependency implementation, we
can add the TaskDependency to the dependsOn set for tasks which use
the configuration. The TaskDependency would return the set of
publish tasks for the project dependencies in the configuration.
This is an excellent idea.
We could simply add two properties to a configuration (let's not care
about the naming right now).
List projectDependenciesConfigurations
Task publishProjectArtifactsTask
For any interested reader: A configuration can have two roles. One is
to produce project artifacts to be used by a dependent project. The
other is to resolve project artifacts of projects it depends on. Not
every configuration has two roles, they may have only one of this role
or none. In this case the lists above are empty.
Now, if an archive task in a project is created, Gradle adds it to the
publishProjectArtifactTask of the corresponding configuration. If you
assign a project dependency to a configuration, the configuration of
the project the project depends on, is added to the
projectDependenciesConfigurations.
Let's introduce now a convenience method for a configuration like
buildDependentProjects which returns a TaskDependency with the
publishProjectArtifactTasks of the projectDependenciesConfigurations.
Then you can do:
dependencies {
compile "junit:junit:4.4", project(':api")
}
createTask('printDependencies', dependsOn:
dependencies.compile.buildDependentProjects) {
println(dependencies.compile.resolve())
}
- Hans
With this we can get rid of the ugly linkConfWithTask mechanism.
Our API will become lighter and easier to understand. If a user
wants to resolve a configuration with project dependencies in her
own task, she can do:
dependencies {
compile "junit:junit:4.4", project(':api")
}
createTask('printDependencies', dependsOn: dependencies.compile) {
println(dependencies.compile.resolve())
}
I really like the fact that I can depend on a Configuration directly.
What would happen for a call to Configuration.resolve() when its
resolve task has not been executed?
It also solves a problem Adam has pointed out a while ago, that
right now all the artifacts of the dependent project are build.
With the above approach only the artifacts belonging to the
configuration are build.
- Hans
--
Hans Dockter
Gradle Project lead
http://www.gradle.org
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
--
Hans Dockter
Gradle Project lead
http://www.gradle.org
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email