mirror of https://github.com/sbt/sbt.git
Revert chain resolver by default, for older behavior.
The issue comes into play where we cannot accurately get a publication date from Maven artifacts, leading to the current mechanism having undefined behavior and causing other bugs to pop up in resolution.
This commit is contained in:
parent
01f098cd28
commit
1a38b6902e
|
|
@ -46,7 +46,7 @@ object UpdateOptions {
|
||||||
def apply(): UpdateOptions =
|
def apply(): UpdateOptions =
|
||||||
new UpdateOptions(
|
new UpdateOptions(
|
||||||
circularDependencyLevel = CircularDependencyLevel.Warn,
|
circularDependencyLevel = CircularDependencyLevel.Warn,
|
||||||
latestSnapshots = true,
|
latestSnapshots = false,
|
||||||
consolidatedResolution = false,
|
consolidatedResolution = false,
|
||||||
cachedResolution = false)
|
cachedResolution = false)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,12 +57,20 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting
|
||||||
// and if a previously resolved or cached revision has been found.
|
// and if a previously resolved or cached revision has been found.
|
||||||
def doGetDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision =
|
def doGetDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision =
|
||||||
{
|
{
|
||||||
|
// useLatest - Means we should always download the JARs from the internet, no matter what.
|
||||||
|
// This will only be true *IF* the depenendency is dynamic/changing *and* latestSnapshots is true.
|
||||||
|
// If you find multiple candidates,
|
||||||
|
// - If `isReturnFirst` is true, you return the first value found
|
||||||
|
// - If not, we will ATTEMPT to look at the publish date, which is not correctly discovered for Maven modules and
|
||||||
|
// leads to undefined behavior.
|
||||||
val useLatest = (dd.isChanging || (IvySbt.isChanging(dd.getDependencyRevisionId))) && updateOptions.latestSnapshots
|
val useLatest = (dd.isChanging || (IvySbt.isChanging(dd.getDependencyRevisionId))) && updateOptions.latestSnapshots
|
||||||
if (useLatest) {
|
if (useLatest) {
|
||||||
Message.verbose(s"${getName} is changing. Checking all resolvers on the chain")
|
Message.verbose(s"${getName} is changing. Checking all resolvers on the chain")
|
||||||
}
|
}
|
||||||
val data = new ResolveData(data0, doValidate(data0))
|
val data = new ResolveData(data0, doValidate(data0))
|
||||||
|
// Returns the value if we've already been resolved from some other branch of the resolution tree.
|
||||||
val resolved = Option(data.getCurrentResolvedModuleRevision)
|
val resolved = Option(data.getCurrentResolvedModuleRevision)
|
||||||
|
// If we don't have any previously resolved date, we try to pull the value from the cache.
|
||||||
val resolvedOrCached =
|
val resolvedOrCached =
|
||||||
resolved orElse {
|
resolved orElse {
|
||||||
Message.verbose(getName + ": Checking cache for: " + dd)
|
Message.verbose(getName + ": Checking cache for: " + dd)
|
||||||
|
|
@ -71,31 +79,58 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting
|
||||||
forcedRevision(mr)
|
forcedRevision(mr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default value for resolution. We use this while we loop...
|
||||||
|
// If useLatest is true, we want to try to download from the internet so we DO NOT start with a valid value.
|
||||||
var temp: Option[ResolvedModuleRevision] =
|
var temp: Option[ResolvedModuleRevision] =
|
||||||
if (useLatest) None
|
if (useLatest) None
|
||||||
else resolvedOrCached
|
else resolvedOrCached
|
||||||
|
// Cast resolvers to something useful. TODO - we dropping anything here?
|
||||||
val resolvers = getResolvers.toArray.toVector collect { case x: DependencyResolver => x }
|
val resolvers = getResolvers.toArray.toVector collect { case x: DependencyResolver => x }
|
||||||
|
|
||||||
|
// Here we do an attempt to resolve the artifact from each of the resolvers in the chain.
|
||||||
|
// - If we have a return value already, AND isReturnFirst is true AND useLatest is false, we DO NOT resolve anything
|
||||||
|
// - If we do not, try to resolve.
|
||||||
|
// RETURNS: Left -> Error
|
||||||
|
// Right -> Some(resolved module) // Found in this resolver, can use this result.
|
||||||
|
// Right -> None // Do not use this resolver
|
||||||
val results = resolvers map { x =>
|
val results = resolvers map { x =>
|
||||||
// if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers
|
// if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers, just return None for this guy.
|
||||||
if (isReturnFirst && temp.isDefined && !useLatest) Right(None)
|
if (isReturnFirst && temp.isDefined && !useLatest) Right(None)
|
||||||
else {
|
else {
|
||||||
|
// We actually do resolution.
|
||||||
val resolver = x
|
val resolver = x
|
||||||
val oldLatest: Option[LatestStrategy] = setLatestIfRequired(resolver, Option(getLatestStrategy))
|
val oldLatest: Option[LatestStrategy] = setLatestIfRequired(resolver, Option(getLatestStrategy))
|
||||||
try {
|
try {
|
||||||
val previouslyResolved = temp
|
val previouslyResolved = temp
|
||||||
// if the module qualifies as changing, then resolve all resolvers
|
// if the module qualifies as changing, then resolve all resolvers
|
||||||
if (useLatest) data.setCurrentResolvedModuleRevision(None.orNull)
|
if (useLatest) data.setCurrentResolvedModuleRevision(null)
|
||||||
else data.setCurrentResolvedModuleRevision(temp.orNull)
|
else data.setCurrentResolvedModuleRevision(temp.orNull)
|
||||||
temp = Option(resolver.getDependency(dd, data))
|
temp = Option(resolver.getDependency(dd, data))
|
||||||
val retval = Right(
|
Right(
|
||||||
if (temp eq previouslyResolved) None
|
if (temp eq previouslyResolved) None
|
||||||
else if (useLatest) temp map { x =>
|
else if (useLatest) temp map { x =>
|
||||||
(reparseModuleDescriptor(dd, data, resolver, x), resolver)
|
(reparseModuleDescriptor(dd, data, resolver, x), resolver)
|
||||||
}
|
}
|
||||||
else temp map { x => (forcedRevision(x), resolver) }
|
else temp map { x => (forcedRevision(x), resolver) }
|
||||||
)
|
)
|
||||||
retval match {
|
} catch {
|
||||||
case Right(Some((rmr, _))) =>
|
case ex: Exception =>
|
||||||
|
Message.verbose("problem occurred while resolving " + dd + " with " + resolver
|
||||||
|
+ ": " + IvyStringUtils.getStackTrace(ex))
|
||||||
|
Left(ex)
|
||||||
|
} finally {
|
||||||
|
oldLatest map { _ => doSetLatestStrategy(resolver, oldLatest) }
|
||||||
|
checkInterrupted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val errors = results collect { case Left(e) => e }
|
||||||
|
val foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { case Right(Some(x)) => x }
|
||||||
|
val sorted =
|
||||||
|
if (useLatest) (foundRevisions.sortBy {
|
||||||
|
case (rmr, resolver) =>
|
||||||
|
// Just issue warning about issues with publication date, and fake one on it for now.
|
||||||
rmr.getDescriptor.getPublicationDate match {
|
rmr.getDescriptor.getPublicationDate match {
|
||||||
case null =>
|
case null =>
|
||||||
(resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match {
|
(resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match {
|
||||||
|
|
@ -112,25 +147,6 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting
|
||||||
}
|
}
|
||||||
case _ => // All other cases ok
|
case _ => // All other cases ok
|
||||||
}
|
}
|
||||||
case _ =>
|
|
||||||
}
|
|
||||||
retval
|
|
||||||
} catch {
|
|
||||||
case ex: Exception =>
|
|
||||||
Message.verbose("problem occurred while resolving " + dd + " with " + resolver
|
|
||||||
+ ": " + IvyStringUtils.getStackTrace(ex))
|
|
||||||
Left(ex)
|
|
||||||
} finally {
|
|
||||||
oldLatest map { _ => doSetLatestStrategy(resolver, oldLatest) }
|
|
||||||
checkInterrupted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val errors = results collect { case Left(e) => e }
|
|
||||||
val foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { case Right(Some(x)) => x }
|
|
||||||
val sorted =
|
|
||||||
if (useLatest) (foundRevisions.sortBy {
|
|
||||||
case (rmr, _) =>
|
|
||||||
rmr.getDescriptor.getPublicationDate match {
|
rmr.getDescriptor.getPublicationDate match {
|
||||||
case null => 0L
|
case null => 0L
|
||||||
case d => d.getTime
|
case d => d.getTime
|
||||||
|
|
@ -141,8 +157,7 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting
|
||||||
val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver)
|
val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver)
|
||||||
artifactOpt match {
|
artifactOpt match {
|
||||||
case None if resolver.getName == "inter-project" => // do nothing
|
case None if resolver.getName == "inter-project" => // do nothing
|
||||||
case None => throw new RuntimeException("\t" + resolver.getName
|
case None => throw new RuntimeException(s"\t${resolver.getName}: no ivy file nor artifact found for $rmr")
|
||||||
+ ": no ivy file nor artifact found for " + rmr)
|
|
||||||
case Some(artifactRef) =>
|
case Some(artifactRef) =>
|
||||||
val systemMd = toSystem(rmr.getDescriptor)
|
val systemMd = toSystem(rmr.getDescriptor)
|
||||||
getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef,
|
getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef,
|
||||||
|
|
@ -150,7 +165,8 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting
|
||||||
}
|
}
|
||||||
rmr
|
rmr
|
||||||
}
|
}
|
||||||
else foundRevisions.reverse.headOption map { _._1 }
|
else foundRevisions.reverse.headOption map { _._1 } // we have to reverse because resolvers are hit in reverse order.
|
||||||
|
// If the value is arleady in cache, SORTED will be a Seq(None, None, ...) which means we'll fall over to the prevously cached or resolved version.
|
||||||
val mrOpt: Option[ResolvedModuleRevision] = sorted orElse resolvedOrCached
|
val mrOpt: Option[ResolvedModuleRevision] = sorted orElse resolvedOrCached
|
||||||
mrOpt match {
|
mrOpt match {
|
||||||
case None if errors.size == 1 =>
|
case None if errors.size == 1 =>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue