From 92ca28e25af3383b5db9a79642fc57a2d9de5a90 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Mon, 14 Mar 2016 13:28:50 +0100 Subject: [PATCH] Use configuration of evicted nodes with cached resolution Consider a configuration where we have two projects, A and B. A has a library dependency on "a" % "b" % "1.0.0" % "compile->runtime" and "a" % "b" % "1.0.0" % "compile->runtime2" B depends on project A, and has a library dependency on "a" % "b" % "1.0.1" % "compile->runtime". Note that project B depends on a more recent version of "a" % "b" than project A, and that it depends ONLY on it's "runtime" configuration. However, when compiling project B, we expect to have on the classpath project A, and "a" % "b" % "1.0.1" % "compile->runtime" AND "a" % "b" % "1.0.1" % "compile->runtime2" because it is part of the compile configuration of project A. This commit changes the cached resolution engine so that it behaves like that, by first resolving dependencies on other project and then ensuring that the dependent project specifies dependencies on the same configurations. Mark test dependency-management/cached-resolution-configurations as passing. --- .../CachedResolutionResolveEngine.scala | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 6f4a69065..2e0a940b9 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -331,12 +331,41 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { Left(new ResolveException(messages, failed, failedPaths)) } } - val results = mds map { + val (internal, external) = mds.partition { case (_, _, dd) => cache.internalDependency(dd, projectResolver).isDefined } + val internalResults = internal map { case (md, changing, dd) => cache.getOrElseUpdateMiniGraph(md, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { doWork(md, dd) } } + val externalResults = external map { + case (md0, changing, dd) => + val configurationsInInternal = internalResults flatMap { + case Right(ur) => ur.allModules.flatMap { + case md => + val sameName = md.name == dd.getDependencyId.getName + val sameOrg = md.organization == dd.getDependencyId.getOrganisation + if (sameName && sameOrg) md.configurations + else None + } + case _ => Nil + } + + dd match { + case d: DefaultDependencyDescriptor => + configurationsInInternal foreach { c => + val configurations = c.split(";").map(_.split("->")) + configurations foreach { conf => d.addDependencyConfiguration(conf(0), conf(1)) } + } + + case _ => () + } + + // cache.getOrElseUpdateMiniGraph(md0, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { + doWork(md0, dd) + // } + } + val results = internalResults ++ externalResults val uReport = mergeResults(md0, results, missingOk, System.currentTimeMillis - start, os, log) val cacheManager = getSettings.getResolutionCacheManager cacheManager.saveResolvedModuleDescriptor(md0)