mirror of https://github.com/sbt/sbt.git
Merge branch 'develop' into bsp-diagnostics-fix
This commit is contained in:
commit
d0b8982bf4
|
|
@ -34,4 +34,14 @@ object Remove {
|
|||
def removeValue(a: Seq[T], b: Option[T]): Seq[T] = b.fold(a)(a filterNot _.==)
|
||||
def removeValues(a: Seq[T], b: Option[T]): Seq[T] = b.fold(a)(a filterNot _.==)
|
||||
}
|
||||
implicit def removeSet[T, V <: T]: Sequence[Set[T], Set[V], V] =
|
||||
new Sequence[Set[T], Set[V], V] {
|
||||
def removeValue(a: Set[T], b: V): Set[T] = a - b
|
||||
def removeValues(a: Set[T], b: Set[V]): Set[T] = a diff (b.toSeq: Seq[T]).toSet
|
||||
}
|
||||
implicit def removeMap[A, B, X <: A]: Sequence[Map[A, B], Seq[X], X] =
|
||||
new Sequence[Map[A, B], Seq[X], X] {
|
||||
def removeValue(a: Map[A, B], b: X): Map[A, B] = a - b
|
||||
def removeValues(a: Map[A, B], b: Seq[X]): Map[A, B] = a -- b
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
package sbt
|
||||
|
||||
import java.io.File
|
||||
|
||||
import java.util.regex.Pattern
|
||||
import sbt.Def.{ ScopedKey, Setting }
|
||||
import sbt.Keys._
|
||||
import sbt.SlashSyntax0._
|
||||
|
|
@ -284,8 +284,8 @@ object Cross {
|
|||
}
|
||||
|
||||
def logSwitchInfo(
|
||||
included: Seq[(ProjectRef, Seq[ScalaVersion])],
|
||||
excluded: Seq[(ProjectRef, Seq[ScalaVersion])]
|
||||
included: Seq[(ResolvedReference, ScalaVersion, Seq[ScalaVersion])],
|
||||
excluded: Seq[(ResolvedReference, Seq[ScalaVersion])]
|
||||
) = {
|
||||
|
||||
instance.foreach {
|
||||
|
|
@ -304,56 +304,96 @@ object Cross {
|
|||
def detailedLog(msg: => String) =
|
||||
if (switch.verbose) state.log.info(msg) else state.log.debug(msg)
|
||||
|
||||
def logProject: (ProjectRef, Seq[ScalaVersion]) => Unit = (proj, scalaVersions) => {
|
||||
val current = if (proj == currentRef) "*" else " "
|
||||
detailedLog(s" $current ${proj.project} ${scalaVersions.mkString("(", ", ", ")")}")
|
||||
def logProject: (ResolvedReference, Seq[ScalaVersion]) => Unit = (ref, scalaVersions) => {
|
||||
val current = if (ref == currentRef) "*" else " "
|
||||
ref match {
|
||||
case proj: ProjectRef =>
|
||||
detailedLog(s" $current ${proj.project} ${scalaVersions.mkString("(", ", ", ")")}")
|
||||
case _ => // don't log BuildRefs
|
||||
}
|
||||
}
|
||||
detailedLog("Switching Scala version on:")
|
||||
included.foreach(logProject.tupled)
|
||||
included.foreach { case (project, _, versions) => logProject(project, versions) }
|
||||
detailedLog("Excluding projects:")
|
||||
excluded.foreach(logProject.tupled)
|
||||
}
|
||||
|
||||
val projects: Seq[(ResolvedReference, Seq[ScalaVersion])] = {
|
||||
val projects: Seq[(ResolvedReference, Option[ScalaVersion], Seq[ScalaVersion])] = {
|
||||
val projectScalaVersions =
|
||||
structure.allProjectRefs.map(proj => proj -> crossVersions(extracted, proj))
|
||||
if (switch.version.force) {
|
||||
logSwitchInfo(projectScalaVersions, Nil)
|
||||
projectScalaVersions ++ structure.units.keys
|
||||
projectScalaVersions.map {
|
||||
case (ref, options) => (ref, Some(version), options)
|
||||
} ++ structure.units.keys
|
||||
.map(BuildRef.apply)
|
||||
.map(proj => proj -> crossVersions(extracted, proj))
|
||||
.map(proj => (proj, Some(version), crossVersions(extracted, proj)))
|
||||
} else if (version.contains('*')) {
|
||||
projectScalaVersions.map {
|
||||
case (project, scalaVersions) =>
|
||||
globFilter(version, scalaVersions) match {
|
||||
case Nil => (project, None, scalaVersions)
|
||||
case Seq(version) => (project, Some(version), scalaVersions)
|
||||
case multiple =>
|
||||
sys.error(
|
||||
s"Multiple crossScalaVersions matched query '$version': ${multiple.mkString(", ")}"
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val binaryVersion = CrossVersion.binaryScalaVersion(version)
|
||||
|
||||
val (included, excluded) = projectScalaVersions.partition {
|
||||
case (_, scalaVersions) =>
|
||||
scalaVersions.exists(v => CrossVersion.binaryScalaVersion(v) == binaryVersion)
|
||||
projectScalaVersions.map {
|
||||
case (project, scalaVersions) =>
|
||||
if (scalaVersions.exists(v => CrossVersion.binaryScalaVersion(v) == binaryVersion))
|
||||
(project, Some(version), scalaVersions)
|
||||
else
|
||||
(project, None, scalaVersions)
|
||||
}
|
||||
if (included.isEmpty) {
|
||||
sys.error(
|
||||
s"""Switch failed: no subprojects list "$version" (or compatible version) in crossScalaVersions setting.
|
||||
|If you want to force it regardless, call ++ $version!""".stripMargin
|
||||
)
|
||||
}
|
||||
logSwitchInfo(included, excluded)
|
||||
included
|
||||
}
|
||||
}
|
||||
|
||||
(setScalaVersionForProjects(version, instance, projects, state, extracted), projects.map(_._1))
|
||||
val included = projects.collect {
|
||||
case (project, Some(version), scalaVersions) => (project, version, scalaVersions)
|
||||
}
|
||||
val excluded = projects.collect {
|
||||
case (project, None, scalaVersions) => (project, scalaVersions)
|
||||
}
|
||||
|
||||
if (included.isEmpty) {
|
||||
sys.error(
|
||||
s"""Switch failed: no subprojects list "$version" (or compatible version) in crossScalaVersions setting.
|
||||
|If you want to force it regardless, call ++ $version!""".stripMargin
|
||||
)
|
||||
}
|
||||
|
||||
logSwitchInfo(included, excluded)
|
||||
|
||||
(setScalaVersionsForProjects(instance, included, state, extracted), included.map(_._1))
|
||||
}
|
||||
|
||||
private def setScalaVersionForProjects(
|
||||
version: String,
|
||||
def globFilter(pattern: String, candidates: Seq[String]): Seq[String] = {
|
||||
def createGlobRegex(remainingPattern: String): String =
|
||||
remainingPattern.indexOf("*") match {
|
||||
case -1 => Pattern.quote(remainingPattern)
|
||||
case n =>
|
||||
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(
|
||||
instance: Option[(File, ScalaInstance)],
|
||||
projects: Seq[(ResolvedReference, Seq[String])],
|
||||
projects: Seq[(ResolvedReference, String, Seq[String])],
|
||||
state: State,
|
||||
extracted: Extracted
|
||||
): State = {
|
||||
import extracted._
|
||||
|
||||
val newSettings = projects.flatMap {
|
||||
case (project, scalaVersions) =>
|
||||
case (project, version, scalaVersions) =>
|
||||
val scope = Scope(Select(project), Zero, Zero, Zero)
|
||||
|
||||
instance match {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -41,3 +41,24 @@ $ exists lib/target/scala-2.13
|
|||
-$ exists lib/target/scala-2.12
|
||||
# -$ exists sbt-foo/target/scala-2.12
|
||||
-$ exists sbt-foo/target/scala-2.13
|
||||
|
||||
# test wildcard switching (2.12)
|
||||
> clean
|
||||
> ++ 2.12.* -v compile
|
||||
$ exists lib/target/scala-2.12
|
||||
-$ exists lib/target/scala-2.13
|
||||
$ exists sbt-foo/target/scala-2.12
|
||||
-$ exists sbt-foo/target/scala-2.13
|
||||
|
||||
# test wildcard switching (2.13)
|
||||
> clean
|
||||
> ++ 2.13.* -v compile
|
||||
$ exists lib/target/scala-2.13
|
||||
-$ exists lib/target/scala-2.12
|
||||
# -$ exists sbt-foo/target/scala-2.12
|
||||
-$ exists sbt-foo/target/scala-2.13
|
||||
|
||||
# test wildcard switching (no matches)
|
||||
-> ++ 3.*
|
||||
# test wildcard switching (multiple matches)
|
||||
-> ++ 2.*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
val intsTask = taskKey[Seq[Int]]("A seq of ints task")
|
||||
val intsSetting = settingKey[Seq[Int]]("A seq of ints setting")
|
||||
val intsFromScalaV = settingKey[Seq[Int]]("a seq of ints from scalaVersion")
|
||||
val intsSetSetting = settingKey[Set[Int]]("A set of ints setting")
|
||||
val stringIntMapSetting = settingKey[Map[String, Int]]("A map of string to int setting")
|
||||
|
||||
scalaVersion := "2.11.6"
|
||||
|
||||
|
|
@ -22,9 +24,19 @@ intsFromScalaV --= { if (scalaVersion.value == "2.11.6") Seq(1, 2) else Seq(4) }
|
|||
intsFromScalaV -= { if (scalaVersion.value == "2.11.6") Option(6) else None }
|
||||
intsFromScalaV --= { if (scalaVersion.value == "2.11.6") Option(7) else None }
|
||||
|
||||
intsSetSetting := Set(1, 2, 3, 4, 5, 6, 7)
|
||||
intsSetSetting -= 3
|
||||
intsSetSetting --= Set(1, 2)
|
||||
|
||||
stringIntMapSetting := Map("a" -> 1, "b" -> 2 , "c" -> 3, "d" -> 4, "e" -> 5)
|
||||
stringIntMapSetting -= "c"
|
||||
stringIntMapSetting --= Seq("a", "b")
|
||||
|
||||
val check = taskKey[Unit]("Runs the check")
|
||||
check := {
|
||||
assert(intsTask.value == Seq(4, 5), s"intsTask should be Seq(4, 5) but is ${intsTask.value}")
|
||||
assert(intsSetting.value == Seq(4, 5), s"intsSetting should be Seq(4, 5) but is ${intsSetting.value}")
|
||||
assert(intsFromScalaV.value == Seq(4, 5), s"intsFromScalaV should be Seq(4, 5) but is ${intsFromScalaV.value}")
|
||||
assert(intsSetSetting.value == Set(4, 5, 6, 7), s"intsSetSetting should be Set(4, 5, 6, 7) but is ${intsSetSetting.value}")
|
||||
assert(stringIntMapSetting.value == Map("d" -> 4, "e" -> 5), s"stringIntMapSetting should be Map(d -> 4, e -> 5) but is ${stringIntMapSetting.value}")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue