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)?


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com

Reply via email to