mirror of https://github.com/sbt/sbt.git
Remove coded uplication in `updateEither`
This commit reduces the code duplication in `updateEither` which was duplicating a good deal of the resolution logic to deal with the different resolution mechanisms: the simple one and the cached one. It also unifies the signatures of the helpers that are invoked by `updateEither`, removing the weirdness of the different return type signatures and ad-hoc logic handling.
This commit is contained in:
parent
b68498d013
commit
eea500d64f
|
|
@ -236,56 +236,32 @@ object IvyActions {
|
||||||
logicalClock: LogicalClock,
|
logicalClock: LogicalClock,
|
||||||
depDir: Option[File],
|
depDir: Option[File],
|
||||||
log: Logger
|
log: Logger
|
||||||
): Either[UnresolvedWarning, UpdateReport] =
|
): Either[UnresolvedWarning, UpdateReport] = {
|
||||||
module.withModule(log) {
|
module.withModule(log) {
|
||||||
case (ivy, md, default)
|
case (ivy, moduleDescriptor, defaultConf) =>
|
||||||
if module.owner.configuration.updateOptions.cachedResolution && depDir.isDefined =>
|
// Warn about duplicated and inconsistent dependencies
|
||||||
ivy.getResolveEngine match {
|
val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor)
|
||||||
case x: CachedResolutionResolveEngine =>
|
iw.foreach(log.warn(_))
|
||||||
val iw = IvySbt.inconsistentDuplicateWarning(md)
|
|
||||||
iw foreach { log.warn(_) }
|
// Create inputs, resolve and retrieve the module descriptor
|
||||||
val resolveOptions = new ResolveOptions
|
val inputs = ResolutionInputs(ivy, moduleDescriptor, configuration, log)
|
||||||
val resolveId = ResolveOptions.getDefaultResolveId(md)
|
val resolutionResult: Either[ResolveException, UpdateReport] = {
|
||||||
resolveOptions.setResolveId(resolveId)
|
if (module.owner.configuration.updateOptions.cachedResolution && depDir.isDefined) {
|
||||||
resolveOptions.setArtifactFilter(configuration.artifactFilter)
|
val cache = depDir.getOrElse(sys.error("Missing directory for cached resolution."))
|
||||||
resolveOptions.setLog(ivyLogLevel(configuration.logging))
|
cachedResolveAndRetrieve(inputs, logicalClock, cache)
|
||||||
x.customResolve(
|
} else resolveAndRetrieve(inputs, defaultConf)
|
||||||
md,
|
|
||||||
configuration.missingOk,
|
|
||||||
logicalClock,
|
|
||||||
resolveOptions,
|
|
||||||
depDir getOrElse {
|
|
||||||
sys.error("dependency base directory is not specified")
|
|
||||||
},
|
|
||||||
log
|
|
||||||
) match {
|
|
||||||
case Left(x) =>
|
|
||||||
Left(UnresolvedWarning(x, uwconfig))
|
|
||||||
case Right(uReport) =>
|
|
||||||
configuration.retrieve match {
|
|
||||||
case Some(rConf) => Right(retrieve(log, ivy, uReport, rConf))
|
|
||||||
case None => Right(uReport)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case (ivy, md, default) =>
|
|
||||||
val iw = IvySbt.inconsistentDuplicateWarning(md)
|
|
||||||
iw foreach { log.warn(_) }
|
|
||||||
val (report, err) =
|
|
||||||
resolve(configuration.logging)(ivy, md, default, configuration.artifactFilter)
|
|
||||||
err match {
|
|
||||||
case Some(x) if !configuration.missingOk =>
|
|
||||||
Left(UnresolvedWarning(x, uwconfig))
|
|
||||||
case _ =>
|
|
||||||
val cachedDescriptor = ivy.getSettings.getResolutionCacheManager
|
|
||||||
.getResolvedIvyFileInCache(md.getModuleRevisionId)
|
|
||||||
val uReport = IvyRetrieve.updateReport(report, cachedDescriptor)
|
|
||||||
configuration.retrieve match {
|
|
||||||
case Some(rConf) => Right(retrieve(log, ivy, uReport, rConf))
|
|
||||||
case None => Right(uReport)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert to unresolved warning or retrieve update report
|
||||||
|
resolutionResult.fold(
|
||||||
|
exception => Left(UnresolvedWarning(exception, uwconfig)),
|
||||||
|
updateReport => {
|
||||||
|
val retrieveConf = configuration.retrieve
|
||||||
|
Right(retrieveConf.map(retrieve(log, ivy, updateReport, _)).getOrElse(updateReport))
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@deprecated("No longer used.", "0.13.6")
|
@deprecated("No longer used.", "0.13.6")
|
||||||
def processUnresolved(err: ResolveException, log: Logger): Unit = ()
|
def processUnresolved(err: ResolveException, log: Logger): Unit = ()
|
||||||
def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)(
|
def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)(
|
||||||
|
|
@ -496,38 +472,104 @@ object IvyActions {
|
||||||
.withConfigurations(if (confs) m.configurations else None)
|
.withConfigurations(if (confs) m.configurations else None)
|
||||||
.branch(m.branchName)
|
.branch(m.branchName)
|
||||||
|
|
||||||
private[this] def resolve(logging: UpdateLogging)(
|
/**
|
||||||
|
* Represents the inputs to pass in to [[resolveAndRetrieve]] and [[cachedResolveAndRetrieve]].
|
||||||
|
*
|
||||||
|
* @param ivy The ivy instance to resolve and retrieve dependencies.
|
||||||
|
* @param module The module descriptor to be resolved.
|
||||||
|
* @param updateConfiguration The update configuration for [[ResolveOptions]].
|
||||||
|
* @param log The logger.
|
||||||
|
*/
|
||||||
|
private case class ResolutionInputs(
|
||||||
ivy: Ivy,
|
ivy: Ivy,
|
||||||
module: DefaultModuleDescriptor,
|
module: DefaultModuleDescriptor,
|
||||||
defaultConf: String,
|
updateConfiguration: UpdateConfiguration,
|
||||||
filter: ArtifactTypeFilter
|
log: Logger
|
||||||
): (ResolveReport, Option[ResolveException]) = {
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the internal entrypoint of module resolution and retrieval.
|
||||||
|
*
|
||||||
|
* This method is the responsible of populating [[ResolveOptions]] and pass
|
||||||
|
* it in to the ivy instance to perform the module resolution.
|
||||||
|
*
|
||||||
|
* It returns an already resolved [[UpdateReport]] instead of a [[ResolveReport]]
|
||||||
|
* like its counterpart [[CachedResolutionResolveEngine.customResolve]].
|
||||||
|
*
|
||||||
|
* @param inputs The resolution inputs.
|
||||||
|
* @param defaultModuleConfiguration The default ivy configuration.
|
||||||
|
* @return The result of the resolution.
|
||||||
|
*/
|
||||||
|
private[this] def resolveAndRetrieve(
|
||||||
|
inputs: ResolutionInputs,
|
||||||
|
defaultModuleConfiguration: String
|
||||||
|
): Either[ResolveException, UpdateReport] = {
|
||||||
|
// Populate resolve options from the passed arguments
|
||||||
|
val ivyInstance = inputs.ivy
|
||||||
|
val moduleDescriptor = inputs.module
|
||||||
|
val updateConfiguration = inputs.updateConfiguration
|
||||||
|
val logging = updateConfiguration.logging
|
||||||
val resolveOptions = new ResolveOptions
|
val resolveOptions = new ResolveOptions
|
||||||
val resolveId = ResolveOptions.getDefaultResolveId(module)
|
val resolveId = ResolveOptions.getDefaultResolveId(moduleDescriptor)
|
||||||
resolveOptions.setResolveId(resolveId)
|
resolveOptions.setResolveId(resolveId)
|
||||||
resolveOptions.setArtifactFilter(filter)
|
resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter)
|
||||||
resolveOptions.setLog(ivyLogLevel(logging))
|
resolveOptions.setLog(ivyLogLevel(logging))
|
||||||
ResolutionCache.cleanModule(
|
ResolutionCache.cleanModule(
|
||||||
module.getModuleRevisionId,
|
moduleDescriptor.getModuleRevisionId,
|
||||||
resolveId,
|
resolveId,
|
||||||
ivy.getSettings.getResolutionCacheManager
|
ivyInstance.getSettings.getResolutionCacheManager
|
||||||
)
|
)
|
||||||
val resolveReport = ivy.resolve(module, resolveOptions)
|
|
||||||
val err =
|
val resolveReport = ivyInstance.resolve(moduleDescriptor, resolveOptions)
|
||||||
if (resolveReport.hasError) {
|
if (resolveReport.hasError && !inputs.updateConfiguration.missingOk) {
|
||||||
val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct
|
// If strict error, collect report information and generated UnresolvedWarning
|
||||||
val failedPaths = Map(resolveReport.getUnresolvedDependencies map { node =>
|
val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct
|
||||||
val m = IvyRetrieve.toModuleID(node.getId)
|
val failedPaths = resolveReport.getUnresolvedDependencies.map { node =>
|
||||||
val path = IvyRetrieve.findPath(node, module.getModuleRevisionId) map { x =>
|
val moduleID = IvyRetrieve.toModuleID(node.getId)
|
||||||
IvyRetrieve.toModuleID(x.getId)
|
val path = IvyRetrieve
|
||||||
}
|
.findPath(node, moduleDescriptor.getModuleRevisionId)
|
||||||
m -> path
|
.map(x => IvyRetrieve.toModuleID(x.getId))
|
||||||
}: _*)
|
moduleID -> path
|
||||||
val failed = failedPaths.keys.toSeq
|
}.toMap
|
||||||
Some(new ResolveException(messages, failed, failedPaths))
|
val failedModules = failedPaths.keys.toSeq
|
||||||
} else None
|
Left(new ResolveException(messages, failedModules, failedPaths))
|
||||||
(resolveReport, err)
|
} else {
|
||||||
|
// If no strict error, we convert the resolve report into an update report
|
||||||
|
val cachedDescriptor = ivyInstance.getSettings.getResolutionCacheManager
|
||||||
|
.getResolvedIvyFileInCache(moduleDescriptor.getModuleRevisionId)
|
||||||
|
Right(IvyRetrieve.updateReport(resolveReport, cachedDescriptor))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves and retrieves a module with a cache mechanism defined
|
||||||
|
* <a href="http://www.scala-sbt.org/0.13/docs/Cached-Resolution.html">here</a>.
|
||||||
|
*
|
||||||
|
* It's the cached version of [[resolveAndRetrieve]].
|
||||||
|
*
|
||||||
|
* @param inputs The resolution inputs.
|
||||||
|
* @param logicalClock The clock to check if a file is outdated or not.
|
||||||
|
* @param cache The optional cache dependency.
|
||||||
|
* @return The result of the cached resolution.
|
||||||
|
*/
|
||||||
|
private[this] def cachedResolveAndRetrieve(
|
||||||
|
inputs: ResolutionInputs,
|
||||||
|
logicalClock: LogicalClock,
|
||||||
|
cache: File
|
||||||
|
): Either[ResolveException, UpdateReport] = {
|
||||||
|
val log = inputs.log
|
||||||
|
val descriptor = inputs.module
|
||||||
|
val updateConfiguration = inputs.updateConfiguration
|
||||||
|
val resolver = inputs.ivy.getResolveEngine.asInstanceOf[CachedResolutionResolveEngine]
|
||||||
|
val resolveOptions = new ResolveOptions
|
||||||
|
val resolveId = ResolveOptions.getDefaultResolveId(descriptor)
|
||||||
|
resolveOptions.setResolveId(resolveId)
|
||||||
|
resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter)
|
||||||
|
resolveOptions.setLog(ivyLogLevel(updateConfiguration.logging))
|
||||||
|
val acceptError = updateConfiguration.missingOk
|
||||||
|
resolver.customResolve(descriptor, acceptError, logicalClock, resolveOptions, cache, log)
|
||||||
|
}
|
||||||
|
|
||||||
private def retrieve(
|
private def retrieve(
|
||||||
log: Logger,
|
log: Logger,
|
||||||
ivy: Ivy,
|
ivy: Ivy,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue