On 28/06/2012, at 11:40 AM, Daz DeBoer wrote: > For java code, it seems like there are at least 2 axes that could contribute > to the artifact 'type': > 1) client vs api vs test vs core > 2) code vs source vs javadoc > > Would these all be wrapped up under the single concept of 'type'? It seems > like they are both valuable things to model explicitly.
Right. We should treat them separately. The idea is that an artefact's type defines the format of the artefact, and how the artefact can be used. A jar, for example, can really only be used in a classpath. A set of c++ headers can really only be used for c++ compilation. The artefact type doesn't say anything about the purpose of the artefact, just its format. It doesn't answer: what's the meaning of the stuff inside the artefact? ie. which class paths does this particular jar belong in? My thought was to model this at the component level, rather than the artefact level. A component type would have a set of 'usages' associated with it. A usage would imply a set of zero or more of the component's artefacts plus a set of zero or more dependencies on other components. We could potentially model this at the artefact level as well, as the artefact's 'purpose'. For a given artefact, there is a many-to-many relationship with the places it needs to be used. For example, if I package my component in a single jar, then that jar must be included in the consumer's compile classpath, runtime classpath, test compilation classpath, and so on. If I package my component as an api jar + impl jar, then the api jar must be included in the consumer's compile classpath, both jars in the runtime classpath, and so on. The question is whether a source or javadoc artefact is a 'format' or a 'purpose'. I'd say it's both: a source zip has a particular format (i.e. it's a zip), and a particular purpose (i.e. it contains source). You could package up the source in any archive format and still have a source artefact (e.g. as a tgz in for a c++ based component). > Daz > > On 19 June 2012 16:59, Adam Murdoch <[email protected]> wrote: > Hi, > > There are a couple of dependency management issues we want to fix by > introducing the concept of an artefact type. > > Currently, artefacts are opaque generic things that we know nothing about. > Which means we can't do anything particularly useful other than copy them > around or download and plonk them in a cache directory. There are some > problems with this: > * Native executables need to follow a particular platform-specific naming > scheme (or at least, should) and need to have the execute bit set. > * Native libraries need to follow a particular platform-specific naming > scheme, and the name should honour the soname/install_path baked into the > binary. > * Some types of artefacts, such as c++ headers or javascript source files or > api documentation, need to be arranged in a particular hierarchy relative to > each other (or, some artefacts represent a file tree, rather than a file). > * There's no well-defined way to find the source and documentation of a > component that we're using. > * There's no good identifier for an artefact. Currently, you can use any > attribute from the union of those supported by ivy and maven. Which means > that you have to couple your dependency declarations to how the dependency > happens to be published. > > Instead, I think we want to change things so that we explicitly model > artefact types and define a set of well-known types. > > 1. An artifact will have a name and a type. > 2. The artefact (name, type) must be unique for a given module. > 3. The artefact extension and classifier attributes will be deprecated and > removed from our DSL. > 4. When publishing to an Ivy repository, the type will be used to map the > name to an Ivy artefact with (name, extension, type, m:classifier), which > then feeds into the artefact pattern to end up with a destination location > for the artefact. > 5. When publishing to a Maven repository, the type will be used to map to > name to a Maven artefact with (artifactId, extension, classifier), which then > is used to determine the destination location for the artefact. > > Things get more interesting when resolving. > > A Maven dependency declaration has a 'type' attribute associated with it, > which defaults to 'jar'. Maven maps this type to an (extension, classifier) > that it uses to look for the target artefact. One question is how we > interpret the type attribute. Do we: > * Map (group, artifactId, version, type) to Gradle module (group, artifactId, > version) and artifact (name, type), then do an exact match on the name + type > from the artefacts of the target module? > * Map (group, artifactId, version, type) to Gradle module (group, artifactId, > version) and artefact type, then select the artefacts of the target module > that have the specified type? > > The result will be the same when the dependency resolves to a module in a > maven repository. It may be different when the dependency resolves to a > module in an ivy repository. I think the second option works better, as it > gives the consumer the opportunity to state what type of things it is after, > and the producer the opportunity to decide how the artefacts are structured. > > Another question is how we interpret a missing type attribute in a maven > dependency declaration. Do we: > * Always look for artefacts of type 'jar'? > * Look for artefacts of a type that is specific to the resolve we're doing? > That is, look for jars when resolving the Java compile classpath, look for > c++ headers when resolving the C++ compile paths, and so on. > > I like the second option, but it's probably not the right way to go here. It > might be useful, in that it would allow us to publish single variant non-jar > projects to an existing maven repository and consume these Gradle-produced > artefacts from another Gradle build via the Maven repository. > > An ivy dependency declaration allows you to request one or more artefacts > identified by (name, type, extension). We would map the (type, extension) to > a Gradle artefact type, and then back to the repository specific type when > looking for the artefact in a particular repository. > > An ivy dependency also allows you to filter the artefacts by name, type > and/or extension. We would map the repository specific type to an ivy > artefact type and apply the filters. > > What this means is that, except for some adapters in the resolver, our > resolve and publish code would deal with the Gradle concept of an artefact > rather than the merged Ivy + maven concept that we use now. We would also > expose the Gradle artefact in the resolve results. > > > -- > Adam Murdoch > Gradle Co-founder > http://www.gradle.org > VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting > http://www.gradleware.com > > > > > -- > Darrell (Daz) DeBoer > Principal Engineer, Gradleware > http://www.gradleware.com > -- Adam Murdoch Gradle Co-founder http://www.gradle.org VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting http://www.gradleware.com
