Let ++ fall back to a bincompat Scala version

Fixes https://github.com/sbt/sbt/issues/7327

**Problem**
In builds with mixed Scala patch versions (like scalameta),
it's possible for a core subproject to be set to the lastest 2.12.x,
but the compiler plugin component is cross published to 2.12.0 etc.
`++ 2.12.0` in this case does not work since sbt 1.7.x onwards requires
the queried Scala version to be listed in `crossScalaVersions`.

**Solution**
This implements sbt 1.6.x-like fallback mechanism,
but instead of using the queried version (e.g. 2.12.0) it will set
the Scala version to one of listed versions that is binary compatible.
This commit is contained in:
Eugene Yokota 2023-07-09 18:31:55 -04:00
parent 4b0b929838
commit de20328029
3 changed files with 21 additions and 4 deletions

View File

@ -20,7 +20,7 @@ import sbt.internal.util.MessageOnlyException
import sbt.internal.util.complete.DefaultParsers._
import sbt.internal.util.complete.{ DefaultParsers, Parser }
import sbt.io.IO
import sbt.librarymanagement.{ SemanticSelector, VersionNumber }
import sbt.librarymanagement.{ CrossVersion, SemanticSelector, VersionNumber }
/**
* Cross implements the Scala cross building commands:
@ -340,8 +340,23 @@ object Cross {
case (project, scalaVersions) =>
val selector = SemanticSelector(version)
scalaVersions.filter(v => selector.matches(VersionNumber(v))) match {
case Nil => (project, None, scalaVersions)
case Seq(version) => (project, Some(version), scalaVersions)
case Nil =>
// The Scala version queried via ++, like ++2.13.1 was not found.
// However, it's possible to keep the build going by falling back to a
// binary-compatible Scala version if available.
// In sbt 1.6.x (prior to https://github.com/sbt/sbt/pull/6946), we use to
// use the queried ++2.13.1 version as the fallback, which was wrong and unsafe.
// Instead this picks an actual Scala version listed in `crossScalaVersion`.
val svOpt = scalaVersions.find(
CrossVersion.isScalaBinaryCompatibleWith(newVersion = version, _)
)
svOpt.foreach { sv =>
state.log.info(
s"Falling back ${project.project} to listed $sv instead of unlisted $version"
)
}
(project, svOpt, scalaVersions)
case multiple =>
sys.error(
s"Multiple crossScalaVersions matched query '$version': ${multiple.mkString(", ")}"

View File

@ -1 +1 @@
sbt.version=1.9.0
sbt.version=1.9.1

View File

@ -1,6 +1,8 @@
-> ++2.12.0-magic
-> ++2.12.12
> ++2.12.12
> clean
> ++2.13.11 compile