On 30/01/2013, at 10:09 PM, Luke Daley wrote: > > On 28/01/2013, at 10:37 PM, Adam Murdoch <[email protected]> wrote: > >> >> On 28/01/2013, at 9:54 PM, Luke Daley wrote: >> >>> >>> On 24/01/2013, at 4:17 AM, Adam Murdoch <[email protected]> wrote: >>> >>>> >>>> On 24/01/2013, at 12:57 AM, Luke Daley wrote: >>>> >>>>> >>>>> On 17/01/2013, at 11:54 PM, Adam Murdoch <[email protected]> >>>>> wrote: >>>>> >>>>>> >>>>>> On 17/01/2013, at 11:20 PM, Luke Daley wrote: >>>>>> >>>>>>> What's the relationship between a component and a “functional source >>>>>>> set”? >>>>>> >>>>>> It varies. The model would be something like this: >>>>>> >>>>>> - A component is physically represented using one or more packagings. >>>>>> - A packaging is built from one or more input build items. >>>>>> - A packaging is a build item. >>>>>> - A (functional) source set is a build item. >>>>>> >>>>>> So, for a Java library, it'd look like this: >>>>>> >>>>>> production source set ---> production class packaging ---> production >>>>>> jar packaging >>>>>> >>>>>> Add in some test fixtures: >>>>>> >>>>>> production class packaging ---+ >>>>>> +---> test fixture class packaging ---> test >>>>>> fixture jar packaging >>>>>> test fixture source set ------+ >>>>>> >>>>>> Maybe add some source and docs: >>>>>> >>>>>> +---> api doc packaging >>>>>> production source set --+ >>>>>> +---> source packaging >>>>>> >>>>>> The production jar, test fixture jar, api doc and source packagings are >>>>>> all aspects of the Java library component. >>>>>> >>>>>> For a C library, it might look like this: >>>>>> >>>>>> production source set --+--> windows 32bit shared lib packaging >>>>>> +--> windows 32bit static lib packaging >>>>>> +--> linux 64bit shared lib packaging >>>>>> +--> … >>>>>> >>>>>> Each of these platform-specific packagings, along with the API docs and >>>>>> source packagings, are all aspects of the component. >>>>> >>>>> The term “packaging” really starts to break down here. It seems intuitive >>>>> to say that a classes dir and a jar are the same thing packaged >>>>> differently, but if you try and say that javadoc is another type of >>>>> packaging it doesn't feel natural. >>>>> >>>>> I originally took you to mean that different packagings were functionally >>>>> equivalent, but required different methods of consumption. >>>> >>>> That's what I meant. The stuff above isn't quite right. All of the things >>>> above are build items. Some of them are ways of packaging a component (ie >>>> a packaging is-a build item). >>>> >>>>> It seems that you're using it in a more general sense, something closer >>>>> to “facet”. The javadoc and the class files are different facets of the >>>>> same logical entity. >>>>> >>>>> So maybe components have facets, and a facet can be packaged in different >>>>> ways. >>>> >>>> We've been calling this a 'usage'. That is, there are a number of ways you >>>> can use a given type of component, and a given usage implies one or more >>>> (mutually exclusive) packagings: >>>> >>>> * One such usage might be to read the API documentation for the component, >>>> where the API docs can be packaged as a directory of HTML, or a ZIP file >>>> or a PDF. >>>> * Another might be to compile some source against it (to build a windows >>>> 32 bit debug binary), where the headers can be packaged as a directory of >>>> headers. Or as a ZIP, or in a distribution. >>>> * Another might be to link a binary against it (to build a windows 32 bit >>>> debug binary), where the library is packaged as a .lib or a .so file, >>>> depending on platform. >>>> * Another might be to link it at runtime (into a windows 32 but debug >>>> executable), where the library is packaged as a .dll or a .so, depending >>>> on the platform. >>> >>> This doesn't get around the problem that you are calling the API docs a >>> “packaging”, and that in that case two different packagings of the same >>> logical entity are not functionally equivalent. >> >> Not quite. There are two entities here: the executable library and the api >> documentation. And each entity has a different set of packagings. So the >> executable thing can be packaged as a jar or a classes directory or a shared >> native library or whatever, and the documentation thing can be packaged as >> html or pdf or a zip of html or whatever. > > So a component has one or more variants, that has one or more usages, that > has one ore more packagings? > >> I think the question here is how the executable thing and the documentation >> thing relate to each other, and to the library as a whole. Is the library >> just a composite thing, so that a library has-a executable part and has-a >> api documentation part? And the packaging for a library would have-a set of >> executable packaging and have-a set of documentation packagings. > > I think we want to avoid creating a bounded set of usages, and abstracting > too much. A library simply has many usages. > > As a thought experiment, I'd like to propose an approach based on RDF (the > graph based data model of SemWeb) modelling > > Inherent in RDF is the idea that you cannot get models right unless they are > trivially simple, and then they are of limited utility. The solution to this > problem is to somewhat flip the problem around. Instead of trying to predict > what information needs to be captured to make sense of the data in different > contexts, just collect what you know about the data as facts. In order to > make sense of the data in different contexts, you insert connecting facts > that allow you to draw new inferences. This allows you to effectively change > the model over time, after the fact. It's also more likely that you can > effectively collect facts from the start than model effectively. > > In practical terms, this might mean that we change how we are thinking about > this a little. > > This would be like saying that we have the logical concept of a component. A > component has one or more physical manifestations (packaging) and there are > facts we know about each packaging (e.g. is javadoc, minimum jdk version, is > source, is a jar, has debug symbols, compiled for this architecture). > Packagings can also be related to each other through these facts (this is the > source for that). > > When we need to query to find certain things, we can inject new facts to > create inferences. For example we can inject that jars and directories of > class files are executable (in a sense). We can inject that javadoc is > documentation. More generally, we inject facts about the facts that give the > data shape for our context. This is challenging just like up front modelling, > but the benefit is that it is more malleable and flexible over time. The > facts rarely change, but how you make sense of them does.
It doesn't really seem like this is any different to what we're doing already. What we're putting together here is a meta-model, that states facts about what a model must describe in order to be understood by Gradle. In parallel with that, we're putting together a number of separate models that conform to this meta-model: 1. An abstract model of the things that we use for resolving. Our infrastructure uses this model to resolve things for consumption. 2. An abstract model of the things that we use for building. Our infrastructure uses this model to build things. 3. A set of concrete models that describe certain specific domains, such as things that run on the JVM or native binaries or reports or tests or whatever. The models are there so that various parties can collaborate, if they choose to. If you want to use our dependency resolution, you need to describe the world using our resolution model. Generally, you would do that by translating from some other source model. We don't really care what that other model is. There may be multiple such models. Often it will be one of the concrete models we provide, but doesn't have to be. If the source model conforms to our meta-model, then we can automate the translation for you. If it doesn't, you need to translate it yourself. Similarly for building things. If you want us to help you build stuff, then you need to describe these things in our build model. Again, you would usually do this by translating from some source model or models. The concrete models are about collaborating not just with Gradle, but also with other parties, such as the consumers of your software, plugin authors, tooling integrators, other parts of your organisation, and so on. Because they are concrete, they are also much simpler to use. You can opt in or opt out of using these models. You can define your own, and if they conform to the meta-model, we can translate them for you. Over time, these models, including the meta-model, will change, and will be versioned. While not necessarily represented as (subject, predicate, object), it will certainly be possible to take an object described in one of these models and translate it to such a description, if you care to consume it that way. As far as encoding these models goes, there will be multiple sources: Gradle domain objects, publication descriptors, rules, Java classes + annotations, etc. We don't really care where the model comes from or how it is translated to the model that we consume. -- Adam Murdoch Gradle Co-founder http://www.gradle.org VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting http://www.gradleware.com
