On 27/10/2012, at 7:25 AM, Adam Murdoch wrote:

> 
> On 26/10/2012, at 8:12 PM, Luke Daley wrote:
> 
>> The spec for publication 
>> (https://github.com/gradle/gradle/blob/master/design-docs/publication-model.md)
>>  treats a repository that is something that is used for both consumption and 
>> publication.
>> 
>> I want to explore this a little to make sure it's right. Something about it 
>> makes me uneasy, but I can't construct a really solid argument as to why. So 
>> I'm just going to walk through the concepts to see if we all agree it makes 
>> sense.
>> 
>> The proposed model has the following components:
>> 
>> 1. Resolver - can be used to find/retrieve artifacts from somewhere
>> 2. Publisher - can be used to transfer artifacts to somewhere
>> 3. Repository - A description of “somewhere” and how to access it, can 
>> provide a Resolver and/or a Publisher
>> 
>> From a DSL/user POV, only Repository is exposed. Users configure Repository 
>> objects for the purpose of resolving *and* publication. Resolver and 
>> Publisher may be public one day, but this would be part of the extension API 
>> for plugging in new “somewhere” types.
>> 
>> There's an assumption in here that:
>> 
>> 1. The exact same set of information that needs to be configured for 
>> resolving is the same that is needed for publication, or
>> 2. Repository types expose certain configuration that is particular to 
>> resolving or publication
>> 
>> Some questions:
>> 
>> 1. What would we do when you consume via http, but publish via sftp (to the 
>> same somewhere)? Are these two different Repository objects?
>> 2. What if I consume over http, but publish over https (with everything else 
>> being the same)?
>> 3. When would we ever reuse the same Repository object for consumption and 
>> publication?
>> 
>> 
>> It feels like we have something missing here. That is, I think Repository is 
>> the wrong commonality here. What is common is how to determine the address 
>> that some artifact should be found at (for consumption or publication), 
>> which is something like a Layout I think.
>> 
>> The only thing I see that converging on Repository gives us is DSL 
>> consistency in two different spaces, but I also see this as a risk in that 
>> we need to make this DSL coherent for both cases.
>> 
>> 
>> Also, who says we are publishing to a consumable repository? What if 
>> publication means calling a SOAP web service and we have no need of ever 
>> consuming from this guy for resolution? We'd have to have a Repository impl 
>> with the Resolver part empty.
> 
> I wouldn't necessarily model this case as a repository. All we need for 
> publishing is something that can be converted to a Publisher, and all we need 
> for resolving is something that can be converted to a Resolver. So, we might 
> keep Repository as something that can do both, and introduce new types that 
> may or may not be related to Repository to represent a read-only source and a 
> write-only destination.
> 
> There are 3 basic approaches we can take here:
> 
> * A Repository type with optional publish and resolve operations. Convert to 
> a Resolver when resolving and a Publisher when publishing.
> * A ResolvableRepository that can resolve, and a PublishableRepository that 
> can publish. Convert to a Resolver when resolving and a Publisher when 
> publishing.
> * Both of the above.

To clarify this a bit:

The first approach is to say: There is a thing called a (binary artefact) 
repository that hosts binary artefacts. It has zero or one endpoints for 
pushing artefacts to, and it has zero or more endpoints for retrieving 
artefacts from. When an artefact is pushed to the publish endpoint, it will be 
visible via the retrieve endpoints. The goal of publishing artefacts to a 
repository is so that they can be retrieved again later by some other build.

The second approach is to say: There's no such thing as a repository. There are 
publish endpoints that we can push artefacts to, and resolve endpoints that we 
can retrieve artefacts from. It's a coincidence, and irrelevant, that artefacts 
pushed to a given publish endpoint might be visible via some other endpoint. 
The goal of publishing artefacts to an endpoint is so that they can be reused 
in some unspecified, and irrelevant, way.

The first approach does a better job of describing reality. The second approach 
does a better job of adapting to publishing to new kinds of destinations.

Why might it be useful to model repositories? In the general sense, the closer 
the model is to reality, the more interesting things that we haven't thought of 
yet we can do in the future. For example, if we know that we're going to later 
be resolving artefacts from the same repository that we're publishing to, we 
can also copy the artefacts to our artefact cache, ready to go at resolve time. 
This would be quite useful for CI build machines. There will be other, as yet 
undiscovered, useful ways we can use this information.

The third approach is to say: To best capture reality and allow us to do 
interesting things, our model should describe reality as closely as possible. 
The reality for a vast majority of builds is that there is a repository that 
artefacts are both retrieved from and published to. To allow for future kinds 
of destinations, our infrastructure and services should care only about 
retrieve and publish endpoints. So, different views for different consumers of 
the information.


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