diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 4b6cd3e9e..3ee26964e 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -11,7 +11,7 @@ import org.apache.ivy.core import core.resolve._ import core.module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } import core.report.{ ResolveReport, ConfigurationResolveReport, DownloadReport } -import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor, Configuration => IvyConfiguration } +import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule } import core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.util.Message import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } @@ -59,11 +59,28 @@ private[sbt] class CachedResolutionResolveCache() { } def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], prOpt: Option[ProjectResolver]): (DefaultModuleDescriptor, Boolean) = { + def excludeRuleString(rule: ExcludeRule): String = + s"""Exclude(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" + def includeRuleString(rule: IncludeRule): String = + s"""Include(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" val mrid = dd.getDependencyRevisionId val confMap = (dd.getModuleConfigurations map { conf => conf + "->(" + dd.getDependencyConfigurations(conf).mkString(",") + ")" }) - val depsString = mrid.toString + ";" + confMap.mkString(";") + val exclusions = (dd.getModuleConfigurations.toVector flatMap { conf => + dd.getExcludeRules(conf).toVector match { + case Vector() => None + case rules => Some(conf + "->(" + (rules map excludeRuleString).mkString(",") + ")") + } + }) + val inclusions = (dd.getModuleConfigurations.toVector flatMap { conf => + dd.getIncludeRules(conf).toVector match { + case Vector() => None + case rules => Some(conf + "->(" + (rules map includeRuleString).mkString(",") + ")") + } + }) + val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + + s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};""" val sha1 = Hash.toHex(Hash(depsString)) val md1 = new DefaultModuleDescriptor(createID(sbtOrgTemp, "temp-resolve-" + sha1, "1.0"), "release", null, false) with ArtificialModuleDescriptor { def targetModuleRevisionId: ModuleRevisionId = mrid diff --git a/sbt/src/sbt-test/dependency-management/cached-resolution3/multi.sbt b/sbt/src/sbt-test/dependency-management/cached-resolution3/multi.sbt new file mode 100644 index 000000000..3d3196156 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/cached-resolution3/multi.sbt @@ -0,0 +1,45 @@ +// https://github.com/sbt/sbt/issues/1649 +lazy val check = taskKey[Unit]("Runs the check") + +def commonSettings: Seq[Def.Setting[_]] = + Seq( + ivyPaths := new IvyPaths( (baseDirectory in ThisBuild).value, Some((baseDirectory in LocalRootProject).value / "ivy-cache")), + dependencyCacheDirectory := (baseDirectory in LocalRootProject).value / "dependency", + scalaVersion := "2.10.4", + resolvers += Resolver.sonatypeRepo("snapshots") + ) + +def cachedResolutionSettings: Seq[Def.Setting[_]] = + commonSettings ++ Seq( + updateOptions := updateOptions.value.withCachedResolution(true) + ) + +lazy val a = project. + settings(cachedResolutionSettings: _*). + settings( + libraryDependencies += "net.databinder" %% "unfiltered-uploads" % "0.8.0" exclude("commons-io", "commons-io") + ) + +lazy val b = project. + settings(cachedResolutionSettings: _*). + settings( + libraryDependencies += "net.databinder" %% "unfiltered-uploads" % "0.8.0" + ) + +lazy val root = (project in file(".")). + aggregate(a, b). + settings( + organization in ThisBuild := "org.example", + version in ThisBuild := "1.0", + check := { + // sys.error(dependencyCacheDirectory.value.toString) + val acp = (externalDependencyClasspath in Compile in a).value.sortBy {_.data.getName} + val bcp = (externalDependencyClasspath in Compile in b).value.sortBy {_.data.getName} + if (acp exists { _.data.getName contains "commons-io" }) { + sys.error("commons-io found when it should be excluded") + } + if (!(bcp exists { _.data.getName contains "commons-io" })) { + sys.error("commons-io NOT found when it should NOT be excluded") + } + } + ) diff --git a/sbt/src/sbt-test/dependency-management/cached-resolution3/test b/sbt/src/sbt-test/dependency-management/cached-resolution3/test new file mode 100644 index 000000000..081d79708 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/cached-resolution3/test @@ -0,0 +1,5 @@ +> a/update + +> b/update + +> check