Adapt ScalaOverride to Scala 3

This commit is contained in:
Adrien Piquerez 2020-12-18 16:55:36 +01:00
parent 0672da475d
commit 24f85fd18c
3 changed files with 198 additions and 52 deletions

View File

@ -1,16 +1,30 @@
package sbt.librarymanagement
object ScalaArtifacts {
val Organization = "org.scala-lang"
val LibraryID = "scala-library"
val CompilerID = "scala-compiler"
val ReflectID = "scala-reflect"
val ActorsID = "scala-actors"
val ScalapID = "scalap"
val Artifacts = Vector(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID)
final val Organization = "org.scala-lang"
final val LibraryID = "scala-library"
final val CompilerID = "scala-compiler"
final val ReflectID = "scala-reflect"
final val ActorsID = "scala-actors"
final val ScalapID = "scalap"
final val Artifacts = Vector(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID)
val Scala3LibraryID = "scala3-library"
val Scala3CompilerID = "scala3-compiler"
final val Scala3LibraryID = "scala3-library"
final val Scala3CompilerID = "scala3-compiler"
final val Scala3InterfacesID = "scala3-interfaces"
final val TastyCoreID = "tasty-core"
private[sbt] final val Scala3LibraryPrefix = Scala3LibraryID + "_"
private[sbt] final val Scala3CompilerPrefix = Scala3CompilerID + "_"
private[sbt] final val TastyCorePrefix = TastyCoreID + "_"
def isScala2Artifact(name: String): Boolean = {
name == LibraryID || name == CompilerID || name == ReflectID || name == ActorsID || name == ScalapID
}
def isScala3Artifact(name: String): Boolean = {
name.startsWith(Scala3LibraryPrefix) || name.startsWith(Scala3CompilerPrefix) ||
name.startsWith(TastyCorePrefix) || name == Scala3InterfacesID
}
def isScala3(scalaVersion: String): Boolean = scalaVersion.startsWith("3.")

View File

@ -12,7 +12,7 @@ import org.apache.ivy.plugins.matcher.ExactPatternMatcher
import org.apache.ivy.plugins.namespace.NamespaceTransformer
import sbt.util.Logger
import sbt.librarymanagement.ScalaArtifacts._
import sbt.librarymanagement.{ ScalaModuleInfo, CrossVersion, Configuration }
import sbt.librarymanagement.{ Configuration, CrossVersion, ScalaModuleInfo }
object IvyScalaUtil {
@ -48,38 +48,43 @@ object IvyScalaUtil {
scalaVersionConfigs0: Vector[String]
) extends DependencyDescriptorMediator {
private[this] val scalaVersionConfigs = scalaVersionConfigs0.toSet
private val binaryVersion = CrossVersion.binaryScalaVersion(scalaVersion)
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 })
dd.getModuleConfigurations exists { scalaVersionConfigs }
// Do not rewrite the dependencies of Scala dependencies themselves, this prevents bootstrapping
// a Scala compiler using another Scala compiler.
def dependeeQualifies: Boolean =
dd.getParentRevisionId == null || (
dd.getParentRevisionId.getName match {
case _ @(CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) =>
false
case _ =>
true
}
)
dd.getParentRevisionId == null ||
!isScala2Artifact(dd.getParentRevisionId.getName) ||
!isScala3Artifact(dd.getParentRevisionId.getName)
def matchBinaryVersion(version: String): Boolean =
CrossVersion.binaryScalaVersion(version) == binaryVersion
val transformer =
new NamespaceTransformer {
def transform(mrid: ModuleRevisionId): ModuleRevisionId = {
if (mrid == null) mrid
else
mrid.getName match {
case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID)
if configQualifies && dependeeQualifies =>
ModuleRevisionId.newInstance(
scalaOrganization,
name,
mrid.getBranch,
scalaVersion,
mrid.getQualifiedExtraAttributes
)
case _ => mrid
}
else if ((isScala2Artifact(mrid.getName) || isScala3Artifact(mrid.getName)) &&
configQualifies &&
dependeeQualifies) {
// do not override the binary incompatible Scala version because:
// - the artifacts compiled with Scala 3 depends on the Scala 2.13 scala-library
// - the Scala 2 TASTy reader can consume the Scala 3 artifacts
val newScalaVersion =
if (matchBinaryVersion(mrid.getRevision)) scalaVersion
else mrid.getRevision
ModuleRevisionId.newInstance(
scalaOrganization,
mrid.getName,
mrid.getBranch,
newScalaVersion,
mrid.getQualifiedExtraAttributes
)
} else mrid
}
def isIdentity: Boolean = false

View File

@ -11,10 +11,13 @@ import verify.BasicTestSuite
object ScalaOverrideTest extends BasicTestSuite {
val OtherOrgID = "other.org"
def check(org0: String, version0: String)(org1: String, name1: String, version1: String) = {
val scalaConfigs = Configurations.default.toVector filter { Configurations.underScalaVersion } map {
_.name
}
private val scalaConfigs =
Configurations.default.filter(Configurations.underScalaVersion).map(_.name)
def checkOrgAndVersion(
org0: String,
version0: String
)(org1: String, name1: String, version1: String): Unit = {
val osm = new OverrideScalaMediator(org0, version0, scalaConfigs)
val mrid = ModuleRevisionId.newInstance(org1, name1, version1)
@ -25,8 +28,36 @@ object ScalaOverrideTest extends BasicTestSuite {
assert(res.getDependencyRevisionId == ModuleRevisionId.newInstance(org0, name1, version0))
}
test("""OverrideScalaMediator should override compiler version""") {
check(Organization, "2.11.8")(
def checkOnlyOrg(
org0: String,
version0: String
)(org1: String, name1: String, version1: String): Unit = {
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)
assert(res.getDependencyRevisionId == ModuleRevisionId.newInstance(org0, name1, version1))
}
def checkNoOverride(
org0: String,
version0: String
)(org1: String, name1: String, version1: String): Unit = {
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)
assert(res.getDependencyRevisionId == mrid)
}
test("OverrideScalaMediator should override compiler version") {
checkOrgAndVersion(Organization, "2.11.8")(
Organization,
CompilerID,
"2.11.9"
@ -34,7 +65,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override library version") {
check(Organization, "2.11.8")(
checkOrgAndVersion(Organization, "2.11.8")(
Organization,
LibraryID,
"2.11.8"
@ -42,7 +73,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override reflect version") {
check(Organization, "2.11.8")(
checkOrgAndVersion(Organization, "2.11.8")(
Organization,
ReflectID,
"2.11.7"
@ -50,7 +81,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override actors version") {
check(Organization, "2.11.8")(
checkOrgAndVersion(Organization, "2.11.8")(
Organization,
ActorsID,
"2.11.6"
@ -58,7 +89,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override scalap version") {
check(Organization, "2.11.8")(
checkOrgAndVersion(Organization, "2.11.8")(
Organization,
ScalapID,
"2.11.5"
@ -66,7 +97,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override default compiler organization") {
check(OtherOrgID, "2.11.8")(
checkOrgAndVersion(OtherOrgID, "2.11.8")(
Organization,
CompilerID,
"2.11.9"
@ -74,7 +105,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override default library organization") {
check(OtherOrgID, "2.11.8")(
checkOrgAndVersion(OtherOrgID, "2.11.8")(
Organization,
LibraryID,
"2.11.8"
@ -82,7 +113,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override default reflect organization") {
check(OtherOrgID, "2.11.8")(
checkOrgAndVersion(OtherOrgID, "2.11.8")(
Organization,
ReflectID,
"2.11.7"
@ -90,7 +121,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override default actors organization") {
check(OtherOrgID, "2.11.8")(
checkOrgAndVersion(OtherOrgID, "2.11.8")(
Organization,
ActorsID,
"2.11.6"
@ -98,7 +129,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override default scalap organization") {
check(OtherOrgID, "2.11.8")(
checkOrgAndVersion(OtherOrgID, "2.11.8")(
Organization,
ScalapID,
"2.11.5"
@ -106,7 +137,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override custom compiler organization") {
check(Organization, "2.11.8")(
checkOrgAndVersion(Organization, "2.11.8")(
OtherOrgID,
CompilerID,
"2.11.9"
@ -114,7 +145,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override custom library organization") {
check(Organization, "2.11.8")(
checkOrgAndVersion(Organization, "2.11.8")(
OtherOrgID,
LibraryID,
"2.11.8"
@ -122,7 +153,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override custom reflect organization") {
check(Organization, "2.11.8")(
checkOrgAndVersion(Organization, "2.11.8")(
OtherOrgID,
ReflectID,
"2.11.7"
@ -130,7 +161,7 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override custom actors organization") {
check(Organization, "2.11.8")(
checkOrgAndVersion(Organization, "2.11.8")(
OtherOrgID,
ActorsID,
"2.11.6"
@ -138,10 +169,106 @@ object ScalaOverrideTest extends BasicTestSuite {
}
test("it should override custom scalap organization") {
check(Organization, "2.11.8")(
checkOrgAndVersion(Organization, "2.11.8")(
OtherOrgID,
ScalapID,
"2.11.5"
)
}
test("it should override Scala 3 compiler version") {
checkOrgAndVersion(Organization, "3.1.0")(
Organization,
Scala3CompilerPrefix + "3",
"3.0.0"
)
}
test("it should override Scala 3 library version") {
checkOrgAndVersion(Organization, "3.1.0")(
Organization,
Scala3LibraryPrefix + "3",
"3.0.0"
)
}
test("it should override Scala 3 interfaces version") {
checkOrgAndVersion(Organization, "3.1.0")(
Organization,
Scala3InterfacesID,
"3.0.0"
)
}
test("it should override TASTy core version") {
checkOrgAndVersion(Organization, "3.1.0")(
Organization,
TastyCorePrefix + "3",
"3.0.0"
)
}
test("it should not override Scala 2 library version when using Scala 3") {
checkNoOverride(Organization, "3.1.0")(
Organization,
LibraryID,
"2.13.4"
)
}
test("it should not override TASTy core version when using Scala 2") {
checkNoOverride(Organization, "2.13.4")(
Organization,
TastyCorePrefix + "3",
"3.0.0"
)
}
test("it should override default Scala 3 compiler organization") {
checkOrgAndVersion(OtherOrgID, "3.1.0")(
Organization,
Scala3CompilerPrefix + "3",
"3.0.0"
)
}
test("it should override default Scala 3 library organization") {
checkOrgAndVersion(OtherOrgID, "3.1.0")(
Organization,
Scala3LibraryPrefix + "3",
"3.0.0"
)
}
test("it should override default Scala 3 interfaces organization") {
checkOrgAndVersion(OtherOrgID, "3.1.0")(
Organization,
Scala3InterfacesID,
"3.0.0"
)
}
test("it should override default Scala 3 TASTy core organization") {
checkOrgAndVersion(OtherOrgID, "3.1.0")(
Organization,
TastyCorePrefix + "3",
"3.0.0"
)
}
test("it should override default Scala 2 library organization when in Scala 3") {
checkOnlyOrg(OtherOrgID, "3.1.0")(
Organization,
LibraryID,
"2.13.4"
)
}
test("it should override default TASTy core organization when in Scala 2") {
checkOnlyOrg(OtherOrgID, "2.13.4")(
Organization,
TastyCorePrefix + "3",
"3.0.0"
)
}
}