diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 320f549a0..76ba4ce33 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -168,7 +168,19 @@ final class IvySbt(val configuration: IvyConfiguration, fileToStore: File => Cac case pc: PomConfiguration => configurePom(pc) case ifc: IvyFileConfiguration => configureIvyFile(ifc) } - moduleSettings.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration, configuration.log)) + + val configs = + moduleSettings match { + case ic: InlineConfiguration => ic.configurations + case pc: PomConfiguration => Configurations.default ++ Configurations.defaultInternal + case ifc: IvyFileConfiguration => Configurations.default ++ Configurations.defaultInternal + } + moduleSettings.ivyScala match { + case Some(is) => + val svc = configs.toVector filter Configurations.underScalaVersion map { _.name } + IvyScala.checkModule(baseModule, baseConfiguration, svc, configuration.log)(is) + case _ => // do nothing + } IvySbt.addExtraNamespace(baseModule) (baseModule, baseConfiguration) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index f3b267e24..8e30e5c6c 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -47,6 +47,15 @@ object Configurations { private[sbt] def DefaultConfiguration(mavenStyle: Boolean) = if (mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration private[sbt] def defaultConfiguration(mavenStyle: Boolean) = if (mavenStyle) Configurations.Compile else Configurations.Default private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) + + /** Returns true if the configuration should be under the influence of scalaVersion. */ + private[sbt] def underScalaVersion(c: Configuration): Boolean = + c match { + case Default | Compile | IntegrationTest | Provided | Runtime | Test | Optional | + CompilerPlugin | CompileInternal | RuntimeInternal | TestInternal => true + case config => + config.extendsConfigs exists underScalaVersion + } } abstract class ConfigurationExtra { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala index 39ecbace4..13cd79154 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala @@ -47,24 +47,28 @@ import ScalaArtifacts._ private[sbt] abstract class IvyScalaFunctions { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ - def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala): Unit = { + def checkModule(module: DefaultModuleDescriptor, conf: String, scalaVersionConfigs: Vector[String], log: Logger)(check: IvyScala): Unit = { if (check.checkExplicit) - checkDependencies(module, check.scalaOrganization, check.scalaArtifacts, check.scalaBinaryVersion, check.configurations, log) + checkDependencies(module, check.scalaOrganization, check.scalaArtifacts, check.scalaBinaryVersion, scalaVersionConfigs, log) if (check.filterImplicit) excludeScalaJars(module, check.configurations) if (check.overrideScalaVersion) - overrideScalaVersion(module, check.scalaOrganization, check.scalaFullVersion) + overrideScalaVersion(module, check.scalaOrganization, check.scalaFullVersion, scalaVersionConfigs) } - class OverrideScalaMediator(scalaOrganization: String, scalaVersion: String) extends DependencyDescriptorMediator { + class OverrideScalaMediator(scalaOrganization: String, scalaVersion: String, scalaVersionConfigs0: Vector[String]) extends DependencyDescriptorMediator { + private[this] val scalaVersionConfigs = scalaVersionConfigs0.toSet def mediate(dd: DependencyDescriptor): DependencyDescriptor = { + // Mediate only for the dependencies in scalaVersion configurations. https://github.com/sbt/sbt/issues/2786 + def configQualifies: Boolean = + (dd.getModuleConfigurations exists { scalaVersionConfigs }) val transformer = new NamespaceTransformer { def transform(mrid: ModuleRevisionId): ModuleRevisionId = { if (mrid == null) mrid else mrid.getName match { - case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) => + case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) if configQualifies => ModuleRevisionId.newInstance(scalaOrganization, name, mrid.getBranch, scalaVersion, mrid.getQualifiedExtraAttributes) case _ => mrid } @@ -77,8 +81,8 @@ private[sbt] abstract class IvyScalaFunctions { } } - def overrideScalaVersion(module: DefaultModuleDescriptor, organization: String, version: String): Unit = { - val mediator = new OverrideScalaMediator(organization, version) + def overrideScalaVersion(module: DefaultModuleDescriptor, organization: String, version: String, scalaVersionConfigs: Vector[String]): Unit = { + val mediator = new OverrideScalaMediator(organization, version, scalaVersionConfigs) module.addDependencyDescriptorMediator(new ModuleId(Organization, "*"), ExactPatternMatcher.INSTANCE, mediator) if (organization != Organization) module.addDependencyDescriptorMediator(new ModuleId(organization, "*"), ExactPatternMatcher.INSTANCE, mediator) @@ -94,8 +98,8 @@ private[sbt] abstract class IvyScalaFunctions { * Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the * dependencies matches scalaVersion. */ - private def checkDependencies(module: ModuleDescriptor, scalaOrganization: String, scalaArtifacts: Seq[String], scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger): Unit = { - val configSet = if (configurations.isEmpty) (c: String) => true else configurationSet(configurations) + private def checkDependencies(module: ModuleDescriptor, scalaOrganization: String, scalaArtifacts: Vector[String], scalaBinaryVersion: String, scalaVersionConfigs0: Vector[String], log: Logger): Unit = { + val scalaVersionConfigs: String => Boolean = if (scalaVersionConfigs0.isEmpty) (c: String) => false else scalaVersionConfigs0.toSet def binaryScalaWarning(dep: DependencyDescriptor): Option[String] = { val id = dep.getDependencyRevisionId @@ -103,7 +107,7 @@ private[sbt] abstract class IvyScalaFunctions { def isScalaLangOrg = id.getOrganisation == scalaOrganization def isScalaArtifact = scalaArtifacts.contains(id.getName) def hasBinVerMismatch = depBinaryVersion != scalaBinaryVersion - def matchesOneOfTheConfigs = dep.getModuleConfigurations.exists(configSet) + def matchesOneOfTheConfigs = dep.getModuleConfigurations exists { scalaVersionConfigs } val mismatched = isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs if (mismatched) Some("Binary version (" + depBinaryVersion + ") for dependency " + id + diff --git a/librarymanagement/src/test/scala/ScalaOverrideTest.scala b/librarymanagement/src/test/scala/ScalaOverrideTest.scala index bf0b82e3e..f14a2d6ca 100644 --- a/librarymanagement/src/test/scala/ScalaOverrideTest.scala +++ b/librarymanagement/src/test/scala/ScalaOverrideTest.scala @@ -12,10 +12,12 @@ class ScalaOverrideTest extends UnitSpec { val OtherOrgID = "other.org" def check(org0: String, version0: String)(org1: String, name1: String, version1: String) = { - val osm = new OverrideScalaMediator(org0, version0) + val scalaConfigs = Configurations.default.toVector filter { Configurations.underScalaVersion } map { _.name } + val osm = new OverrideScalaMediator(org0, version0, scalaConfigs) val mrid = ModuleRevisionId.newInstance(org1, name1, version1) val dd = new DefaultDependencyDescriptor(mrid, false) + dd.addDependencyConfiguration("compile", "compile") val res = osm.mediate(dd) res.getDependencyRevisionId shouldBe ModuleRevisionId.newInstance(org0, name1, version0) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f93084d11..82c63e485 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -34,7 +34,6 @@ object Dependencies { } def addSbtIO(p: Project): Project = addSbtModule(p, sbtIoPath, "io", sbtIO) - def addSbtUtilCollection(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCollection", utilCollection) def addSbtUtilLogging(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging) def addSbtUtilTesting(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilTesting", utilTesting, Some(Test)) @@ -42,7 +41,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cf13e211b2cb31f0d3b317289dca70eca3362f6" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-48dd0744422128446aee9ac31aa356ee203cc9f4" val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5")