mirror of https://github.com/sbt/sbt.git
Apply scalaVersion enforcement to Compile related configs
Fixes #2786. Ref #2634. sbt 0.13.12 added Ivy mediator that enforces scalaOrganization and scalaVersion for Scala toolchain artifacts. This turns out to be a bit too aggressive because Ivy configurations can be used as an independent dependency graph that does not rely on the scalaVersion used by Compile configuration. By enforcing scalaVersion in those graph causes runtime failure. This change checks if the configuration extends Default, Compile, Provided, or Optional before enforcing scalaVersion.
This commit is contained in:
parent
c3f5805574
commit
c12c9c6187
|
|
@ -168,7 +168,21 @@ 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 ic: InlineConfigurationWithExcludes => ic.configurations
|
||||
case ec: EmptyConfiguration => Nil
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue