On 1/06/10 10:25 AM, Jason Porter wrote:
On Mon, May 31, 2010 at 17:09, Adam Murdoch<[email protected]> wrote:
On 29/05/10 3:57 AM, Steve Appling wrote:
We would really like to resolve the issues related to circular
dependencies (GRADLE-914 in particular) sometime soon. I know this is
marked for 0.9, but so are 91 other issues. Is this something that anyone
is planning on addressing in the short term (within the next couple of
weeks)? If not, does anyone understand the underlying problem enough to
point me in the right direction?
I know of 2 problems. There may be more, but this is as far as I got:
1. The compile configuration is now transitive by default (for good or bad).
:( That blows. Should be non transitive, if you need it on your
compile path, put it there. This way I know exact what I need to
compile, not some third level transitive dependency that happens to be
there. Major sad face on this one.
I tend to agree. Ideally this is a short term solution.
An alternative to making the compile configuration non transitive is
instead to have a rule which does some static analysis of the source to
enforce that only the direct dependencies of the compile configuration
are used directly by the source. This rule might be evaluated by a
post-compilation task (against the bytecode), or even during compilation
(against the source).
The advantage of a static analysis approach is that we can use the same
mechanism to evaluate additional rules - such as, to enforce that every
dependency declared in the compile configuration must actually be used
by the source. Or to limit the use of a given dependency to a particular
source package.
Something like this might eventually evolve into a structure definition
DSL. You might be able to, for example, define which classes make up the
API of your code, and Gradle could enforce that the API is independent
of the implementation, that other projects use only the API classes, and
so on. It could use exactly the same information to determine which
classes to include in the javadoc, and to automatically generate an API jar.
But, this does highlight some awkwardness in the dependency
dsl, where the only options are to include the jar on its own or the entire
transitive closure of everything the jar might need (even though it doesn't
for the purposes of compiling a dependent project). I think we need
something more flexible here, so we can provide a better default behaviour.
This would be nice so we can get back to compile being non-transitive.
What I'd like to do is something like this:
- Assume that we've split Configuration into 2 pieces: the incoming
dependencies and the outgoing publications. Publications are the things
that end up being published to the repository and in the generated
pom.xml or ivy.xml
- Each java project has 2 publications: An 'api' publication and a
'runtime' publication.
- The api publication represents the artifacts that a dependent project
needs in order to compile against the project. This would by default
contain only the jar of the project (or only the api jar of the project,
if such a thing exists)
- The runtime publication represents the artifacts that the project
needs in order to be used at runtime. This would by default contain the
jar of the project, plus all the runtime dependencies.
- It will be possible (and easy) to alter the publications: You will be
able to add new publications, and add jars, artifacts, dependencies, and
other publications to a given publication. There also be some way to
control how a given publication is mapped to a given dependency
descriptor (pom.xml, ivy.xml, manifest.mf, etc).
- A compile dependency would include all the artifacts from the api
publication of the target project at compile time and all the artifacts
from the runtime publication of the target project at runtime.
- A runtime dependency would include all the artifacts from the runtime
publication of the target project at runtime.
- The above would work the same way for external dependencies. A
dependency with a Gradle published ivy.xml would use the api and runtime
configurations declared in the ivy.xml. A dependency with a pom.xml
would treat the compile scope as the api publication and the runtime
scope as the runtime publication. A dependency with an ivy.xml would
treat the non-transitive default configuration as the api publication
and the transitive default configuration as the runtime publication.
What this means is that, by default, things work as they did when
compile was not transitive. However, this also gives the publishing
project the ability to declare the things which make up its API, and
allow all dependent project to just pick that up without having to
repeat this information in their dependency declarations. Also, it
introduces an important concept to the Gradle domain model: that a java
project has an API.
--
Adam Murdoch
Gradle Developer
http://www.gradle.org
CTO, Gradle Inc. - Gradle Training, Support, Consulting
http://www.gradle.biz
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email