On 30/08/2013, at 7:38 AM, Adam Murdoch <adam.murd...@gradleware.com> wrote:
> > On 30/08/2013, at 6:39 AM, johnrengelman <john.r.engel...@gmail.com> wrote: > >> I've gone back to the drawing board and came up with a simpler solution where >> in ExternalResourceResolver >> I check for any artifact existing and then only mark the artifact as >> resolved by that repository if one is found. > > We want to behave differently in this case for the Maven cache compared to > arbitrary repository. It's expected in the Maven cache for an artefact to be > missing, but it means a badly formed module everywhere else. > > I think we want something like this: > > 1. If we find a pom and no artifact in the Maven cache > * If we can find the module in some other repository, silently ignore > the stuff in the Maven cache and use the module from the other repository. > * If we cannot find the module in some other repository, fail with an > 'artefact missing' exception. > 2. If we find a pom and no artefact in some repository, fail with an > 'artefact missing' exception. > > Or, perhaps it might be nicer in #2 if we warn instead of fail when we can > find the module in another repository. > > Regardless of exactly what we do here, it's not the resolvers responsibility > to decide whether to fail or continue the search. Instead, it should just > communicate what it found, so that `UserResolverChain`, which is coordinating > the search, can take care of stopping or continuing or whatever. To do this, > we might add some new states to > `BuildableModuleVersionMetaDataResolveResult`, so that the resolver can let > the search algorithm know that it found a badly formed or partial module. Thinking about this a little more: There are some performance implications here, in that we'd be probing whether remote artefacts exist before we know whether we need them, or which artefacts we need. For example, the module version may later be evicted by conflict resolution, in which case the question of whether the artefact exists or the module is badly formed is not really relevant. Or, a more interesting example: my-lib:1.2 depends on other-lib:1.4@jar and my-lib:1.3 depends on other-lib:1.4@zip. If conflict resolution chooses my-lib:1.3, then we only care if the zip exists. Similarly, there are some usability implications, in that we'd be failing or complaining about broken things before we know whether we need them or not. So, I think we want an algorithm something like this: To resolve the metadata for a dependency: 1. ExternalResourceResolver.getDependency() does not check the artefacts. It only considers the meta-data. 2. UserResolverChain stops as soon as something finds the meta-data for a dependency, in the case of a static dependency. For a dynamic dependency it queries all resolvers and selects the 'best' match. That is, we stop as soon as we think we have the meta-data for a module. The graph is then resolved, and we lock down exactly which versions and artefacts we need. Then, to resolve an artefact: 1. UserResolverChain uses the resolver which found the meta-data for the selected version. 2. If found, then we're finished. 3. If not found, and this is not a Maven cache, then fail (or maybe warn and continue on). 4. Otherwise, search in the other repositories for the selected version: 1. Fetch the meta-data for the selected version. If not found, continue to the next repository. 2. Compare the meta-data with that from the original repository. If it is different, then fail (or maybe warn an continue on). 3. Fetch the artefact. If not found, then fail (or maybe warn and continue on). That is, we prefer the repository where we found the meta-data, but we can deal with a partial module and look for a copy elsewhere. For now, I wouldn't bother with trying to generalise this, and would go with something like your original plan: 1. For a Maven cache, if the pom exists and there are no other artefacts and the packaging is not pom, then mark the module as 'not found' (and maybe log an info or debug message informing the user of that fact). 2. For everything else, do not check whether the artefacts exists or not. If the meta-data is found, then the module must be used. -- Adam Murdoch Gradle Co-founder http://www.gradle.org VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting http://www.gradleware.com Join us at the Gradle eXchange 2013, Oct 28th in London, UK: http://skillsmatter.com/event/java-jee/gradle-exchange-2013