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

Reply via email to