Fix sbt/sbt#2650: Degrade log level and clarify

To ensure that SNAPSHOTs are always the latest, we go through all the
resolved modules and check their timestamps. Good.

However, if in the process of reparsing/redownloading the module
descriptor we fail (or it's not found in that resolver at all), then we
cannot refresh the resolved module that could have been internalized or
heavily cached in memory by ivy. We do this for correctness.

This patch does two things:

1. Adds more comments.
2. Warns only when there are parsing errors in ivy files.
3. Adds debug info in the rest of the cases.

This removes the pain of seeing `Unable to parse` that could be caused by
other reasons that are not related to parsing at all and which would not
affect the algorithm at hand. For instance, if we get a URLResource,
that's totally fine -- there is no way we could parse the ivy file. Ivy
uses URLResources in several cases where the artifact origin URL is
specified.
This commit is contained in:
jvican 2017-05-11 17:32:19 +02:00
parent ccc63d3ee0
commit 92cc5339eb
No known key found for this signature in database
GPG Key ID: 42DAFA0F112E8050
1 changed files with 26 additions and 15 deletions

View File

@ -306,34 +306,45 @@ private[sbt] case class SbtChainResolver(
}
}
// Ivy seem to not want to use the module descriptor found at the latest resolver
/* Ivy keeps module descriptors in memory, so we need to make sure that the
* resolved module revision is in fact the one found in the latest resolver. */
private[this] def reparseModuleDescriptor(
dd: DependencyDescriptor,
data: ResolveData,
resolver: DependencyResolver,
rmr: ResolvedModuleRevision
): ResolvedModuleRevision =
// TODO - Redownloading/parsing the ivy file is not really the best way to make this correct.
// We should figure out a better alternative, or directly attack the resolvers Ivy uses to
// give them correct behavior around -SNAPSHOT.
previouslyResolved: ResolvedModuleRevision
): ResolvedModuleRevision = {
// TODO: Figure out better alternative or directly attack the
// resolvers ivy uses to get correct behaviour for SNAPSHOT
Option(resolver.findIvyFileRef(dd, data)) flatMap { ivyFile =>
ivyFile.getResource match {
case r: FileResource =>
val urlDescriptor = r.getFile.toURI.toURL
try {
val parser = rmr.getDescriptor.getParser
val md = parser.parseDescriptor(settings, r.getFile.toURI.toURL, r, false)
Some(new ResolvedModuleRevision(resolver, resolver, md, rmr.getReport, true))
val parser = previouslyResolved.getDescriptor.getParser
val md = parser.parseDescriptor(settings, urlDescriptor, r, false)
val report = previouslyResolved.getReport
// Note that we always set force for SNAPSHOT resolution...
Some(new ResolvedModuleRevision(resolver, resolver, md, report, true))
} catch {
case _: ParseException => None
case _: ParseException =>
Message.warn(s"The descriptor in $urlDescriptor from $resolver could not be parsed.")
Some(previouslyResolved)
}
case _ => None
case unhandledResource =>
val unhandledClassName = unhandledResource.getClass.getName
val tip = s"Returning previously resolved $previouslyResolved."
Message.debug(s"Latest snapshots option does not handle `$unhandledClassName`. $tip")
Some(previouslyResolved)
}
} getOrElse {
Message.warn(
s"Unable to reparse ${dd.getDependencyRevisionId} from $resolver, using ${rmr.getPublicationDate}"
)
rmr
val previousRevision = dd.getDependencyRevisionId
val date = previouslyResolved.getPublicationDate
// Change from warn to debug -- see https://github.com/sbt/sbt/issues/2650.
Message.debug(s"Unable to find new descriptor for $previousRevision at $date in $resolver.")
previouslyResolved
}
}
/** Ported from BasicResolver#findFirstAirfactRef. */
private[this] def findFirstArtifactRef(