make default conflict manager ignore force

see comment on IvySbt.latestNoForce
This commit is contained in:
Mark Harrah 2011-03-16 20:10:41 -04:00
parent ac280e5fe7
commit b1d39404a1
1 changed files with 38 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import Artifact.{defaultExtension, defaultType}
import java.io.File
import java.util.concurrent.Callable
import java.util.{Collection, Collections}
import org.apache.ivy.{core, plugins, util, Ivy}
import core.IvyPatternHelper
@ -14,7 +15,10 @@ import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager}
import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact}
import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor}
import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId}
import core.resolve.IvyNode
import core.settings.IvySettings
import plugins.conflict.{ConflictManager, LatestConflictManager}
import plugins.latest.LatestRevisionStrategy
import plugins.matcher.PatternMatcher
import plugins.parser.m2.PomModuleDescriptorParser
import plugins.resolver.ChainResolver
@ -44,7 +48,7 @@ final class IvySbt(val configuration: IvyConfiguration)
// Ivy is not thread-safe nor can the cache be used concurrently.
// If provided a GlobalLock, we can use that to ensure safe access to the cache.
// Otherwise, we can at least synchronize within the JVM.
// For thread-safety In particular, Ivy uses a static DocumentBuilder, which is not thread-safe.
// For thread-safety in particular, Ivy uses a static DocumentBuilder, which is not thread-safe.
configuration.lock match
{
case Some(lock) => lock(ivyLockFile, new Callable[T] { def call = action() })
@ -55,6 +59,7 @@ final class IvySbt(val configuration: IvyConfiguration)
{
val is = new IvySettings
is.setBaseDir(baseDirectory)
is.setDefaultConflictManager(IvySbt.latestNoForce(is))
configuration match
{
case e: ExternalIvyConfiguration => is.load(e.file)
@ -392,4 +397,36 @@ private object IvySbt
case Some(confs) => confs.map(_.name).toList.toArray
case None => module.getPublicConfigurationsNames
}
// same as Ivy's builtin latest-revision manager except that it ignores the force setting,
// which seems to be added to dependencies read from poms (perhaps only in certain circumstances)
// causing revisions of indirect dependencies other than latest to be selected
def latestNoForce(settings: IvySettings): ConflictManager =
{
import collection.JavaConversions._
new LatestConflictManager("latest-revision-no-force", new LatestRevisionStrategy)
{
setSettings(settings)
override def resolveConflicts(parent: IvyNode, conflicts: Collection[_]): Collection[_] =
if(conflicts.size < 2)
conflicts
else
resolveMultiple(parent, conflicts.asInstanceOf[Collection[IvyNode]]).asInstanceOf[Collection[_]]
def resolveMultiple(parent: IvyNode, conflicts: Collection[IvyNode]): Collection[IvyNode] =
{
val matcher = settings.getVersionMatcher
val dynamic = conflicts.exists { node => matcher.isDynamic(node.getResolvedId) }
if(dynamic) null else {
try {
val l = getStrategy.findLatest(toArtifactInfo(conflicts), null).asInstanceOf[{def getNode(): IvyNode}]
if(l eq null) conflicts else Collections.singleton(l.getNode)
}
catch { case e: LatestConflictManager.NoConflictResolvedYetException => null }
}
}
}
}
}