On Tue, Jun 1, 2010 at 23:20, Adam Murdoch <[email protected]> wrote: > > > 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).
Interesting idea. Sounds really good in theory, in practice though I think it would add unnecessary time to a build (unless of course we're able to get Gradle so fast it doesn't matter). If it's a large build I think it could be really devastating. If this were to be implemented there should be an easy way to opt-out of it. Thought I just had: Would it be possible to do some basic static analysis pre-compile and separate out the compilation into individual parallel steps so you could parallelize your compile step? It may not be that great for smaller projects, but may very well be a huge win for larger / multi project builds. WDYT? > 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. This sort of thing is much more helpful to people building frameworks and other reusable components, but for an application developer (something that isn't necessarily consumed by other projects) it's less useful. >>> 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. I really like this idea, it plays nice with ivy and maven metadata artifacts. This is probably the direction it should go. It would be really awesome to only define your dependencies once and let Gradle figure out what's runtime and what's compile time, this would be a huge win IMO, though maybe that's a little over ambitious idea :) I could easily see the static analysis happening for this to determine what to put in which scope / configuration for your project's publications. > > -- > 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 > > > -- Jason Porter Software Engineer Open Source Advocate PGP key id: 926CCFF5 PGP key available at: keyserver.net, pgp.mit.edu --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email
