On Dec 11, 2012, at 6:37 AM, Adam Murdoch <[email protected]> wrote:
> > On 11/12/2012, at 10:34 AM, Hans Dockter wrote: > >> >> On Dec 11, 2012, at 12:03 AM, Adam Murdoch <[email protected]> >> wrote: >> >> <snip> >> >>>>> >>>>> The obvious downside here is that version is required for a project >>>>> dependency, but version is almost always a calculated value. Another >>>>> downside is that projects already have a convenient identifier in their >>>>> path, whereas this approach would require a project to define an >>>>> additional identifier. >>>> >>>> This is also about expressiveness. Despite the fact that the difference >>>> between external libraries and project dependencies is fuzzy from an >>>> organizational point of view there is often a big difference. So it is >>>> nice to easily see the from an organization point of view different types >>>> of dependencies. >>> >>> Not sure what you mean here. >> >> Right now a reader of the build script can easily distinguish between >> project dependencies and external ones. This is not unimportant. There is >> the organizational difference between code my team/company is working on vs. >> classical libraries. Having a single notation wouldn't be very expressive in >> regard to this. > > Ok, I understand. This is a very good point. > >> With your proposal below you can have the expressiveness you want to >> distinguish different types of dependencies in your build. >> >>> >>>> >>>>> >>>>> 2. References to locally built things and things in a repository share a >>>>> new namespace. Every dependency declaration would use a single >>>>> identifier, and there would be a separate mapping, shared by all the >>>>> projects, from identifier to (group, module, version) or project. >>>>> >>>>> The idea here is that we also deal with the 'dependencyManagement' use >>>>> case as well, so that you define (group, module, version) in one place >>>>> and use a simple name everywhere that you need to refer to the >>>>> dependency. This is, in practise what larger builds do already, so it's >>>>> not necessarily more 'complicated'. >>>>> >>>>> allprojects { >>>>> modules { >>>>> someRepoThing 'my.org:some-repo-thing:1.2' >>>>> } >>>>> } >>>>> >>>>> dependencies { >>>>> compile someRepoThing >>>>> runtime someLocalThing // Probably some default rule to look for a >>>>> locally built component called 'someLocalThing' >>>>> } >>>>> >>>>> The obvious downside here is that you need to extra work if the >>>>> dependency is not reused. Plus it means every dependency declaration in >>>>> every Gradle build script in existence would need to change. >>>>> >>>>> 3. A combination of the above, so that all dependency declarations refer >>>>> to things using (group, component, version), but group and version are >>>>> optional. If not specified, we look for a mapping from component name to >>>>> (group, component, version) or (project, component). We'd have some place >>>>> where you can register these mapping to things in repositories, and >>>>> probably also have a default mapping where we look for a locally built >>>>> component with the given name and same group as the referring project. >>>>> >>>>> allprojects { >>>>> dependencies.modules { >>>>> junit "junit:junit:4.11" >>>>> } >>>>> } >>>>> >>>>> dependencies { >>>>> compile "com.google.guava:guava:13" >>>>> testCompile "junit" // or perhaps ":junit:" - maps to >>>>> "junit:junit:4.11" >>>>> testCompile "junit:4.8.2" // maps to "junit:junit:4.8.2" >>>>> runtime "some-local-thing" // default rule maps to component >>>>> 'some-local-thing' built by another project >>>>> } >>>>> >>>>> For me, this one is almost all upsides. It gives me a unified way to >>>>> refer to things, using (if I like) a simple name, and a place to define >>>>> meta-data about external things in a single place (such as, every >>>>> dependency to 'junit' should use 'junit:junit:4.11' unless otherwise >>>>> specified, or "my-lib" uses semantic versioning, or "groovy-all" >>>>> conflicts with "groovy", etc). It also gives me a point where I can put >>>>> logic in to influence whether a given dependency declaration is mapped to >>>>> a locally built thing or a thing in a repository. >>>> >>>> I like this very, very much. >>>> >>>>> >>>>> One major downside is that every project dependency in the world would >>>>> need to be changed, because project dependencies would go away (via a >>>>> long period of deprecation). >>>> >>>> They wouldn't necessarily need to go away. We should easily be able to map >>>> them as long as we want. >>> >>> If they don't go away, then you're really talking about option 4. below. >>> The point of option 3. is that there is exactly one way to express a >>> dependency and it's a separate mapping step as to whether that ends up >>> pointing to something external or something local. >> >> What I mean is that we can treat the 'old' notation as syntactic sugar and >> translate it internally to the new mechanism. This would not provide 100 >> percent the same behavior but possibly be good enough backwards >> compatibility wise after a next major release. > > Ok. This is an option. Would using a project dependency mean that there must > be a project on the other end (ie you can't substitute an external thing in > instead)? Or would using a project dependency mean that there is usually a > project on the other end, but might not be (ie you can substitute an external > thing in)? I guess the focus at that point should be to enable the power of the new mechanism instead of trying to reproduce the old inflexibility. So I would say you can substitute an external thing in. Hans
