Remove compatibility check from ++

Problem
-------
Since sbt-doge merger `++ <sv> <command1>` has used binary compatibility
as a test to select subproject, but it causes surprising situations like
sbt/sbt#6915, and it blurs the responsibility of YAML file and build
file as the version specified in the version can override the Scala
version test on local laptop.

Solution
--------
This removes the compatibiliy check (backward-only or otherwise),
and require that `<sv>` match one of `crossScalaVersions` using the new
Semantic Version selector pattern.
This commit is contained in:
Eugene Yokota 2022-07-02 18:19:42 -04:00
parent 6d0ef2093d
commit 05d3d8689b
4 changed files with 16 additions and 19 deletions

View File

@ -19,7 +19,7 @@ import sbt.internal.util.MessageOnlyException
import sbt.internal.util.complete.DefaultParsers._ import sbt.internal.util.complete.DefaultParsers._
import sbt.internal.util.complete.{ DefaultParsers, Parser } import sbt.internal.util.complete.{ DefaultParsers, Parser }
import sbt.io.IO import sbt.io.IO
import sbt.librarymanagement.{ CrossVersion, SemanticSelector, VersionNumber } import sbt.librarymanagement.{ SemanticSelector, VersionNumber }
/** /**
* Cross implements the Scala cross building commands: * Cross implements the Scala cross building commands:
@ -334,10 +334,10 @@ object Cross {
} ++ structure.units.keys } ++ structure.units.keys
.map(BuildRef.apply) .map(BuildRef.apply)
.map(proj => (proj, Some(version), crossVersions(extracted, proj))) .map(proj => (proj, Some(version), crossVersions(extracted, proj)))
} else if (isSelector(version)) { } else {
val selector = SemanticSelector(version)
projectScalaVersions.map { projectScalaVersions.map {
case (project, scalaVersions) => case (project, scalaVersions) =>
val selector = SemanticSelector(version)
scalaVersions.filter(v => selector.matches(VersionNumber(v))) match { scalaVersions.filter(v => selector.matches(VersionNumber(v))) match {
case Nil => (project, None, scalaVersions) case Nil => (project, None, scalaVersions)
case Seq(version) => (project, Some(version), scalaVersions) case Seq(version) => (project, Some(version), scalaVersions)
@ -347,18 +347,7 @@ object Cross {
) )
} }
} }
} else }
// This is the default implementation for ++ <sv> <command1>
// It checks that <sv> is backward compatible with one of the Scala versions listed
// in crossScalaVersions setting. Note this must account for the fact that in Scala 3.x
// 3.1.0 is not compatible with 3.0.0.
projectScalaVersions.map {
case (project, scalaVersions) =>
if (scalaVersions.exists(CrossVersion.isScalaBinaryCompatibleWith(version, _)))
(project, Some(version), scalaVersions)
else
(project, None, scalaVersions)
}
} }
val included = projects.collect { val included = projects.collect {

View File

@ -387,17 +387,23 @@ $SwitchCommand [<scala-version>=]<scala-home>[!] [-v] [<command>]
Uses the Scala installation at <scala-home> by configuring the scalaHome setting for Uses the Scala installation at <scala-home> by configuring the scalaHome setting for
all projects. all projects.
If <scala-version> is specified, it is used as the value of the scalaVersion setting. If <scala-version> is specified, it is used to select the value of the scalaVersion setting
from one of the values of crossScalaVersions setting.
This is important when using managed dependencies. This version will determine the This is important when using managed dependencies. This version will determine the
cross-version used as well as transitive dependencies. cross-version used as well as transitive dependencies.
Only projects that are listed to be binary compatible with the selected Scala version <scala-version> may be an actual Scala version such as 3.1.3, or a Semantic Version selector
pattern such as 2.13.x. Only subprojects that are listed to match the version pattern
have their Scala version switched. If ! is supplied, then all projects projects have have their Scala version switched. If ! is supplied, then all projects projects have
their Scala version switched. their Scala version switched.
If -v is supplied, verbose logging of the Scala version switching is done. If -v is supplied, verbose logging of the Scala version switching is done.
If <command> is provided, it is then executed. If <command> is provided, it is then executed. For example:
++ 2.13.x test
The above will run test on all subprojects that contain a 2.13 Scala version.
See also `help $CrossCommand` See also `help $CrossCommand`
""" """

View File

@ -1,4 +1,4 @@
lazy val scala212 = "2.12.12" lazy val scala212 = "2.12.16"
lazy val scala213 = "2.13.1" lazy val scala213 = "2.13.1"
ThisBuild / scalaVersion := scala212 ThisBuild / scalaVersion := scala212

View File

@ -1,5 +1,7 @@
-> ++2.12.0-magic -> ++2.12.0-magic
-> ++2.12.12
> ++2.13.1 compile > ++2.13.1 compile
$ exists core/target/scala-2.13 $ exists core/target/scala-2.13