mirror of https://github.com/sbt/sbt.git
More flexible Scala version switch
By using SemanticSelector instead of custom globbing. Follow-up on https://github.com/sbt/sbt/pull/6894, fixes https://github.com/sbt/sbt/issues/6934
This commit is contained in:
parent
1db7dd328a
commit
8973fce1fa
|
|
@ -8,7 +8,6 @@
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.regex.Pattern
|
|
||||||
import sbt.Def.{ ScopedKey, Setting }
|
import sbt.Def.{ ScopedKey, Setting }
|
||||||
import sbt.Keys._
|
import sbt.Keys._
|
||||||
import sbt.SlashSyntax0._
|
import sbt.SlashSyntax0._
|
||||||
|
|
@ -19,7 +18,7 @@ import sbt.internal.util.AttributeKey
|
||||||
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
|
import sbt.librarymanagement.{ CrossVersion, SemanticSelector, VersionNumber }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cross implements the Scala cross building commands:
|
* Cross implements the Scala cross building commands:
|
||||||
|
|
@ -327,10 +326,11 @@ 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 (version.contains('*')) {
|
} else if (isSelector(version)) {
|
||||||
|
val selector = SemanticSelector(version)
|
||||||
projectScalaVersions.map {
|
projectScalaVersions.map {
|
||||||
case (project, scalaVersions) =>
|
case (project, scalaVersions) =>
|
||||||
globFilter(version, scalaVersions) 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)
|
||||||
case multiple =>
|
case multiple =>
|
||||||
|
|
@ -370,19 +370,13 @@ object Cross {
|
||||||
(setScalaVersionsForProjects(instance, included, state, extracted), included.map(_._1))
|
(setScalaVersionsForProjects(instance, included, state, extracted), included.map(_._1))
|
||||||
}
|
}
|
||||||
|
|
||||||
def globFilter(pattern: String, candidates: Seq[String]): Seq[String] = {
|
// determine whether this is a 'specific' version or a selector
|
||||||
def createGlobRegex(remainingPattern: String): String =
|
// to be passed to SemanticSelector
|
||||||
remainingPattern.indexOf("*") match {
|
private def isSelector(version: String): Boolean =
|
||||||
case -1 => Pattern.quote(remainingPattern)
|
version.contains('*') || version.contains('x') || version.contains('X') || version.contains(' ') ||
|
||||||
case n =>
|
version.contains('<') || version.contains('>') || version.contains('|') || version.contains(
|
||||||
val chunk = Pattern.quote(remainingPattern.substring(0, n)) + ".*"
|
'='
|
||||||
if (remainingPattern.length > n)
|
)
|
||||||
chunk + createGlobRegex(remainingPattern.substring(n + 1))
|
|
||||||
else chunk
|
|
||||||
}
|
|
||||||
val compiledPattern = Pattern.compile(createGlobRegex(pattern))
|
|
||||||
candidates.filter(compiledPattern.matcher(_).matches())
|
|
||||||
}
|
|
||||||
|
|
||||||
private def setScalaVersionsForProjects(
|
private def setScalaVersionsForProjects(
|
||||||
instance: Option[(File, ScalaInstance)],
|
instance: Option[(File, ScalaInstance)],
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
* sbt
|
|
||||||
* Copyright 2011 - 2018, Lightbend, Inc.
|
|
||||||
* Copyright 2008 - 2010, Mark Harrah
|
|
||||||
* Licensed under Apache License 2.0 (see LICENSE)
|
|
||||||
*/
|
|
||||||
|
|
||||||
package sbt
|
|
||||||
|
|
||||||
object CrossSpec extends verify.BasicTestSuite {
|
|
||||||
import Cross._
|
|
||||||
|
|
||||||
test("glob filter should work as expected") {
|
|
||||||
assert(globFilter("2.13.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Seq("2.13.16"))
|
|
||||||
assert(globFilter("3.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Seq("3.0.1"))
|
|
||||||
assert(globFilter("3.*", Seq("3.0.1", "30.1")) == Seq("3.0.1"))
|
|
||||||
assert(globFilter("2.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Seq("2.12.8", "2.13.16"))
|
|
||||||
assert(globFilter("4.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -52,7 +52,7 @@ $ exists sbt-foo/target/scala-2.12
|
||||||
|
|
||||||
# test wildcard switching (2.13)
|
# test wildcard switching (2.13)
|
||||||
> clean
|
> clean
|
||||||
> ++ 2.13.* -v compile
|
> ++ 2.13.x -v compile
|
||||||
$ exists lib/target/scala-2.13
|
$ exists lib/target/scala-2.13
|
||||||
-$ exists lib/target/scala-2.12
|
-$ exists lib/target/scala-2.12
|
||||||
# -$ exists sbt-foo/target/scala-2.12
|
# -$ exists sbt-foo/target/scala-2.12
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue