diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5ace4600a1..a9173d91a7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,3 +4,10 @@ updates: directory: "/" schedule: interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + target-branch: "develop" + commit-message: + prefix: "[2.x] " diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc7a5dc195..88c47b39e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,30 +12,30 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-20.04 - java: 17 + - os: ubuntu-22.04 + java: 21 distribution: temurin jobtype: 1 - os: ubuntu-latest - java: 17 + java: 21 distribution: temurin jobtype: 2 - os: ubuntu-latest - java: 17 + java: 21 distribution: temurin jobtype: 3 - os: ubuntu-latest - java: 17 + java: 21 distribution: temurin jobtype: 4 - os: ubuntu-latest - java: 17 + java: 21 distribution: temurin jobtype: 5 - - os: ubuntu-latest - java: 8 - distribution: adopt - jobtype: 6 + # - os: ubuntu-latest + # java: 8 + # distribution: adopt + # jobtype: 6 - os: ubuntu-latest java: 8 distribution: adopt @@ -49,14 +49,13 @@ jobs: distribution: adopt jobtype: 9 runs-on: ${{ matrix.os }} + timeout-minutes: 25 env: JAVA_OPTS: -Xms800M -Xmx2G -Xss6M -XX:ReservedCodeCacheSize=128M -server -Dsbt.io.virtual=false -Dfile.encoding=UTF-8 JVM_OPTS: -Xms800M -Xmx2G -Xss6M -XX:ReservedCodeCacheSize=128M -server -Dsbt.io.virtual=false -Dfile.encoding=UTF-8 - SCALA_212: 2.12.19 - SCALA_3: 3.1.0 + SCALA_212: 2.12.20 UTIL_TESTS: "utilCache/test utilControl/test utilInterface/test utilLogging/test utilPosition/test utilRelation/test utilScripted/test utilTracking/test" - SBT_LOCAL: false - TEST_SBT_VER: 1.5.0 + TEST_SBT_VER: 1.10.7 SBT_ETC_FILE: $HOME/etc/sbt/sbtopts JDK11: adopt@1.11.0-9 SPARK_LOCAL_IP: "127.0.0.1" @@ -79,13 +78,15 @@ jobs: uses: actions/checkout@v4 with: repository: sbt/zinc - ref: develop + ref: 1.10.x path: zinc - name: Setup JDK uses: actions/setup-java@v4 with: distribution: "${{ matrix.distribution }}" java-version: "${{ matrix.java }}" + - name: Setup SBT + uses: sbt/setup-sbt@v1 - name: Set up Python 3.12 uses: actions/setup-python@v5 with: @@ -140,13 +141,13 @@ jobs: if: ${{ matrix.jobtype == 5 }} shell: bash run: | - ./sbt -v "++2.13.x; all utilControl/test utilRelation/test utilPosition/test; ++$SCALA_3!; all utilControl/test utilRelation/test utilPosition/test" - - name: Build and test (6) + ./sbt -v "++2.13.x; all utilControl/test utilRelation/test utilPosition/test" + - name: Multirepo integration test if: ${{ matrix.jobtype == 6 }} shell: bash run: | # build from fresh IO, LM, and Zinc - BUILD_VERSION="1.5.0-SNAPSHOT" + BUILD_VERSION="${TEST_SBT_VER}-SNAPSHOT" cd io sbt -v -Dsbt.build.version=${BUILD_VERSION} +publishLocal cd ../ @@ -159,6 +160,9 @@ jobs: run: | # test building sbtn on Linux sbt "-Dsbt.io.virtual=false" nativeImage + # smoke test native Image + ./client/target/bin/sbtn --sbt-script=$(pwd)/sbt about + ./client/target/bin/sbtn --sbt-script=$(pwd)/sbt shutdown # test launcher script echo build using JDK 8 test using JDK 8 and JDK 11 cd launcher-package @@ -186,6 +190,9 @@ jobs: run: | # test building sbtn on Windows sbt "-Dsbt.io.virtual=false" nativeImage + # smoke test native Image + ./client/target/bin/sbtn --sbt-script=$(pwd)/launcher-package/src/universal/bin/sbt.bat about + ./client/target/bin/sbtn --sbt-script=$(pwd)/launcher-package/src/universal/bin/sbt.bat shutdown # test launcher script echo build using JDK 8, test using JDK 8, on Windows cd launcher-package diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index f9ead39fdc..c7ec83e666 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -4,21 +4,7 @@ jobs: check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Check CLA - env: - AUTHOR: ${{ github.event.pull_request.user.login }} - run: | - echo "Pull request submitted by $AUTHOR"; - signed=$(curl -s "https://www.lightbend.com/contribute/cla/scala/check/$AUTHOR" | jq -r ".signed"); - if [ "$signed" = "true" ] ; then - echo "CLA check for $AUTHOR successful"; - else - echo "CLA check for $AUTHOR failed"; - echo "Please sign the Scala CLA to contribute to the Scala compiler."; - echo "Go to https://www.lightbend.com/contribute/cla/scala and then"; - echo "comment on the pull request to ask for a new check."; - echo ""; - echo "Check if CLA is signed: https://www.lightbend.com/contribute/cla/scala/check/$AUTHOR"; - exit 1; - fi; + - name: Check CLA + uses: scala/cla-checker@v1 + with: + author: ${{ github.event.pull_request.user.login }} diff --git a/.github/workflows/dependency-graph.yml b/.github/workflows/dependency-graph.yml index de558d3bb3..387a2a275f 100644 --- a/.github/workflows/dependency-graph.yml +++ b/.github/workflows/dependency-graph.yml @@ -2,7 +2,7 @@ name: Submit Dependency Graph on: push: - branches: [1.9.x] # default branch of the project + branches: [1.10.x, develop] permissions: {} jobs: submit-graph: @@ -13,4 +13,5 @@ jobs: runs-on: ubuntu-latest # or windows-latest, or macOS-latest steps: - uses: actions/checkout@v4 + - uses: sbt/setup-sbt@v1 - uses: scalacenter/sbt-dependency-submission@v3 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 767d589869..2ae4630801 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -38,7 +38,7 @@ jobs: uses: actions/checkout@v4 with: repository: sbt/zinc - ref: develop + ref: 1.10.x path: zinc - name: Setup JDK uses: actions/setup-java@v4 diff --git a/.java-version b/.java-version deleted file mode 100644 index 6259340971..0000000000 --- a/.java-version +++ /dev/null @@ -1 +0,0 @@ -1.8 diff --git a/DEVELOPING.md b/DEVELOPING.md index 8616765d3e..a56641dd08 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -18,6 +18,12 @@ The `develop` branch represents sbt 2.x, the next major sbt series. Next minor branch is where new features should be added as long as it is binary compatible with sbt 1.x. The `stable` branch represents the current stable sbt release. Only bug fixes are back-ported to the stable branch. +### Note on supported JDK version for the sbt build + +The sbt build itself currently doesn't support any JDK beyond version 21. You may run into deprecation warnings (which would become build errors due to build configuration) if you use any later JDK version to build sbt. + +If you're using Metals as IDE, also check the `Java Version` setting. The default at the time of writing this is `17`, but this may change in the future, or you may have set it to a later version yourself. (Be aware that Metals may download a JDK in the background if you haven't switch to a local JDK matching the version before changing this setting. Also, this setting is currently only available as a `User` setting, so you can't set it for a single workspace. Don't forget to switch back if you need to for other projects). + ### Instruction to build just sbt Sbt has a number of sub-modules. If the change you are making is just contained in sbt/sbt (not one of the sub-modules), diff --git a/build.sbt b/build.sbt index 3eba2b7190..84d5c182cf 100644 --- a/build.sbt +++ b/build.sbt @@ -11,7 +11,7 @@ import scala.util.Try // ThisBuild settings take lower precedence, // but can be shared across the multi projects. ThisBuild / version := { - val v = "1.10.0-SNAPSHOT" + val v = "1.10.11-SNAPSHOT" nightlyVersion.getOrElse(v) } ThisBuild / version2_13 := "2.0.0-SNAPSHOT" @@ -48,7 +48,7 @@ ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" Global / semanticdbEnabled := !(Global / insideCI).value // Change main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala too, if you change this. -Global / semanticdbVersion := "4.7.8" +Global / semanticdbVersion := "4.9.9" val excludeLint = SettingKey[Set[Def.KeyedInitialize[_]]]("excludeLintKeys") Global / excludeLint := (Global / excludeLint).?.value.getOrElse(Set.empty) Global / excludeLint += componentID @@ -378,8 +378,8 @@ lazy val utilLogging = (project in file("internal") / "util-logging") Seq( jline, jline3Terminal, - jline3JNA, - jline3Jansi, + jline3JNI, + jline3Native, log4jApi, log4jCore, disruptor, @@ -758,7 +758,7 @@ lazy val protocolProj = (project in file("protocol")) // General command support and core commands not specific to a build system lazy val commandProj = (project in file("main-command")) .enablePlugins(ContrabandPlugin, JsonCodecPlugin) - .dependsOn(protocolProj, completeProj, utilLogging) + .dependsOn(protocolProj, completeProj, utilLogging, runProj) .settings( testedBaseSettings, name := "Command", @@ -1071,6 +1071,8 @@ lazy val mainProj = (project in file("main")) exclude[MissingClassProblem]("sbt.internal.server.BuildServerReporter$"), exclude[IncompatibleTemplateDefProblem]("sbt.internal.server.BuildServerReporter"), exclude[MissingClassProblem]("sbt.internal.CustomHttp*"), + exclude[ReversedMissingMethodProblem]("sbt.JobHandle.isAutoCancel"), + exclude[ReversedMissingMethodProblem]("sbt.BackgroundJobService.createWorkingDirectory"), ) ) .configure( @@ -1165,23 +1167,32 @@ lazy val sbtClientProj = (project in file("client")) .dependsOn(commandProj) .settings( commonBaseSettings, - scalaVersion := "2.12.11", // The thin client does not build with 2.12.12 publish / skip := true, name := "sbt-client", mimaPreviousArtifacts := Set.empty, crossPaths := false, exportJars := true, - libraryDependencies += jansi, libraryDependencies += scalatest % Test, Compile / mainClass := Some("sbt.client.Client"), nativeImageReady := { () => () }, - nativeImageVersion := "22.2.0", - nativeImageOutput := target.value / "bin" / "sbtn", + nativeImageVersion := "23.0", + nativeImageJvm := "graalvm-java23", + nativeImageOutput := { + val outputDir = (target.value / "bin").toPath + if (!Files.exists(outputDir)) { + Files.createDirectories(outputDir) + } + outputDir.resolve("sbtn").toFile + }, nativeImageOptions ++= Seq( "--no-fallback", s"--initialize-at-run-time=sbt.client", + // "The current machine does not support all of the following CPU features that are required by + // the image: [CX8, CMOV, FXSR, MMX, SSE, SSE2, SSE3, SSSE3, SSE4_1, SSE4_2, POPCNT, LZCNT, AVX, + // AVX2, BMI1, BMI2, FMA, F16C]." + "-march=compatibility", // "--verbose", "-H:IncludeResourceBundles=jline.console.completer.CandidateListCompletionHandler", "-H:+ReportExceptionStackTraces", @@ -1305,52 +1316,6 @@ lazy val sbtIgnoredProblems = { ) } -def runNpm(command: String, base: File, log: sbt.internal.util.ManagedLogger) = { - import scala.sys.process._ - try { - val exitCode = Process(s"npm $command", Option(base)) ! log - if (exitCode != 0) throw new Exception("Process returned exit code: " + exitCode) - } catch { - case e: java.io.IOException => log.warn("failed to run npm " + e.getMessage) - } -} - -lazy val vscodePlugin = (project in file("vscode-sbt-scala")) - .settings( - bspEnabled := false, - crossPaths := false, - crossScalaVersions := Seq(baseScalaVersion), - publish / skip := true, - Compile / compile := { - val _ = update.value - runNpm("run compile", baseDirectory.value, streams.value.log) - sbt.internal.inc.Analysis.empty - }, - update := { - val old = update.value - val t = target.value / "updated" - val base = baseDirectory.value - val log = streams.value.log - if (t.exists) () - else { - runNpm("install", base, log) - IO.touch(t) - } - old - }, - cleanFiles ++= { - val base = baseDirectory.value - Vector( - target.value / "updated", - base / "node_modules", - base / "client" / "node_modules", - base / "client" / "server", - base / "client" / "out", - base / "server" / "node_modules" - ) filter { _.exists } - } - ) - def scriptedTask(launch: Boolean): Def.Initialize[InputTask[Unit]] = Def.inputTask { val _ = publishLocalBinAll.value val launchJar = s"-Dsbt.launch.jar=${(bundledLauncherProj / Compile / packageBin).value}" @@ -1464,7 +1429,7 @@ lazy val docProjects: ScopeFilter = ScopeFilter( inConfigurations(Compile) ) lazy val javafmtOnCompile = taskKey[Unit]("Formats java sources before compile") -lazy val scriptedProjects = ScopeFilter(inAnyProject -- inProjects(vscodePlugin)) +lazy val scriptedProjects = ScopeFilter(inAnyProject) def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("setupBuildScala212") { state => diff --git a/client/src/main/java/sbt/client/Client.java b/client/src/main/java/sbt/client/Client.java index 6ffe838ffe..491d725b88 100644 --- a/client/src/main/java/sbt/client/Client.java +++ b/client/src/main/java/sbt/client/Client.java @@ -9,19 +9,17 @@ package sbt.client; import sbt.internal.client.NetworkClient; -import java.nio.file.Paths; -import org.fusesource.jansi.AnsiConsole; public class Client { public static void main(final String[] args) { - boolean isWin = System.getProperty("os.name").toLowerCase().startsWith("win"); + boolean hadError = false; try { - if (isWin) AnsiConsole.systemInstall(); NetworkClient.main(args); } catch (final Throwable t) { t.printStackTrace(); + hadError = true; } finally { - if (isWin) AnsiConsole.systemUninstall(); + if (hadError) System.exit(1); } } } diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Util.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Util.scala index 324c62dfb2..4e4d3e8b7c 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Util.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Util.scala @@ -8,10 +8,13 @@ package sbt.internal.util +import java.nio.file.{ Path, Paths } import java.util.Locale import scala.reflect.macros.blackbox import scala.language.experimental.macros +import scala.language.reflectiveCalls +import scala.util.control.NonFatal object Util { def makeList[T](size: Int, value: T): List[T] = List.fill(size)(value) @@ -77,4 +80,50 @@ object Util { class Macro(val c: blackbox.Context) { def ignore(f: c.Tree): c.Expr[Unit] = c.universe.reify({ c.Expr[Any](f).splice; () }) } + + /** + * Given a list of event handlers expressed partial functions, combine them + * together using orElse from the left. + */ + def reduceIntents[A1, A2](intents: PartialFunction[A1, A2]*): PartialFunction[A1, A2] = + intents.toList.reduceLeft(_ orElse _) + + lazy val majorJavaVersion: Int = + try { + val javaVersion = sys.props.get("java.version").getOrElse("1.0") + if (javaVersion.startsWith("1.")) { + javaVersion.split("\\.")(1).toInt + } else { + javaVersion.split("\\.")(0).toInt + } + } catch { + case NonFatal(_) => 0 + } + + private type GetId = { + def getId: Long + } + private type ThreadId = { + def threadId: Long + } + + /** + * Returns current thread id. + * Thread.threadId was added in JDK 19, and deprecated Thread#getId + * https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Thread.html#threadId() + */ + def threadId: Long = + if (majorJavaVersion < 19) { + (Thread.currentThread(): AnyRef) match { + case g: GetId @unchecked => g.getId + } + } else { + (Thread.currentThread(): AnyRef) match { + case g: ThreadId @unchecked => g.threadId + } + } + + lazy val javaHome: Path = + if (sys.props("java.home").endsWith("jre")) Paths.get(sys.props("java.home")).getParent() + else Paths.get(sys.props("java.home")) } diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala b/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala index 20db30ab02..9b8b86d4f2 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala @@ -130,7 +130,7 @@ object LineReader { Option(mask.map(reader.readLine(prompt, _)).getOrElse(reader.readLine(prompt))) } catch { case e: EndOfFileException => - if (terminal == Terminal.console && System.console == null) None + if (terminal == Terminal.console && !Terminal.hasConsole) None else Some("exit") case _: IOError | _: ClosedException => Some("exit") case _: UserInterruptException | _: ClosedByInterruptException | diff --git a/internal/util-control/src/main/scala/sbt/internal/util/ErrorHandling.scala b/internal/util-control/src/main/scala/sbt/internal/util/ErrorHandling.scala index 06160b3cd0..58b460ccbc 100644 --- a/internal/util-control/src/main/scala/sbt/internal/util/ErrorHandling.scala +++ b/internal/util-control/src/main/scala/sbt/internal/util/ErrorHandling.scala @@ -23,9 +23,16 @@ object ErrorHandling { try { Right(f) } catch { - case ex @ (_: Exception | _: StackOverflowError) => Left(ex) - case err @ (_: ThreadDeath | _: VirtualMachineError) => throw err - case x: Throwable => Left(x) + case ex @ (_: Exception | _: StackOverflowError) => + Left(ex) + case err: VirtualMachineError => + throw err + case err if err.getClass.getName == "java.lang.ThreadDeath" => + // ThreadDeath is deprecated + // https://bugs.openjdk.org/browse/JDK-8289610 + throw err + case x: Throwable => + Left(x) } def convert[T](f: => T): Either[Exception, T] = diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/JLine3.scala b/internal/util-logging/src/main/scala/sbt/internal/util/JLine3.scala index bea9b3c995..51b2c5e408 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/JLine3.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/JLine3.scala @@ -19,9 +19,8 @@ import org.jline.terminal.{ Attributes, Size, Terminal => JTerminal } import org.jline.terminal.Attributes.{ InputFlag, LocalFlag } import org.jline.terminal.Terminal.SignalHandler import org.jline.terminal.impl.{ AbstractTerminal, DumbTerminal } -import org.jline.terminal.impl.jansi.JansiTerminalProvider import org.jline.terminal.spi.{ SystemStream, TerminalProvider } -import org.jline.utils.OSUtils +import sbt.internal.util.Terminal.hasConsole import scala.collection.JavaConverters._ import scala.util.Try import java.util.concurrent.LinkedBlockingQueue @@ -29,41 +28,13 @@ import java.util.concurrent.LinkedBlockingQueue private[sbt] object JLine3 { private[util] val initialAttributes = new AtomicReference[Attributes] - private[this] val forceWindowsJansiHolder = new AtomicBoolean(false) - private[sbt] def forceWindowsJansi(): Unit = forceWindowsJansiHolder.set(true) - private[this] def windowsJansi(): org.jline.terminal.Terminal = { - val provider = new JansiTerminalProvider - val termType = sys.props.get("org.jline.terminal.type").orElse(sys.env.get("TERM")).orNull - provider.winSysTerminal( - "console", - termType, - OSUtils.IS_CONEMU, - Charset.forName("UTF-8"), - false, - SignalHandler.SIG_DFL, - true, - SystemStream.Output - ) - } - private val jansi = { - val (major, minor) = - (JansiTerminalProvider.getJansiMajorVersion, JansiTerminalProvider.getJansiMinorVersion) - (major > 1 || minor >= 18) && Util.isWindows - } private[util] def system: org.jline.terminal.Terminal = { val term = - if (forceWindowsJansiHolder.get) windowsJansi() - else { - // Only use jna on windows. Both jna and jansi use illegal reflective - // accesses on posix system. - org.jline.terminal.TerminalBuilder - .builder() - .system(System.console != null) - .jna(Util.isWindows && !jansi) - .jansi(jansi) - .paused(true) - .build() - } + org.jline.terminal.TerminalBuilder + .builder() + .system(hasConsole) + .paused(true) + .build() initialAttributes.get match { case null => initialAttributes.set(term.getAttributes) case _ => diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala b/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala index 85176a9889..9a1a3c8a87 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala @@ -273,7 +273,7 @@ object Terminal { * the sbt client to detach from the server it launches. */ def close(): Unit = { - if (System.console == null) { + if (!hasConsole) { originalOut.close() originalIn.close() originalErr.close() @@ -350,7 +350,17 @@ object Terminal { private[this] val isDumb = Some("dumb") == sys.env.get("TERM") private[this] def isDumbTerminal = isDumb || System.getProperty("jline.terminal", "") == "none" - private[this] val hasConsole = Option(java.lang.System.console).isDefined + private[sbt] val hasConsole = { + System.console != null && { + try { + val isTerminal = System.console.getClass.getMethod("isTerminal") + isTerminal.invoke(System.console).asInstanceOf[Boolean] + } catch { + case _: NoSuchMethodException => + true + } + } + } private[this] def useColorDefault: Boolean = { // This approximates that both stdin and stdio are connected, // so by default color will be turned off for pipes and redirects. @@ -692,7 +702,7 @@ object Terminal { inputStream.read match { case -1 => case `NO_BOOT_CLIENTS_CONNECTED` => - if (System.console == null) { + if (!Terminal.hasConsole) { result.put(-1) running.set(false) } diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/WindowsInputStream.scala b/internal/util-logging/src/main/scala/sbt/internal/util/WindowsInputStream.scala index 4c0f42f01e..0fd469a502 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/WindowsInputStream.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/WindowsInputStream.scala @@ -11,7 +11,7 @@ package sbt.internal.util import java.io.InputStream import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.atomic.AtomicBoolean -import org.fusesource.jansi.internal.Kernel32 +import org.jline.nativ.Kernel32 import org.jline.utils.InfoCmp.Capability import scala.annotation.tailrec import Terminal.SimpleInputStream diff --git a/internal/util-scripted/src/main/scala/sbt/internal/scripted/FileCommands.scala b/internal/util-scripted/src/main/scala/sbt/internal/scripted/FileCommands.scala index 1de3ff6075..a8bd975446 100644 --- a/internal/util-scripted/src/main/scala/sbt/internal/scripted/FileCommands.scala +++ b/internal/util-scripted/src/main/scala/sbt/internal/scripted/FileCommands.scala @@ -11,11 +11,15 @@ package internal package scripted import java.io.File +import sbt.nio.file.{ FileTreeView, Glob, PathFilter, RecursiveGlob } import sbt.io.{ IO, Path } import sbt.io.syntax._ import Path._ class FileCommands(baseDirectory: File) extends BasicStatementHandler { + final val OR = "||" + lazy val view = FileTreeView.Ops(FileTreeView.default) + val baseGlob = Glob(baseDirectory) lazy val commands = commandMap def commandMap = Map( @@ -51,8 +55,42 @@ class FileCommands(baseDirectory: File) extends BasicStatementHandler { def spaced[T](l: Seq[T]) = l.mkString(" ") def fromStrings(paths: List[String]) = paths.map(fromString) def fromString(path: String) = new File(baseDirectory, path) + def filterFromStrings(exprs: List[String]): List[PathFilter] = { + def globs(exprs: List[String]): List[PathFilter] = + exprs.map { g => + if (g.startsWith("/")) (Glob(g): PathFilter) + else (Glob(baseDirectory, g): PathFilter) + } + def orGlobs = { + val exprs1 = exprs + .mkString("") + .split(OR) + .filter(_ != OR) + .toList + .map(_.trim) + val combined = globs(exprs1) match { + case Nil => sys.error("unexpected Nil") + case g :: Nil => g + case g :: gs => + gs.foldLeft(g) { + case (acc, g) => acc || g + } + } + List(combined) + } + if (exprs.contains("||")) orGlobs + else globs(exprs) + } + def touch(paths: List[String]): Unit = IO.touch(fromStrings(paths)) - def delete(paths: List[String]): Unit = IO.delete(fromStrings(paths)) + def delete(paths: List[String]): Unit = + IO.delete( + (filterFromStrings(paths) + .flatMap { filter => + view.list(baseGlob / RecursiveGlob, filter) + }) + .map(_._1.toFile) + ) /*def sync(from: String, to: String) = IO.sync(fromString(from), fromString(to), log)*/ def copyFile(from: String, to: String): Unit = @@ -78,13 +116,16 @@ class FileCommands(baseDirectory: File) extends BasicStatementHandler { scriptError(s"$pathA is not newer than $pathB") } } + // use FileTreeView to test if a file with the given filter exists + def exists0(filter: PathFilter): Boolean = + view.list(baseGlob / RecursiveGlob, filter).nonEmpty def exists(paths: List[String]): Unit = { - val notPresent = fromStrings(paths).filter(!_.exists) + val notPresent = filterFromStrings(paths).filter(!exists0(_)) if (notPresent.nonEmpty) scriptError("File(s) did not exist: " + notPresent.mkString("[ ", " , ", " ]")) } def absent(paths: List[String]): Unit = { - val present = fromStrings(paths).filter(_.exists) + val present = filterFromStrings(paths).filter(exists0) if (present.nonEmpty) scriptError("File(s) existed: " + present.mkString("[ ", " , ", " ]")) } diff --git a/launcher-package/build.sbt b/launcher-package/build.sbt index 436ab3c48d..b58d8b2770 100755 --- a/launcher-package/build.sbt +++ b/launcher-package/build.sbt @@ -26,7 +26,7 @@ lazy val sbtVersionToRelease = sys.props.getOrElse("sbt.build.version", sys.env. })) lazy val scala210 = "2.10.7" -lazy val scala212 = "2.12.19" +lazy val scala212 = "2.12.20" lazy val scala210Jline = "org.scala-lang" % "jline" % scala210 lazy val jansi = { if (sbtVersionToRelease startsWith "1.") "org.fusesource.jansi" % "jansi" % "1.12" @@ -34,7 +34,7 @@ lazy val jansi = { } lazy val scala212Compiler = "org.scala-lang" % "scala-compiler" % scala212 lazy val scala212Jline = "jline" % "jline" % "2.14.6" -// use the scala-xml version used by the compiler not the latest: https://github.com/scala/scala/blob/v2.12.19/versions.properties +// use the scala-xml version used by the compiler not the latest: https://github.com/scala/scala/blob/v2.12.20/versions.properties lazy val scala212Xml = "org.scala-lang.modules" % "scala-xml_2.12" % "2.2.0" lazy val sbtActual = "org.scala-sbt" % "sbt" % sbtVersionToRelease @@ -121,7 +121,7 @@ val root = (project in file(".")). file }, // update sbt.sh at root - sbtnVersion := "1.10.0", + sbtnVersion := "1.10.8", sbtnJarsBaseUrl := "https://github.com/sbt/sbtn-dist/releases/download", sbtnJarsMappings := { val baseUrl = sbtnJarsBaseUrl.value diff --git a/launcher-package/integration-test/src/test/scala/RunnerTest.scala b/launcher-package/integration-test/src/test/scala/RunnerTest.scala index f3d4065026..4ea58563b0 100755 --- a/launcher-package/integration-test/src/test/scala/RunnerTest.scala +++ b/launcher-package/integration-test/src/test/scala/RunnerTest.scala @@ -4,6 +4,7 @@ import minitest._ import scala.sys.process._ import java.io.File import java.util.Locale +import sbt.io.IO object SbtRunnerTest extends SimpleTestSuite with PowerAssertions { // 1.3.0, 1.3.0-M4 @@ -20,6 +21,10 @@ object SbtRunnerTest extends SimpleTestSuite with PowerAssertions { sbt.internal.Process(Seq(sbtScript.getAbsolutePath) ++ args, new File("citest"), "JAVA_OPTS" -> javaOpts, "SBT_OPTS" -> sbtOpts) + def sbtProcessInDir(dir: File)(args: String*) = + sbt.internal.Process(Seq(sbtScript.getAbsolutePath) ++ args, dir, + "JAVA_OPTS" -> "", + "SBT_OPTS" -> "") test("sbt runs") { assert(sbtScript.exists) @@ -28,19 +33,32 @@ object SbtRunnerTest extends SimpleTestSuite with PowerAssertions { () } + def testVersion(lines: List[String]): Unit = { + assert(lines.size >= 2) + val expected0 = s"(?m)^sbt version in this project: $versionRegEx(\\r)?" + assert(lines(0).matches(expected0)) + val expected1 = s"sbt runner version: $versionRegEx$$" + assert(lines(1).matches(expected1)) + } + test("sbt -V|-version|--version should print sbtVersion") { val out = sbtProcess("-version").!!.trim - val expectedVersion = - s"""|(?m)^sbt version in this project: $versionRegEx(\\r)? - |sbt script version: $versionRegEx$$ - |""".stripMargin.trim.replace("\n", "\\n") - assert(out.matches(expectedVersion)) + testVersion(out.linesIterator.toList) val out2 = sbtProcess("--version").!!.trim - assert(out2.matches(expectedVersion)) + testVersion(out2.linesIterator.toList) val out3 = sbtProcess("-V").!!.trim - assert(out3.matches(expectedVersion)) + testVersion(out3.linesIterator.toList) + } + + test("sbt -V in empty directory") { + IO.withTemporaryDirectory { tmp => + val out = sbtProcessInDir(tmp)("-V").!!.trim + val expectedVersion = "^"+versionRegEx+"$" + val targetDir = new File(tmp, "target") + assert(!targetDir.exists, "expected target directory to not exist, but existed") + } () } @@ -68,6 +86,27 @@ object SbtRunnerTest extends SimpleTestSuite with PowerAssertions { } } + test("sbt in empty directory") { + IO.withTemporaryDirectory { tmp => + val out = sbtProcessInDir(tmp)("about").! + assert(out == 1) + } + IO.withTemporaryDirectory { tmp => + val out = sbtProcessInDir(tmp)("about", "--allow-empty").! + assert(out == 0) + } + () + } + + test("sbt --script-version in empty directory") { + IO.withTemporaryDirectory { tmp => + val out = sbtProcessInDir(tmp)("--script-version").!!.trim + val expectedVersion = "^"+versionRegEx+"$" + assert(out.matches(expectedVersion)) + } + () + } + /* test("sbt --client") { val out = sbtProcess("--client", "--no-colors", "compile").!!.linesIterator.toList diff --git a/launcher-package/src/universal/bin/sbt.bat b/launcher-package/src/universal/bin/sbt.bat index de25ca25d5..983b618a7d 100755 --- a/launcher-package/src/universal/bin/sbt.bat +++ b/launcher-package/src/universal/bin/sbt.bat @@ -45,12 +45,13 @@ set sbt_args_timings= set sbt_args_traces= set sbt_args_sbt_boot= set sbt_args_sbt_cache= -set sbt_args_sbt_create= +set sbt_args_allow_empty= set sbt_args_sbt_dir= set sbt_args_sbt_version= set sbt_args_mem= set sbt_args_client= set sbt_args_no_server= +set is_this_dir_sbt=0 rem users can set SBT_OPTS via .sbtopts if exist .sbtopts for /F %%A in (.sbtopts) do ( @@ -72,11 +73,13 @@ rem TODO: remove/deprecate sbtconfig.txt and parse the sbtopts files rem FIRST we load the config file of extra options. set SBT_CONFIG=!SBT_HOME!\conf\sbtconfig.txt set SBT_CFG_OPTS= -for /F "tokens=* eol=# usebackq delims=" %%i in ("!SBT_CONFIG!") do ( - set DO_NOT_REUSE_ME=%%i - rem ZOMG (Part #2) WE use !! here to delay the expansion of - rem SBT_CFG_OPTS, otherwise it remains "" for this loop. - set SBT_CFG_OPTS=!SBT_CFG_OPTS! !DO_NOT_REUSE_ME! +if exist "!SBT_CONFIG!" ( + for /F "tokens=* eol=# usebackq delims=" %%i in ("!SBT_CONFIG!") do ( + set DO_NOT_REUSE_ME=%%i + rem ZOMG (Part #2) WE use !! here to delay the expansion of + rem SBT_CFG_OPTS, otherwise it remains "" for this loop. + set SBT_CFG_OPTS=!SBT_CFG_OPTS! !DO_NOT_REUSE_ME! + ) ) rem poor man's jenv (which is not available on Windows) @@ -235,12 +238,14 @@ if defined _traces_arg ( goto args_loop ) -if "%~0" == "-sbt-create" set _sbt_create_arg=true -if "%~0" == "--sbt-create" set _sbt_create_arg=true +if "%~0" == "-sbt-create" set _allow_empty_arg=true +if "%~0" == "--sbt-create" set _allow_empty_arg=true +if "%~0" == "-allow-empty" set _allow_empty_arg=true +if "%~0" == "--allow-empty" set _allow_empty_arg=true -if defined _sbt_create_arg ( - set _sbt_create_arg= - set sbt_args_sbt_create=1 +if defined _allow_empty_arg ( + set _allow_empty_arg= + set sbt_args_allow_empty=1 goto args_loop ) @@ -472,6 +477,11 @@ if "%~0" == "new" ( set sbt_new=true ) ) +if "%~0" == "init" ( + if not defined SBT_ARGS ( + set sbt_new=true + ) +) if "%g:~0,2%" == "-D" ( rem special handling for -D since '=' gets parsed away @@ -523,28 +533,22 @@ set SBT_ARGS=!SBT_ARGS! %0 goto args_loop :args_end +if exist build.sbt ( + set is_this_dir_sbt=1 +) +if exist project\build.properties ( + set is_this_dir_sbt=1 +) + rem Confirm a user's intent if the current directory does not look like an sbt rem top-level directory and the "new" command was not given. -if not defined sbt_args_sbt_create if not defined sbt_args_print_version if not defined sbt_args_print_sbt_version if not defined sbt_args_print_sbt_script_version if not defined shutdownall if not exist build.sbt ( - if not exist project\ ( +if not defined sbt_args_allow_empty if not defined sbt_args_print_version if not defined sbt_args_print_sbt_version if not defined sbt_args_print_sbt_script_version if not defined shutdownall ( + if not !is_this_dir_sbt! equ 1 ( if not defined sbt_new ( - echo [warn] Neither build.sbt nor a 'project' directory in the current directory: "%CD%" - setlocal -:confirm - echo c^) continue - echo q^) quit - - set /P reply=^? - if /I "!reply!" == "c" ( - goto confirm_end - ) else if /I "!reply!" == "q" ( - exit /B 1 - ) - - goto confirm -:confirm_end - endlocal + echo [error] Neither build.sbt nor a 'project' directory in the current directory: "%CD%" + echo [error] run 'sbt new', touch build.sbt, or run 'sbt --allow-empty'. + goto error ) ) ) @@ -671,9 +675,14 @@ if !sbt_args_print_sbt_version! equ 1 ( ) if !sbt_args_print_version! equ 1 ( - call :set_sbt_version - echo sbt version in this project: !sbt_version! - echo sbt script version: !init_sbt_version! + if !is_this_dir_sbt! equ 1 ( + call :set_sbt_version + echo sbt version in this project: !sbt_version! + ) + echo sbt runner version: !init_sbt_version! + echo. + echo [info] sbt runner ^(sbt-the-batch-script^) is a runner to run any declared version of sbt. + echo [info] Actual version of the sbt is declared using project\build.properties for each build. goto :eof ) @@ -890,27 +899,27 @@ for /F "delims=.-_ tokens=1-2" %%v in ("!sbtV!") do ( set sbtBinaryV_1=%%v set sbtBinaryV_2=%%w ) -set native_client_ready= +rem default to run_native_client=1 for sbt 2.x if !sbtBinaryV_1! geq 2 ( - set native_client_ready=1 + if !sbt_args_client! equ 0 ( + set run_native_client= + ) else ( + set run_native_client=1 + ) ) else ( if !sbtBinaryV_1! geq 1 ( if !sbtBinaryV_2! geq 4 ( - set native_client_ready=1 + if !sbt_args_client! equ 1 ( + set run_native_client=1 + ) ) ) ) -if !native_client_ready! equ 1 ( - if !sbt_args_client! equ 1 ( - set run_native_client=1 - ) -) -set native_client_ready= exit /B 0 :checkjava -set /a required_version=6 +set /a required_version=8 if /I !JAVA_VERSION! GEQ !required_version! ( exit /B 0 ) diff --git a/launcher-package/src/universal/conf/sbtopts b/launcher-package/src/universal/conf/sbtopts index c6f4e7bec2..5990223b7c 100644 --- a/launcher-package/src/universal/conf/sbtopts +++ b/launcher-package/src/universal/conf/sbtopts @@ -9,7 +9,7 @@ # Starts sbt even if the current directory contains no sbt project. # --sbt-create +#--allow-empty # Path to global settings/plugins directory (default: ~/.sbt) # @@ -31,11 +31,11 @@ # #-no-share -# Put SBT in offline mode. +# Put sbt in offline mode. # #-offline -# Sets the SBT version to use. +# Sets the sbt version to use. #-sbt-version 0.11.3 # Scala version (default: latest release) diff --git a/main-command/src/main/scala/sbt/BasicKeys.scala b/main-command/src/main/scala/sbt/BasicKeys.scala index f01b1f6a40..7d6693e199 100644 --- a/main-command/src/main/scala/sbt/BasicKeys.scala +++ b/main-command/src/main/scala/sbt/BasicKeys.scala @@ -93,7 +93,7 @@ object BasicKeys { val serverIdleTimeout = AttributeKey[Option[FiniteDuration]]( - "serverIdleTimeOut", + "serverIdleTimeout", "If set to a defined value, sbt server will exit if it goes at least the specified duration without receiving any commands.", 10000 ) diff --git a/main-command/src/main/scala/sbt/internal/CommandChannel.scala b/main-command/src/main/scala/sbt/internal/CommandChannel.scala index db53b95580..3e0d7a518d 100644 --- a/main-command/src/main/scala/sbt/internal/CommandChannel.scala +++ b/main-command/src/main/scala/sbt/internal/CommandChannel.scala @@ -63,6 +63,8 @@ abstract class CommandChannel { } } } + protected def appendExec(commandLine: String, execId: Option[String]): Boolean = + append(Exec(commandLine, execId.orElse(Some(Exec.newExecId)), Some(CommandSource(name)))) def poll: Option[Exec] = Option(commandQueue.poll) def prompt(e: ConsolePromptEvent): Unit = userThread.onConsolePromptEvent(e) @@ -81,20 +83,21 @@ abstract class CommandChannel { private[sbt] final def logLevel: Level.Value = level.get private[this] def setLevel(value: Level.Value, cmd: String): Boolean = { level.set(value) - append(Exec(cmd, Some(Exec.newExecId), Some(CommandSource(name)))) + appendExec(cmd, None) } - private[sbt] def onCommand: String => Boolean = { - case "error" => setLevel(Level.Error, "error") - case "debug" => setLevel(Level.Debug, "debug") - case "info" => setLevel(Level.Info, "info") - case "warn" => setLevel(Level.Warn, "warn") - case cmd => - if (cmd.nonEmpty) append(Exec(cmd, Some(Exec.newExecId), Some(CommandSource(name)))) - else false - } - private[sbt] def onFastTrackTask: String => Boolean = { s: String => + private[sbt] def onCommandLine(cmd: String): Boolean = + cmd match { + case "error" => setLevel(Level.Error, "error") + case "debug" => setLevel(Level.Debug, "debug") + case "info" => setLevel(Level.Info, "info") + case "warn" => setLevel(Level.Warn, "warn") + case cmd => + if (cmd.nonEmpty) appendExec(cmd, None) + else false + } + private[sbt] def onFastTrackTask(cmd: String): Boolean = { fastTrack.synchronized(fastTrack.forEach { q => - q.add(new FastTrackTask(this, s)) + q.add(new FastTrackTask(this, cmd)) () }) true diff --git a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala index 34c544011c..6bc13337fb 100644 --- a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala +++ b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala @@ -15,14 +15,24 @@ import java.lang.ProcessBuilder.Redirect import java.net.{ Socket, SocketException } import java.nio.file.Files import java.util.UUID +import java.util.Date import java.util.concurrent.atomic.{ AtomicBoolean, AtomicReference } import java.util.concurrent.{ ConcurrentHashMap, LinkedBlockingQueue, TimeUnit } +import java.text.DateFormat import sbt.BasicCommandStrings.{ DashDashDetachStdio, DashDashServer, Shutdown, TerminateAction } import sbt.internal.client.NetworkClient.Arguments import sbt.internal.langserver.{ LogMessageParams, MessageType, PublishDiagnosticsParams } +import sbt.internal.worker.{ ClientJobParams, JvmRunInfo, NativeRunInfo, RunInfo } import sbt.internal.protocol._ -import sbt.internal.util.{ ConsoleAppender, ConsoleOut, Signals, Terminal, Util } +import sbt.internal.util.{ + ConsoleAppender, + ConsoleOut, + MessageOnlyException, + Signals, + Terminal, + Util +} import sbt.io.IO import sbt.io.syntax._ import sbt.protocol._ @@ -41,6 +51,7 @@ import Serialization.{ attach, cancelReadSystemIn, cancelRequest, + clientJob, promptChannel, readSystemIn, systemIn, @@ -61,6 +72,7 @@ import Serialization.{ } import NetworkClient.Arguments import java.util.concurrent.TimeoutException +import sbt.util.Logger trait ConsoleInterface { def appendLog(level: Level.Value, message: => String): Unit @@ -141,6 +153,7 @@ class NetworkClient( private lazy val noTab = arguments.completionArguments.contains("--no-tab") private lazy val noStdErr = arguments.completionArguments.contains("--no-stderr") && !sys.env.contains("SBTN_AUTO_COMPLETE") && !sys.env.contains("SBTC_AUTO_COMPLETE") + private def shutdownOnly = arguments.commandArguments == Seq(Shutdown) private def mkSocket(file: File): (Socket, Option[String]) = ClientSocket.socket(file, useJNI) @@ -164,6 +177,11 @@ class NetworkClient( case null => inputThread.set(new RawInputThread) case _ => } + private lazy val log: Logger = new Logger { + def trace(t: => Throwable): Unit = () + def success(message: => String): Unit = () + def log(level: Level.Value, message: => String): Unit = console.appendLog(level, message) + } private[sbt] def connectOrStartServerAndConnect( promptCompleteUsers: Boolean, @@ -171,7 +189,10 @@ class NetworkClient( ): (Socket, Option[String]) = try { if (!portfile.exists) { - if (promptCompleteUsers) { + if (shutdownOnly) { + console.appendLog(Level.Info, "no sbt server is running. ciao") + System.exit(0) + } else if (promptCompleteUsers) { val msg = if (noTab) "" else "No sbt server is running. Press to start one..." errorStream.print(s"\n$msg") if (noStdErr) System.exit(0) @@ -293,7 +314,18 @@ class NetworkClient( } // initiate handshake val execId = UUID.randomUUID.toString - val initCommand = InitCommand(tkn, Option(execId), Some(true)) + val skipAnalysis = true + val opts = InitializeOption( + token = tkn, + skipAnalysis = Some(skipAnalysis), + canWork = Some(true), + ) + val initCommand = InitCommand( + token = tkn, // duplicated with opts for compatibility + execId = Option(execId), + skipAnalysis = Some(skipAnalysis), // duplicated with opts for compatibility + initializationOptions = Some(opts), + ) conn.sendString(Serialization.serializeCommandAsJsonMessage(initCommand)) connectionHolder.set(conn) conn @@ -527,61 +559,77 @@ class NetworkClient( .getOrElse(1) case _ => 1 } - private def completeExec(execId: String, exitCode: => Int): Unit = + + private val onAttachResponse: PartialFunction[JsonRpcResponseMessage, Unit] = { + case msg if attachUUID.get == msg.id => + attachUUID.set(null) + attached.set(true) + Option(inputThread.get).foreach(_.drain()) + () + } + def completeExec(execId: String, exitCode: Int) = { pendingResults.remove(execId) match { - case null => + case null => () case (q, startTime, name) => val now = System.currentTimeMillis - val message = timing(startTime, now) - val ec = exitCode + val message = NetworkClient.timing(startTime, now) if (batchMode.get || !attached.get) { - if (ec == 0) console.success(message) + if (exitCode == 0) console.success(message) else console.appendLog(Level.Error, message) } - Util.ignoreResult(q.offer(ec)) - } - def onResponse(msg: JsonRpcResponseMessage): Unit = { - completeExec(msg.id, getExitCode(msg.result)) - pendingCancellations.remove(msg.id) match { - case null => - case q => q.offer(msg.toString.contains("Task cancelled")) - } - msg.id match { - case execId => - if (attachUUID.get == msg.id) { - attachUUID.set(null) - attached.set(true) - Option(inputThread.get).foreach(_.drain()) - } - pendingCompletions.remove(execId) match { - case null => - case completions => - completions(msg.result match { - case Some(o: JObject) => - o.value - .foldLeft(CompletionResponse(Vector.empty[String])) { - case (resp, i) => - if (i.field == "items") - resp.withItems( - Converter - .fromJson[Vector[String]](i.value) - .getOrElse(Vector.empty[String]) - ) - else if (i.field == "cachedTestNames") - resp.withCachedTestNames( - Converter.fromJson[Boolean](i.value).getOrElse(true) - ) - else if (i.field == "cachedMainClassNames") - resp.withCachedMainClassNames( - Converter.fromJson[Boolean](i.value).getOrElse(true) - ) - else resp - } - case _ => CompletionResponse(Vector.empty[String]) - }) - } + Util.ignoreResult(q.offer(exitCode)) } } + private val onExecResponse: PartialFunction[JsonRpcResponseMessage, Unit] = { + case msg if pendingResults.containsKey(msg.id) => + completeExec(msg.id, getExitCode(msg.result)) + } + private val onCancellationResponse: PartialFunction[JsonRpcResponseMessage, Unit] = { + case msg if pendingCancellations.containsKey(msg.id) => + pendingCancellations.remove(msg.id) match { + case null => () + case q => Util.ignoreResult(q.offer(msg.toString.contains("Task cancelled"))) + } + } + private val onCompletionResponse: PartialFunction[JsonRpcResponseMessage, Unit] = { + case msg if pendingCompletions.containsKey(msg.id) => + pendingCompletions.remove(msg.id) match { + case null => () + case completions => + completions(msg.result match { + case Some(o: JObject) => + o.value + .foldLeft(CompletionResponse(Vector.empty[String])) { + case (resp, i) => + if (i.field == "items") + resp.withItems( + Converter + .fromJson[Vector[String]](i.value) + .getOrElse(Vector.empty[String]) + ) + else if (i.field == "cachedTestNames") + resp.withCachedTestNames( + Converter.fromJson[Boolean](i.value).getOrElse(true) + ) + else if (i.field == "cachedMainClassNames") + resp.withCachedMainClassNames( + Converter.fromJson[Boolean](i.value).getOrElse(true) + ) + else resp + } + case _ => CompletionResponse(Vector.empty[String]) + }) + } + } + // cache the composed plan + private val responsePlan = Util.reduceIntents[JsonRpcResponseMessage, Unit]( + onExecResponse, + onCancellationResponse, + onAttachResponse, + onCompletionResponse, + { case _ => () }, + ) + def onResponse(msg: JsonRpcResponseMessage): Unit = responsePlan(msg) def onNotification(msg: JsonRpcNotificationMessage): Unit = { def splitToMessage: Vector[(Level.Value, String)] = @@ -623,6 +671,12 @@ class NetworkClient( case Success(params) => splitDiagnostics(params); Vector() case Failure(_) => Vector() } + case (`clientJob`, Some(json)) => + import sbt.internal.worker.codec.JsonProtocol._ + Converter.fromJson[ClientJobParams](json) match { + case Success(params) => clientSideRun(params).get; Vector.empty + case Failure(_) => Vector.empty + } case (`Shutdown`, Some(_)) => Vector.empty case (msg, _) if msg.startsWith("build/") => Vector.empty case _ => @@ -669,6 +723,58 @@ class NetworkClient( } } + private def clientSideRun(params: ClientJobParams): Try[Unit] = + params.runInfo match { + case Some(info) => clientSideRun(info) + case _ => Failure(new MessageOnlyException(s"runInfo is not specified in $params")) + } + + private def clientSideRun(runInfo: RunInfo): Try[Unit] = { + def jvmRun(info: JvmRunInfo): Try[Unit] = { + val option = ForkOptions( + javaHome = info.javaHome.map(new File(_)), + outputStrategy = None, // TODO: Handle buffered output etc + bootJars = Vector.empty, + workingDirectory = info.workingDirectory.map(new File(_)), + runJVMOptions = info.jvmOptions, + connectInput = info.connectInput, + envVars = info.environmentVariables, + ) + // ForkRun handles exit code handling and cancellation + val runner = new ForkRun(option) + runner + .run( + mainClass = info.mainClass, + classpath = info.classpath.map(_.path).map(new File(_)), + options = info.args, + log = log + ) + } + def nativeRun(info: NativeRunInfo): Try[Unit] = { + import java.lang.{ ProcessBuilder => JProcessBuilder } + val option = ForkOptions( + javaHome = None, + outputStrategy = None, // TODO: Handle buffered output etc + bootJars = Vector.empty, + workingDirectory = info.workingDirectory.map(new File(_)), + runJVMOptions = Vector.empty, + connectInput = info.connectInput, + envVars = info.environmentVariables, + ) + val command = info.cmd :: info.args.toList + val jpb = new JProcessBuilder(command: _*) + val exitCode = try Fork.blockForExitCode(Fork.forkInternal(option, Nil, jpb)) + catch { + case _: InterruptedException => + log.warn("run canceled") + 1 + } + Run.processExitCode(exitCode, "runner") + } + if (runInfo.jvm) jvmRun(runInfo.jvmRunInfo.getOrElse(sys.error("missing jvmRunInfo"))) + else nativeRun(runInfo.nativeRunInfo.getOrElse(sys.error("missing nativeRunInfo"))) + } + def onRequest(msg: JsonRpcRequestMessage): Unit = { import sbt.protocol.codec.JsonProtocol._ (msg.method, msg.params) match { @@ -1006,26 +1112,6 @@ class NetworkClient( RawInputThread.this.interrupt() } } - - // copied from Aggregation - private def timing(startTime: Long, endTime: Long): String = { - import java.text.DateFormat - val format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM) - val nowString = format.format(new java.util.Date(endTime)) - val total = math.max(0, (endTime - startTime + 500) / 1000) - val totalString = s"$total s" + - (if (total <= 60) "" - else { - val maybeHours = total / 3600 match { - case 0 => "" - case h => f"$h%02d:" - } - val mins = f"${total % 3600 / 60}%02d" - val secs = f"${total % 60}%02d" - s" ($maybeHours$mins:$secs)" - }) - s"Total time: $totalString, completed $nowString" - } } object NetworkClient { @@ -1138,6 +1224,32 @@ object NetworkClient { ) } + private[sbt] def timing(format: DateFormat, startTime: Long, endTime: Long): String = { + // sbt#7558 + // JDK 20+ emits special space (NNBSP) as part of formatted date + // Which sometimes becomes garbled in standard output + // Therefore we replace NNBSP (u202f) with standard space (u0020) + val nowString = format.format(new Date(endTime)).replace("\u202F", "\u0020") + val total = (endTime - startTime + 500) / 1000 + val totalString = s"$total s" + + (if (total <= 60) "" + else { + val hours = total / 3600 match { + case 0 => "0" + case h => f"$h%02d" + } + val mins = f"${total % 3600 / 60}%02d" + val secs = f"${total % 60}%02d" + s" ($hours:$mins:$secs.0)" + }) + s"Total time: $totalString, completed $nowString" + } + + private[sbt] def timing(startTime: Long, endTime: Long): String = { + val format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM) + timing(format, startTime, endTime) + } + def client( baseDirectory: File, args: Array[String], @@ -1236,7 +1348,6 @@ object NetworkClient { System.out.flush() }) Runtime.getRuntime.addShutdownHook(hook) - if (Util.isNonCygwinWindows) sbt.internal.util.JLine3.forceWindowsJansi() val parsed = parseArgs(restOfArgs) System.exit(Terminal.withStreams(isServer = false, isSubProcess = false) { val term = Terminal.console diff --git a/main-command/src/main/scala/sbt/internal/server/ServerHandler.scala b/main-command/src/main/scala/sbt/internal/server/ServerHandler.scala index b503e503c0..9a20f82532 100644 --- a/main-command/src/main/scala/sbt/internal/server/ServerHandler.scala +++ b/main-command/src/main/scala/sbt/internal/server/ServerHandler.scala @@ -79,6 +79,7 @@ trait ServerCallback { private[sbt] def authOptions: Set[ServerAuthentication] private[sbt] def authenticate(token: String): Boolean private[sbt] def setInitialized(value: Boolean): Unit + private[sbt] def setInitializeOption(opts: InitializeOption): Unit private[sbt] def onSettingQuery(execId: Option[String], req: Q): Unit private[sbt] def onCompletionRequest(execId: Option[String], cp: CP): Unit private[sbt] def onCancellationRequest(execId: Option[String], crp: CRP): Unit diff --git a/main-command/src/main/scala/sbt/internal/ui/UITask.scala b/main-command/src/main/scala/sbt/internal/ui/UITask.scala index e3540c570b..b4ceb047dd 100644 --- a/main-command/src/main/scala/sbt/internal/ui/UITask.scala +++ b/main-command/src/main/scala/sbt/internal/ui/UITask.scala @@ -17,6 +17,7 @@ import sbt.BasicKeys.{ historyPath, colorShellPrompt } import sbt.State import sbt.internal.CommandChannel import sbt.internal.util.ConsoleAppender.{ ClearPromptLine, ClearScreenAfterCursor, DeleteLine } +import sbt.internal.util.Terminal.hasConsole import sbt.internal.util._ import sbt.internal.util.complete.{ Parser } @@ -27,7 +28,7 @@ private[sbt] trait UITask extends Runnable with AutoCloseable { private[sbt] val reader: UITask.Reader private[this] final def handleInput(s: Either[String, String]): Boolean = s match { case Left(m) => channel.onFastTrackTask(m) - case Right(cmd) => channel.onCommand(cmd) + case Right(cmd) => channel.onCommandLine(cmd) } private[this] val isStopped = new AtomicBoolean(false) override def run(): Unit = { @@ -55,6 +56,20 @@ private[sbt] object UITask { object Reader { // Avoid filling the stack trace since it isn't helpful here object interrupted extends InterruptedException + + /** + * Return Left for fast track commands, otherwise return Right(...). + */ + def splitCommand(cmd: String): Either[String, String] = + // We need to put the empty string on the fast track queue so that we can + // reprompt the user if another command is running on the server. + if (cmd.isEmpty()) Left("") + else + cmd match { + case Shutdown | TerminateAction | Cancel => Left(cmd) + case cmd => Right(cmd) + } + def terminalReader(parser: Parser[_])( terminal: Terminal, state: State @@ -70,22 +85,15 @@ private[sbt] object UITask { if (thread.isInterrupted || closed.get) throw interrupted (try reader.readLine(clear + terminal.prompt.mkPrompt()) finally reader.close) match { - case None if terminal == Terminal.console && System.console == null => + case None if terminal == Terminal.console && !hasConsole => // No stdin is attached to the process so just ignore the result and // block until the thread is interrupted. this.synchronized(this.wait()) Right("") // should be unreachable // JLine returns null on ctrl+d when there is no other input. This interprets // ctrl+d with no imput as an exit - case None => Left(TerminateAction) - case Some(s: String) => - s.trim() match { - // We need to put the empty string on the fast track queue so that we can - // reprompt the user if another command is running on the server. - case "" => Left("") - case cmd @ (`Shutdown` | `TerminateAction` | `Cancel`) => Left(cmd) - case cmd => Right(cmd) - } + case None => Left(TerminateAction) + case Some(s: String) => splitCommand(s.trim()) } } terminal.setPrompt(Prompt.Pending) diff --git a/main/src/main/java/sbt/internal/MetaBuildLoader.java b/main/src/main/java/sbt/internal/MetaBuildLoader.java index c1980117f6..7bc9beac9c 100644 --- a/main/src/main/java/sbt/internal/MetaBuildLoader.java +++ b/main/src/main/java/sbt/internal/MetaBuildLoader.java @@ -14,6 +14,7 @@ import java.net.URLClassLoader; import java.util.LinkedHashSet; import java.util.Set; +import java.util.Stack; import java.util.regex.Pattern; import xsbti.AppProvider; import xsbti.ScalaProvider; @@ -65,32 +66,26 @@ public void close() throws IOException { * library. */ public static MetaBuildLoader makeLoader(final AppProvider appProvider) throws IOException { - final String jlineJars = "jline-?[0-9.]+-sbt-.*|jline-terminal(-(jna|jansi))?-[0-9.]+"; + final String jlineJars = + "jline-?[0-9.]+-sbt-.*|jline-terminal(-(jni))?-[0-9.]+|jline-native-[0-9.]+"; final String testInterfaceJars = "test-interface(-.*)?"; final String compilerInterfaceJars = "compiler-interface(-.*)?"; final String utilInterfaceJars = "util-interface(-.*)?"; final String jansiJars = "jansi-[0-9.]+"; - final String jnaJars = "jna-(platform-)?[0-9.]+"; final String fullPattern = String.format( - "^(%s|%s|%s|%s|%s|%s)\\.jar", - jlineJars, - testInterfaceJars, - compilerInterfaceJars, - utilInterfaceJars, - jansiJars, - jnaJars); + "^(%s|%s|%s|%s|%s)\\.jar", + jlineJars, testInterfaceJars, compilerInterfaceJars, utilInterfaceJars, jansiJars); final Pattern pattern = Pattern.compile(fullPattern); final File[] cp = appProvider.mainClasspath(); final URL[] interfaceURLs = new URL[3]; - final URL[] jlineURLs = new URL[7]; + final Stack jlineURLs = new Stack<>(); final File[] extra = appProvider.id().classpathExtra() == null ? new File[0] : appProvider.id().classpathExtra(); final Set bottomClasspath = new LinkedHashSet<>(); { int interfaceIndex = 0; - int jlineIndex = 0; for (final File file : cp) { final String name = file.getName(); if ((name.contains("test-interface") @@ -100,8 +95,7 @@ public static MetaBuildLoader makeLoader(final AppProvider appProvider) throws I interfaceURLs[interfaceIndex] = file.toURI().toURL(); interfaceIndex += 1; } else if (pattern.matcher(name).find()) { - jlineURLs[jlineIndex] = file.toURI().toURL(); - jlineIndex += 1; + jlineURLs.push(file.toURI().toURL()); } else { bottomClasspath.add(file); } @@ -150,7 +144,7 @@ public String toString() { }; final SbtInterfaceLoader interfaceLoader = new SbtInterfaceLoader(interfaceURLs, topLoader); - final JLineLoader jlineLoader = new JLineLoader(jlineURLs, interfaceLoader); + final JLineLoader jlineLoader = new JLineLoader(jlineURLs.toArray(new URL[0]), interfaceLoader); final File[] siJars = scalaProvider.jars(); final URL[] lib = new URL[1]; int scalaRestCount = siJars.length - 1; diff --git a/main/src/main/scala/sbt/BackgroundJobService.scala b/main/src/main/scala/sbt/BackgroundJobService.scala index 6dc8deb810..2b113c1c1f 100644 --- a/main/src/main/scala/sbt/BackgroundJobService.scala +++ b/main/src/main/scala/sbt/BackgroundJobService.scala @@ -70,6 +70,8 @@ abstract class BackgroundJobService extends Closeable { def waitFor(job: JobHandle): Unit + private[sbt] def createWorkingDirectory: File + /** Copies classpath to temporary directories. */ def copyClasspath(products: Classpath, full: Classpath, workingDirectory: File): Classpath @@ -100,4 +102,5 @@ abstract class JobHandle { def id: Long def humanReadableName: String def spawningTask: ScopedKey[_] + def isAutoCancel: Boolean } diff --git a/main/src/main/scala/sbt/Cross.scala b/main/src/main/scala/sbt/Cross.scala index 6dc8dffd39..5fb67a6677 100644 --- a/main/src/main/scala/sbt/Cross.scala +++ b/main/src/main/scala/sbt/Cross.scala @@ -122,7 +122,10 @@ object Cross { .map { case uri ~ seg1 ~ cmd => (uri, seg1, cmd) } Parser.parse(command, parser) match { case Right((uri, seg1, cmd)) => - structure.allProjectRefs.find(p => uri.contains(p.build.toString) && seg1 == p.project) match { + structure.allProjectRefs.find { + case p if uri.isDefined => seg1 == p.project && uri.contains(p.build.toString) + case p => seg1 == p.project + } match { case Some(proj) => (Seq(proj), cmd) case _ => (resolveAggregates(extracted), command) } diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index fa2c3eb7d8..dbbbe84b13 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -9,8 +9,7 @@ package sbt import java.io.{ File, PrintWriter } -import java.net.{ URI, URL } -import java.nio.file.{ Paths, Path => NioPath } +import java.nio.file.{ Path => NioPath } import java.util.Optional import java.util.concurrent.TimeUnit import lmcoursier.CoursierDependencyResolution @@ -51,6 +50,7 @@ import sbt.internal.server.{ BspCompileTask, BuildServerProtocol, BuildServerReporter, + ClientJob, Definition, LanguageServerProtocol, ServerHandler, @@ -180,6 +180,7 @@ object Defaults extends BuildCommon { apiMappings := Map.empty, autoScalaLibrary :== true, managedScalaInstance :== true, + allowUnsafeScalaLibUpgrade :== false, classpathEntryDefinesClass := { (file: File) => sys.error("use classpathEntryDefinesClassVF instead") }, @@ -221,7 +222,7 @@ object Defaults extends BuildCommon { closeClassLoaders :== SysProp.closeClassLoaders, allowZombieClassLoaders :== true, packageTimestamp :== Package.defaultTimestamp, - ) ++ BuildServerProtocol.globalSettings + ) ++ BuildServerProtocol.globalSettings ++ ClientJob.globalSettings private[sbt] lazy val globalIvyCore: Seq[Setting[_]] = Seq( @@ -265,6 +266,7 @@ object Defaults extends BuildCommon { csrLogger := LMCoursier.coursierLoggerTask.value, csrMavenProfiles :== Set.empty, csrReconciliations :== LMCoursier.relaxedForAllModules, + csrMavenDependencyOverride :== false, csrSameVersions := Seq( ScalaArtifacts.Artifacts.map(a => InclExclRule(scalaOrganization.value, a)).toSet ) @@ -405,13 +407,12 @@ object Defaults extends BuildCommon { val boot = app.provider.scalaProvider.launcher.bootDirectory val ih = app.provider.scalaProvider.launcher.ivyHome val coursierCache = csrCacheDirectory.value - val javaHome = Paths.get(sys.props("java.home")) Map( "BASE" -> base.toPath, "SBT_BOOT" -> boot.toPath, "CSR_CACHE" -> coursierCache.toPath, "IVY_HOME" -> ih.toPath, - "JAVA_HOME" -> javaHome, + "JAVA_HOME" -> Util.javaHome, ) }, fileConverter := MappedFileConverter(rootPaths.value, allowMachinePath.value), @@ -710,7 +711,20 @@ object Defaults extends BuildCommon { crossPaths.value ), cleanIvy := IvyActions.cleanCachedResolutionCache(ivyModule.value, streams.value.log), - clean := clean.dependsOn(cleanIvy).value, + clean := { + val _ = cleanIvy.value + try { + val store = AnalysisUtil.staticCachedStore( + analysisFile = (Compile / compileAnalysisFile).value.toPath, + useTextAnalysis = !(Compile / enableBinaryCompileAnalysis).value, + useConsistent = (Compile / enableConsistentCompileAnalysis).value, + ) + store.clearCache() + } catch { + case NonFatal(_) => () + } + clean.value + }, scalaCompilerBridgeBinaryJar := Def.settingDyn { val sv = scalaVersion.value if (ScalaArtifacts.isScala3(sv) || VersionNumber(sv) @@ -914,7 +928,20 @@ object Defaults extends BuildCommon { tastyFiles.map(_.getAbsoluteFile) } else Nil }.value, - clean := (compileOutputs / clean).value, + clean := { + val _ = (compileOutputs / clean).value + val analysisFile = compileAnalysisFile.value + try { + val store = AnalysisUtil.staticCachedStore( + analysisFile = analysisFile.toPath, + useTextAnalysis = !enableBinaryCompileAnalysis.value, + useConsistent = enableConsistentCompileAnalysis.value, + ) + store.clearCache() + } catch { + case NonFatal(_) => () + } + }, earlyOutputPing := Def.promise[Boolean], compileProgress := { val s = streams.value @@ -1151,6 +1178,7 @@ object Defaults extends BuildCommon { def scalaInstanceFromUpdate: Initialize[Task[ScalaInstance]] = Def.task { val sv = scalaVersion.value val fullReport = update.value + val s = streams.value // For Scala 3, update scala-library.jar in `scala-tool` and `scala-doc-tool` in case a newer version // is present in the `compile` configuration. This is needed once forwards binary compatibility is dropped @@ -1177,24 +1205,38 @@ object Defaults extends BuildCommon { ) if (Classpaths.isScala213(sv)) { - for { - compileReport <- fullReport.configuration(Configurations.Compile) - libName <- ScalaArtifacts.Artifacts - } { - for (lib <- compileReport.modules.find(_.module.name == libName)) { - val libVer = lib.module.revision - val n = name.value - if (VersionNumber(sv).matchesSemVer(SemanticSelector(s"<$libVer"))) - sys.error( - s"""expected `$n/scalaVersion` to be "$libVer" or later, - |but found "$sv"; upgrade scalaVersion to fix the build. - | - |to support backwards-only binary compatibility (SIP-51), - |the Scala 2.13 compiler cannot be older than $libName on the - |dependency classpath. - |see `$n/evicted` to know why $libName $libVer is getting pulled in. - |""".stripMargin - ) + val scalaDeps = for { + compileReport <- fullReport.configuration(Configurations.Compile).iterator + libName <- ScalaArtifacts.Artifacts.iterator + lib <- compileReport.modules.find(_.module.name == libName) + } yield lib + for (lib <- scalaDeps.take(1)) { + val libVer = lib.module.revision + val libName = lib.module.name + val proj = Def.displayBuildRelative(thisProjectRef.value.build, thisProjectRef.value) + if (VersionNumber(sv).matchesSemVer(SemanticSelector(s"<$libVer"))) { + val err = !allowUnsafeScalaLibUpgrade.value + val fix = + if (err) + """Upgrade the `scalaVersion` to fix the build. If upgrading the Scala compiler version is + |not possible (for example due to a regression in the compiler or a missing dependency), + |this error can be demoted by setting `allowUnsafeScalaLibUpgrade := true`.""".stripMargin + else + s"""Note that the dependency classpath and the runtime classpath of your project + |contain the newer $libName $libVer, even if the scalaVersion is $sv. + |Compilation (macro expansion) or using the Scala REPL in sbt may fail with a LinkageError.""".stripMargin + + val msg = + s"""Expected `$proj scalaVersion` to be $libVer or later, but found $sv. + |To support backwards-only binary compatibility (SIP-51), the Scala 2.13 compiler + |should not be older than $libName on the dependency classpath. + | + |$fix + | + |See `$proj evicted` to know why $libName $libVer is getting pulled in. + |""".stripMargin + if (err) sys.error(msg) + else s.log.warn(msg) } } } @@ -1768,17 +1810,17 @@ object Defaults extends BuildCommon { // drop base directories, since there are no valid mappings for these def sourceMappings: Initialize[Task[Seq[(File, String)]]] = Def.task { - val sdirs = unmanagedSourceDirectories.value ++ managedSourceDirectories.value + val sdirs = sourceDirectories.value val base = baseDirectory.value val relative = (f: File) => relativeTo(sdirs)(f).orElse(relativeTo(base)(f)).orElse(flat(f)) val exclude = Set(sdirs, base) - (unmanagedSources.value ++ managedSources.value).flatMap { + sources.value.flatMap { case s if !exclude(s) => relative(s).map(s -> _) case _ => None } } - def resourceMappings = relativeMappings(unmanagedResources, unmanagedResourceDirectories) + def resourceMappings = relativeMappings(resources, resourceDirectories) def relativeMappings( files: Taskable[Seq[File]], @@ -1818,16 +1860,8 @@ object Defaults extends BuildCommon { extraPrefix: String ): Initialize[File] = Def.setting { - val f = artifactName.value crossTarget.value / - (prefix(configuration.value.name) + extraPrefix) / f( - ScalaVersion( - (artifactName / scalaVersion).value, - (artifactName / scalaBinaryVersion).value - ), - projectID.value, - art.value - ) + (prefix(configuration.value.name) + "early") / "early.jar" } private[sbt] def prefixArtifactPathSetting( @@ -2047,6 +2081,11 @@ object Defaults extends BuildCommon { def foregroundRunMainTask: Initialize[InputTask[Unit]] = Def.inputTask { val handle = bgRunMain.evaluated + handle match { + case threadJobHandle: AbstractBackgroundJobService#ThreadJobHandle => + threadJobHandle.isAutoCancel = true + case _ => + } val service = bgJobService.value service.waitForTry(handle).get } @@ -2055,6 +2094,11 @@ object Defaults extends BuildCommon { def foregroundRunTask: Initialize[InputTask[Unit]] = Def.inputTask { val handle = bgRun.evaluated + handle match { + case threadJobHandle: AbstractBackgroundJobService#ThreadJobHandle => + threadJobHandle.isAutoCancel = true + case _ => + } val service = bgJobService.value service.waitForTry(handle).get } @@ -2551,9 +2595,10 @@ object Defaults extends BuildCommon { private[sbt] def jnone[A]: Optional[A] = none[A].toOptional def compileAnalysisSettings: Seq[Setting[_]] = Seq( previousCompile := { - val setup = compileIncSetup.value + // Avoid compileIncSetup since it would trigger upstream compilation + val analysisFile = compileAnalysisFile.value val store = AnalysisUtil.staticCachedStore( - analysisFile = setup.cacheFile.toPath, + analysisFile = analysisFile.toPath, useTextAnalysis = !enableBinaryCompileAnalysis.value, useConsistent = enableConsistentCompileAnalysis.value, ) @@ -2585,11 +2630,20 @@ object Defaults extends BuildCommon { } def sbtPluginExtra(m: ModuleID, sbtV: String, scalaV: String): ModuleID = - m.extra( - PomExtraDependencyAttributes.SbtVersionKey -> sbtV, - PomExtraDependencyAttributes.ScalaVersionKey -> scalaV - ) - .withCrossVersion(Disabled()) + partialVersion(sbtV) match { + case Some((0, _)) | Some((1, _)) => + m.extra( + PomExtraDependencyAttributes.SbtVersionKey -> sbtV, + PomExtraDependencyAttributes.ScalaVersionKey -> scalaV + ) + .withCrossVersion(Disabled()) + case Some(_) => + // this produces a normal suffix like _sjs1_2.13 + val prefix = s"sbt${binarySbtVersion(sbtV)}_" + m.cross(CrossVersion.binaryWith(prefix, "")) + case None => + sys.error(s"unknown sbt version $sbtV") + } def discoverSbtPluginNames: Initialize[Task[PluginDiscovery.DiscoveredNames]] = Def.taskDyn { if (sbtPlugin.value) Def.task(PluginDiscovery.discoverSourceAll(compile.value)) @@ -2662,7 +2716,7 @@ object Defaults extends BuildCommon { lazy val configSettings: Seq[Setting[_]] = Classpaths.configSettings ++ configTasks ++ configPaths ++ packageConfig ++ Classpaths.compilerPluginConfig ++ deprecationSettings ++ - BuildServerProtocol.configSettings + BuildServerProtocol.configSettings ++ ClientJob.configSettings lazy val compileSettings: Seq[Setting[_]] = configSettings ++ (mainBgRunMainTask +: mainBgRunTask) ++ Classpaths.addUnmanagedLibrary @@ -2913,7 +2967,7 @@ object Classpaths { Defaults.globalDefaults( Seq( publishMavenStyle :== true, - sbtPluginPublishLegacyMavenStyle := true, + sbtPluginPublishLegacyMavenStyle :== true, publishArtifact :== true, (Test / publishArtifact) :== false ) @@ -2921,8 +2975,10 @@ object Classpaths { private lazy val publishSbtPluginMavenStyle = Def.task(sbtPlugin.value && publishMavenStyle.value) private lazy val packagedDefaultArtifacts = packaged(defaultArtifactTasks) - private lazy val emptyArtifacts = Def.task(Map.empty[Artifact, File]) - + private lazy val sbt2Plus: Def.Initialize[Boolean] = Def.setting { + val sbtV = (pluginCrossBuild / sbtBinaryVersion).value + sbtV != "1.0" && !sbtV.startsWith("0.") + } val jvmPublishSettings: Seq[Setting[_]] = Seq( artifacts := artifactDefs(defaultArtifactTasks).value, packagedArtifacts := Def @@ -2942,13 +2998,31 @@ object Classpaths { * valid POM file, that is a POM file that Maven can resolve. */ private def mavenArtifactsOfSbtPlugin: Def.Initialize[Task[Map[Artifact, File]]] = + Def.task { + // This is a conditional task. The top-level must be an if expression. + if (sbt2Plus.value) { + // Both POMs and JARs are Maven-compatible in sbt 2.x, so ignore the workarounds + packagedDefaultArtifacts.value + } else { + val crossVersion = sbtCrossVersion.value + val legacyPomArtifact = (makePom / artifact).value + def addSuffix(a: Artifact): Artifact = a.withName(crossVersion(a.name)) + Map(addSuffix(legacyPomArtifact) -> makeMavenPomOfSbtPlugin.value) ++ + pomConsistentArtifactsForLegacySbt.value ++ + legacyPackagedArtifacts.value + } + } + + private def legacyPackagedArtifacts: Def.Initialize[Task[Map[Artifact, File]]] = Def.task { + // This is a conditional task. The top-level must be an if expression. + if (sbtPluginPublishLegacyMavenStyle.value) packagedDefaultArtifacts.value + else Map.empty[Artifact, File] + } + + private def pomConsistentArtifactsForLegacySbt: Def.Initialize[Task[Map[Artifact, File]]] = Def.task { val crossVersion = sbtCrossVersion.value - val legacyArtifact = (makePom / artifact).value - val pom = makeMavenPomOfSbtPlugin.value val legacyPackages = packaged(defaultPackages).value - - def addSuffix(a: Artifact): Artifact = a.withName(crossVersion(a.name)) def copyArtifact(artifact: Artifact, file: File): (Artifact, File) = { val nameWithSuffix = crossVersion(artifact.name) val targetFile = @@ -2956,11 +3030,9 @@ object Classpaths { IO.copyFile(file, targetFile) artifact.withName(nameWithSuffix) -> targetFile } - val packages = legacyPackages.map { case (artifact, file) => copyArtifact(artifact, file) } - val legacyPackagedArtifacts = Def - .ifS(sbtPluginPublishLegacyMavenStyle.toTask)(packagedDefaultArtifacts)(emptyArtifacts) - .value - packages + (addSuffix(legacyArtifact) -> pom) ++ legacyPackagedArtifacts + legacyPackages.map { + case (artifact, file) => copyArtifact(artifact, file); + } } private def sbtCrossVersion: Def.Initialize[String => String] = Def.setting { @@ -3005,6 +3077,7 @@ object Classpaths { publishM2 := publishOrSkip(publishM2Configuration, publishM2 / skip).value ) + @nowarn("cat=deprecation") private[this] def baseGlobalDefaults = Defaults.globalDefaults( Seq( @@ -3075,6 +3148,7 @@ object Classpaths { ) ) + @nowarn("cat=deprecation") val ivyBaseSettings: Seq[Setting[_]] = baseGlobalDefaults ++ sbtClassifiersTasks ++ Seq( conflictWarning := conflictWarning.value.copy(label = Reference.display(thisProjectRef.value)), unmanagedBase := baseDirectory.value / "lib", diff --git a/main/src/main/scala/sbt/EvaluateTask.scala b/main/src/main/scala/sbt/EvaluateTask.scala index d6eb8a9948..ec425eb23b 100644 --- a/main/src/main/scala/sbt/EvaluateTask.scala +++ b/main/src/main/scala/sbt/EvaluateTask.scala @@ -531,6 +531,7 @@ object EvaluateTask { log.warn("Canceling execution...") RunningProcesses.killAll() ConcurrentRestrictions.cancelAll() + DefaultBackgroundJobService.stop() shutdownImpl(true) } } diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 284d9f4721..dd290c3db7 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -29,6 +29,7 @@ import sbt.internal.remotecache.RemoteCacheArtifact import sbt.internal.server.BuildServerProtocol.BspFullWorkspace import sbt.internal.server.{ BuildServerReporter, ServerHandler } import sbt.internal.util.{ AttributeKey, ProgressState, SourcePosition } +import sbt.internal.worker.ClientJobParams import sbt.io._ import sbt.librarymanagement.Configurations.CompilerPlugin import sbt.librarymanagement.LibraryManagementCodec._ @@ -437,6 +438,8 @@ object Keys { val bspScalaMainClasses = inputKey[Unit]("Implementation of buildTarget/scalaMainClasses").withRank(DTask) val bspScalaMainClassesItem = taskKey[ScalaMainClassesItem]("").withRank(DTask) val bspReporter = taskKey[BuildServerReporter]("").withRank(DTask) + val clientJob = inputKey[ClientJobParams]("Translates a task into a job specification").withRank(Invisible) + val clientJobRunInfo = inputKey[ClientJobParams]("Translates the run task into a job specification").withRank(Invisible) val useCoursier = settingKey[Boolean]("Use Coursier for dependency resolution.").withRank(BSetting) val csrCacheDirectory = settingKey[File]("Coursier cache directory. Uses -Dsbt.coursier.home or Coursier's default.").withRank(CSetting) @@ -454,6 +457,7 @@ object Keys { val csrPublications = taskKey[Seq[(lmcoursier.definitions.Configuration, lmcoursier.definitions.Publication)]]("") val csrReconciliations = settingKey[Seq[(ModuleMatchers, Reconciliation)]]("Strategy to reconcile version conflicts.") val csrSameVersions = settingKey[Seq[Set[InclExclRule]]]("Modules to keep at the same version.") + val csrMavenDependencyOverride = settingKey[Boolean]("Enables Maven dependency override (bill of materials) support") val internalConfigurationMap = settingKey[Configuration => Configuration]("Maps configurations to the actual configuration used to define the classpath.").withRank(CSetting) val classpathConfiguration = taskKey[Configuration]("The configuration used to define the classpath.").withRank(CTask) @@ -530,6 +534,7 @@ object Keys { val otherResolvers = taskKey[Seq[Resolver]]("Resolvers not included in the main resolver chain, such as those in module configurations.").withRank(CSetting) val scalaCompilerBridgeResolvers = taskKey[Seq[Resolver]]("Resolvers used to resolve compiler bridges.").withRank(CSetting) val includePluginResolvers = settingKey[Boolean]("Include the resolvers from the metabuild.").withRank(CSetting) + @deprecated("JCenter has sunset", "1.10.4") val useJCenter = settingKey[Boolean]("Use JCenter as the default repository.").withRank(CSetting) val moduleConfigurations = settingKey[Seq[ModuleConfiguration]]("Defines module configurations, which override resolvers on a per-module basis.").withRank(BMinusSetting) val retrievePattern = settingKey[String]("Pattern used to retrieve managed dependencies to the current build.").withRank(DSetting) @@ -569,6 +574,7 @@ object Keys { val conflictManager = settingKey[ConflictManager]("Selects the conflict manager to use for dependency management.").withRank(CSetting) val autoScalaLibrary = settingKey[Boolean]("Adds a dependency on scala-library if true.").withRank(ASetting) val managedScalaInstance = settingKey[Boolean]("Automatically obtains Scala tools as managed dependencies if true.").withRank(BSetting) + val allowUnsafeScalaLibUpgrade = settingKey[Boolean]("Allow the Scala library on the compilation classpath to be newer than the scalaVersion (see Scala SIP-51).").withRank(CSetting) val sbtResolver = settingKey[Resolver]("Provides a resolver for obtaining sbt as a dependency.").withRank(BMinusSetting) val sbtResolvers = settingKey[Seq[Resolver]]("The external resolvers for sbt and plugin dependencies.").withRank(BMinusSetting) val sbtDependency = settingKey[ModuleID]("Provides a definition for declaring the current version of sbt.").withRank(BMinusSetting) diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 48d24b3e59..cae9826808 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -27,6 +27,7 @@ import sbt.internal.inc.ScalaInstance import sbt.internal.io.Retry import sbt.internal.nio.{ CheckBuildSources, FileTreeRepository } import sbt.internal.server.{ BuildServerProtocol, NetworkChannel } +import sbt.internal.util.Terminal.hasConsole import sbt.internal.util.Types.{ const, idFun } import sbt.internal.util.complete.{ Parser, SizeParser } import sbt.internal.util.{ Terminal => ITerminal, _ } @@ -151,8 +152,7 @@ private[sbt] object xMain { try Some(new BootServerSocket(configuration)) -> None catch { - case e: ServerAlreadyBootingException - if System.console != null && !ITerminal.startedByRemoteClient => + case e: ServerAlreadyBootingException if hasConsole && !ITerminal.startedByRemoteClient => printThrowable(e) println("Create a new server? y/n (default y)") val exit = diff --git a/main/src/main/scala/sbt/PluginCross.scala b/main/src/main/scala/sbt/PluginCross.scala index 823db18c7f..6ce9bc5c56 100644 --- a/main/src/main/scala/sbt/PluginCross.scala +++ b/main/src/main/scala/sbt/PluginCross.scala @@ -100,7 +100,7 @@ private[sbt] object PluginCross { VersionNumber(sv) match { case VersionNumber(Seq(0, 12, _*), _, _) => "2.9.2" case VersionNumber(Seq(0, 13, _*), _, _) => "2.10.7" - case VersionNumber(Seq(1, 0, _*), _, _) => "2.12.19" + case VersionNumber(Seq(1, 0, _*), _, _) => "2.12.20" case _ => sys.error(s"Unsupported sbt binary version: $sv") } } diff --git a/main/src/main/scala/sbt/ScriptedPlugin.scala b/main/src/main/scala/sbt/ScriptedPlugin.scala index 85f8c9181b..7ec7dbd5fd 100644 --- a/main/src/main/scala/sbt/ScriptedPlugin.scala +++ b/main/src/main/scala/sbt/ScriptedPlugin.scala @@ -71,13 +71,11 @@ object ScriptedPlugin extends AutoPlugin { "org.scala-sbt" % "scripted-sbt" % scriptedSbt.value % ScriptedConf, "org.scala-sbt" % "sbt-launch" % scriptedSbt.value % ScriptedLaunchConf ) - case Some((1, _)) => + case _ => Seq( "org.scala-sbt" %% "scripted-sbt" % scriptedSbt.value % ScriptedConf, "org.scala-sbt" % "sbt-launch" % scriptedSbt.value % ScriptedLaunchConf ) - case Some((x, y)) => sys error s"Unknown sbt version ${scriptedSbt.value} ($x.$y)" - case None => sys error s"Unknown sbt version ${scriptedSbt.value}" }), scriptedClasspath := getJars(ScriptedConf).value, scriptedTests := scriptedTestsTask.value, diff --git a/main/src/main/scala/sbt/TemplateCommandUtil.scala b/main/src/main/scala/sbt/TemplateCommandUtil.scala index afb2c5ac7f..71f8035189 100644 --- a/main/src/main/scala/sbt/TemplateCommandUtil.scala +++ b/main/src/main/scala/sbt/TemplateCommandUtil.scala @@ -22,6 +22,7 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy.{ IvyConfiguration, IvyDependencyResolution } import sbt.internal.inc.classpath.ClasspathUtil import BasicCommandStrings._, BasicKeys._ +import sbt.internal.util.Terminal.hasConsole private[sbt] object TemplateCommandUtil { def templateCommand: Command = templateCommand0(TemplateCommand) @@ -84,7 +85,9 @@ private[sbt] object TemplateCommandUtil { hit } match { case Some(_) => // do nothing - case None => System.err.println("Template not found for: " + arguments.mkString(" ")) + case None => + val error = "Template not found for: " + arguments.mkString(" ") + throw new IllegalArgumentException(error) } private def tryTemplate( @@ -183,7 +186,7 @@ private[sbt] object TemplateCommandUtil { "disneystreaming/smithy4s.g8" -> "A Smithy4s project", ) private def fortifyArgs(templates: List[(String, String)]): List[String] = - if (System.console eq null) Nil + if (!hasConsole) Nil else ITerminal.withStreams(true, false) { assert(templates.size <= 20, "template list cannot have more than 20 items") @@ -276,12 +279,13 @@ private[sbt] object TemplateCommandUtil { case TypelevelToolkitSlug :: Nil => typelevelToolkitTemplate() case SbtCrossPlatformSlug :: Nil => sbtCrossPlatformTemplate() case _ => - System.err.println("Local template not found for: " + arguments.mkString(" ")) + val error = "Local template not found for: " + arguments.mkString(" ") + throw new IllegalArgumentException(error) } - private final val defaultScalaV = "3.3.0" + private final val defaultScalaV = "3.3.4" private def scalaToolkitTemplate(): Unit = { - val defaultScalaToolkitV = "0.2.0" + val defaultScalaToolkitV = "0.5.0" val scalaV = ask("Scala version", defaultScalaV) val toolkitV = ask("Scala Toolkit version", defaultScalaToolkitV) val content = s""" @@ -299,7 +303,7 @@ libraryDependencies += (toolkitTest % Test) } private def typelevelToolkitTemplate(): Unit = { - val defaultTypelevelToolkitV = "0.1.3" + val defaultTypelevelToolkitV = "0.1.28" val scalaV = ask("Scala version", defaultScalaV) val toolkitV = ask("Typelevel Toolkit version", defaultTypelevelToolkitV) val content = s""" @@ -335,9 +339,9 @@ lazy val core = (projectMatrix in file("core")) IO.write(new File("build.sbt"), content) val pluginsContent = """ -addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.9.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.1") -addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.10") +addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.10.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.17.0") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.5") """ IO.write(new File("project/plugins.sbt"), pluginsContent) copyResource("ScalaMain.scala.txt", new File("core/src/main/scala/example/Main.scala")) diff --git a/main/src/main/scala/sbt/coursierint/LMCoursier.scala b/main/src/main/scala/sbt/coursierint/LMCoursier.scala index 84ed5339d4..fd7ebb5463 100644 --- a/main/src/main/scala/sbt/coursierint/LMCoursier.scala +++ b/main/src/main/scala/sbt/coursierint/LMCoursier.scala @@ -121,6 +121,7 @@ object LMCoursier { depsOverrides, None, Nil, + None, log ) @@ -172,6 +173,60 @@ object LMCoursier { depsOverrides, updateConfig, Nil, + None, + log + ) + + // For binary compatibility / MiMa + def coursierConfiguration( + rs: Seq[Resolver], + interProjectDependencies: Seq[CProject], + extraProjects: Seq[CProject], + fallbackDeps: Seq[FallbackDependency], + appConfig: AppConfiguration, + classifiers: Option[Seq[Classifier]], + profiles: Set[String], + scalaOrg: String, + scalaVer: String, + scalaBinaryVer: String, + autoScalaLib: Boolean, + scalaModInfo: Option[ScalaModuleInfo], + excludeDeps: Seq[InclExclRule], + credentials: Seq[Credentials], + createLogger: Option[CacheLogger], + cacheDirectory: File, + reconciliation: Seq[(ModuleMatchers, Reconciliation)], + ivyHome: Option[File], + strict: Option[CStrict], + depsOverrides: Seq[ModuleID], + updateConfig: Option[UpdateConfiguration], + sameVersions: Seq[Set[InclExclRule]], + log: Logger + ): CoursierConfiguration = + coursierConfiguration( + rs, + interProjectDependencies, + extraProjects, + fallbackDeps, + appConfig, + classifiers, + profiles, + scalaOrg, + scalaVer, + scalaBinaryVer, + autoScalaLib, + scalaModInfo, + excludeDeps, + credentials, + createLogger, + cacheDirectory, + reconciliation, + ivyHome, + strict, + depsOverrides, + updateConfig, + sameVersions, + None, log ) @@ -198,6 +253,7 @@ object LMCoursier { depsOverrides: Seq[ModuleID], updateConfig: Option[UpdateConfiguration], sameVersions: Seq[Set[InclExclRule]], + enableDependencyOverrides: Option[Boolean], log: Logger ): CoursierConfiguration = { val coursierExcludeDeps = Inputs @@ -252,6 +308,7 @@ object LMCoursier { .withForceVersions(userForceVersions.toVector) .withMissingOk(missingOk) .withSameVersions(sameVersions) + .withEnableDependencyOverrides(enableDependencyOverrides) } def coursierConfigurationTask: Def.Initialize[Task[CoursierConfiguration]] = Def.task { @@ -279,6 +336,7 @@ object LMCoursier { dependencyOverrides.value, Some(updateConfiguration.value), csrSameVersions.value, + Some(csrMavenDependencyOverride.value), streams.value.log ) } @@ -308,6 +366,7 @@ object LMCoursier { dependencyOverrides.value, Some(updateConfiguration.value), csrSameVersions.value, + Some(csrMavenDependencyOverride.value), streams.value.log ) } @@ -337,6 +396,7 @@ object LMCoursier { dependencyOverrides.value, Some(updateConfiguration.value), csrSameVersions.value, + Some(csrMavenDependencyOverride.value), streams.value.log ) } @@ -366,6 +426,7 @@ object LMCoursier { dependencyOverrides.value, Some(updateConfiguration.value), csrSameVersions.value, + Some(csrMavenDependencyOverride.value), streams.value.log ) } diff --git a/main/src/main/scala/sbt/internal/AbstractTaskProgress.scala b/main/src/main/scala/sbt/internal/AbstractTaskProgress.scala index 18e6ffe2da..bce7bb2baa 100644 --- a/main/src/main/scala/sbt/internal/AbstractTaskProgress.scala +++ b/main/src/main/scala/sbt/internal/AbstractTaskProgress.scala @@ -9,6 +9,7 @@ package sbt package internal +import sbt.internal.util.Util import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicLong import scala.collection.JavaConverters._ @@ -122,7 +123,8 @@ private[sbt] abstract class AbstractTaskExecuteProgress extends ExecuteProgress[ object AbstractTaskExecuteProgress { private[sbt] class Timer() { val startNanos: Long = System.nanoTime() - val threadId: Long = Thread.currentThread().getId + val threadName: String = Thread.currentThread().getName + val threadId: Long = Util.threadId var endNanos: Long = 0L def stop(): Unit = { endNanos = System.nanoTime() diff --git a/main/src/main/scala/sbt/internal/Aggregation.scala b/main/src/main/scala/sbt/internal/Aggregation.scala index 8a26dcd77e..311e1beb1d 100644 --- a/main/src/main/scala/sbt/internal/Aggregation.scala +++ b/main/src/main/scala/sbt/internal/Aggregation.scala @@ -17,6 +17,7 @@ import sbt.SlashSyntax0._ import sbt.internal.util.complete.Parser import sbt.internal.util.complete.Parser.{ failure, seq, success } import sbt.internal.util._ +import sbt.internal.client.NetworkClient import sbt.std.Transform.DummyTaskMap import sbt.util.{ Logger, Show } import scala.annotation.nowarn @@ -152,20 +153,7 @@ object Aggregation { } def timing(format: java.text.DateFormat, startTime: Long, endTime: Long): String = { - val nowString = format.format(new java.util.Date(endTime)) - val total = (endTime - startTime + 500) / 1000 - val totalString = s"$total s" + - (if (total <= 60) "" - else { - val maybeHours = total / 3600 match { - case 0 => "" - case h => f"$h%02d:" - } - val mins = f"${total % 3600 / 60}%02d" - val secs = f"${total % 60}%02d" - s" ($maybeHours$mins:$secs)" - }) - s"Total time: $totalString, completed $nowString" + NetworkClient.timing(format, startTime, endTime) } def defaultFormat: DateFormat = { diff --git a/main/src/main/scala/sbt/internal/AnalysisUtil.scala b/main/src/main/scala/sbt/internal/AnalysisUtil.scala index d200ddfde8..049e3cf5ab 100644 --- a/main/src/main/scala/sbt/internal/AnalysisUtil.scala +++ b/main/src/main/scala/sbt/internal/AnalysisUtil.scala @@ -11,7 +11,6 @@ package internal import java.nio.file.Path import sbt.internal.inc.MixedAnalyzingCompiler -import scala.concurrent.ExecutionContext import xsbti.compile.{ AnalysisStore => XAnalysisStore } import xsbti.compile.analysis.ReadWriteMappers @@ -31,10 +30,10 @@ private[sbt] object AnalysisUtil { MixedAnalyzingCompiler.staticCachedStore( analysisFile = analysisFile, useTextAnalysis = useTextAnalysis, - useConsistent = false, + useConsistent = useConsistent, mappers = ReadWriteMappers.getEmptyMappers(), - sort = true, - ec = ExecutionContext.global, + // reproducisble = true will wipe out the timestamp, which we need for sbt 1.x + reproducible = false, parallelism = parallelism, ) } diff --git a/main/src/main/scala/sbt/internal/Continuous.scala b/main/src/main/scala/sbt/internal/Continuous.scala index b78f167d20..50e3a4d01e 100644 --- a/main/src/main/scala/sbt/internal/Continuous.scala +++ b/main/src/main/scala/sbt/internal/Continuous.scala @@ -1129,7 +1129,7 @@ private[sbt] object Continuous extends DeprecatedContinuous { val callbacks: Callbacks, val dynamicInputs: mutable.Set[DynamicInput], val pending: Boolean, - var failAction: Option[Watch.Action], + var terminationAction: Option[Watch.Action], ) { def this( count: Int, @@ -1162,7 +1162,8 @@ private[sbt] object Continuous extends DeprecatedContinuous { afterWatch, callbacks, dynamicInputs, - p + p, + terminationAction, ) private def withCount(c: Int): ContinuousState = new ContinuousState( @@ -1173,7 +1174,8 @@ private[sbt] object Continuous extends DeprecatedContinuous { afterWatch, callbacks, dynamicInputs, - pending + pending, + terminationAction, ) } } @@ -1341,12 +1343,13 @@ private[sbt] object ContinuousCommands { case Watch.Trigger => Right(s"$runWatch ${channel.name}") case Watch.Reload => val rewatch = s"$ContinuousExecutePrefix ${ws.count} ${cs.commands mkString "; "}" + cs.terminationAction = Some(Watch.Reload) stop.map(_ :: "reload" :: rewatch :: Nil mkString "; ") case Watch.Prompt => stop.map(_ :: s"$PromptChannel ${channel.name}" :: Nil mkString ";") case Watch.Run(commands) => stop.map(_ +: commands.map(_.commandLine).filter(_.nonEmpty) mkString "; ") case a @ Watch.HandleError(_) => - cs.failAction = Some(a) + cs.terminationAction = Some(a) stop.map(_ :: s"$failWatch ${channel.name}" :: Nil mkString "; ") case _ => stop } @@ -1394,7 +1397,7 @@ private[sbt] object ContinuousCommands { } val commands = cs.commands.mkString("; ") val count = cs.count - val action = cs.failAction.getOrElse(Watch.CancelWatch) + val action = cs.terminationAction.getOrElse(Watch.CancelWatch) val st = cs.callbacks.onTermination(action, commands, count, newState) if (error) st.fail else st case _ => if (error) state.fail else state diff --git a/main/src/main/scala/sbt/internal/CrossJava.scala b/main/src/main/scala/sbt/internal/CrossJava.scala index 38765232c0..6761b30f1a 100644 --- a/main/src/main/scala/sbt/internal/CrossJava.scala +++ b/main/src/main/scala/sbt/internal/CrossJava.scala @@ -412,13 +412,19 @@ private[sbt] object CrossJava { class MacOsDiscoverConfig extends JavaDiscoverConf { val base: File = file("/Library") / "Java" / "JavaVirtualMachines" + // User-specific JDKs are installed, for example, by IntelliJ IDEA + private val baseInUserHome: File = Path.userHome / "Library" / "Java" / "JavaVirtualMachines" def javaHomes: Vector[(String, File)] = - wrapNull(base.list()) - .collect { - case dir @ JavaHomeDir(version) => - version -> (base / dir / "Contents" / "Home") - } + findAllHomes(base) ++ + findAllHomes(baseInUserHome) + + private def findAllHomes(root: File): Vector[(String, File)] = { + wrapNull(root.list()).collect { + case dir @ JavaHomeDir(version) => + version -> (root / dir / "Contents" / "Home") + } + } } class JabbaDiscoverConfig extends JavaDiscoverConf { diff --git a/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala b/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala index 37d3022290..232204d467 100644 --- a/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala +++ b/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala @@ -114,7 +114,8 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe override val spawningTask: ScopedKey[_], val logger: ManagedLogger, val workingDirectory: File, - val job: BackgroundJob + val job: BackgroundJob, + @volatile var isAutoCancel: Boolean = false, ) extends AbstractJobHandle { // EC for onStop handler below implicit val executionContext: ExecutionContext = @@ -140,6 +141,17 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe private final class DeadHandle(override val id: Long, override val humanReadableName: String) extends AbstractJobHandle { override val spawningTask: ScopedKey[_] = unknownTask + override val isAutoCancel = false + } + + private[sbt] def createWorkingDirectory: File = { + val id = nextId.getAndIncrement() + createWorkingDirectory(id) + } + private[sbt] def createWorkingDirectory(id: Long): File = { + val workingDir = serviceTempDir / s"job-$id" + IO.createDirectory(workingDir) + workingDir } def doRunInBackground( @@ -151,8 +163,7 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe val extracted = Project.extract(state) val logger = LogManager.constructBackgroundLog(extracted.structure.data, state, context)(spawningTask) - val workingDir = serviceTempDir / s"job-$id" - IO.createDirectory(workingDir) + val workingDir = createWorkingDirectory(id) val job = try { new ThreadJobHandle(id, spawningTask, logger, workingDir, start(logger, workingDir)) } catch { @@ -508,6 +519,15 @@ private[sbt] object DefaultBackgroundJobService { backgroundJobServices.values.forEach(_.shutdown()) backgroundJobServices.clear() } + + private[sbt] def stop(): Unit = { + backgroundJobServices + .values() + .forEach(jobService => { + jobService.jobs.filter(_.isAutoCancel).foreach(jobService.stop) + }) + } + private[sbt] lazy val backgroundJobServiceSetting: Setting[_] = (GlobalScope / Keys.bgJobService) := { val path = (GlobalScope / sbt.Keys.bgJobServiceDirectory).value diff --git a/main/src/main/scala/sbt/internal/GCUtil.scala b/main/src/main/scala/sbt/internal/GCUtil.scala index e114c9e858..53a5c00317 100644 --- a/main/src/main/scala/sbt/internal/GCUtil.scala +++ b/main/src/main/scala/sbt/internal/GCUtil.scala @@ -36,14 +36,6 @@ private[sbt] object GCUtil { log.debug(s"Forcing garbage collection...") // Force the detection of finalizers for scala.reflect weakhashsets System.gc() - // Force finalizers to run. - try { - System.runFinalization() - } catch { - case _: NoSuchMethodError => - } - // Force actually cleaning the weak hash maps. - System.gc() } catch { case NonFatal(_) => // gotta catch em all } diff --git a/main/src/main/scala/sbt/internal/InstallSbtn.scala b/main/src/main/scala/sbt/internal/InstallSbtn.scala index 693830f937..6315a2a6dd 100644 --- a/main/src/main/scala/sbt/internal/InstallSbtn.scala +++ b/main/src/main/scala/sbt/internal/InstallSbtn.scala @@ -11,6 +11,7 @@ package internal import Def._ import Keys.{ sbtVersion, state, terminal } +import sbt.internal.util.Terminal.hasConsole import java.io.{ File, FileInputStream, FileOutputStream, InputStream, IOException } import java.net.URI @@ -37,7 +38,7 @@ private[sbt] object InstallSbtn { Files.deleteIfExists(tmp) () } - val shell = if (System.console != null) getShell(term) else "none" + val shell = if (hasConsole) getShell(term) else "none" shell match { case "none" => case s => diff --git a/main/src/main/scala/sbt/internal/LintUnused.scala b/main/src/main/scala/sbt/internal/LintUnused.scala index c2d2db0062..8df675c15b 100644 --- a/main/src/main/scala/sbt/internal/LintUnused.scala +++ b/main/src/main/scala/sbt/internal/LintUnused.scala @@ -34,6 +34,7 @@ object LintUnused { commands, crossScalaVersions, crossSbtVersions, + allowUnsafeScalaLibUpgrade, initialize, lintUnusedKeysOnLoad, onLoad, diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index 431c617f7b..f3f2265a61 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -1054,7 +1054,7 @@ private[sbt] object Load { def settings(files: Seq[File]): Seq[Setting[_]] = { if (files.nonEmpty) log.info( - s"${files.map(_.getName).mkString(s"loading settings for project ${p.id} from ", ",", " ...")}" + s"${files.map(_.getName).mkString(s"loading settings for project ${p.id} from ", ", ", "...")}" ) for { file <- files diff --git a/main/src/main/scala/sbt/internal/SysProp.scala b/main/src/main/scala/sbt/internal/SysProp.scala index 260c6420ac..6a2dfc7aa3 100644 --- a/main/src/main/scala/sbt/internal/SysProp.scala +++ b/main/src/main/scala/sbt/internal/SysProp.scala @@ -140,7 +140,7 @@ object SysProp { def turbo: Boolean = getOrFalse("sbt.turbo") def pipelining: Boolean = getOrFalse("sbt.pipelining") // opt-in or out of Zinc's consistent Analysis format. - def analysis2024: Boolean = getOrTrue("sbt.analysis2024") + def analysis2024: Boolean = getOrFalse("sbt.analysis2024") def taskTimings: Boolean = getOrFalse("sbt.task.timings") def taskTimingsOnShutdown: Boolean = getOrFalse("sbt.task.timings.on.shutdown") diff --git a/main/src/main/scala/sbt/internal/TaskTraceEvent.scala b/main/src/main/scala/sbt/internal/TaskTraceEvent.scala index 57b2900e75..914ee84a19 100644 --- a/main/src/main/scala/sbt/internal/TaskTraceEvent.scala +++ b/main/src/main/scala/sbt/internal/TaskTraceEvent.scala @@ -61,7 +61,7 @@ private[sbt] final class TaskTraceEvent def durationEvent(name: String, cat: String, t: Timer): String = { val sb = new java.lang.StringBuilder(name.length + 2) CompactPrinter.print(new JString(name), sb) - s"""{"name": ${sb.toString}, "cat": "$cat", "ph": "X", "ts": ${(t.startMicros)}, "dur": ${(t.durationMicros)}, "pid": 0, "tid": ${t.threadId}}""" + s"""{"name": ${sb.toString}, "cat": "$cat", "ph": "X", "ts": ${(t.startMicros)}, "dur": ${(t.durationMicros)}, "pid": 0, "tid": "${t.threadId}"}""" } val entryIterator = currentTimings while (entryIterator.hasNext) { diff --git a/main/src/main/scala/sbt/internal/server/BspCompileTask.scala b/main/src/main/scala/sbt/internal/server/BspCompileTask.scala index 205b11b573..b2aed4e55f 100644 --- a/main/src/main/scala/sbt/internal/server/BspCompileTask.scala +++ b/main/src/main/scala/sbt/internal/server/BspCompileTask.scala @@ -38,7 +38,7 @@ object BspCompileTask { val task = BspCompileTask(targetId, project, config, ci) try { task.notifyStart() - val result = Retry(compile(task)) + val result = Retry.io(compile(task)) task.notifySuccess(result) result } catch { diff --git a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala index 88e07d77de..9bb371a78e 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala @@ -34,6 +34,7 @@ import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter, Parser => import xsbti.CompileFailed import java.io.File +import java.nio.file.Paths import java.util.concurrent.atomic.AtomicBoolean import scala.collection.mutable @@ -247,7 +248,7 @@ object BuildServerProtocol { state.respondEvent(result) } }.evaluated, - bspScalaMainClasses / aggregate := false + bspScalaMainClasses / aggregate := false, ) // This will be scoped to Compile, Test, IntegrationTest etc @@ -344,7 +345,7 @@ object BuildServerProtocol { } else { new BuildServerForwarder(meta, logger, underlying) } - } + }, ) private[sbt] object Method { final val Initialize = "build/initialize" @@ -614,12 +615,19 @@ object BuildServerProtocol { val thisProjectRef = Keys.thisProjectRef.value val thisConfig = Keys.configuration.value val scalaJars = Keys.scalaInstance.value.allJars.map(_.toURI.toString) + val (javaHomeForTarget, isForkedJava) = javaHome.value match { + case Some(forkedJava) => (Some(forkedJava.toURI), true) + case None => (sys.props.get("java.home").map(Paths.get(_)).map(_.toUri), false) + } + val javaVersionForTarget = extractJavaVersion(javacOptions.value, isForkedJava) + val jvmBuildTarget = JvmBuildTarget(javaHomeForTarget, javaVersionForTarget) val compileData = ScalaBuildTarget( scalaOrganization = scalaOrganization.value, scalaVersion = scalaVersion.value, scalaBinaryVersion = scalaBinaryVersion.value, platform = ScalaPlatform.JVM, - jars = scalaJars.toVector + jars = scalaJars.toVector, + jvmBuildTarget = jvmBuildTarget, ) val configuration = Keys.configuration.value val displayName = BuildTargetName.fromScope(thisProject.id, configuration.name) @@ -659,7 +667,11 @@ object BuildServerProtocol { scalaVersion = scalaProvider.version(), scalaBinaryVersion = binaryScalaVersion(scalaProvider.version()), platform = ScalaPlatform.JVM, - jars = scalaJars.toVector.map(_.toURI.toString) + jars = scalaJars.toVector.map(_.toURI.toString), + jvmBuildTarget = JvmBuildTarget( + sys.props.get("java.home").map(Paths.get(_)).map(_.toUri), + sys.props.get("java.version") + ), ) val sbtVersionValue = sbtVersion.value val sbtData = SbtBuildTarget( @@ -985,6 +997,26 @@ object BuildServerProtocol { ) } + private def extractJavaVersion( + javacOptions: Seq[String], + isForkedJava: Boolean + ): Option[String] = { + def getVersionAfterFlag(flag: String): Option[String] = { + val index = javacOptions.indexOf(flag) + if (index >= 0) javacOptions.lift(index + 1) + else None + } + + val versionFromJavacOption = getVersionAfterFlag("--release") + .orElse(getVersionAfterFlag("--target")) + .orElse(getVersionAfterFlag("-target")) + + versionFromJavacOption.orElse { + // TODO: extract java version from forked javac + if (isForkedJava) None else sys.props.get("java.version") + } + } + // naming convention still seems like the only reliable way to get IntelliJ to import this correctly // https://github.com/JetBrains/intellij-scala/blob/a54c2a7c157236f35957049cbfd8c10587c9e60c/scala/scala-impl/src/org/jetbrains/sbt/language/SbtFileImpl.scala#L82-L84 private def toSbtTargetIdName(ref: LoadedBuildUnit): String = { diff --git a/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala b/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala index 5b25d17b08..b4ef0d320f 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala @@ -25,6 +25,7 @@ import xsbti.{ import scala.collection.JavaConverters._ import scala.collection.mutable +import java.nio.file.Path /** Provides methods for sending success and failure reports and publishing diagnostics. @@ -90,7 +91,7 @@ final class BuildServerReporterImpl( import sbt.internal.inc.JavaInterfaceUtil._ private lazy val exchange = StandardMain.exchange - private val problemsByFile = mutable.Map[VirtualFileRef, Vector[Problem]]() + private val problemsByFile = mutable.Map[Path, Vector[Problem]]() // sometimes the compiler returns a fake position such as // on Windows, this causes InvalidPathException (see #5994 and #6720) @@ -114,9 +115,10 @@ final class BuildServerReporterImpl( override def sendFailureReport(sources: Array[VirtualFile]): Unit = { for (source <- sources) { - val problems = problemsByFile.getOrElse(source, Vector.empty) + val problems = problemsByFile.getOrElse(converter.toPath(source), Vector.empty) sendReport(source, problems) } + notifyFirstReport() } private def sendReport(source: VirtualFileRef, problems: Vector[Problem]): Unit = { @@ -153,7 +155,11 @@ final class BuildServerReporterImpl( id <- problem.position.sourcePath.toOption (document, diagnostic) <- mapProblemToDiagnostic(problem) } { - val fileRef = VirtualFileRef.of(id) + // Note: We're putting the real path in `fileRef` because the `id` String can take + // two forms, either a ${something}/relativePath, or the absolute path of the source. + // But where we query this, we always have _only_ a ${something}/relativePath available. + // So here we "normalize" to the real path. + val fileRef = converter.toPath(VirtualFileRef.of(id)) problemsByFile(fileRef) = problemsByFile.getOrElse(fileRef, Vector.empty) :+ problem val params = PublishDiagnosticsParams( diff --git a/main/src/main/scala/sbt/internal/server/ClientJob.scala b/main/src/main/scala/sbt/internal/server/ClientJob.scala new file mode 100644 index 0000000000..e016b98f00 --- /dev/null +++ b/main/src/main/scala/sbt/internal/server/ClientJob.scala @@ -0,0 +1,94 @@ +/* + * sbt + * Copyright 2023, Scala center + * Copyright 2011 - 2022, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt +package internal +package server + +import java.io.File +import sbt.BuildSyntax._ +import sbt.Def._ +import sbt.Keys._ +import sbt.SlashSyntax0._ +import sbt.internal.util.complete.Parser +import sbt.internal.worker.{ ClientJobParams, FilePath, JvmRunInfo, RunInfo } +import sbt.io.IO +import sbt.protocol.Serialization + +/** + * A ClientJob represents a unit of work that sbt server process + * can outsourse back to the client. Initially intended for sbtn client-side run. + */ +object ClientJob { + lazy val globalSettings: Seq[Def.Setting[_]] = Seq( + clientJob := clientJobTask.evaluated, + clientJob / aggregate := false, + ) + + private def clientJobTask: Def.Initialize[InputTask[ClientJobParams]] = Def.inputTaskDyn { + val tokens = spaceDelimited().parsed + val state = Keys.state.value + val p = Act.aggregatedKeyParser(state) + if (tokens.isEmpty) { + sys.error("expected an argument, for example foo/run") + } + val scopedKey = Parser.parse(tokens.head, p) match { + case Right(x :: Nil) => x + case Right(xs) => sys.error("too many keys") + case Left(err) => sys.error(err) + } + if (scopedKey.key == run.key) + clientJobRunInfo.in(scopedKey.scope).toTask(" " + tokens.tail.mkString(" ")) + else sys.error(s"unsupported task for clientJob $scopedKey") + } + + // This will be scoped to Compile, Test, etc + lazy val configSettings: Seq[Def.Setting[_]] = Seq( + clientJobRunInfo := clientJobRunInfoTask.evaluated, + ) + + private def clientJobRunInfoTask: Def.Initialize[InputTask[ClientJobParams]] = Def.inputTask { + val state = Keys.state.value + val args = spaceDelimited().parsed + val mainClass = (Keys.run / Keys.mainClass).value + val service = bgJobService.value + val fo = (Keys.run / Keys.forkOptions).value + val workingDir = service.createWorkingDirectory + val cp = service.copyClasspath( + exportedProductJars.value, + fullClasspathAsJars.value, + workingDir, + hashContents = true, + ) + val strategy = fo.outputStrategy.map(_.getClass().getSimpleName().filter(_ != '$')) + // sbtn doesn't set java.home, so we need to do the fallback here + val javaHome = + fo.javaHome.map(IO.toURI).orElse(sys.props.get("java.home").map(x => IO.toURI(new File(x)))) + val jvmRunInfo = JvmRunInfo( + args = args.toVector, + classpath = cp.map(x => IO.toURI(x.data)).map(FilePath(_, "")).toVector, + mainClass = mainClass.getOrElse(sys.error("no main class")), + connectInput = fo.connectInput, + javaHome = javaHome, + outputStrategy = strategy, + workingDirectory = fo.workingDirectory.map(IO.toURI), + jvmOptions = fo.runJVMOptions, + environmentVariables = fo.envVars.toMap, + ) + val info = RunInfo( + jvm = true, + jvmRunInfo = jvmRunInfo, + ) + val result = ClientJobParams( + runInfo = info + ) + import sbt.internal.worker.codec.JsonProtocol._ + state.notifyEvent(Serialization.clientJob, result) + result + } +} diff --git a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala index 2bf2878bda..5ea1918128 100644 --- a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala @@ -62,6 +62,7 @@ private[sbt] object LanguageServerProtocol { else throw LangServerError(ErrorCodes.InvalidRequest, "invalid token") } else () setInitialized(true) + setInitializeOption(opt) if (!opt.skipAnalysis.getOrElse(false)) appendExec("collectAnalyses", None) jsonRpcRespond(InitializeResult(serverCapabilities), Some(r.id)) diff --git a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala index 95c0e16c0d..36ace91f14 100644 --- a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala +++ b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala @@ -24,6 +24,7 @@ import java.util.concurrent.atomic.{ AtomicBoolean, AtomicReference } import sbt.BasicCommandStrings.{ Shutdown, TerminateAction } import sbt.internal.langserver.{ CancelRequestParams, ErrorCodes, LogMessageParams, MessageType } import sbt.internal.protocol.{ + InitializeOption, JsonRpcNotificationMessage, JsonRpcRequestMessage, JsonRpcResponseError, @@ -83,6 +84,10 @@ final class NetworkChannel( private val delimiter: Byte = '\n'.toByte private val out = connection.getOutputStream private var initialized = false + + /** Reference to the client-side custom options + */ + private val initializeOption = new AtomicReference[InitializeOption](null) private val pendingRequests: mutable.Map[String, JsonRpcRequestMessage] = mutable.Map() private[this] val inputBuffer = new LinkedBlockingQueue[Int]() @@ -124,7 +129,7 @@ final class NetworkChannel( self.jsonRpcNotify(method, params) def appendExec(commandLine: String, execId: Option[String]): Boolean = - self.append(Exec(commandLine, execId, Some(CommandSource(name)))) + self.appendExec(commandLine, execId) def appendExec(exec: Exec): Boolean = self.append(exec) @@ -133,6 +138,8 @@ final class NetworkChannel( private[sbt] def authOptions: Set[ServerAuthentication] = self.authOptions private[sbt] def authenticate(token: String): Boolean = self.authenticate(token) private[sbt] def setInitialized(value: Boolean): Unit = self.setInitialized(value) + private[sbt] def setInitializeOption(opts: InitializeOption): Unit = + self.setInitializeOption(opts) private[sbt] def onSettingQuery(execId: Option[String], req: SettingQuery): Unit = self.onSettingQuery(execId, req) private[sbt] def onCompletionRequest(execId: Option[String], cp: CompletionParams): Unit = @@ -141,6 +148,15 @@ final class NetworkChannel( self.onCancellationRequest(execId, crp) } + protected def setInitializeOption(opts: InitializeOption): Unit = initializeOption.set(opts) + + // Returns true if sbtn has declared with canWork: true + protected def clientCanWork: Boolean = + Option(initializeOption.get) match { + case Some(opts) => opts.canWork.getOrElse(false) + case _ => false + } + protected def authenticate(token: String): Boolean = instance.authenticate(token) protected def setInitialized(value: Boolean): Unit = initialized = value @@ -163,7 +179,7 @@ final class NetworkChannel( } } - val thread = new Thread(s"sbt-networkchannel-${connection.getPort}") { + private[this] val thread = new Thread(s"sbt-networkchannel-${connection.getPort}") { private val ct = "Content-Type: " private val x1 = "application/sbt-x1" override def run(): Unit = { @@ -241,7 +257,6 @@ final class NetworkChannel( } } } - thread.start() private[sbt] def isLanguageServerProtocol: Boolean = true @@ -365,46 +380,11 @@ final class NetworkChannel( impl() }, s"sbt-$name-write-thread") writeThread.setDaemon(true) - writeThread.start() def publishBytes(event: Array[Byte], delimit: Boolean): Unit = try pendingWrites.put(event -> delimit) catch { case _: InterruptedException => } - def onCommand(command: CommandMessage): Unit = command match { - case x: InitCommand => onInitCommand(x) - case x: ExecCommand => onExecCommand(x) - case x: SettingQuery => onSettingQuery(None, x) - } - - private def onInitCommand(cmd: InitCommand): Unit = { - if (auth(ServerAuthentication.Token)) { - cmd.token match { - case Some(x) => - authenticate(x) match { - case true => - initialized = true - notifyEvent(ChannelAcceptedEvent(name)) - case _ => sys.error("invalid token") - } - case None => sys.error("init command but without token.") - } - } else { - initialized = true - } - } - - private def onExecCommand(cmd: ExecCommand) = { - if (initialized) { - append( - Exec(cmd.commandLine, cmd.execId orElse Some(Exec.newExecId), Some(CommandSource(name))) - ) - () - } else { - log.warn(s"ignoring command $cmd before initialization") - } - } - protected def onSettingQuery(execId: Option[String], req: SettingQuery) = { if (initialized) { StandardMain.exchange.withState { s => @@ -914,6 +894,9 @@ final class NetworkChannel( } } private[sbt] def isAttached: Boolean = attached.get + + thread.start() + writeThread.start() } object NetworkChannel { diff --git a/main/src/main/scala/sbt/plugins/DependencyTreeSettings.scala b/main/src/main/scala/sbt/plugins/DependencyTreeSettings.scala index 9cf6ee368c..85618a77df 100644 --- a/main/src/main/scala/sbt/plugins/DependencyTreeSettings.scala +++ b/main/src/main/scala/sbt/plugins/DependencyTreeSettings.scala @@ -147,8 +147,9 @@ object DependencyTreeSettings { .asciiTree(GraphTransformations.reverseGraphStartingAt(graph, module), graphWidth) } .mkString("\n") - - streams.value.log.info(output) + synchronized { + streams.value.log.info(output) + } output }, ) ++ @@ -171,7 +172,9 @@ object DependencyTreeSettings { key := { val s = streams.value val str = (key / asString).value - s.log.info(str) + synchronized { + s.log.info(str) + } }, key / toFile := { val (targetFile, force) = targetFileAndForceParser.parsed @@ -198,7 +201,7 @@ object DependencyTreeSettings { rendering.DOT.AngleBrackets, dependencyDotNodeColors.value ) - val link = DagreHTML.createLink(dotGraph, target.value) + val link = DagreHTML.createLink(dotGraph, dependencyBrowseGraphTarget.value) streams.value.log.info(s"HTML graph written to $link") link } @@ -207,7 +210,7 @@ object DependencyTreeSettings { Def.task { val graph = dependencyTreeModuleGraph0.value val renderedTree = TreeView.createJson(graph) - val link = TreeView.createLink(renderedTree, target.value) + val link = TreeView.createLink(renderedTree, dependencyBrowseTreeTarget.value) streams.value.log.info(s"HTML tree written to $link") link } @@ -245,7 +248,10 @@ object DependencyTreeSettings { Def.task { val uri = uriKey.value streams.value.log.info(s"Opening ${uri} in browser...") - java.awt.Desktop.getDesktop.browse(uri) + val desktop = java.awt.Desktop.getDesktop + desktop.synchronized { + desktop.browse(uri) + } uri } diff --git a/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala b/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala index 51e60575b5..4aedac6aa8 100644 --- a/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala +++ b/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala @@ -27,7 +27,7 @@ object Giter8TemplatePlugin extends AutoPlugin { ModuleID( "org.scala-sbt.sbt-giter8-resolver", "sbt-giter8-resolver", - "0.16.2" + "0.17.0" ) cross CrossVersion.binary, "sbtgiter8resolver.Giter8TemplateResolver" ) diff --git a/main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala b/main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala index 5d603bc113..46a0183978 100644 --- a/main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala +++ b/main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala @@ -27,7 +27,7 @@ object SemanticdbPlugin extends AutoPlugin { semanticdbEnabled := SysProp.semanticdb, semanticdbIncludeInJar := false, semanticdbOptions := List(), - semanticdbVersion := "4.7.8" + semanticdbVersion := "4.9.9" ) override lazy val projectSettings: Seq[Def.Setting[_]] = Seq( diff --git a/main/src/test/scala/TagsTest.scala b/main/src/test/scala/TagsTest.scala index 270ca646ee..e75dd7e183 100644 --- a/main/src/test/scala/TagsTest.scala +++ b/main/src/test/scala/TagsTest.scala @@ -18,7 +18,7 @@ object TagsTest extends Properties("Tags") { def tagMap: Gen[TagMap] = for (ts <- listOf(tagAndFrequency)) yield ts.toMap def tagAndFrequency: Gen[(Tag, Int)] = - for (t <- tag; count <- Arbitrary.arbitrary[Int]) yield (t, count) + for (t <- tag; count <- Gen.choose(0, Int.MaxValue)) yield (t, count) def tag: Gen[Tag] = for (s <- Gen.alphaStr if !s.isEmpty) yield Tag(s) def size: Gen[Size] = for (i <- Arbitrary.arbitrary[Int] if i != Int.MinValue) yield Size(math.abs(i)) diff --git a/main/src/test/scala/sbt/internal/AggregationSpec.scala b/main/src/test/scala/sbt/internal/AggregationSpec.scala index 9acf09dc39..b6cbdb681e 100644 --- a/main/src/test/scala/sbt/internal/AggregationSpec.scala +++ b/main/src/test/scala/sbt/internal/AggregationSpec.scala @@ -12,14 +12,18 @@ object AggregationSpec extends verify.BasicTestSuite { val timing = Aggregation.timing(Aggregation.defaultFormat, 0, _: Long) test("timing should format total time properly") { - assert(timing(101).startsWith("Total time: 0 s,")) - assert(timing(1000).startsWith("Total time: 1 s,")) - assert(timing(3000).startsWith("Total time: 3 s,")) - assert(timing(30399).startsWith("Total time: 30 s,")) - assert(timing(60399).startsWith("Total time: 60 s,")) - assert(timing(60699).startsWith("Total time: 61 s (01:01),")) - assert(timing(303099).startsWith("Total time: 303 s (05:03),")) - assert(timing(6003099).startsWith("Total time: 6003 s (01:40:03),")) - assert(timing(96003099).startsWith("Total time: 96003 s (26:40:03),")) + assert(timing(101).startsWith("Total time: 0 s")) + assert(timing(1000).startsWith("Total time: 1 s")) + assert(timing(3000).startsWith("Total time: 3 s")) + assert(timing(30399).startsWith("Total time: 30 s")) + assert(timing(60399).startsWith("Total time: 60 s")) + assert(timing(60699).startsWith("Total time: 61 s (0:01:01.0)")) + assert(timing(303099).startsWith("Total time: 303 s (0:05:03.0)")) + assert(timing(6003099).startsWith("Total time: 6003 s (01:40:03.0)")) + assert(timing(96003099).startsWith("Total time: 96003 s (26:40:03.0)")) + } + + test("timing should not emit special space characters") { + assert(!timing(96003099).contains("\u202F")) } } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 2bf0d2741d..f3ef989a25 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,29 +4,29 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { // WARNING: Please Scala update versions in PluginCross.scala too - val scala212 = "2.12.19" - val scala213 = "2.13.14" + val scala212 = "2.12.20" + val scala213 = "2.13.16" val checkPluginCross = settingKey[Unit]("Make sure scalaVersion match up") val baseScalaVersion = scala212 def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") // sbt modules - private val ioVersion = nightlyVersion.getOrElse("1.10.0") + private val ioVersion = nightlyVersion.getOrElse("1.10.5") private val lmVersion = - sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.10.1") - val zincVersion = nightlyVersion.getOrElse("1.10.1") + sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.10.4") + val zincVersion = nightlyVersion.getOrElse("1.10.8") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion private val libraryManagementCore = "org.scala-sbt" %% "librarymanagement-core" % lmVersion private val libraryManagementIvy = "org.scala-sbt" %% "librarymanagement-ivy" % lmVersion - val launcherVersion = "1.4.3" + val launcherVersion = "1.4.4" val launcherInterface = "org.scala-sbt" % "launcher-interface" % launcherVersion val rawLauncher = "org.scala-sbt" % "launcher" % launcherVersion val testInterface = "org.scala-sbt" % "test-interface" % "1.0" - val ipcSocket = "org.scala-sbt.ipcsocket" % "ipcsocket" % "1.6.2" + val ipcSocket = "org.scala-sbt.ipcsocket" % "ipcsocket" % "1.6.3" private val compilerInterface = "org.scala-sbt" % "compiler-interface" % zincVersion private val compilerClasspath = "org.scala-sbt" %% "zinc-classpath" % zincVersion @@ -77,23 +77,20 @@ object Dependencies { def addSbtZincCompile = addSbtModule(sbtZincPath, "zincCompile", zincCompile) def addSbtZincCompileCore = addSbtModule(sbtZincPath, "zincCompileCore", zincCompileCore) - val lmCoursierShaded = "io.get-coursier" %% "lm-coursier-shaded" % "2.1.4" + val lmCoursierShaded = "io.get-coursier" %% "lm-coursier-shaded" % "2.1.8" def sjsonNew(n: String) = Def.setting("com.eed3si9n" %% n % "0.10.1") // contrabandSjsonNewVersion.value val sjsonNewScalaJson = sjsonNew("sjson-new-scalajson") val sjsonNewMurmurhash = sjsonNew("sjson-new-murmurhash") - // JLine 3 version must be coordinated together with JAnsi version - // and the JLine 2 fork version, which uses the same JAnsi - val jline = "org.scala-sbt.jline" % "jline" % "2.14.7-sbt-9c3b6aca11c57e339441442bbf58e550cdfecb79" - val jline3Version = "3.24.1" + val jline = "org.scala-sbt.jline" % "jline" % "2.14.7-sbt-9a88bc413e2b34a4580c001c654d1a7f4f65bf18" + val jline3Version = "3.27.1" val jline3Terminal = "org.jline" % "jline-terminal" % jline3Version - val jline3Jansi = "org.jline" % "jline-terminal-jansi" % jline3Version - val jline3JNA = "org.jline" % "jline-terminal-jna" % jline3Version + val jline3JNI = "org.jline" % "jline-terminal-jni" % jline3Version + val jline3Native = "org.jline" % "jline-native" % jline3Version val jline3Reader = "org.jline" % "jline-reader" % jline3Version val jline3Builtins = "org.jline" % "jline-builtins" % jline3Version - val jansi = "org.fusesource.jansi" % "jansi" % "2.4.1" val scalatest = "org.scalatest" %% "scalatest" % "3.2.10" val scalacheck = "org.scalacheck" %% "scalacheck" % "1.15.4" val junit = "junit" % "junit" % "4.13.1" diff --git a/project/Util.scala b/project/Util.scala index cf8b75cc85..df8b3a06a2 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -2,8 +2,6 @@ import scala.util.control.NonFatal import sbt._ import Keys._ -import sbt.internal.inc.Analysis - object Util { val version2_13 = settingKey[String]("version number") val ExclusiveTest: Tags.Tag = Tags.Tag("exclusive-test") @@ -75,30 +73,6 @@ object Util { run.run(mainClass, cp.files, args, s.log).failed foreach (e => sys error e.getMessage) (out ** "*.java").get } - def lastCompilationTime(analysis: Analysis): Long = { - val lastCompilation = analysis.compilations.allCompilations.lastOption - lastCompilation.map(_.getStartTime) getOrElse 0L - } - def generateVersionFile( - version: String, - dir: File, - s: TaskStreams, - analysis: Analysis - ): Seq[File] = { - import java.util.{ Date, TimeZone } - val formatter = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss") - formatter.setTimeZone(TimeZone.getTimeZone("GMT")) - val timestamp = formatter.format(new Date) - val content = versionLine(version) + "\ntimestamp=" + timestamp - val f = dir / "xsbt.version.properties" - // TODO: replace lastModified() with sbt.io.IO.getModifiedTimeOrZero(), once the build - // has been upgraded to a version of sbt that includes that call. - if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) { - s.log.info("Writing version information to " + f + " :\n" + content) - IO.write(f, content) - } - f :: Nil - } def versionLine(version: String): String = "version=" + version def containsVersion(propFile: File, version: String): Boolean = IO.read(propFile).contains(versionLine(version)) diff --git a/project/build.properties b/project/build.properties index 081fdbbc76..73df629ac1 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.0 +sbt.version=1.10.7 diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/JvmBuildTarget.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/JvmBuildTarget.scala new file mode 100644 index 0000000000..488b8b8e68 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/JvmBuildTarget.scala @@ -0,0 +1,48 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.bsp +/** + * Contains jvm-specific metadata, specifically JDK reference + * @param javaHome Uri representing absolute path to jdk + * @param javaVersion The java version this target is supposed to use (can be set using javac `-target` flag) + */ +final class JvmBuildTarget private ( + val javaHome: Option[java.net.URI], + val javaVersion: Option[String]) extends Serializable { + + + + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { + case x: JvmBuildTarget => (this.javaHome == x.javaHome) && (this.javaVersion == x.javaVersion) + case _ => false + }) + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.internal.bsp.JvmBuildTarget".##) + javaHome.##) + javaVersion.##) + } + override def toString: String = { + "JvmBuildTarget(" + javaHome + ", " + javaVersion + ")" + } + private[this] def copy(javaHome: Option[java.net.URI] = javaHome, javaVersion: Option[String] = javaVersion): JvmBuildTarget = { + new JvmBuildTarget(javaHome, javaVersion) + } + def withJavaHome(javaHome: Option[java.net.URI]): JvmBuildTarget = { + copy(javaHome = javaHome) + } + def withJavaHome(javaHome: java.net.URI): JvmBuildTarget = { + copy(javaHome = Option(javaHome)) + } + def withJavaVersion(javaVersion: Option[String]): JvmBuildTarget = { + copy(javaVersion = javaVersion) + } + def withJavaVersion(javaVersion: String): JvmBuildTarget = { + copy(javaVersion = Option(javaVersion)) + } +} +object JvmBuildTarget { + + def apply(javaHome: Option[java.net.URI], javaVersion: Option[String]): JvmBuildTarget = new JvmBuildTarget(javaHome, javaVersion) + def apply(javaHome: java.net.URI, javaVersion: String): JvmBuildTarget = new JvmBuildTarget(Option(javaHome), Option(javaVersion)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/ScalaBuildTarget.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/ScalaBuildTarget.scala index 32e5885a91..e686d84dd5 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/ScalaBuildTarget.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/ScalaBuildTarget.scala @@ -14,28 +14,30 @@ package sbt.internal.bsp For example, 2.12 if scalaVersion is 2.12.4. * @param platform The target platform for this target * @param jars A sequence of Scala jars such as scala-library, scala-compiler and scala-reflect. + * @param jvmBuildTarget The jvm build target describing jdk to be used */ final class ScalaBuildTarget private ( val scalaOrganization: String, val scalaVersion: String, val scalaBinaryVersion: String, val platform: Int, - val jars: Vector[String]) extends Serializable { + val jars: Vector[String], + val jvmBuildTarget: Option[sbt.internal.bsp.JvmBuildTarget]) extends Serializable { override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { - case x: ScalaBuildTarget => (this.scalaOrganization == x.scalaOrganization) && (this.scalaVersion == x.scalaVersion) && (this.scalaBinaryVersion == x.scalaBinaryVersion) && (this.platform == x.platform) && (this.jars == x.jars) + case x: ScalaBuildTarget => (this.scalaOrganization == x.scalaOrganization) && (this.scalaVersion == x.scalaVersion) && (this.scalaBinaryVersion == x.scalaBinaryVersion) && (this.platform == x.platform) && (this.jars == x.jars) && (this.jvmBuildTarget == x.jvmBuildTarget) case _ => false }) override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.ScalaBuildTarget".##) + scalaOrganization.##) + scalaVersion.##) + scalaBinaryVersion.##) + platform.##) + jars.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.ScalaBuildTarget".##) + scalaOrganization.##) + scalaVersion.##) + scalaBinaryVersion.##) + platform.##) + jars.##) + jvmBuildTarget.##) } override def toString: String = { - "ScalaBuildTarget(" + scalaOrganization + ", " + scalaVersion + ", " + scalaBinaryVersion + ", " + platform + ", " + jars + ")" + "ScalaBuildTarget(" + scalaOrganization + ", " + scalaVersion + ", " + scalaBinaryVersion + ", " + platform + ", " + jars + ", " + jvmBuildTarget + ")" } - private[this] def copy(scalaOrganization: String = scalaOrganization, scalaVersion: String = scalaVersion, scalaBinaryVersion: String = scalaBinaryVersion, platform: Int = platform, jars: Vector[String] = jars): ScalaBuildTarget = { - new ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars) + private[this] def copy(scalaOrganization: String = scalaOrganization, scalaVersion: String = scalaVersion, scalaBinaryVersion: String = scalaBinaryVersion, platform: Int = platform, jars: Vector[String] = jars, jvmBuildTarget: Option[sbt.internal.bsp.JvmBuildTarget] = jvmBuildTarget): ScalaBuildTarget = { + new ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars, jvmBuildTarget) } def withScalaOrganization(scalaOrganization: String): ScalaBuildTarget = { copy(scalaOrganization = scalaOrganization) @@ -52,8 +54,15 @@ final class ScalaBuildTarget private ( def withJars(jars: Vector[String]): ScalaBuildTarget = { copy(jars = jars) } + def withJvmBuildTarget(jvmBuildTarget: Option[sbt.internal.bsp.JvmBuildTarget]): ScalaBuildTarget = { + copy(jvmBuildTarget = jvmBuildTarget) + } + def withJvmBuildTarget(jvmBuildTarget: sbt.internal.bsp.JvmBuildTarget): ScalaBuildTarget = { + copy(jvmBuildTarget = Option(jvmBuildTarget)) + } } object ScalaBuildTarget { - def apply(scalaOrganization: String, scalaVersion: String, scalaBinaryVersion: String, platform: Int, jars: Vector[String]): ScalaBuildTarget = new ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars) + def apply(scalaOrganization: String, scalaVersion: String, scalaBinaryVersion: String, platform: Int, jars: Vector[String], jvmBuildTarget: Option[sbt.internal.bsp.JvmBuildTarget]): ScalaBuildTarget = new ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars, jvmBuildTarget) + def apply(scalaOrganization: String, scalaVersion: String, scalaBinaryVersion: String, platform: Int, jars: Vector[String], jvmBuildTarget: sbt.internal.bsp.JvmBuildTarget): ScalaBuildTarget = new ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars, Option(jvmBuildTarget)) } diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/BuildServerCapabilitiesFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/BuildServerCapabilitiesFormats.scala index 9c8684ba3c..6aba27ae75 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/BuildServerCapabilitiesFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/BuildServerCapabilitiesFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait BuildServerCapabilitiesFormats { self: sbt.internal.bsp.codec.CompileProviderFormats with sbt.internal.bsp.codec.TestProviderFormats with sbt.internal.bsp.codec.RunProviderFormats with sjsonnew.BasicJsonProtocol => +trait BuildServerCapabilitiesFormats { self: sbt.internal.bsp.codec.CompileProviderFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.TestProviderFormats with sbt.internal.bsp.codec.RunProviderFormats => implicit lazy val BuildServerCapabilitiesFormat: JsonFormat[sbt.internal.bsp.BuildServerCapabilities] = new JsonFormat[sbt.internal.bsp.BuildServerCapabilities] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.BuildServerCapabilities = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/BuildTargetFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/BuildTargetFormats.scala index 8515f37eec..76eff0d93a 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/BuildTargetFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/BuildTargetFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait BuildTargetFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.bsp.codec.BuildTargetCapabilitiesFormats with sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => +trait BuildTargetFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.BuildTargetCapabilitiesFormats with sbt.internal.util.codec.JValueFormats => implicit lazy val BuildTargetFormat: JsonFormat[sbt.internal.bsp.BuildTarget] = new JsonFormat[sbt.internal.bsp.BuildTarget] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.BuildTarget = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DebugSessionParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DebugSessionParamsFormats.scala index 8d4ccab6ef..2ea073b09d 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DebugSessionParamsFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DebugSessionParamsFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait DebugSessionParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => +trait DebugSessionParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.util.codec.JValueFormats => implicit lazy val DebugSessionParamsFormat: JsonFormat[sbt.internal.bsp.DebugSessionParams] = new JsonFormat[sbt.internal.bsp.DebugSessionParams] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.DebugSessionParams = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DependencySourcesResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DependencySourcesResultFormats.scala index 974150a782..0901c083f4 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DependencySourcesResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DependencySourcesResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait DependencySourcesResultFormats { self: sbt.internal.bsp.codec.DependencySourcesItemFormats with sjsonnew.BasicJsonProtocol => +trait DependencySourcesResultFormats { self: sbt.internal.bsp.codec.DependencySourcesItemFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol => implicit lazy val DependencySourcesResultFormat: JsonFormat[sbt.internal.bsp.DependencySourcesResult] = new JsonFormat[sbt.internal.bsp.DependencySourcesResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.DependencySourcesResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DiagnosticFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DiagnosticFormats.scala index 0e0291d9f9..6a8fb8bffb 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DiagnosticFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DiagnosticFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait DiagnosticFormats { self: sbt.internal.bsp.codec.RangeFormats with sbt.internal.bsp.codec.DiagnosticRelatedInformationFormats with sbt.internal.bsp.codec.ScalaDiagnosticFormats with sjsonnew.BasicJsonProtocol => +trait DiagnosticFormats { self: sbt.internal.bsp.codec.RangeFormats with sbt.internal.bsp.codec.PositionFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.DiagnosticRelatedInformationFormats with sbt.internal.bsp.codec.LocationFormats with sbt.internal.bsp.codec.ScalaDiagnosticFormats with sbt.internal.bsp.codec.ScalaActionFormats with sbt.internal.bsp.codec.ScalaWorkspaceEditFormats with sbt.internal.bsp.codec.ScalaTextEditFormats => implicit lazy val DiagnosticFormat: JsonFormat[sbt.internal.bsp.Diagnostic] = new JsonFormat[sbt.internal.bsp.Diagnostic] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.Diagnostic = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DiagnosticRelatedInformationFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DiagnosticRelatedInformationFormats.scala index 7886ec851e..b4271dbcda 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DiagnosticRelatedInformationFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/DiagnosticRelatedInformationFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait DiagnosticRelatedInformationFormats { self: sbt.internal.bsp.codec.LocationFormats with sjsonnew.BasicJsonProtocol => +trait DiagnosticRelatedInformationFormats { self: sbt.internal.bsp.codec.LocationFormats with sbt.internal.bsp.codec.RangeFormats with sbt.internal.bsp.codec.PositionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val DiagnosticRelatedInformationFormat: JsonFormat[sbt.internal.bsp.DiagnosticRelatedInformation] = new JsonFormat[sbt.internal.bsp.DiagnosticRelatedInformation] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.DiagnosticRelatedInformation = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/InitializeBuildParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/InitializeBuildParamsFormats.scala index 943feb6643..31e0eeceae 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/InitializeBuildParamsFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/InitializeBuildParamsFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait InitializeBuildParamsFormats { self: sbt.internal.bsp.codec.BuildClientCapabilitiesFormats with sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => +trait InitializeBuildParamsFormats { self: sbt.internal.bsp.codec.BuildClientCapabilitiesFormats with sjsonnew.BasicJsonProtocol with sbt.internal.util.codec.JValueFormats => implicit lazy val InitializeBuildParamsFormat: JsonFormat[sbt.internal.bsp.InitializeBuildParams] = new JsonFormat[sbt.internal.bsp.InitializeBuildParams] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.InitializeBuildParams = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/InitializeBuildResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/InitializeBuildResultFormats.scala index 1b555b42cb..8854dfe95a 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/InitializeBuildResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/InitializeBuildResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait InitializeBuildResultFormats { self: sbt.internal.bsp.codec.BuildServerCapabilitiesFormats with sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => +trait InitializeBuildResultFormats { self: sbt.internal.bsp.codec.BuildServerCapabilitiesFormats with sbt.internal.bsp.codec.CompileProviderFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.TestProviderFormats with sbt.internal.bsp.codec.RunProviderFormats with sbt.internal.util.codec.JValueFormats => implicit lazy val InitializeBuildResultFormat: JsonFormat[sbt.internal.bsp.InitializeBuildResult] = new JsonFormat[sbt.internal.bsp.InitializeBuildResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.InitializeBuildResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JavacOptionsResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JavacOptionsResultFormats.scala index ee381306ad..a3f054618f 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JavacOptionsResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JavacOptionsResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait JavacOptionsResultFormats { self: sbt.internal.bsp.codec.JavacOptionsItemFormats with sjsonnew.BasicJsonProtocol => +trait JavacOptionsResultFormats { self: sbt.internal.bsp.codec.JavacOptionsItemFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol => implicit lazy val JavacOptionsResultFormat: JsonFormat[sbt.internal.bsp.JavacOptionsResult] = new JsonFormat[sbt.internal.bsp.JavacOptionsResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.JavacOptionsResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JsonProtocol.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JsonProtocol.scala index f6cae48d80..c98c92a87b 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JsonProtocol.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JsonProtocol.scala @@ -55,6 +55,7 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.TestResultFormats with sbt.internal.bsp.codec.RunParamsFormats with sbt.internal.bsp.codec.RunResultFormats + with sbt.internal.bsp.codec.JvmBuildTargetFormats with sbt.internal.bsp.codec.ScalaBuildTargetFormats with sbt.internal.bsp.codec.ScalacOptionsParamsFormats with sbt.internal.bsp.codec.ScalacOptionsItemFormats diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JvmBuildTargetFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JvmBuildTargetFormats.scala new file mode 100644 index 0000000000..301e778ba8 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JvmBuildTargetFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.bsp.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait JvmBuildTargetFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val JvmBuildTargetFormat: JsonFormat[sbt.internal.bsp.JvmBuildTarget] = new JsonFormat[sbt.internal.bsp.JvmBuildTarget] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.JvmBuildTarget = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val javaHome = unbuilder.readField[Option[java.net.URI]]("javaHome") + val javaVersion = unbuilder.readField[Option[String]]("javaVersion") + unbuilder.endObject() + sbt.internal.bsp.JvmBuildTarget(javaHome, javaVersion) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.bsp.JvmBuildTarget, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("javaHome", obj.javaHome) + builder.addField("javaVersion", obj.javaVersion) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JvmRunEnvironmentResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JvmRunEnvironmentResultFormats.scala index 6a9d40a5e3..36f1cb72ca 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JvmRunEnvironmentResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JvmRunEnvironmentResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait JvmRunEnvironmentResultFormats { self: sbt.internal.bsp.codec.JvmEnvironmentItemFormats with sjsonnew.BasicJsonProtocol => +trait JvmRunEnvironmentResultFormats { self: sbt.internal.bsp.codec.JvmEnvironmentItemFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol => implicit lazy val JvmRunEnvironmentResultFormat: JsonFormat[sbt.internal.bsp.JvmRunEnvironmentResult] = new JsonFormat[sbt.internal.bsp.JvmRunEnvironmentResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.JvmRunEnvironmentResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JvmTestEnvironmentResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JvmTestEnvironmentResultFormats.scala index cd9c9d2978..60598fa654 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JvmTestEnvironmentResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/JvmTestEnvironmentResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait JvmTestEnvironmentResultFormats { self: sbt.internal.bsp.codec.JvmEnvironmentItemFormats with sjsonnew.BasicJsonProtocol => +trait JvmTestEnvironmentResultFormats { self: sbt.internal.bsp.codec.JvmEnvironmentItemFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol => implicit lazy val JvmTestEnvironmentResultFormat: JsonFormat[sbt.internal.bsp.JvmTestEnvironmentResult] = new JsonFormat[sbt.internal.bsp.JvmTestEnvironmentResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.JvmTestEnvironmentResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/LocationFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/LocationFormats.scala index 54da583612..e6fb639126 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/LocationFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/LocationFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait LocationFormats { self: sbt.internal.bsp.codec.RangeFormats with sjsonnew.BasicJsonProtocol => +trait LocationFormats { self: sbt.internal.bsp.codec.RangeFormats with sbt.internal.bsp.codec.PositionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val LocationFormat: JsonFormat[sbt.internal.bsp.Location] = new JsonFormat[sbt.internal.bsp.Location] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.Location = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsItemFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsItemFormats.scala index f3c0795ee6..602b0e51fe 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsItemFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsItemFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait OutputPathsItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.bsp.codec.OutputPathItemFormats with sjsonnew.BasicJsonProtocol => +trait OutputPathsItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.OutputPathItemFormats => implicit lazy val OutputPathsItemFormat: JsonFormat[sbt.internal.bsp.OutputPathsItem] = new JsonFormat[sbt.internal.bsp.OutputPathsItem] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.OutputPathsItem = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsResultFormats.scala index 0aa4750972..c2c7851101 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait OutputPathsResultFormats { self: sbt.internal.bsp.codec.OutputPathsItemFormats with sjsonnew.BasicJsonProtocol => +trait OutputPathsResultFormats { self: sbt.internal.bsp.codec.OutputPathsItemFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.OutputPathItemFormats => implicit lazy val OutputPathsResultFormat: JsonFormat[sbt.internal.bsp.OutputPathsResult] = new JsonFormat[sbt.internal.bsp.OutputPathsResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.OutputPathsResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/PublishDiagnosticsParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/PublishDiagnosticsParamsFormats.scala index 0b5551c66d..d8bf69965a 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/PublishDiagnosticsParamsFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/PublishDiagnosticsParamsFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait PublishDiagnosticsParamsFormats { self: sbt.internal.bsp.codec.TextDocumentIdentifierFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.bsp.codec.DiagnosticFormats with sjsonnew.BasicJsonProtocol => +trait PublishDiagnosticsParamsFormats { self: sbt.internal.bsp.codec.TextDocumentIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.bsp.codec.DiagnosticFormats with sbt.internal.bsp.codec.RangeFormats with sbt.internal.bsp.codec.PositionFormats with sbt.internal.bsp.codec.DiagnosticRelatedInformationFormats with sbt.internal.bsp.codec.LocationFormats with sbt.internal.bsp.codec.ScalaDiagnosticFormats with sbt.internal.bsp.codec.ScalaActionFormats with sbt.internal.bsp.codec.ScalaWorkspaceEditFormats with sbt.internal.bsp.codec.ScalaTextEditFormats => implicit lazy val PublishDiagnosticsParamsFormat: JsonFormat[sbt.internal.bsp.PublishDiagnosticsParams] = new JsonFormat[sbt.internal.bsp.PublishDiagnosticsParams] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.PublishDiagnosticsParams = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ResourcesResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ResourcesResultFormats.scala index 6add5e4591..e8e2350296 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ResourcesResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ResourcesResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ResourcesResultFormats { self: sbt.internal.bsp.codec.ResourcesItemFormats with sjsonnew.BasicJsonProtocol => +trait ResourcesResultFormats { self: sbt.internal.bsp.codec.ResourcesItemFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ResourcesResultFormat: JsonFormat[sbt.internal.bsp.ResourcesResult] = new JsonFormat[sbt.internal.bsp.ResourcesResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ResourcesResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/RunParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/RunParamsFormats.scala index 808c53fcf7..8c4e47a02a 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/RunParamsFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/RunParamsFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait RunParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => +trait RunParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.util.codec.JValueFormats => implicit lazy val RunParamsFormat: JsonFormat[sbt.internal.bsp.RunParams] = new JsonFormat[sbt.internal.bsp.RunParams] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.RunParams = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SbtBuildTargetFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SbtBuildTargetFormats.scala index 788d26a981..4e057a969d 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SbtBuildTargetFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SbtBuildTargetFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SbtBuildTargetFormats { self: sbt.internal.bsp.codec.ScalaBuildTargetFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol => +trait SbtBuildTargetFormats { self: sbt.internal.bsp.codec.ScalaBuildTargetFormats with sbt.internal.bsp.codec.JvmBuildTargetFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.BuildTargetIdentifierFormats => implicit lazy val SbtBuildTargetFormat: JsonFormat[sbt.internal.bsp.SbtBuildTarget] = new JsonFormat[sbt.internal.bsp.SbtBuildTarget] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.SbtBuildTarget = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaActionFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaActionFormats.scala index 6df072a384..9262da34c3 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaActionFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaActionFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ScalaActionFormats { self: sbt.internal.bsp.codec.ScalaWorkspaceEditFormats with sjsonnew.BasicJsonProtocol => +trait ScalaActionFormats { self: sbt.internal.bsp.codec.ScalaWorkspaceEditFormats with sbt.internal.bsp.codec.ScalaTextEditFormats with sbt.internal.bsp.codec.RangeFormats with sbt.internal.bsp.codec.PositionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ScalaActionFormat: JsonFormat[sbt.internal.bsp.ScalaAction] = new JsonFormat[sbt.internal.bsp.ScalaAction] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalaAction = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaBuildTargetFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaBuildTargetFormats.scala index 900994c4ed..67b1389a36 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaBuildTargetFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaBuildTargetFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ScalaBuildTargetFormats { self: sjsonnew.BasicJsonProtocol => +trait ScalaBuildTargetFormats { self: sbt.internal.bsp.codec.JvmBuildTargetFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ScalaBuildTargetFormat: JsonFormat[sbt.internal.bsp.ScalaBuildTarget] = new JsonFormat[sbt.internal.bsp.ScalaBuildTarget] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalaBuildTarget = { __jsOpt match { @@ -16,8 +16,9 @@ implicit lazy val ScalaBuildTargetFormat: JsonFormat[sbt.internal.bsp.ScalaBuild val scalaBinaryVersion = unbuilder.readField[String]("scalaBinaryVersion") val platform = unbuilder.readField[Int]("platform") val jars = unbuilder.readField[Vector[String]]("jars") + val jvmBuildTarget = unbuilder.readField[Option[sbt.internal.bsp.JvmBuildTarget]]("jvmBuildTarget") unbuilder.endObject() - sbt.internal.bsp.ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars) + sbt.internal.bsp.ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars, jvmBuildTarget) case None => deserializationError("Expected JsObject but found None") } @@ -29,6 +30,7 @@ implicit lazy val ScalaBuildTargetFormat: JsonFormat[sbt.internal.bsp.ScalaBuild builder.addField("scalaBinaryVersion", obj.scalaBinaryVersion) builder.addField("platform", obj.platform) builder.addField("jars", obj.jars) + builder.addField("jvmBuildTarget", obj.jvmBuildTarget) builder.endObject() } } diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaDiagnosticFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaDiagnosticFormats.scala index 0813333522..e5f1d0dbf6 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaDiagnosticFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaDiagnosticFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ScalaDiagnosticFormats { self: sbt.internal.bsp.codec.ScalaActionFormats with sjsonnew.BasicJsonProtocol => +trait ScalaDiagnosticFormats { self: sbt.internal.bsp.codec.ScalaActionFormats with sbt.internal.bsp.codec.ScalaWorkspaceEditFormats with sbt.internal.bsp.codec.ScalaTextEditFormats with sbt.internal.bsp.codec.RangeFormats with sbt.internal.bsp.codec.PositionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ScalaDiagnosticFormat: JsonFormat[sbt.internal.bsp.ScalaDiagnostic] = new JsonFormat[sbt.internal.bsp.ScalaDiagnostic] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalaDiagnostic = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaMainClassesItemFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaMainClassesItemFormats.scala index 2f96a2dc56..549559ac52 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaMainClassesItemFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaMainClassesItemFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ScalaMainClassesItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.bsp.codec.ScalaMainClassFormats with sjsonnew.BasicJsonProtocol => +trait ScalaMainClassesItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.ScalaMainClassFormats => implicit lazy val ScalaMainClassesItemFormat: JsonFormat[sbt.internal.bsp.ScalaMainClassesItem] = new JsonFormat[sbt.internal.bsp.ScalaMainClassesItem] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalaMainClassesItem = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaMainClassesResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaMainClassesResultFormats.scala index b7410be21b..be3c8eb57c 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaMainClassesResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaMainClassesResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ScalaMainClassesResultFormats { self: sbt.internal.bsp.codec.ScalaMainClassesItemFormats with sjsonnew.BasicJsonProtocol => +trait ScalaMainClassesResultFormats { self: sbt.internal.bsp.codec.ScalaMainClassesItemFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.ScalaMainClassFormats => implicit lazy val ScalaMainClassesResultFormat: JsonFormat[sbt.internal.bsp.ScalaMainClassesResult] = new JsonFormat[sbt.internal.bsp.ScalaMainClassesResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalaMainClassesResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestClassesResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestClassesResultFormats.scala index ab51a7bb20..80331a4fd2 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestClassesResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestClassesResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ScalaTestClassesResultFormats { self: sbt.internal.bsp.codec.ScalaTestClassesItemFormats with sjsonnew.BasicJsonProtocol => +trait ScalaTestClassesResultFormats { self: sbt.internal.bsp.codec.ScalaTestClassesItemFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ScalaTestClassesResultFormat: JsonFormat[sbt.internal.bsp.ScalaTestClassesResult] = new JsonFormat[sbt.internal.bsp.ScalaTestClassesResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalaTestClassesResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestParamsFormats.scala index 3837db231c..c4d0fb6cfa 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestParamsFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestParamsFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ScalaTestParamsFormats { self: sbt.internal.bsp.codec.ScalaTestClassesItemFormats with sjsonnew.BasicJsonProtocol => +trait ScalaTestParamsFormats { self: sbt.internal.bsp.codec.ScalaTestClassesItemFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ScalaTestParamsFormat: JsonFormat[sbt.internal.bsp.ScalaTestParams] = new JsonFormat[sbt.internal.bsp.ScalaTestParams] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalaTestParams = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTextEditFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTextEditFormats.scala index 320ff8a552..9ffda9946f 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTextEditFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTextEditFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ScalaTextEditFormats { self: sbt.internal.bsp.codec.RangeFormats with sjsonnew.BasicJsonProtocol => +trait ScalaTextEditFormats { self: sbt.internal.bsp.codec.RangeFormats with sbt.internal.bsp.codec.PositionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ScalaTextEditFormat: JsonFormat[sbt.internal.bsp.ScalaTextEdit] = new JsonFormat[sbt.internal.bsp.ScalaTextEdit] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalaTextEdit = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaWorkspaceEditFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaWorkspaceEditFormats.scala index 6e09a05af4..b439045cc3 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaWorkspaceEditFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaWorkspaceEditFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ScalaWorkspaceEditFormats { self: sbt.internal.bsp.codec.ScalaTextEditFormats with sjsonnew.BasicJsonProtocol => +trait ScalaWorkspaceEditFormats { self: sbt.internal.bsp.codec.ScalaTextEditFormats with sbt.internal.bsp.codec.RangeFormats with sbt.internal.bsp.codec.PositionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ScalaWorkspaceEditFormat: JsonFormat[sbt.internal.bsp.ScalaWorkspaceEdit] = new JsonFormat[sbt.internal.bsp.ScalaWorkspaceEdit] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalaWorkspaceEdit = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalacOptionsResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalacOptionsResultFormats.scala index ac7a2863b5..6eb060da9c 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalacOptionsResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalacOptionsResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ScalacOptionsResultFormats { self: sbt.internal.bsp.codec.ScalacOptionsItemFormats with sjsonnew.BasicJsonProtocol => +trait ScalacOptionsResultFormats { self: sbt.internal.bsp.codec.ScalacOptionsItemFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ScalacOptionsResultFormat: JsonFormat[sbt.internal.bsp.ScalacOptionsResult] = new JsonFormat[sbt.internal.bsp.ScalacOptionsResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalacOptionsResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SourcesItemFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SourcesItemFormats.scala index 6862a8575c..4602ed51d9 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SourcesItemFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SourcesItemFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SourcesItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.bsp.codec.SourceItemFormats with sjsonnew.BasicJsonProtocol => +trait SourcesItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.SourceItemFormats => implicit lazy val SourcesItemFormat: JsonFormat[sbt.internal.bsp.SourcesItem] = new JsonFormat[sbt.internal.bsp.SourcesItem] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.SourcesItem = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SourcesResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SourcesResultFormats.scala index d021e1e4f7..b0d29da9fb 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SourcesResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/SourcesResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SourcesResultFormats { self: sbt.internal.bsp.codec.SourcesItemFormats with sjsonnew.BasicJsonProtocol => +trait SourcesResultFormats { self: sbt.internal.bsp.codec.SourcesItemFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.SourceItemFormats => implicit lazy val SourcesResultFormat: JsonFormat[sbt.internal.bsp.SourcesResult] = new JsonFormat[sbt.internal.bsp.SourcesResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.SourcesResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskFinishParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskFinishParamsFormats.scala index d9186fe333..d83eaf20c6 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskFinishParamsFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskFinishParamsFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait TaskFinishParamsFormats { self: sbt.internal.bsp.codec.TaskIdFormats with sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => +trait TaskFinishParamsFormats { self: sbt.internal.bsp.codec.TaskIdFormats with sjsonnew.BasicJsonProtocol with sbt.internal.util.codec.JValueFormats => implicit lazy val TaskFinishParamsFormat: JsonFormat[sbt.internal.bsp.TaskFinishParams] = new JsonFormat[sbt.internal.bsp.TaskFinishParams] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.TaskFinishParams = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskProgressParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskProgressParamsFormats.scala index 4931e0a29e..7743336cba 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskProgressParamsFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskProgressParamsFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait TaskProgressParamsFormats { self: sbt.internal.bsp.codec.TaskIdFormats with sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => +trait TaskProgressParamsFormats { self: sbt.internal.bsp.codec.TaskIdFormats with sjsonnew.BasicJsonProtocol with sbt.internal.util.codec.JValueFormats => implicit lazy val TaskProgressParamsFormat: JsonFormat[sbt.internal.bsp.TaskProgressParams] = new JsonFormat[sbt.internal.bsp.TaskProgressParams] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.TaskProgressParams = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskStartParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskStartParamsFormats.scala index a6f4ef766f..f333512b56 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskStartParamsFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TaskStartParamsFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait TaskStartParamsFormats { self: sbt.internal.bsp.codec.TaskIdFormats with sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => +trait TaskStartParamsFormats { self: sbt.internal.bsp.codec.TaskIdFormats with sjsonnew.BasicJsonProtocol with sbt.internal.util.codec.JValueFormats => implicit lazy val TaskStartParamsFormat: JsonFormat[sbt.internal.bsp.TaskStartParams] = new JsonFormat[sbt.internal.bsp.TaskStartParams] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.TaskStartParams = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TestParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TestParamsFormats.scala index 7e07dd1887..9dd0dd6836 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TestParamsFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/TestParamsFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait TestParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => +trait TestParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.util.codec.JValueFormats => implicit lazy val TestParamsFormat: JsonFormat[sbt.internal.bsp.TestParams] = new JsonFormat[sbt.internal.bsp.TestParams] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.TestParams = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/WorkspaceBuildTargetsResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/WorkspaceBuildTargetsResultFormats.scala index d21532d726..9157e04a3e 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/WorkspaceBuildTargetsResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/WorkspaceBuildTargetsResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.bsp.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait WorkspaceBuildTargetsResultFormats { self: sbt.internal.bsp.codec.BuildTargetFormats with sjsonnew.BasicJsonProtocol => +trait WorkspaceBuildTargetsResultFormats { self: sbt.internal.bsp.codec.BuildTargetFormats with sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.BuildTargetCapabilitiesFormats with sbt.internal.util.codec.JValueFormats => implicit lazy val WorkspaceBuildTargetsResultFormat: JsonFormat[sbt.internal.bsp.WorkspaceBuildTargetsResult] = new JsonFormat[sbt.internal.bsp.WorkspaceBuildTargetsResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.WorkspaceBuildTargetsResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/graph/codec/ModuleModelFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/graph/codec/ModuleModelFormats.scala index eaf3c902c7..eeef032845 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/graph/codec/ModuleModelFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/graph/codec/ModuleModelFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.graph.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ModuleModelFormats { self: sbt.internal.graph.codec.ModuleModelFormats with sjsonnew.BasicJsonProtocol => +trait ModuleModelFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val ModuleModelFormat: JsonFormat[sbt.internal.graph.ModuleModel] = new JsonFormat[sbt.internal.graph.ModuleModel] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.graph.ModuleModel = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/DiagnosticFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/DiagnosticFormats.scala index 6873fcf62a..e46132f3f6 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/DiagnosticFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/DiagnosticFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.langserver.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait DiagnosticFormats { self: sbt.internal.langserver.codec.RangeFormats with sjsonnew.BasicJsonProtocol => +trait DiagnosticFormats { self: sbt.internal.langserver.codec.RangeFormats with sbt.internal.langserver.codec.PositionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val DiagnosticFormat: JsonFormat[sbt.internal.langserver.Diagnostic] = new JsonFormat[sbt.internal.langserver.Diagnostic] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.Diagnostic = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeResultFormats.scala index 37b42fbd42..eba490e178 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeResultFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeResultFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.langserver.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait InitializeResultFormats { self: sbt.internal.langserver.codec.ServerCapabilitiesFormats with sjsonnew.BasicJsonProtocol => +trait InitializeResultFormats { self: sbt.internal.langserver.codec.ServerCapabilitiesFormats with sbt.internal.langserver.codec.TextDocumentSyncOptionsFormats with sbt.internal.langserver.codec.SaveOptionsFormats with sjsonnew.BasicJsonProtocol => implicit lazy val InitializeResultFormat: JsonFormat[sbt.internal.langserver.InitializeResult] = new JsonFormat[sbt.internal.langserver.InitializeResult] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.InitializeResult = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/LocationFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/LocationFormats.scala index 04566a4cf4..d8bcde3314 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/LocationFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/LocationFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.langserver.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait LocationFormats { self: sbt.internal.langserver.codec.RangeFormats with sjsonnew.BasicJsonProtocol => +trait LocationFormats { self: sbt.internal.langserver.codec.RangeFormats with sbt.internal.langserver.codec.PositionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val LocationFormat: JsonFormat[sbt.internal.langserver.Location] = new JsonFormat[sbt.internal.langserver.Location] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.Location = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PublishDiagnosticsParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PublishDiagnosticsParamsFormats.scala index a9730ce2fa..669b702e3d 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PublishDiagnosticsParamsFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PublishDiagnosticsParamsFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.langserver.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait PublishDiagnosticsParamsFormats { self: sbt.internal.langserver.codec.DiagnosticFormats with sjsonnew.BasicJsonProtocol => +trait PublishDiagnosticsParamsFormats { self: sbt.internal.langserver.codec.DiagnosticFormats with sbt.internal.langserver.codec.RangeFormats with sbt.internal.langserver.codec.PositionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val PublishDiagnosticsParamsFormat: JsonFormat[sbt.internal.langserver.PublishDiagnosticsParams] = new JsonFormat[sbt.internal.langserver.PublishDiagnosticsParams] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.PublishDiagnosticsParams = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ServerCapabilitiesFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ServerCapabilitiesFormats.scala index b980c95fed..dd45045776 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ServerCapabilitiesFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ServerCapabilitiesFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.langserver.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ServerCapabilitiesFormats { self: sbt.internal.langserver.codec.TextDocumentSyncOptionsFormats with sjsonnew.BasicJsonProtocol => +trait ServerCapabilitiesFormats { self: sbt.internal.langserver.codec.TextDocumentSyncOptionsFormats with sbt.internal.langserver.codec.SaveOptionsFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ServerCapabilitiesFormat: JsonFormat[sbt.internal.langserver.ServerCapabilities] = new JsonFormat[sbt.internal.langserver.ServerCapabilities] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.ServerCapabilities = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentPositionParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentPositionParamsFormats.scala index f5aa877e3f..91de603986 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentPositionParamsFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentPositionParamsFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.internal.langserver.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait TextDocumentPositionParamsFormats { self: sbt.internal.langserver.codec.TextDocumentIdentifierFormats with sbt.internal.langserver.codec.PositionFormats with sjsonnew.BasicJsonProtocol => +trait TextDocumentPositionParamsFormats { self: sbt.internal.langserver.codec.TextDocumentIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.langserver.codec.PositionFormats => implicit lazy val TextDocumentPositionParamsFormat: JsonFormat[sbt.internal.langserver.TextDocumentPositionParams] = new JsonFormat[sbt.internal.langserver.TextDocumentPositionParams] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.TextDocumentPositionParams = { __jsOpt match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentPositionParamsInterfaceFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentPositionParamsInterfaceFormats.scala index 3dff106a5f..83843d5e2d 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentPositionParamsInterfaceFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentPositionParamsInterfaceFormats.scala @@ -6,6 +6,6 @@ package sbt.internal.langserver.codec import _root_.sjsonnew.JsonFormat -trait TextDocumentPositionParamsInterfaceFormats { self: sbt.internal.langserver.codec.TextDocumentIdentifierFormats with sbt.internal.langserver.codec.PositionFormats with sjsonnew.BasicJsonProtocol with sbt.internal.langserver.codec.TextDocumentPositionParamsFormats => +trait TextDocumentPositionParamsInterfaceFormats { self: sbt.internal.langserver.codec.TextDocumentIdentifierFormats with sjsonnew.BasicJsonProtocol with sbt.internal.langserver.codec.PositionFormats with sbt.internal.langserver.codec.TextDocumentPositionParamsFormats => implicit lazy val TextDocumentPositionParamsInterfaceFormat: JsonFormat[sbt.internal.langserver.TextDocumentPositionParamsInterface] = flatUnionFormat1[sbt.internal.langserver.TextDocumentPositionParamsInterface, sbt.internal.langserver.TextDocumentPositionParams]("type") } diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/InitializeOption.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/InitializeOption.scala index b900d641d6..0a5f72a079 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/protocol/InitializeOption.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/InitializeOption.scala @@ -4,24 +4,30 @@ // DO NOT EDIT MANUALLY package sbt.internal.protocol +/** + * Passed into InitializeParams as part of "initialize" request as the user-defined option. + * https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize + */ final class InitializeOption private ( val token: Option[String], - val skipAnalysis: Option[Boolean]) extends Serializable { + val skipAnalysis: Option[Boolean], + val canWork: Option[Boolean]) extends Serializable { - private def this(token: Option[String]) = this(token, None) + private def this(token: Option[String]) = this(token, None, None) + private def this(token: Option[String], skipAnalysis: Option[Boolean]) = this(token, skipAnalysis, None) override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { - case x: InitializeOption => (this.token == x.token) && (this.skipAnalysis == x.skipAnalysis) + case x: InitializeOption => (this.token == x.token) && (this.skipAnalysis == x.skipAnalysis) && (this.canWork == x.canWork) case _ => false }) override def hashCode: Int = { - 37 * (37 * (37 * (17 + "sbt.internal.protocol.InitializeOption".##) + token.##) + skipAnalysis.##) + 37 * (37 * (37 * (37 * (17 + "sbt.internal.protocol.InitializeOption".##) + token.##) + skipAnalysis.##) + canWork.##) } override def toString: String = { - "InitializeOption(" + token + ", " + skipAnalysis + ")" + "InitializeOption(" + token + ", " + skipAnalysis + ", " + canWork + ")" } - private[this] def copy(token: Option[String] = token, skipAnalysis: Option[Boolean] = skipAnalysis): InitializeOption = { - new InitializeOption(token, skipAnalysis) + private[this] def copy(token: Option[String] = token, skipAnalysis: Option[Boolean] = skipAnalysis, canWork: Option[Boolean] = canWork): InitializeOption = { + new InitializeOption(token, skipAnalysis, canWork) } def withToken(token: Option[String]): InitializeOption = { copy(token = token) @@ -35,6 +41,12 @@ final class InitializeOption private ( def withSkipAnalysis(skipAnalysis: Boolean): InitializeOption = { copy(skipAnalysis = Option(skipAnalysis)) } + def withCanWork(canWork: Option[Boolean]): InitializeOption = { + copy(canWork = canWork) + } + def withCanWork(canWork: Boolean): InitializeOption = { + copy(canWork = Option(canWork)) + } } object InitializeOption { @@ -42,4 +54,6 @@ object InitializeOption { def apply(token: String): InitializeOption = new InitializeOption(Option(token)) def apply(token: Option[String], skipAnalysis: Option[Boolean]): InitializeOption = new InitializeOption(token, skipAnalysis) def apply(token: String, skipAnalysis: Boolean): InitializeOption = new InitializeOption(Option(token), Option(skipAnalysis)) + def apply(token: Option[String], skipAnalysis: Option[Boolean], canWork: Option[Boolean]): InitializeOption = new InitializeOption(token, skipAnalysis, canWork) + def apply(token: String, skipAnalysis: Boolean, canWork: Boolean): InitializeOption = new InitializeOption(Option(token), Option(skipAnalysis), Option(canWork)) } diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/InitializeOptionFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/InitializeOptionFormats.scala index f7f3a09e79..a5b04d6a42 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/InitializeOptionFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/InitializeOptionFormats.scala @@ -13,8 +13,9 @@ implicit lazy val InitializeOptionFormat: JsonFormat[sbt.internal.protocol.Initi unbuilder.beginObject(__js) val token = unbuilder.readField[Option[String]]("token") val skipAnalysis = unbuilder.readField[Option[Boolean]]("skipAnalysis") + val canWork = unbuilder.readField[Option[Boolean]]("canWork") unbuilder.endObject() - sbt.internal.protocol.InitializeOption(token, skipAnalysis) + sbt.internal.protocol.InitializeOption(token, skipAnalysis, canWork) case None => deserializationError("Expected JsObject but found None") } @@ -23,6 +24,7 @@ implicit lazy val InitializeOptionFormat: JsonFormat[sbt.internal.protocol.Initi builder.beginObject() builder.addField("token", obj.token) builder.addField("skipAnalysis", obj.skipAnalysis) + builder.addField("canWork", obj.canWork) builder.endObject() } } diff --git a/protocol/src/main/contraband-scala/sbt/internal/worker/ClientJobParams.scala b/protocol/src/main/contraband-scala/sbt/internal/worker/ClientJobParams.scala new file mode 100644 index 0000000000..d72bf2b9f2 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/worker/ClientJobParams.scala @@ -0,0 +1,45 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.worker +/** + * Client-side job support. + * + * Notification: sbt/clientJob + * + * Parameter for the sbt/clientJob notification. + * A client-side job represents a unit of work that sbt server + * can outsourse back to the client, for example for run task. + */ +final class ClientJobParams private ( + val runInfo: Option[sbt.internal.worker.RunInfo]) extends Serializable { + + + + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { + case x: ClientJobParams => (this.runInfo == x.runInfo) + case _ => false + }) + override def hashCode: Int = { + 37 * (37 * (17 + "sbt.internal.worker.ClientJobParams".##) + runInfo.##) + } + override def toString: String = { + "ClientJobParams(" + runInfo + ")" + } + private[this] def copy(runInfo: Option[sbt.internal.worker.RunInfo] = runInfo): ClientJobParams = { + new ClientJobParams(runInfo) + } + def withRunInfo(runInfo: Option[sbt.internal.worker.RunInfo]): ClientJobParams = { + copy(runInfo = runInfo) + } + def withRunInfo(runInfo: sbt.internal.worker.RunInfo): ClientJobParams = { + copy(runInfo = Option(runInfo)) + } +} +object ClientJobParams { + + def apply(runInfo: Option[sbt.internal.worker.RunInfo]): ClientJobParams = new ClientJobParams(runInfo) + def apply(runInfo: sbt.internal.worker.RunInfo): ClientJobParams = new ClientJobParams(Option(runInfo)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/worker/FilePath.scala b/protocol/src/main/contraband-scala/sbt/internal/worker/FilePath.scala new file mode 100644 index 0000000000..24647f3c09 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/worker/FilePath.scala @@ -0,0 +1,36 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.worker +final class FilePath private ( + val path: java.net.URI, + val digest: String) extends Serializable { + + + + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { + case x: FilePath => (this.path == x.path) && (this.digest == x.digest) + case _ => false + }) + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.internal.worker.FilePath".##) + path.##) + digest.##) + } + override def toString: String = { + "FilePath(" + path + ", " + digest + ")" + } + private[this] def copy(path: java.net.URI = path, digest: String = digest): FilePath = { + new FilePath(path, digest) + } + def withPath(path: java.net.URI): FilePath = { + copy(path = path) + } + def withDigest(digest: String): FilePath = { + copy(digest = digest) + } +} +object FilePath { + + def apply(path: java.net.URI, digest: String): FilePath = new FilePath(path, digest) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/worker/JvmRunInfo.scala b/protocol/src/main/contraband-scala/sbt/internal/worker/JvmRunInfo.scala new file mode 100644 index 0000000000..d0d6b5b73d --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/worker/JvmRunInfo.scala @@ -0,0 +1,84 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.worker +final class JvmRunInfo private ( + val args: Vector[String], + val classpath: Vector[sbt.internal.worker.FilePath], + val mainClass: String, + val connectInput: Boolean, + val javaHome: Option[java.net.URI], + val outputStrategy: Option[String], + val workingDirectory: Option[java.net.URI], + val jvmOptions: Vector[String], + val environmentVariables: scala.collection.immutable.Map[String, String], + val inputs: Vector[sbt.internal.worker.FilePath], + val outputs: Vector[sbt.internal.worker.FilePath]) extends Serializable { + + private def this(args: Vector[String], classpath: Vector[sbt.internal.worker.FilePath], mainClass: String, connectInput: Boolean, javaHome: Option[java.net.URI], outputStrategy: Option[String], workingDirectory: Option[java.net.URI], jvmOptions: Vector[String], environmentVariables: scala.collection.immutable.Map[String, String]) = this(args, classpath, mainClass, connectInput, javaHome, outputStrategy, workingDirectory, jvmOptions, environmentVariables, Vector(), Vector()) + + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { + case x: JvmRunInfo => (this.args == x.args) && (this.classpath == x.classpath) && (this.mainClass == x.mainClass) && (this.connectInput == x.connectInput) && (this.javaHome == x.javaHome) && (this.outputStrategy == x.outputStrategy) && (this.workingDirectory == x.workingDirectory) && (this.jvmOptions == x.jvmOptions) && (this.environmentVariables == x.environmentVariables) && (this.inputs == x.inputs) && (this.outputs == x.outputs) + case _ => false + }) + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.worker.JvmRunInfo".##) + args.##) + classpath.##) + mainClass.##) + connectInput.##) + javaHome.##) + outputStrategy.##) + workingDirectory.##) + jvmOptions.##) + environmentVariables.##) + inputs.##) + outputs.##) + } + override def toString: String = { + "JvmRunInfo(" + args + ", " + classpath + ", " + mainClass + ", " + connectInput + ", " + javaHome + ", " + outputStrategy + ", " + workingDirectory + ", " + jvmOptions + ", " + environmentVariables + ", " + inputs + ", " + outputs + ")" + } + private[this] def copy(args: Vector[String] = args, classpath: Vector[sbt.internal.worker.FilePath] = classpath, mainClass: String = mainClass, connectInput: Boolean = connectInput, javaHome: Option[java.net.URI] = javaHome, outputStrategy: Option[String] = outputStrategy, workingDirectory: Option[java.net.URI] = workingDirectory, jvmOptions: Vector[String] = jvmOptions, environmentVariables: scala.collection.immutable.Map[String, String] = environmentVariables, inputs: Vector[sbt.internal.worker.FilePath] = inputs, outputs: Vector[sbt.internal.worker.FilePath] = outputs): JvmRunInfo = { + new JvmRunInfo(args, classpath, mainClass, connectInput, javaHome, outputStrategy, workingDirectory, jvmOptions, environmentVariables, inputs, outputs) + } + def withArgs(args: Vector[String]): JvmRunInfo = { + copy(args = args) + } + def withClasspath(classpath: Vector[sbt.internal.worker.FilePath]): JvmRunInfo = { + copy(classpath = classpath) + } + def withMainClass(mainClass: String): JvmRunInfo = { + copy(mainClass = mainClass) + } + def withConnectInput(connectInput: Boolean): JvmRunInfo = { + copy(connectInput = connectInput) + } + def withJavaHome(javaHome: Option[java.net.URI]): JvmRunInfo = { + copy(javaHome = javaHome) + } + def withJavaHome(javaHome: java.net.URI): JvmRunInfo = { + copy(javaHome = Option(javaHome)) + } + def withOutputStrategy(outputStrategy: Option[String]): JvmRunInfo = { + copy(outputStrategy = outputStrategy) + } + def withOutputStrategy(outputStrategy: String): JvmRunInfo = { + copy(outputStrategy = Option(outputStrategy)) + } + def withWorkingDirectory(workingDirectory: Option[java.net.URI]): JvmRunInfo = { + copy(workingDirectory = workingDirectory) + } + def withWorkingDirectory(workingDirectory: java.net.URI): JvmRunInfo = { + copy(workingDirectory = Option(workingDirectory)) + } + def withJvmOptions(jvmOptions: Vector[String]): JvmRunInfo = { + copy(jvmOptions = jvmOptions) + } + def withEnvironmentVariables(environmentVariables: scala.collection.immutable.Map[String, String]): JvmRunInfo = { + copy(environmentVariables = environmentVariables) + } + def withInputs(inputs: Vector[sbt.internal.worker.FilePath]): JvmRunInfo = { + copy(inputs = inputs) + } + def withOutputs(outputs: Vector[sbt.internal.worker.FilePath]): JvmRunInfo = { + copy(outputs = outputs) + } +} +object JvmRunInfo { + + def apply(args: Vector[String], classpath: Vector[sbt.internal.worker.FilePath], mainClass: String, connectInput: Boolean, javaHome: Option[java.net.URI], outputStrategy: Option[String], workingDirectory: Option[java.net.URI], jvmOptions: Vector[String], environmentVariables: scala.collection.immutable.Map[String, String]): JvmRunInfo = new JvmRunInfo(args, classpath, mainClass, connectInput, javaHome, outputStrategy, workingDirectory, jvmOptions, environmentVariables) + def apply(args: Vector[String], classpath: Vector[sbt.internal.worker.FilePath], mainClass: String, connectInput: Boolean, javaHome: java.net.URI, outputStrategy: String, workingDirectory: java.net.URI, jvmOptions: Vector[String], environmentVariables: scala.collection.immutable.Map[String, String]): JvmRunInfo = new JvmRunInfo(args, classpath, mainClass, connectInput, Option(javaHome), Option(outputStrategy), Option(workingDirectory), jvmOptions, environmentVariables) + def apply(args: Vector[String], classpath: Vector[sbt.internal.worker.FilePath], mainClass: String, connectInput: Boolean, javaHome: Option[java.net.URI], outputStrategy: Option[String], workingDirectory: Option[java.net.URI], jvmOptions: Vector[String], environmentVariables: scala.collection.immutable.Map[String, String], inputs: Vector[sbt.internal.worker.FilePath], outputs: Vector[sbt.internal.worker.FilePath]): JvmRunInfo = new JvmRunInfo(args, classpath, mainClass, connectInput, javaHome, outputStrategy, workingDirectory, jvmOptions, environmentVariables, inputs, outputs) + def apply(args: Vector[String], classpath: Vector[sbt.internal.worker.FilePath], mainClass: String, connectInput: Boolean, javaHome: java.net.URI, outputStrategy: String, workingDirectory: java.net.URI, jvmOptions: Vector[String], environmentVariables: scala.collection.immutable.Map[String, String], inputs: Vector[sbt.internal.worker.FilePath], outputs: Vector[sbt.internal.worker.FilePath]): JvmRunInfo = new JvmRunInfo(args, classpath, mainClass, connectInput, Option(javaHome), Option(outputStrategy), Option(workingDirectory), jvmOptions, environmentVariables, inputs, outputs) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/worker/NativeRunInfo.scala b/protocol/src/main/contraband-scala/sbt/internal/worker/NativeRunInfo.scala new file mode 100644 index 0000000000..5caffe8fd4 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/worker/NativeRunInfo.scala @@ -0,0 +1,69 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.worker +final class NativeRunInfo private ( + val cmd: String, + val args: Vector[String], + val connectInput: Boolean, + val outputStrategy: Option[String], + val workingDirectory: Option[java.net.URI], + val environmentVariables: scala.collection.immutable.Map[String, String], + val inputs: Vector[sbt.internal.worker.FilePath], + val outputs: Vector[sbt.internal.worker.FilePath]) extends Serializable { + + private def this(cmd: String, args: Vector[String], connectInput: Boolean, outputStrategy: Option[String], workingDirectory: Option[java.net.URI], environmentVariables: scala.collection.immutable.Map[String, String]) = this(cmd, args, connectInput, outputStrategy, workingDirectory, environmentVariables, Vector(), Vector()) + + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { + case x: NativeRunInfo => (this.cmd == x.cmd) && (this.args == x.args) && (this.connectInput == x.connectInput) && (this.outputStrategy == x.outputStrategy) && (this.workingDirectory == x.workingDirectory) && (this.environmentVariables == x.environmentVariables) && (this.inputs == x.inputs) && (this.outputs == x.outputs) + case _ => false + }) + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.worker.NativeRunInfo".##) + cmd.##) + args.##) + connectInput.##) + outputStrategy.##) + workingDirectory.##) + environmentVariables.##) + inputs.##) + outputs.##) + } + override def toString: String = { + "NativeRunInfo(" + cmd + ", " + args + ", " + connectInput + ", " + outputStrategy + ", " + workingDirectory + ", " + environmentVariables + ", " + inputs + ", " + outputs + ")" + } + private[this] def copy(cmd: String = cmd, args: Vector[String] = args, connectInput: Boolean = connectInput, outputStrategy: Option[String] = outputStrategy, workingDirectory: Option[java.net.URI] = workingDirectory, environmentVariables: scala.collection.immutable.Map[String, String] = environmentVariables, inputs: Vector[sbt.internal.worker.FilePath] = inputs, outputs: Vector[sbt.internal.worker.FilePath] = outputs): NativeRunInfo = { + new NativeRunInfo(cmd, args, connectInput, outputStrategy, workingDirectory, environmentVariables, inputs, outputs) + } + def withCmd(cmd: String): NativeRunInfo = { + copy(cmd = cmd) + } + def withArgs(args: Vector[String]): NativeRunInfo = { + copy(args = args) + } + def withConnectInput(connectInput: Boolean): NativeRunInfo = { + copy(connectInput = connectInput) + } + def withOutputStrategy(outputStrategy: Option[String]): NativeRunInfo = { + copy(outputStrategy = outputStrategy) + } + def withOutputStrategy(outputStrategy: String): NativeRunInfo = { + copy(outputStrategy = Option(outputStrategy)) + } + def withWorkingDirectory(workingDirectory: Option[java.net.URI]): NativeRunInfo = { + copy(workingDirectory = workingDirectory) + } + def withWorkingDirectory(workingDirectory: java.net.URI): NativeRunInfo = { + copy(workingDirectory = Option(workingDirectory)) + } + def withEnvironmentVariables(environmentVariables: scala.collection.immutable.Map[String, String]): NativeRunInfo = { + copy(environmentVariables = environmentVariables) + } + def withInputs(inputs: Vector[sbt.internal.worker.FilePath]): NativeRunInfo = { + copy(inputs = inputs) + } + def withOutputs(outputs: Vector[sbt.internal.worker.FilePath]): NativeRunInfo = { + copy(outputs = outputs) + } +} +object NativeRunInfo { + + def apply(cmd: String, args: Vector[String], connectInput: Boolean, outputStrategy: Option[String], workingDirectory: Option[java.net.URI], environmentVariables: scala.collection.immutable.Map[String, String]): NativeRunInfo = new NativeRunInfo(cmd, args, connectInput, outputStrategy, workingDirectory, environmentVariables) + def apply(cmd: String, args: Vector[String], connectInput: Boolean, outputStrategy: String, workingDirectory: java.net.URI, environmentVariables: scala.collection.immutable.Map[String, String]): NativeRunInfo = new NativeRunInfo(cmd, args, connectInput, Option(outputStrategy), Option(workingDirectory), environmentVariables) + def apply(cmd: String, args: Vector[String], connectInput: Boolean, outputStrategy: Option[String], workingDirectory: Option[java.net.URI], environmentVariables: scala.collection.immutable.Map[String, String], inputs: Vector[sbt.internal.worker.FilePath], outputs: Vector[sbt.internal.worker.FilePath]): NativeRunInfo = new NativeRunInfo(cmd, args, connectInput, outputStrategy, workingDirectory, environmentVariables, inputs, outputs) + def apply(cmd: String, args: Vector[String], connectInput: Boolean, outputStrategy: String, workingDirectory: java.net.URI, environmentVariables: scala.collection.immutable.Map[String, String], inputs: Vector[sbt.internal.worker.FilePath], outputs: Vector[sbt.internal.worker.FilePath]): NativeRunInfo = new NativeRunInfo(cmd, args, connectInput, Option(outputStrategy), Option(workingDirectory), environmentVariables, inputs, outputs) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/worker/RunInfo.scala b/protocol/src/main/contraband-scala/sbt/internal/worker/RunInfo.scala new file mode 100644 index 0000000000..855bd06d38 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/worker/RunInfo.scala @@ -0,0 +1,49 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.worker +final class RunInfo private ( + val jvm: Boolean, + val jvmRunInfo: Option[sbt.internal.worker.JvmRunInfo], + val nativeRunInfo: Option[sbt.internal.worker.NativeRunInfo]) extends Serializable { + + private def this(jvm: Boolean, jvmRunInfo: Option[sbt.internal.worker.JvmRunInfo]) = this(jvm, jvmRunInfo, None) + + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { + case x: RunInfo => (this.jvm == x.jvm) && (this.jvmRunInfo == x.jvmRunInfo) && (this.nativeRunInfo == x.nativeRunInfo) + case _ => false + }) + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "sbt.internal.worker.RunInfo".##) + jvm.##) + jvmRunInfo.##) + nativeRunInfo.##) + } + override def toString: String = { + "RunInfo(" + jvm + ", " + jvmRunInfo + ", " + nativeRunInfo + ")" + } + private[this] def copy(jvm: Boolean = jvm, jvmRunInfo: Option[sbt.internal.worker.JvmRunInfo] = jvmRunInfo, nativeRunInfo: Option[sbt.internal.worker.NativeRunInfo] = nativeRunInfo): RunInfo = { + new RunInfo(jvm, jvmRunInfo, nativeRunInfo) + } + def withJvm(jvm: Boolean): RunInfo = { + copy(jvm = jvm) + } + def withJvmRunInfo(jvmRunInfo: Option[sbt.internal.worker.JvmRunInfo]): RunInfo = { + copy(jvmRunInfo = jvmRunInfo) + } + def withJvmRunInfo(jvmRunInfo: sbt.internal.worker.JvmRunInfo): RunInfo = { + copy(jvmRunInfo = Option(jvmRunInfo)) + } + def withNativeRunInfo(nativeRunInfo: Option[sbt.internal.worker.NativeRunInfo]): RunInfo = { + copy(nativeRunInfo = nativeRunInfo) + } + def withNativeRunInfo(nativeRunInfo: sbt.internal.worker.NativeRunInfo): RunInfo = { + copy(nativeRunInfo = Option(nativeRunInfo)) + } +} +object RunInfo { + + def apply(jvm: Boolean, jvmRunInfo: Option[sbt.internal.worker.JvmRunInfo]): RunInfo = new RunInfo(jvm, jvmRunInfo) + def apply(jvm: Boolean, jvmRunInfo: sbt.internal.worker.JvmRunInfo): RunInfo = new RunInfo(jvm, Option(jvmRunInfo)) + def apply(jvm: Boolean, jvmRunInfo: Option[sbt.internal.worker.JvmRunInfo], nativeRunInfo: Option[sbt.internal.worker.NativeRunInfo]): RunInfo = new RunInfo(jvm, jvmRunInfo, nativeRunInfo) + def apply(jvm: Boolean, jvmRunInfo: sbt.internal.worker.JvmRunInfo, nativeRunInfo: sbt.internal.worker.NativeRunInfo): RunInfo = new RunInfo(jvm, Option(jvmRunInfo), Option(nativeRunInfo)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/worker/codec/ClientJobParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/ClientJobParamsFormats.scala new file mode 100644 index 0000000000..e045d628ca --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/ClientJobParamsFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.worker.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ClientJobParamsFormats { self: sbt.internal.worker.codec.RunInfoFormats with sbt.internal.worker.codec.JvmRunInfoFormats with sbt.internal.worker.codec.FilePathFormats with sjsonnew.BasicJsonProtocol with sbt.internal.worker.codec.NativeRunInfoFormats => +implicit lazy val ClientJobParamsFormat: JsonFormat[sbt.internal.worker.ClientJobParams] = new JsonFormat[sbt.internal.worker.ClientJobParams] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.worker.ClientJobParams = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val runInfo = unbuilder.readField[Option[sbt.internal.worker.RunInfo]]("runInfo") + unbuilder.endObject() + sbt.internal.worker.ClientJobParams(runInfo) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.worker.ClientJobParams, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("runInfo", obj.runInfo) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/worker/codec/FilePathFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/FilePathFormats.scala new file mode 100644 index 0000000000..ebbac551ff --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/FilePathFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.worker.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait FilePathFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val FilePathFormat: JsonFormat[sbt.internal.worker.FilePath] = new JsonFormat[sbt.internal.worker.FilePath] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.worker.FilePath = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val path = unbuilder.readField[java.net.URI]("path") + val digest = unbuilder.readField[String]("digest") + unbuilder.endObject() + sbt.internal.worker.FilePath(path, digest) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.worker.FilePath, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("path", obj.path) + builder.addField("digest", obj.digest) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/worker/codec/JsonProtocol.scala b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/JsonProtocol.scala new file mode 100644 index 0000000000..fa29c174cd --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/JsonProtocol.scala @@ -0,0 +1,13 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.worker.codec +trait JsonProtocol extends sjsonnew.BasicJsonProtocol + with sbt.internal.worker.codec.FilePathFormats + with sbt.internal.worker.codec.JvmRunInfoFormats + with sbt.internal.worker.codec.NativeRunInfoFormats + with sbt.internal.worker.codec.RunInfoFormats + with sbt.internal.worker.codec.ClientJobParamsFormats +object JsonProtocol extends JsonProtocol \ No newline at end of file diff --git a/protocol/src/main/contraband-scala/sbt/internal/worker/codec/JvmRunInfoFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/JvmRunInfoFormats.scala new file mode 100644 index 0000000000..793828b5ef --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/JvmRunInfoFormats.scala @@ -0,0 +1,47 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.worker.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait JvmRunInfoFormats { self: sbt.internal.worker.codec.FilePathFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val JvmRunInfoFormat: JsonFormat[sbt.internal.worker.JvmRunInfo] = new JsonFormat[sbt.internal.worker.JvmRunInfo] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.worker.JvmRunInfo = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val args = unbuilder.readField[Vector[String]]("args") + val classpath = unbuilder.readField[Vector[sbt.internal.worker.FilePath]]("classpath") + val mainClass = unbuilder.readField[String]("mainClass") + val connectInput = unbuilder.readField[Boolean]("connectInput") + val javaHome = unbuilder.readField[Option[java.net.URI]]("javaHome") + val outputStrategy = unbuilder.readField[Option[String]]("outputStrategy") + val workingDirectory = unbuilder.readField[Option[java.net.URI]]("workingDirectory") + val jvmOptions = unbuilder.readField[Vector[String]]("jvmOptions") + val environmentVariables = unbuilder.readField[scala.collection.immutable.Map[String, String]]("environmentVariables") + val inputs = unbuilder.readField[Vector[sbt.internal.worker.FilePath]]("inputs") + val outputs = unbuilder.readField[Vector[sbt.internal.worker.FilePath]]("outputs") + unbuilder.endObject() + sbt.internal.worker.JvmRunInfo(args, classpath, mainClass, connectInput, javaHome, outputStrategy, workingDirectory, jvmOptions, environmentVariables, inputs, outputs) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.worker.JvmRunInfo, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("args", obj.args) + builder.addField("classpath", obj.classpath) + builder.addField("mainClass", obj.mainClass) + builder.addField("connectInput", obj.connectInput) + builder.addField("javaHome", obj.javaHome) + builder.addField("outputStrategy", obj.outputStrategy) + builder.addField("workingDirectory", obj.workingDirectory) + builder.addField("jvmOptions", obj.jvmOptions) + builder.addField("environmentVariables", obj.environmentVariables) + builder.addField("inputs", obj.inputs) + builder.addField("outputs", obj.outputs) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/worker/codec/NativeRunInfoFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/NativeRunInfoFormats.scala new file mode 100644 index 0000000000..73588aa9f3 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/NativeRunInfoFormats.scala @@ -0,0 +1,41 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.worker.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait NativeRunInfoFormats { self: sbt.internal.worker.codec.FilePathFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val NativeRunInfoFormat: JsonFormat[sbt.internal.worker.NativeRunInfo] = new JsonFormat[sbt.internal.worker.NativeRunInfo] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.worker.NativeRunInfo = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val cmd = unbuilder.readField[String]("cmd") + val args = unbuilder.readField[Vector[String]]("args") + val connectInput = unbuilder.readField[Boolean]("connectInput") + val outputStrategy = unbuilder.readField[Option[String]]("outputStrategy") + val workingDirectory = unbuilder.readField[Option[java.net.URI]]("workingDirectory") + val environmentVariables = unbuilder.readField[scala.collection.immutable.Map[String, String]]("environmentVariables") + val inputs = unbuilder.readField[Vector[sbt.internal.worker.FilePath]]("inputs") + val outputs = unbuilder.readField[Vector[sbt.internal.worker.FilePath]]("outputs") + unbuilder.endObject() + sbt.internal.worker.NativeRunInfo(cmd, args, connectInput, outputStrategy, workingDirectory, environmentVariables, inputs, outputs) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.worker.NativeRunInfo, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("cmd", obj.cmd) + builder.addField("args", obj.args) + builder.addField("connectInput", obj.connectInput) + builder.addField("outputStrategy", obj.outputStrategy) + builder.addField("workingDirectory", obj.workingDirectory) + builder.addField("environmentVariables", obj.environmentVariables) + builder.addField("inputs", obj.inputs) + builder.addField("outputs", obj.outputs) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/worker/codec/RunInfoFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/RunInfoFormats.scala new file mode 100644 index 0000000000..16e66747ea --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/worker/codec/RunInfoFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.worker.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait RunInfoFormats { self: sbt.internal.worker.codec.JvmRunInfoFormats with sbt.internal.worker.codec.FilePathFormats with sjsonnew.BasicJsonProtocol with sbt.internal.worker.codec.NativeRunInfoFormats => +implicit lazy val RunInfoFormat: JsonFormat[sbt.internal.worker.RunInfo] = new JsonFormat[sbt.internal.worker.RunInfo] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.worker.RunInfo = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val jvm = unbuilder.readField[Boolean]("jvm") + val jvmRunInfo = unbuilder.readField[Option[sbt.internal.worker.JvmRunInfo]]("jvmRunInfo") + val nativeRunInfo = unbuilder.readField[Option[sbt.internal.worker.NativeRunInfo]]("nativeRunInfo") + unbuilder.endObject() + sbt.internal.worker.RunInfo(jvm, jvmRunInfo, nativeRunInfo) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.worker.RunInfo, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("jvm", obj.jvm) + builder.addField("jvmRunInfo", obj.jvmRunInfo) + builder.addField("nativeRunInfo", obj.nativeRunInfo) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/protocol/InitCommand.scala b/protocol/src/main/contraband-scala/sbt/protocol/InitCommand.scala index ddfe85f45f..26511bc1ee 100644 --- a/protocol/src/main/contraband-scala/sbt/protocol/InitCommand.scala +++ b/protocol/src/main/contraband-scala/sbt/protocol/InitCommand.scala @@ -7,22 +7,24 @@ package sbt.protocol final class InitCommand private ( val token: Option[String], val execId: Option[String], - val skipAnalysis: Option[Boolean]) extends sbt.protocol.CommandMessage() with Serializable { + val skipAnalysis: Option[Boolean], + val initializationOptions: Option[sbt.internal.protocol.InitializeOption]) extends sbt.protocol.CommandMessage() with Serializable { - private def this(token: Option[String], execId: Option[String]) = this(token, execId, None) + private def this(token: Option[String], execId: Option[String]) = this(token, execId, None, None) + private def this(token: Option[String], execId: Option[String], skipAnalysis: Option[Boolean]) = this(token, execId, skipAnalysis, None) override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { - case x: InitCommand => (this.token == x.token) && (this.execId == x.execId) && (this.skipAnalysis == x.skipAnalysis) + case x: InitCommand => (this.token == x.token) && (this.execId == x.execId) && (this.skipAnalysis == x.skipAnalysis) && (this.initializationOptions == x.initializationOptions) case _ => false }) override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "sbt.protocol.InitCommand".##) + token.##) + execId.##) + skipAnalysis.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.protocol.InitCommand".##) + token.##) + execId.##) + skipAnalysis.##) + initializationOptions.##) } override def toString: String = { - "InitCommand(" + token + ", " + execId + ", " + skipAnalysis + ")" + "InitCommand(" + token + ", " + execId + ", " + skipAnalysis + ", " + initializationOptions + ")" } - private[this] def copy(token: Option[String] = token, execId: Option[String] = execId, skipAnalysis: Option[Boolean] = skipAnalysis): InitCommand = { - new InitCommand(token, execId, skipAnalysis) + private[this] def copy(token: Option[String] = token, execId: Option[String] = execId, skipAnalysis: Option[Boolean] = skipAnalysis, initializationOptions: Option[sbt.internal.protocol.InitializeOption] = initializationOptions): InitCommand = { + new InitCommand(token, execId, skipAnalysis, initializationOptions) } def withToken(token: Option[String]): InitCommand = { copy(token = token) @@ -42,6 +44,12 @@ final class InitCommand private ( def withSkipAnalysis(skipAnalysis: Boolean): InitCommand = { copy(skipAnalysis = Option(skipAnalysis)) } + def withInitializationOptions(initializationOptions: Option[sbt.internal.protocol.InitializeOption]): InitCommand = { + copy(initializationOptions = initializationOptions) + } + def withInitializationOptions(initializationOptions: sbt.internal.protocol.InitializeOption): InitCommand = { + copy(initializationOptions = Option(initializationOptions)) + } } object InitCommand { @@ -49,4 +57,6 @@ object InitCommand { def apply(token: String, execId: String): InitCommand = new InitCommand(Option(token), Option(execId)) def apply(token: Option[String], execId: Option[String], skipAnalysis: Option[Boolean]): InitCommand = new InitCommand(token, execId, skipAnalysis) def apply(token: String, execId: String, skipAnalysis: Boolean): InitCommand = new InitCommand(Option(token), Option(execId), Option(skipAnalysis)) + def apply(token: Option[String], execId: Option[String], skipAnalysis: Option[Boolean], initializationOptions: Option[sbt.internal.protocol.InitializeOption]): InitCommand = new InitCommand(token, execId, skipAnalysis, initializationOptions) + def apply(token: String, execId: String, skipAnalysis: Boolean, initializationOptions: sbt.internal.protocol.InitializeOption): InitCommand = new InitCommand(Option(token), Option(execId), Option(skipAnalysis), Option(initializationOptions)) } diff --git a/protocol/src/main/contraband-scala/sbt/protocol/codec/CommandMessageFormats.scala b/protocol/src/main/contraband-scala/sbt/protocol/codec/CommandMessageFormats.scala index 6f95b6f48a..a705d1b488 100644 --- a/protocol/src/main/contraband-scala/sbt/protocol/codec/CommandMessageFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/protocol/codec/CommandMessageFormats.scala @@ -6,6 +6,6 @@ package sbt.protocol.codec import _root_.sjsonnew.JsonFormat -trait CommandMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.codec.InitCommandFormats with sbt.protocol.codec.ExecCommandFormats with sbt.protocol.codec.SettingQueryFormats with sbt.protocol.codec.AttachFormats with sbt.protocol.codec.TerminalCapabilitiesQueryFormats with sbt.protocol.codec.TerminalSetAttributesCommandFormats with sbt.protocol.codec.TerminalAttributesQueryFormats with sbt.protocol.codec.TerminalGetSizeQueryFormats with sbt.protocol.codec.TerminalSetSizeCommandFormats with sbt.protocol.codec.TerminalSetEchoCommandFormats with sbt.protocol.codec.TerminalSetRawModeCommandFormats => +trait CommandMessageFormats { self: sbt.internal.protocol.codec.InitializeOptionFormats with sjsonnew.BasicJsonProtocol with sbt.protocol.codec.InitCommandFormats with sbt.protocol.codec.ExecCommandFormats with sbt.protocol.codec.SettingQueryFormats with sbt.protocol.codec.AttachFormats with sbt.protocol.codec.TerminalCapabilitiesQueryFormats with sbt.protocol.codec.TerminalSetAttributesCommandFormats with sbt.protocol.codec.TerminalAttributesQueryFormats with sbt.protocol.codec.TerminalGetSizeQueryFormats with sbt.protocol.codec.TerminalSetSizeCommandFormats with sbt.protocol.codec.TerminalSetEchoCommandFormats with sbt.protocol.codec.TerminalSetRawModeCommandFormats => implicit lazy val CommandMessageFormat: JsonFormat[sbt.protocol.CommandMessage] = flatUnionFormat11[sbt.protocol.CommandMessage, sbt.protocol.InitCommand, sbt.protocol.ExecCommand, sbt.protocol.SettingQuery, sbt.protocol.Attach, sbt.protocol.TerminalCapabilitiesQuery, sbt.protocol.TerminalSetAttributesCommand, sbt.protocol.TerminalAttributesQuery, sbt.protocol.TerminalGetSizeQuery, sbt.protocol.TerminalSetSizeCommand, sbt.protocol.TerminalSetEchoCommand, sbt.protocol.TerminalSetRawModeCommand]("type") } diff --git a/protocol/src/main/contraband-scala/sbt/protocol/codec/InitCommandFormats.scala b/protocol/src/main/contraband-scala/sbt/protocol/codec/InitCommandFormats.scala index 827b6dc7c0..7d552b17b3 100644 --- a/protocol/src/main/contraband-scala/sbt/protocol/codec/InitCommandFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/protocol/codec/InitCommandFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.protocol.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait InitCommandFormats { self: sjsonnew.BasicJsonProtocol => +trait InitCommandFormats { self: sbt.internal.protocol.codec.InitializeOptionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val InitCommandFormat: JsonFormat[sbt.protocol.InitCommand] = new JsonFormat[sbt.protocol.InitCommand] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.InitCommand = { __jsOpt match { @@ -14,8 +14,9 @@ implicit lazy val InitCommandFormat: JsonFormat[sbt.protocol.InitCommand] = new val token = unbuilder.readField[Option[String]]("token") val execId = unbuilder.readField[Option[String]]("execId") val skipAnalysis = unbuilder.readField[Option[Boolean]]("skipAnalysis") + val initializationOptions = unbuilder.readField[Option[sbt.internal.protocol.InitializeOption]]("initializationOptions") unbuilder.endObject() - sbt.protocol.InitCommand(token, execId, skipAnalysis) + sbt.protocol.InitCommand(token, execId, skipAnalysis, initializationOptions) case None => deserializationError("Expected JsObject but found None") } @@ -25,6 +26,7 @@ implicit lazy val InitCommandFormat: JsonFormat[sbt.protocol.InitCommand] = new builder.addField("token", obj.token) builder.addField("execId", obj.execId) builder.addField("skipAnalysis", obj.skipAnalysis) + builder.addField("initializationOptions", obj.initializationOptions) builder.endObject() } } diff --git a/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala b/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala index 2df56d1ad3..32852fe440 100644 --- a/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala +++ b/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala @@ -4,7 +4,8 @@ // DO NOT EDIT MANUALLY package sbt.protocol.codec -trait JsonProtocol extends sjsonnew.BasicJsonProtocol +trait JsonProtocol extends sbt.internal.protocol.codec.InitializeOptionFormats + with sjsonnew.BasicJsonProtocol with sbt.protocol.codec.InitCommandFormats with sbt.protocol.codec.ExecCommandFormats with sbt.protocol.codec.SettingQueryFormats diff --git a/protocol/src/main/contraband/bsp.contra b/protocol/src/main/contraband/bsp.contra index a931a8fb63..1956cf4404 100644 --- a/protocol/src/main/contraband/bsp.contra +++ b/protocol/src/main/contraband/bsp.contra @@ -605,6 +605,17 @@ type RunResult { } +# JVM extension + +## Contains jvm-specific metadata, specifically JDK reference +type JvmBuildTarget { + ## Uri representing absolute path to jdk + javaHome: java.net.URI + + ## The java version this target is supposed to use (can be set using javac `-target` flag) + javaVersion: String +} + # Scala Extension ## Contains scala-specific metadata for compiling a target containing Scala sources. @@ -626,6 +637,9 @@ type ScalaBuildTarget { ## A sequence of Scala jars such as scala-library, scala-compiler and scala-reflect. jars: [String]! + + ## The jvm build target describing jdk to be used + jvmBuildTarget: sbt.internal.bsp.JvmBuildTarget } ## Scalac options diff --git a/protocol/src/main/contraband/portfile.contra b/protocol/src/main/contraband/portfile.contra index 2e138c3159..ffd5dc6c9a 100644 --- a/protocol/src/main/contraband/portfile.contra +++ b/protocol/src/main/contraband/portfile.contra @@ -16,7 +16,10 @@ type TokenFile { token: String! } +## Passed into InitializeParams as part of "initialize" request as the user-defined option. +## https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize type InitializeOption { token: String skipAnalysis: Boolean @since("1.4.0") + canWork: Boolean @since("1.10.8") } diff --git a/protocol/src/main/contraband/server.contra b/protocol/src/main/contraband/server.contra index 18ec0a0d2f..176db450a7 100644 --- a/protocol/src/main/contraband/server.contra +++ b/protocol/src/main/contraband/server.contra @@ -11,6 +11,7 @@ type InitCommand implements CommandMessage { token: String execId: String skipAnalysis: Boolean @since("1.4.0") + initializationOptions: sbt.internal.protocol.InitializeOption @since("1.10.8") } ## Command to execute sbt command. diff --git a/protocol/src/main/contraband/worker.contra b/protocol/src/main/contraband/worker.contra new file mode 100644 index 0000000000..45a68eb741 --- /dev/null +++ b/protocol/src/main/contraband/worker.contra @@ -0,0 +1,51 @@ +package sbt.internal.worker +@target(Scala) +@codecPackage("sbt.internal.worker.codec") +@fullCodec("JsonProtocol") + +type FilePath { + path: java.net.URI! + digest: String! +} + +type JvmRunInfo { + args: [String], + classpath: [sbt.internal.worker.FilePath], + mainClass: String! + connectInput: Boolean! + javaHome: java.net.URI + outputStrategy: String + workingDirectory: java.net.URI + jvmOptions: [String] + environmentVariables: StringStringMap! + inputs: [sbt.internal.worker.FilePath] @since("0.1.0"), + outputs: [sbt.internal.worker.FilePath] @since("0.1.0"), +} + +type NativeRunInfo { + cmd: String!, + args: [String], + connectInput: Boolean! + outputStrategy: String + workingDirectory: java.net.URI + environmentVariables: StringStringMap! + inputs: [sbt.internal.worker.FilePath] @since("0.1.0"), + outputs: [sbt.internal.worker.FilePath] @since("0.1.0"), +} + +type RunInfo { + jvm: Boolean! + jvmRunInfo: sbt.internal.worker.JvmRunInfo, + nativeRunInfo: sbt.internal.worker.NativeRunInfo @since("0.1.0"), +} + +## Client-side job support. +## +## Notification: sbt/clientJob +## +## Parameter for the sbt/clientJob notification. +## A client-side job represents a unit of work that sbt server +## can outsourse back to the client, for example for run task. +type ClientJobParams { + runInfo: sbt.internal.worker.RunInfo +} diff --git a/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala b/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala index e03b67eae5..ba9042dde8 100644 --- a/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala +++ b/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala @@ -9,6 +9,7 @@ package sbt.internal.bsp import sbt.internal.bsp.codec.JsonProtocol.BspConnectionDetailsFormat +import sbt.internal.util.Util import sbt.io.IO import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter } @@ -25,7 +26,7 @@ object BuildServerConnection { private[sbt] def writeConnectionFile(sbtVersion: String, baseDir: File): Unit = { val bspConnectionFile = new File(baseDir, ".bsp/sbt.json") - val javaHome = System.getProperty("java.home") + val javaHome = Util.javaHome val classPath = System.getProperty("java.class.path") val sbtScript = Option(System.getProperty("sbt.script")) diff --git a/protocol/src/main/scala/sbt/protocol/Serialization.scala b/protocol/src/main/scala/sbt/protocol/Serialization.scala index 2dcd5ae981..1384fb4f24 100644 --- a/protocol/src/main/scala/sbt/protocol/Serialization.scala +++ b/protocol/src/main/scala/sbt/protocol/Serialization.scala @@ -27,6 +27,7 @@ object Serialization { private[sbt] val VsCode = "application/vscode-jsonrpc; charset=utf-8" val readSystemIn = "sbt/readSystemIn" val cancelReadSystemIn = "sbt/cancelReadSystemIn" + val clientJob = "sbt/clientJob" val systemIn = "sbt/systemIn" val systemOut = "sbt/systemOut" val systemErr = "sbt/systemErr" @@ -67,15 +68,10 @@ object Serialization { command match { case x: InitCommand => val execId = x.execId.getOrElse(UUID.randomUUID.toString) - val analysis = s""""skipAnalysis" : ${x.skipAnalysis.getOrElse(false)}""" - val opt = x.token match { - case Some(t) => - val json: JValue = Converter.toJson[String](t).get - val v = CompactPrinter(json) - s"""{ "token": $v, $analysis }""" - case None => s"{ $analysis }" - } - s"""{ "jsonrpc": "2.0", "id": "$execId", "method": "initialize", "params": { "initializationOptions": $opt } }""" + val opts = x.initializationOptions.getOrElse(sys.error("expected initializationOptions")) + import sbt.protocol.codec.JsonProtocol._ + val optsJson = CompactPrinter(Converter.toJson(opts).get) + s"""{ "jsonrpc": "2.0", "id": "$execId", "method": "initialize", "params": { "initializationOptions": $optsJson } }""" case x: ExecCommand => val execId = x.execId.getOrElse(UUID.randomUUID.toString) val json: JValue = Converter.toJson[String](x.commandLine).get diff --git a/run/src/main/scala/sbt/Fork.scala b/run/src/main/scala/sbt/Fork.scala index 3335f53f33..07fc33924b 100644 --- a/run/src/main/scala/sbt/Fork.scala +++ b/run/src/main/scala/sbt/Fork.scala @@ -33,15 +33,8 @@ final class Fork(val commandName: String, val runnerClass: Option[String]) { * It is configured according to `config`. * If `runnerClass` is defined for this Fork instance, it is prepended to `arguments` to define the arguments passed to the forked command. */ - def apply(config: ForkOptions, arguments: Seq[String]): Int = { - val p = fork(config, arguments) - RunningProcesses.add(p) - try p.exitValue() - finally { - if (p.isAlive()) p.destroy() - RunningProcesses.remove(p) - } - } + def apply(config: ForkOptions, arguments: Seq[String]): Int = + Fork.blockForExitCode(fork(config, arguments)) /** * Forks the configured process and returns a `Process` that can be used to wait for completion or to terminate the forked process. @@ -50,37 +43,22 @@ final class Fork(val commandName: String, val runnerClass: Option[String]) { * If `runnerClass` is defined for this Fork instance, it is prepended to `arguments` to define the arguments passed to the forked command. */ def fork(config: ForkOptions, arguments: Seq[String]): Process = { - import config.{ envVars => env, _ } + import config._ val executable = Fork.javaCommand(javaHome, commandName).getAbsolutePath val preOptions = makeOptions(runJVMOptions, bootJars, arguments) val (classpathEnv, options) = Fork.fitClasspath(preOptions) val command = executable +: options - - val environment: List[(String, String)] = env.toList ++ - (classpathEnv map { value => - Fork.ClasspathEnvKey -> value - }) val jpb = if (Fork.shouldUseArgumentsFile(options)) new JProcessBuilder(executable, Fork.createArgumentsFile(options)) else new JProcessBuilder(command.toArray: _*) - workingDirectory foreach (jpb directory _) - environment foreach { case (k, v) => jpb.environment.put(k, v) } - if (connectInput) { - jpb.redirectInput(Redirect.INHERIT) - () - } - val process = Process(jpb) - - outputStrategy.getOrElse(StdoutOutput: OutputStrategy) match { - case StdoutOutput => process.run(connectInput = false) - case out: BufferedOutput => - out.logger.buffer { process.run(out.logger, connectInput = false) } - case out: LoggedOutput => process.run(out.logger, connectInput = false) - case out: CustomOutput => (process #> out.output).run(connectInput = false) + val extraEnv = classpathEnv.toList.map { value => + Fork.ClasspathEnvKey -> value } + Fork.forkInternal(config, extraEnv, jpb) } + private[this] def makeOptions( jvmOptions: Seq[String], bootJars: Iterable[File], @@ -185,4 +163,36 @@ object Fork { pw.close() s"@${file.getAbsolutePath}" } + + private[sbt] def forkInternal( + config: ForkOptions, + extraEnv: List[(String, String)], + jpb: JProcessBuilder + ): Process = { + import config.{ envVars => env, _ } + val environment: List[(String, String)] = env.toList ++ extraEnv + workingDirectory.foreach(jpb directory _) + environment.foreach { case (k, v) => jpb.environment.put(k, v) } + if (connectInput) { + jpb.redirectInput(Redirect.INHERIT) + () + } + val process = Process(jpb) + outputStrategy.getOrElse(StdoutOutput: OutputStrategy) match { + case StdoutOutput => process.run(connectInput = false) + case out: BufferedOutput => + out.logger.buffer { process.run(out.logger, connectInput = false) } + case out: LoggedOutput => process.run(out.logger, connectInput = false) + case out: CustomOutput => (process #> out.output).run(connectInput = false) + } + } + + private[sbt] def blockForExitCode(p: Process): Int = { + RunningProcesses.add(p) + try p.exitValue() + finally { + if (p.isAlive()) p.destroy() + RunningProcesses.remove(p) + } + } } diff --git a/run/src/main/scala/sbt/Run.scala b/run/src/main/scala/sbt/Run.scala index 9e46f2b46c..cda9e58884 100644 --- a/run/src/main/scala/sbt/Run.scala +++ b/run/src/main/scala/sbt/Run.scala @@ -26,25 +26,16 @@ sealed trait ScalaRun { } class ForkRun(config: ForkOptions) extends ScalaRun { def run(mainClass: String, classpath: Seq[File], options: Seq[String], log: Logger): Try[Unit] = { - def processExitCode(exitCode: Int, label: String): Try[Unit] = - if (exitCode == 0) Success(()) - else - Failure( - new MessageOnlyException( - s"""Nonzero exit code returned from $label: $exitCode""".stripMargin - ) - ) - log.info(s"running (fork) $mainClass ${Run.runOptionsStr(options)}") val c = configLogged(log) val scalaOpts = scalaOptions(mainClass, classpath, options) val exitCode = try Fork.java(c, scalaOpts) catch { case _: InterruptedException => - log.warn("Run canceled.") + log.warn("run canceled") 1 } - processExitCode(exitCode, "runner") + Run.processExitCode(exitCode, "runner") } def fork(mainClass: String, classpath: Seq[File], options: Seq[String], log: Logger): Process = { @@ -58,7 +49,7 @@ class ForkRun(config: ForkOptions) extends ScalaRun { } private def configLogged(log: Logger): ForkOptions = { - if (config.outputStrategy.isDefined) config + if (config.outputStrategy.isDefined || config.connectInput) config else config.withOutputStrategy(OutputStrategy.LoggedOutput(log)) } @@ -195,4 +186,13 @@ object Run { case str if str.contains(" ") => "\"" + str + "\"" case str => str }).mkString(" ") + + private[sbt] def processExitCode(exitCode: Int, label: String): Try[Unit] = + if (exitCode == 0) Success(()) + else + Failure( + new MessageOnlyException( + s"""nonzero exit code returned from $label: $exitCode""".stripMargin + ) + ) } diff --git a/sbt b/sbt index 7d3f707e81..217be39ecf 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.10.0" +declare builtin_sbt_version="1.10.11" declare -a residual_args declare -a java_args declare -a scalac_args @@ -24,7 +24,9 @@ declare build_props_sbt_version= declare use_sbtn= declare no_server= declare sbtn_command="$SBTN_CMD" -declare sbtn_version="1.10.0" +declare sbtn_version="1.10.8" +declare use_colors=1 +declare is_this_dir_sbt="" ### ------------------------------- ### ### Helper methods for BASH scripts ### @@ -89,6 +91,14 @@ cygwinpath() { fi } +# Trim leading and trailing spaces from a string. +# Echos the new trimmed string. +trimString() { + local inputStr="$*" + local modStr="${inputStr#"${inputStr%%[![:space:]]*}"}" + modStr="${modStr%"${modStr##*[![:space:]]}"}" + echo "$modStr" +} declare -r sbt_bin_dir="$(dirname "$(realpathish "$0")")" declare -r sbt_home="$(dirname "$sbt_bin_dir")" @@ -96,6 +106,15 @@ declare -r sbt_home="$(dirname "$sbt_bin_dir")" echoerr () { echo 1>&2 "$@" } +RED='\033[0;31m' +NC='\033[0m' # No Color +echoerr_error () { + if [[ $use_colors == "1" ]]; then + echoerr -e "[${RED}error${NC}] $@" + else + echoerr "[error] $@" + fi +} vlog () { [[ $sbt_verbose || $sbt_debug ]] && echoerr "$@" } @@ -172,7 +191,7 @@ acquire_sbtn () { local archive_target= local url= local arch="x86_64" - if [[ "$OSTYPE" == "linux-gnu"* ]]; then + if [[ "$OSTYPE" == "linux"* ]]; then arch=$(uname -m) if [[ "$arch" == "aarch64" ]] || [[ "$arch" == "x86_64" ]]; then archive_target="$p/sbtn-${arch}-pc-linux-${sbtn_v}.tar.gz" @@ -182,6 +201,7 @@ acquire_sbtn () { exit 2 fi elif [[ "$OSTYPE" == "darwin"* ]]; then + arch="universal" archive_target="$p/sbtn-universal-apple-darwin-${sbtn_v}.tar.gz" url="https://github.com/sbt/sbtn-dist/releases/download/v${sbtn_v}/sbtn-universal-apple-darwin-${sbtn_v}.tar.gz" elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then @@ -475,6 +495,27 @@ copyRt() { fi } +detect_working_directory() { + if [[ -f ./build.sbt || -f ./project/build.properties ]]; then + is_this_dir_sbt=1 + fi +} + +# Confirm a user's intent if the current directory does not look like an sbt +# top-level directory and neither the --allow-empty option nor the "new" command was given. +checkWorkingDirectory() { + if [[ ! -n "$allow_empty" ]]; then + [[ -n "$is_this_dir_sbt" || -n "$sbt_new" ]] || { + echoerr_error "Neither build.sbt nor a 'project' directory in the current directory: $(pwd)" + echoerr_error "run 'sbt new', touch build.sbt, or run 'sbt --allow-empty'." + echoerr_error "" + echoerr_error "To opt out of this check, create ${config_home}/sbtopts with:" + echoerr_error "--allow-empty" + exit 1 + } + fi +} + run() { # Copy preloaded repo to user's preloaded directory syncPreloaded @@ -485,7 +526,7 @@ run() { } # TODO - java check should be configurable... - checkJava "6" + checkJava "8" # Java 9 support copyRt @@ -497,13 +538,19 @@ run() { addJava "-Dsbt.cygwin=true" fi + detect_working_directory if [[ $print_sbt_version ]]; then execRunner "$java_cmd" -jar "$sbt_jar" "sbtVersion" | tail -1 | sed -e 's/\[info\]//g' elif [[ $print_sbt_script_version ]]; then echo "$init_sbt_version" elif [[ $print_version ]]; then - execRunner "$java_cmd" -jar "$sbt_jar" "sbtVersion" | tail -1 | sed -e 's/\[info\]/sbt version in this project:/g' - echo "sbt script version: $init_sbt_version" + if [[ -n "$is_this_dir_sbt" ]]; then + execRunner "$java_cmd" -jar "$sbt_jar" "sbtVersion" | tail -1 | sed -e 's/\[info\]/sbt version in this project:/g' + fi + echo "sbt runner version: $init_sbt_version" + echoerr "" + echoerr "[info] sbt runner (sbt-the-shell-script) is a runner to run any declared version of sbt." + echoerr "[info] Actual version of the sbt is declared using project/build.properties for each build." elif [[ $shutdownall ]]; then local sbt_processes=( $(jps -v | grep sbt-launch | cut -f1 -d ' ') ) for procId in "${sbt_processes[@]}"; do @@ -511,6 +558,7 @@ run() { done echo "shutdown ${#sbt_processes[@]} sbt processes" else + checkWorkingDirectory # run sbt execRunner "$java_cmd" \ "${java_args[@]}" \ @@ -535,7 +583,10 @@ declare -r sbt_opts_file=".sbtopts" declare -r build_props_file="$(pwd)/project/build.properties" declare -r etc_sbt_opts_file="/etc/sbt/sbtopts" # this allows /etc/sbt/sbtopts location to be changed -declare -r etc_file="${SBT_ETC_FILE:-$etc_sbt_opts_file}" +declare machine_sbt_opts_file="${etc_sbt_opts_file}" +declare config_home="${XDG_CONFIG_HOME:-$HOME/.config}/sbt" +[[ -f "${config_home}/sbtopts" ]] && machine_sbt_opts_file="${config_home}/sbtopts" +[[ -f "$SBT_ETC_FILE" ]] && machine_sbt_opts_file="$SBT_ETC_FILE" declare -r dist_sbt_opts_file="${sbt_home}/conf/sbtopts" declare -r win_sbt_opts_file="${sbt_home}/conf/sbtconfig.txt" declare sbt_jar="$(jar_file)" @@ -560,7 +611,7 @@ Usage: `basename "$0"` [options] enable or disable supershell (sbt 1.3 and above) --traces generate Trace Event report on shutdown (sbt 1.3 and above) --timings display task timings report on shutdown - --sbt-create start sbt even if current directory contains no sbt project + --allow-empty start sbt even if current directory contains no sbt project --sbt-dir path to global settings/plugins directory (default: ~/.sbt) --sbt-boot path to shared boot directory (default: ~/.sbt/boot in 0.11 series) --sbt-cache path to global cache directory (default: operating system specific) @@ -599,9 +650,9 @@ process_my_args () { case "$1" in -batch|--batch) exec - -sbt-create|--sbt-create) sbt_create=true && shift ;; + -allow-empty|--allow-empty|-sbt-create|--sbt-create) allow_empty=true && shift ;; - new) sbt_new=true && addResidual "$1" && shift ;; + new|init) sbt_new=true && addResidual "$1" && shift ;; *) addResidual "$1" && shift ;; esac @@ -609,23 +660,6 @@ process_my_args () { # Now, ensure sbt version is used. [[ "${sbt_version}XXX" != "XXX" ]] && addJava "-Dsbt.version=$sbt_version" - - # Confirm a user's intent if the current directory does not look like an sbt - # top-level directory and neither the -sbt-create option nor the "new" - # command was given. - [[ -f ./build.sbt || -d ./project || -n "$sbt_create" || -n "$sbt_new" ]] || { - echo "[warn] Neither build.sbt nor a 'project' directory in the current directory: $(pwd)" - while true; do - echo 'c) continue' - echo 'q) quit' - - read -p '? ' || exit 1 - case "$REPLY" in - c|C) break ;; - q|Q) exit 1 ;; - esac - done - } } ## map over argument array. this is used to process both command line arguments and SBT_OPTS @@ -686,6 +720,7 @@ process_args () { export PATH="$2/bin:$PATH" && shift 2 ;; + -Dsbt.color=never|-Dsbt.log.noformat=true) addJava "$1" && use_colors=0 && shift ;; "-D*"|-D*) addJava "$1" && shift ;; -J*) addJava "${1:2}" && shift ;; *) addResidual "$1" && shift ;; @@ -707,6 +742,9 @@ loadConfigFile() { } loadPropFile() { + # trim key and value so as to be more forgiving with spaces around the '=': + k=$(trimString $k) + v=$(trimString $v) while IFS='=' read -r k v; do if [[ "$k" == "sbt.version" ]]; then build_props_sbt_version="$v" @@ -738,7 +776,14 @@ isRunNativeClient() { [[ "$sbtV" == "" ]] && sbtV="0.0.0" sbtBinaryV_1=$(echo "$sbtV" | sed 's/^\([0-9]*\)\.\([0-9]*\).*$/\1/') sbtBinaryV_2=$(echo "$sbtV" | sed 's/^\([0-9]*\)\.\([0-9]*\).*$/\2/') - if (( $sbtBinaryV_1 >= 2 )) || ( (( $sbtBinaryV_1 >= 1 )) && (( $sbtBinaryV_2 >= 4 )) ); then + # Default to true for sbt 2.x + if (( $sbtBinaryV_1 >= 2 )); then + if [[ "$use_sbtn" == "0" ]]; then + echo "false" + else + echo "true" + fi + elif ( (( $sbtBinaryV_1 >= 1 )) && (( $sbtBinaryV_2 >= 4 )) ); then if [[ "$use_sbtn" == "1" ]]; then echo "true" else @@ -760,18 +805,25 @@ runNativeClient() { unset 'original_args[i]' fi done - sbt_script=$0 + + if [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then + sbt_script="$0.bat" + else + sbt_script="$0" + fi sbt_script=${sbt_script/ /%20} execRunner "$sbtn_command" "--sbt-script=$sbt_script" "${original_args[@]}" } original_args=("$@") -# Here we pull in the default settings configuration. -[[ -f "$dist_sbt_opts_file" ]] && set -- $(loadConfigFile "$dist_sbt_opts_file") "$@" - -# Here we pull in the global settings configuration. -[[ -f "$etc_file" ]] && set -- $(loadConfigFile "$etc_file") "$@" +# Pull in the machine-wide settings configuration. +if [[ -f "$machine_sbt_opts_file" ]]; then + set -- $(loadConfigFile "$machine_sbt_opts_file") "$@" +else + # Otherwise pull in the default settings configuration. + [[ -f "$dist_sbt_opts_file" ]] && set -- $(loadConfigFile "$dist_sbt_opts_file") "$@" +fi # Pull in the project-level config file, if it exists. [[ -f "$sbt_opts_file" ]] && set -- $(loadConfigFile "$sbt_opts_file") "$@" diff --git a/sbt-app/src/sbt-test/actions/add-alias/test b/sbt-app/src/sbt-test/actions/add-alias/test index 0269ab4f88..9a7db37822 100644 --- a/sbt-app/src/sbt-test/actions/add-alias/test +++ b/sbt-app/src/sbt-test/actions/add-alias/test @@ -2,3 +2,5 @@ -> demo-failure > +z > z + +$ absent /tmp/non-existent diff --git a/sbt-app/src/sbt-test/actions/clean-managed/test b/sbt-app/src/sbt-test/actions/clean-managed/test index f6fd6ce8f8..5023111888 100644 --- a/sbt-app/src/sbt-test/actions/clean-managed/test +++ b/sbt-app/src/sbt-test/actions/clean-managed/test @@ -1,6 +1,6 @@ > compile -$ exists target/scala-2.12/src_managed/foo.txt target/scala-2.12/src_managed/bar.txt +$ exists target/**/src_managed/foo.txt target/**/src_managed/bar.txt > clean -$ absent target/scala-2.12/src_managed/foo.txt -$ exists target/scala-2.12/src_managed/bar.txt +$ absent target/**/src_managed/foo.txt +$ exists target/**/src_managed/bar.txt diff --git a/sbt-app/src/sbt-test/actions/compile-clean/test b/sbt-app/src/sbt-test/actions/compile-clean/test index 2e805ffd03..7d983f7cae 100644 --- a/sbt-app/src/sbt-test/actions/compile-clean/test +++ b/sbt-app/src/sbt-test/actions/compile-clean/test @@ -1,22 +1,22 @@ $ touch target/cant-touch-this > Test/compile -$ exists target/scala-2.12/classes/A.class -$ exists target/scala-2.12/test-classes/B.class +$ exists target/**/classes/A.class +$ exists target/**/test-classes/B.class > Test/clean $ exists target/cant-touch-this # it should clean only compile classes -$ exists target/scala-2.12/classes/A.class -$ exists target/scala-2.12/classes/X.class -$ absent target/scala-2.12/test-classes/B.class +$ exists target/**/classes/A.class +$ exists target/**/classes/X.class +$ absent target/**/test-classes/B.class # compiling everything again, but now cleaning only compile classes > Test/compile > Compile/clean $ exists target/cant-touch-this # it should clean only compile classes -$ absent target/scala-2.12/classes/A.class -$ exists target/scala-2.12/test-classes/B.class +$ absent target/**/classes/A.class +$ exists target/**/test-classes/B.class # and X has to be kept, because of the cleanKeepFiles override -$ exists target/scala-2.12/classes/X.class +$ exists target/**/classes/X.class diff --git a/sbt-app/src/sbt-test/actions/cross-advanced/build.sbt b/sbt-app/src/sbt-test/actions/cross-advanced/build.sbt index 698d3d3e79..703f9b26a6 100644 --- a/sbt-app/src/sbt-test/actions/cross-advanced/build.sbt +++ b/sbt-app/src/sbt-test/actions/cross-advanced/build.sbt @@ -1,6 +1,6 @@ lazy val check = taskKey[Unit]("") lazy val compile2 = taskKey[Unit]("") -lazy val scala212 = "2.12.19" +lazy val scala212 = "2.12.20" lazy val scala213 = "2.13.12" lazy val root = (project in file(".")) diff --git a/sbt-app/src/sbt-test/actions/cross-advanced/test b/sbt-app/src/sbt-test/actions/cross-advanced/test index 918b697319..47912f43c1 100644 --- a/sbt-app/src/sbt-test/actions/cross-advanced/test +++ b/sbt-app/src/sbt-test/actions/cross-advanced/test @@ -17,7 +17,7 @@ ## test + with command or alias > clean ## for command cross building you do need crossScalaVerions on root -> set root/crossScalaVersions := Seq("2.12.19", "2.13.12") +> set root/crossScalaVersions := Seq("2.12.20", "2.13.12") > + build $ exists foo/target/scala-2.12 $ exists foo/target/scala-2.13 diff --git a/sbt-app/src/sbt-test/actions/cross-incremental/build.sbt b/sbt-app/src/sbt-test/actions/cross-incremental/build.sbt index 751353326d..79b7bdf275 100644 --- a/sbt-app/src/sbt-test/actions/cross-incremental/build.sbt +++ b/sbt-app/src/sbt-test/actions/cross-incremental/build.sbt @@ -1,5 +1,5 @@ -scalaVersion := "2.12.19" -crossScalaVersions := List("2.12.19", "2.13.12") +scalaVersion := "2.12.20" +crossScalaVersions := List("2.12.20", "2.13.12") val setLastModified = taskKey[Unit]("Sets the last modified time for classfiles") setLastModified := { diff --git a/sbt-app/src/sbt-test/actions/cross-multi-parser/build.sbt b/sbt-app/src/sbt-test/actions/cross-multi-parser/build.sbt index bc2b10efbc..bb4a1ec0e7 100644 --- a/sbt-app/src/sbt-test/actions/cross-multi-parser/build.sbt +++ b/sbt-app/src/sbt-test/actions/cross-multi-parser/build.sbt @@ -1 +1 @@ -crossScalaVersions := Seq[String]("2.11.12", "2.12.19") +crossScalaVersions := Seq[String]("2.11.12", "2.12.20") diff --git a/sbt-app/src/sbt-test/actions/cross-multi-parser/test b/sbt-app/src/sbt-test/actions/cross-multi-parser/test index b2666730af..0055182917 100644 --- a/sbt-app/src/sbt-test/actions/cross-multi-parser/test +++ b/sbt-app/src/sbt-test/actions/cross-multi-parser/test @@ -1,5 +1,5 @@ > ++2.11.12; compile -> ++ 2.12.19 ; compile; +> ++ 2.12.20 ; compile; -> ++ 2.12.19 ; compile +> ++ 2.12.20 ; compile diff --git a/sbt-app/src/sbt-test/actions/cross-multiproject/build.sbt b/sbt-app/src/sbt-test/actions/cross-multiproject/build.sbt index 9cdaec3716..4f2d58d77c 100644 --- a/sbt-app/src/sbt-test/actions/cross-multiproject/build.sbt +++ b/sbt-app/src/sbt-test/actions/cross-multiproject/build.sbt @@ -1,4 +1,4 @@ -lazy val scala212 = "2.12.19" +lazy val scala212 = "2.12.20" lazy val scala213 = "2.13.12" ThisBuild / crossScalaVersions := Seq(scala212, scala213) diff --git a/sbt-app/src/sbt-test/actions/cross-multiproject/ref/build.sbt b/sbt-app/src/sbt-test/actions/cross-multiproject/ref/build.sbt index 6fdb53f788..32936b7d0a 100644 --- a/sbt-app/src/sbt-test/actions/cross-multiproject/ref/build.sbt +++ b/sbt-app/src/sbt-test/actions/cross-multiproject/ref/build.sbt @@ -1,4 +1,4 @@ lazy val external = (project in file(".")) .settings( - scalaVersion := "2.12.19" + scalaVersion := "2.12.20" ) diff --git a/sbt-app/src/sbt-test/actions/cross-multiproject/test b/sbt-app/src/sbt-test/actions/cross-multiproject/test index 2cb5f058eb..03a96cb834 100644 --- a/sbt-app/src/sbt-test/actions/cross-multiproject/test +++ b/sbt-app/src/sbt-test/actions/cross-multiproject/test @@ -13,7 +13,7 @@ $ exists lib/target/scala-2.13 # test safe switching > clean -> ++ 2.12.19 -v compile +> ++ 2.12.20 -v compile $ exists lib/target/scala-2.12 -$ exists lib/target/scala-2.13 $ exists sbt-foo/target/scala-2.12 @@ -21,6 +21,12 @@ $ exists sbt-foo/target/scala-2.12 $ exists ref/target/scala-2.12 -$ exists ref/target/scala-2.13 +# test safe switching +> clean +> ++ 2.12.20 -v libProj/compile +$ exists lib/target/scala-2.12 +-$ exists lib/target/scala-2.13 + # Test legacy cross build with command support # > clean # > + build @@ -31,7 +37,7 @@ $ exists ref/target/scala-2.12 # Test ++ leaves crossScalaVersions unchanged > clean -> ++2.12.19 +> ++2.12.20 > +extrasProj/compile $ exists extras/target/scala-2.13 $ exists extras/target/scala-2.12 diff --git a/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt index 38a5a26fee..6e5d27874a 100644 --- a/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt +++ b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt @@ -1,14 +1,14 @@ -scalaVersion := "2.12.19" +scalaVersion := "2.12.20" lazy val core = project .settings( - crossScalaVersions := Seq("2.12.19", "3.0.2", "3.1.2") + crossScalaVersions := Seq("2.12.20", "3.3.1", "3.5.1") ) lazy val subproj = project .dependsOn(core) .settings( - crossScalaVersions := Seq("2.12.19", "3.1.2"), + crossScalaVersions := Seq("2.12.20", "3.5.1"), // a random library compiled against Scala 3.1 - libraryDependencies += "org.http4s" %% "http4s-core" % "0.23.12" + libraryDependencies += "org.http4s" %% "http4s-core" % "0.23.28" ) diff --git a/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/test b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/test index ea7afbf93a..9e96b0f495 100644 --- a/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/test +++ b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/test @@ -1,14 +1,14 @@ -> ++3.0.2 compile +> ++3.3.1 compile -$ exists core/target/scala-3.0.2 --$ exists core/target/scala-3.1.2 --$ exists subproj/target/scala-3.0.2 --$ exists subproj/target/scala-3.1.2 +$ exists core/target/scala-3.3.1 +-$ exists core/target/scala-3.5.1 +-$ exists subproj/target/scala-3.3.1 +-$ exists subproj/target/scala-3.5.1 > clean -> ++3.1.2 compile +> ++3.5.1 compile --$ exists core/target/scala-3.0.2 -$ exists core/target/scala-3.1.2 --$ exists subproj/target/scala-3.0.2 -$ exists subproj/target/scala-3.1.2 +-$ exists core/target/scala-3.3.1 +$ exists core/target/scala-3.5.1 +-$ exists subproj/target/scala-3.3.1 +$ exists subproj/target/scala-3.5.1 diff --git a/sbt-app/src/sbt-test/actions/cross-strict-aggregation/build.sbt b/sbt-app/src/sbt-test/actions/cross-strict-aggregation/build.sbt index 68540aadba..d5b43e3211 100644 --- a/sbt-app/src/sbt-test/actions/cross-strict-aggregation/build.sbt +++ b/sbt-app/src/sbt-test/actions/cross-strict-aggregation/build.sbt @@ -1,4 +1,4 @@ -lazy val scala212 = "2.12.19" +lazy val scala212 = "2.12.20" lazy val scala213 = "2.13.12" ThisBuild / scalaVersion := scala212 diff --git a/sbt-app/src/sbt-test/actions/doc-file-options/build.sbt b/sbt-app/src/sbt-test/actions/doc-file-options/build.sbt index 315d77d228..a8b68c48ab 100644 --- a/sbt-app/src/sbt-test/actions/doc-file-options/build.sbt +++ b/sbt-app/src/sbt-test/actions/doc-file-options/build.sbt @@ -2,7 +2,7 @@ val newContents = "bbbbbbbbb" val rootContentFile = "root.txt" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/actions/doc-scala3/m3/src/main/scala/foo/A.scala b/sbt-app/src/sbt-test/actions/doc-scala3/a/src/main/scala/foo/A.scala similarity index 100% rename from sbt-app/src/sbt-test/actions/doc-scala3/m3/src/main/scala/foo/A.scala rename to sbt-app/src/sbt-test/actions/doc-scala3/a/src/main/scala/foo/A.scala diff --git a/sbt-app/src/sbt-test/actions/doc-scala3/build.sbt b/sbt-app/src/sbt-test/actions/doc-scala3/build.sbt index 583a736e07..daa9348785 100644 --- a/sbt-app/src/sbt-test/actions/doc-scala3/build.sbt +++ b/sbt-app/src/sbt-test/actions/doc-scala3/build.sbt @@ -1,11 +1,9 @@ -lazy val m3 = (project in file("m3")) - .settings( - scalaVersion := "3.0.0-M3", - resolvers += Resolver.JCenterRepository - ) - lazy val rc1 = (project in file("rc1")) .settings( scalaVersion := "3.0.0-RC1" ) +lazy val a = project + .settings( + scalaVersion := "3.4.2", + ) diff --git a/sbt-app/src/sbt-test/actions/doc-scala3/test b/sbt-app/src/sbt-test/actions/doc-scala3/test index c13e97789c..064d840f40 100644 --- a/sbt-app/src/sbt-test/actions/doc-scala3/test +++ b/sbt-app/src/sbt-test/actions/doc-scala3/test @@ -6,10 +6,10 @@ $ exists rc1/target/scala-3.0.0-RC1/api/api/index.html $ exists rc1/target/scala-3.0.0-RC1/api/api/foo/A$.html $ exists rc1/target/scala-3.0.0-RC1/api/api/foo.html -> m3 / doc +> a / doc # there shouldn't be two api/ directories # see https://github.com/lampepfl/dotty/issues/11412 -$ exists m3/target/scala-3.0.0-M3/api/index.html -$ exists m3/target/scala-3.0.0-M3/api/api/foo/A$.html -$ exists m3/target/scala-3.0.0-M3/api/api/foo.html +$ exists a/target/scala-3.4.2/api/index.html +$ exists a/target/scala-3.4.2/api/foo/A$.html +$ exists a/target/scala-3.4.2/api/foo.html diff --git a/sbt-app/src/sbt-test/actions/doc/build.sbt b/sbt-app/src/sbt-test/actions/doc/build.sbt index c74f66a3e5..da46ccd465 100644 --- a/sbt-app/src/sbt-test/actions/doc/build.sbt +++ b/sbt-app/src/sbt-test/actions/doc/build.sbt @@ -5,8 +5,8 @@ import Parsers._ lazy val root = (project in file(".")) .settings( crossPaths := false, - crossScalaVersions := Seq("2.12.19", "2.13.12"), - scalaVersion := "2.12.19", + crossScalaVersions := Seq("2.12.20", "2.13.12"), + scalaVersion := "2.12.20", Compile / doc / scalacOptions += "-Xfatal-warnings", commands += Command.command("excludeB") { s => val impl = """val src = (sources in Compile).value; src.filterNot(_.getName.contains("B"))""" diff --git a/sbt-app/src/sbt-test/actions/generator/build.sbt b/sbt-app/src/sbt-test/actions/generator/build.sbt index 3fdd6bf4fb..3537ae7b09 100644 --- a/sbt-app/src/sbt-test/actions/generator/build.sbt +++ b/sbt-app/src/sbt-test/actions/generator/build.sbt @@ -1,6 +1,6 @@ val buildInfo = taskKey[Seq[File]]("generates the build info") -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/actions/multi-command/build.sbt b/sbt-app/src/sbt-test/actions/multi-command/build.sbt index 6853cdcfaa..606ba16573 100644 --- a/sbt-app/src/sbt-test/actions/multi-command/build.sbt +++ b/sbt-app/src/sbt-test/actions/multi-command/build.sbt @@ -19,4 +19,4 @@ val dynamicTask = taskKey[Unit]("dynamic input task") dynamicTask := { println("not yet et") } -crossScalaVersions := "2.11.12" :: "2.12.19" :: Nil +crossScalaVersions := "2.11.12" :: "2.12.20" :: Nil diff --git a/sbt-app/src/sbt-test/actions/multi-command/test b/sbt-app/src/sbt-test/actions/multi-command/test index 455953b6a4..323702a6d5 100644 --- a/sbt-app/src/sbt-test/actions/multi-command/test +++ b/sbt-app/src/sbt-test/actions/multi-command/test @@ -37,4 +37,4 @@ > ++ 2.11.12 compile; setStringValue bar; checkStringValue bar -> ++2.12.19 compile; setStringValue foo; checkStringValue foo +> ++2.12.20 compile; setStringValue foo; checkStringValue foo diff --git a/sbt-app/src/sbt-test/actions/package-delete-target/build.sbt b/sbt-app/src/sbt-test/actions/package-delete-target/build.sbt index b238d3d930..01163a404f 100644 --- a/sbt-app/src/sbt-test/actions/package-delete-target/build.sbt +++ b/sbt-app/src/sbt-test/actions/package-delete-target/build.sbt @@ -1,5 +1,5 @@ lazy val root = (project in file(".")) .settings( name := "delete-target", - scalaVersion := "2.12.19" + scalaVersion := "2.12.20" ) diff --git a/sbt-app/src/sbt-test/actions/remote-cache-semanticdb/build.sbt b/sbt-app/src/sbt-test/actions/remote-cache-semanticdb/build.sbt index fa9f2fbd75..3153cb66db 100644 --- a/sbt-app/src/sbt-test/actions/remote-cache-semanticdb/build.sbt +++ b/sbt-app/src/sbt-test/actions/remote-cache-semanticdb/build.sbt @@ -1,6 +1,6 @@ name := "my-project" -scalaVersion := "2.12.19" +scalaVersion := "2.12.20" semanticdbIncludeInJar := true diff --git a/sbt-app/src/sbt-test/actions/remote-cache/build.sbt b/sbt-app/src/sbt-test/actions/remote-cache/build.sbt index 2fdefcafc7..e99d9a8548 100644 --- a/sbt-app/src/sbt-test/actions/remote-cache/build.sbt +++ b/sbt-app/src/sbt-test/actions/remote-cache/build.sbt @@ -8,7 +8,7 @@ lazy val CustomArtifact = config("custom-artifact") val recordPreviousIterations = taskKey[Unit]("Record previous iterations.") val checkIterations = inputKey[Unit]("Verifies the accumulated number of iterations of incremental compilation.") -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" ThisBuild / pushRemoteCacheTo := Some( MavenCache("local-cache", (ThisBuild / baseDirectory).value / "r") ) diff --git a/sbt-app/src/sbt-test/actions/task-map/test b/sbt-app/src/sbt-test/actions/task-map/test index 3a88d40a75..a3bec9fa79 100644 --- a/sbt-app/src/sbt-test/actions/task-map/test +++ b/sbt-app/src/sbt-test/actions/task-map/test @@ -1,7 +1,7 @@ > taskB -$ exists target/b -$ exists target/a +$ exists target/**/b +$ exists target/**/a > taskF -$ exists target/e -$ exists target/f +$ exists target/**/e +$ exists target/**/f diff --git a/sbt-app/src/sbt-test/classloader-cache/akka-actor-system/build.sbt b/sbt-app/src/sbt-test/classloader-cache/akka-actor-system/build.sbt index b89e34a3fd..f2309bb9b6 100644 --- a/sbt-app/src/sbt-test/classloader-cache/akka-actor-system/build.sbt +++ b/sbt-app/src/sbt-test/classloader-cache/akka-actor-system/build.sbt @@ -2,7 +2,7 @@ ThisBuild / turbo := true val akkaTest = (project in file(".")).settings( name := "akka-test", - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", libraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-actor" % "2.5.16", "com.lihaoyi" %% "utest" % "0.6.6" % "test" diff --git a/sbt-app/src/sbt-test/classloader-cache/jni/build.sbt b/sbt-app/src/sbt-test/classloader-cache/jni/build.sbt index c4c6ce9993..abbc5b082c 100644 --- a/sbt-app/src/sbt-test/classloader-cache/jni/build.sbt +++ b/sbt-app/src/sbt-test/classloader-cache/jni/build.sbt @@ -13,7 +13,7 @@ def wrap(task: InputKey[Unit]): Def.Initialize[Task[Unit]] = ThisBuild / turbo := true val root = (project in file(".")).settings( - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", javacOptions ++= Seq("-source", "1.8", "-target", "1.8", "-h", sourceDirectory.value.toPath.resolve("main/native/include").toString), libraryDependencies += "com.lihaoyi" %% "utest" % "0.6.6" % "test", diff --git a/sbt-app/src/sbt-test/classloader-cache/library-mismatch/build.sbt b/sbt-app/src/sbt-test/classloader-cache/library-mismatch/build.sbt index dec40d3994..fb6fcaac00 100644 --- a/sbt-app/src/sbt-test/classloader-cache/library-mismatch/build.sbt +++ b/sbt-app/src/sbt-test/classloader-cache/library-mismatch/build.sbt @@ -2,7 +2,7 @@ ThisBuild / turbo := true val snapshot = (project in file(".")).settings( name := "mismatched-libraries", - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", libraryDependencies ++= Seq("com.lihaoyi" %% "utest" % "0.6.6" % "test"), testFrameworks := Seq(TestFramework("utest.runner.Framework")), resolvers += "Local Maven" at file("libraries/ivy").toURI.toURL.toString, diff --git a/sbt-app/src/sbt-test/classloader-cache/runtime-layers/build.sbt b/sbt-app/src/sbt-test/classloader-cache/runtime-layers/build.sbt index d029cd576b..215014a80f 100644 --- a/sbt-app/src/sbt-test/classloader-cache/runtime-layers/build.sbt +++ b/sbt-app/src/sbt-test/classloader-cache/runtime-layers/build.sbt @@ -1,6 +1,6 @@ val layeringStrategyTest = (project in file(".")).settings( name := "layering-strategy-test", - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", organization := "sbt", libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.5.16", ) diff --git a/sbt-app/src/sbt-test/classloader-cache/snapshot/build.sbt b/sbt-app/src/sbt-test/classloader-cache/snapshot/build.sbt index 2cd09fae63..3087df245e 100644 --- a/sbt-app/src/sbt-test/classloader-cache/snapshot/build.sbt +++ b/sbt-app/src/sbt-test/classloader-cache/snapshot/build.sbt @@ -9,7 +9,7 @@ ThisBuild / useCoursier := false val snapshot = (project in file(".")).settings( name := "akka-test", - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", libraryDependencies ++= Seq( "com.lihaoyi" %% "utest" % "0.6.6" % "test" ), diff --git a/sbt-app/src/sbt-test/classloader-cache/snapshot/libraries/library-1/ivy/sbt/foo-lib_2.12/0.1.0-SNAPSHOT/foo-lib_2.12-0.1.0-SNAPSHOT.pom b/sbt-app/src/sbt-test/classloader-cache/snapshot/libraries/library-1/ivy/sbt/foo-lib_2.12/0.1.0-SNAPSHOT/foo-lib_2.12-0.1.0-SNAPSHOT.pom index 233c03dbeb..f358077c95 100644 --- a/sbt-app/src/sbt-test/classloader-cache/snapshot/libraries/library-1/ivy/sbt/foo-lib_2.12/0.1.0-SNAPSHOT/foo-lib_2.12-0.1.0-SNAPSHOT.pom +++ b/sbt-app/src/sbt-test/classloader-cache/snapshot/libraries/library-1/ivy/sbt/foo-lib_2.12/0.1.0-SNAPSHOT/foo-lib_2.12-0.1.0-SNAPSHOT.pom @@ -14,7 +14,7 @@ org.scala-lang scala-library - 2.12.19 + 2.12.20 diff --git a/sbt-app/src/sbt-test/classloader-cache/snapshot/libraries/library-2/ivy/sbt/foo-lib_2.12/0.1.0-SNAPSHOT/foo-lib_2.12-0.1.0-SNAPSHOT.pom b/sbt-app/src/sbt-test/classloader-cache/snapshot/libraries/library-2/ivy/sbt/foo-lib_2.12/0.1.0-SNAPSHOT/foo-lib_2.12-0.1.0-SNAPSHOT.pom index 233c03dbeb..f358077c95 100644 --- a/sbt-app/src/sbt-test/classloader-cache/snapshot/libraries/library-2/ivy/sbt/foo-lib_2.12/0.1.0-SNAPSHOT/foo-lib_2.12-0.1.0-SNAPSHOT.pom +++ b/sbt-app/src/sbt-test/classloader-cache/snapshot/libraries/library-2/ivy/sbt/foo-lib_2.12/0.1.0-SNAPSHOT/foo-lib_2.12-0.1.0-SNAPSHOT.pom @@ -14,7 +14,7 @@ org.scala-lang scala-library - 2.12.19 + 2.12.20 diff --git a/sbt-app/src/sbt-test/classloader-cache/spark/build.sbt b/sbt-app/src/sbt-test/classloader-cache/spark/build.sbt index 43b6315d52..b105446d8f 100644 --- a/sbt-app/src/sbt-test/classloader-cache/spark/build.sbt +++ b/sbt-app/src/sbt-test/classloader-cache/spark/build.sbt @@ -2,7 +2,7 @@ name := "Simple Project" version := "1.0" -scalaVersion := "2.12.19" +scalaVersion := "2.12.20" libraryDependencies += "org.apache.spark" %% "spark-sql" % "2.4.3" diff --git a/sbt-app/src/sbt-test/classloader-cache/utest/build.sbt b/sbt-app/src/sbt-test/classloader-cache/utest/build.sbt index e504b97a7c..3691603200 100644 --- a/sbt-app/src/sbt-test/classloader-cache/utest/build.sbt +++ b/sbt-app/src/sbt-test/classloader-cache/utest/build.sbt @@ -2,7 +2,7 @@ ThisBuild / turbo := true val utestTest = (project in file(".")).settings( name := "utest-test", - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", libraryDependencies ++= Seq( "com.lihaoyi" %% "utest" % "0.6.6" % "test" ), diff --git a/sbt-app/src/sbt-test/compiler-project/error-in-invalidated/build.sbt b/sbt-app/src/sbt-test/compiler-project/error-in-invalidated/build.sbt index ba36bc767e..442a697f7c 100644 --- a/sbt-app/src/sbt-test/compiler-project/error-in-invalidated/build.sbt +++ b/sbt-app/src/sbt-test/compiler-project/error-in-invalidated/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")). settings( diff --git a/sbt-app/src/sbt-test/compiler-project/macro-config/build.sbt b/sbt-app/src/sbt-test/compiler-project/macro-config/build.sbt index f6c50838c3..114444c6fd 100644 --- a/sbt-app/src/sbt-test/compiler-project/macro-config/build.sbt +++ b/sbt-app/src/sbt-test/compiler-project/macro-config/build.sbt @@ -5,7 +5,7 @@ val Macro = config("macro").hide.extend(Compile) lazy val root = (project in file(".")) .settings( - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", // Adds a "macro" configuration for macro dependencies. ivyConfigurations.value += Macro, diff --git a/sbt-app/src/sbt-test/compiler-project/no-bootclasspath/test b/sbt-app/src/sbt-test/compiler-project/no-bootclasspath/test index a62a346985..59b1e34b35 100644 --- a/sbt-app/src/sbt-test/compiler-project/no-bootclasspath/test +++ b/sbt-app/src/sbt-test/compiler-project/no-bootclasspath/test @@ -1,4 +1,4 @@ > set scalaVersion := "2.13.12" > check213 -> set scalaVersion := "2.12.18" +> set scalaVersion := "2.12.20" > check212 diff --git a/sbt-app/src/sbt-test/compiler-project/run-test/build.sbt b/sbt-app/src/sbt-test/compiler-project/run-test/build.sbt index b13d3908c1..60bfe1f866 100644 --- a/sbt-app/src/sbt-test/compiler-project/run-test/build.sbt +++ b/sbt-app/src/sbt-test/compiler-project/run-test/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" libraryDependencies ++= Seq( "com.novocode" % "junit-interface" % "0.5" % Test, diff --git a/sbt-app/src/sbt-test/compiler-project/semantic-errors/build.sbt b/sbt-app/src/sbt-test/compiler-project/semantic-errors/build.sbt index 019d06f898..c861b159be 100644 --- a/sbt-app/src/sbt-test/compiler-project/semantic-errors/build.sbt +++ b/sbt-app/src/sbt-test/compiler-project/semantic-errors/build.sbt @@ -1,7 +1,7 @@ TaskKey[Unit]("checkJavaFailures") := { val reporter = savedReporter.value val ignore = (compile in Compile).failure.value - val ps = reporter.problems + val ps = reporter.problems.filter(_.severity() != xsbti.Severity.Info) assert(!ps.isEmpty, "Failed to report any problems!") // First error should be on a specific line/file val first = ps(0) diff --git a/sbt-app/src/sbt-test/compiler-project/separate-analysis-per-scala/build.sbt b/sbt-app/src/sbt-test/compiler-project/separate-analysis-per-scala/build.sbt index 5b50dc3902..bab8177e6d 100644 --- a/sbt-app/src/sbt-test/compiler-project/separate-analysis-per-scala/build.sbt +++ b/sbt-app/src/sbt-test/compiler-project/separate-analysis-per-scala/build.sbt @@ -1,4 +1,4 @@ -lazy val scala212 = "2.12.19" +lazy val scala212 = "2.12.20" lazy val scala213 = "2.13.12" ThisBuild / scalaVersion := scala212 diff --git a/sbt-app/src/sbt-test/console/project-compiler-bridge/project/build.sbt b/sbt-app/src/sbt-test/console/project-compiler-bridge/project/build.sbt index 8f50479761..76f36acc28 100644 --- a/sbt-app/src/sbt-test/console/project-compiler-bridge/project/build.sbt +++ b/sbt-app/src/sbt-test/console/project-compiler-bridge/project/build.sbt @@ -1 +1 @@ -scalaVersion := "2.12.19" +scalaVersion := "2.12.20" diff --git a/sbt-app/src/sbt-test/dependency-graph/cachedResolution/build.sbt b/sbt-app/src/sbt-test/dependency-graph/cachedResolution/build.sbt index 29548c20ec..4ecda4a163 100644 --- a/sbt-app/src/sbt-test/dependency-graph/cachedResolution/build.sbt +++ b/sbt-app/src/sbt-test/dependency-graph/cachedResolution/build.sbt @@ -1,4 +1,4 @@ -scalaVersion := "2.12.19" +scalaVersion := "2.12.20" libraryDependencies += "org.slf4j" % "slf4j-api" % "1.7.28" updateOptions := updateOptions.value.withCachedResolution(true) diff --git a/sbt-app/src/sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt b/sbt-app/src/sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt index bc11b4a404..c05b42e715 100644 --- a/sbt-app/src/sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt +++ b/sbt-app/src/sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt @@ -1,14 +1,27 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" libraryDependencies ++= Seq( "org.slf4j" % "slf4j-api" % "1.7.2", "ch.qos.logback" % "logback-classic" % "1.0.7" ) +csrMavenDependencyOverride := false TaskKey[Unit]("check") := { val report = updateFull.value val graph = (Test / dependencyTree / asString).value def sanitize(str: String): String = str.split('\n').drop(1).map(_.trim).mkString("\n") + +/* +Started to return: + +ch.qos.logback:logback-core:1.0.7 +default:sbt_8ae1da13_2.12:0.1.0-SNAPSHOT [S] + +-ch.qos.logback:logback-classic:1.0.7 + | +-org.slf4j:slf4j-api:1.6.6 (evicted by: 1.7.2) + | + +-org.slf4j:slf4j-api:1.7.2 +*/ + val expectedGraph = """default:default-e95e05_2.12:0.1-SNAPSHOT [S] | +-ch.qos.logback:logback-classic:1.0.7 diff --git a/sbt-app/src/sbt-test/dependency-graph/toFileSubTask/build.sbt b/sbt-app/src/sbt-test/dependency-graph/toFileSubTask/build.sbt index cfb2954847..66a6c1bff7 100644 --- a/sbt-app/src/sbt-test/dependency-graph/toFileSubTask/build.sbt +++ b/sbt-app/src/sbt-test/dependency-graph/toFileSubTask/build.sbt @@ -1,5 +1,5 @@ // ThisBuild / useCoursier := false -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" ThisBuild / organization := "org.example" ThisBuild / version := "0.1" diff --git a/sbt-app/src/sbt-test/dependency-management/artifact/build.sbt b/sbt-app/src/sbt-test/dependency-management/artifact/build.sbt index c4493475ee..077b2a06be 100644 --- a/sbt-app/src/sbt-test/dependency-management/artifact/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/artifact/build.sbt @@ -6,7 +6,7 @@ lazy val check = taskKey[Unit]("") lazy val checkArtifact = taskKey[Unit]("") ThisBuild / useCoursier := false -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" ThisBuild / version := "0.1.0-SNAPSHOT" ThisBuild / organization := "com.example" ThisBuild / organizationName := "example" diff --git a/sbt-app/src/sbt-test/dependency-management/cache-classifiers/multi.sbt b/sbt-app/src/sbt-test/dependency-management/cache-classifiers/multi.sbt index 2caee109af..f84a40e2b4 100644 --- a/sbt-app/src/sbt-test/dependency-management/cache-classifiers/multi.sbt +++ b/sbt-app/src/sbt-test/dependency-management/cache-classifiers/multi.sbt @@ -1,6 +1,6 @@ import xsbti.AppConfiguration -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" // TTL of Coursier is 24h ThisBuild / useCoursier := false diff --git a/sbt-app/src/sbt-test/dependency-management/cached-resolution-interproj/multi.sbt b/sbt-app/src/sbt-test/dependency-management/cached-resolution-interproj/multi.sbt index b6d099632a..2ea6028a3e 100644 --- a/sbt-app/src/sbt-test/dependency-management/cached-resolution-interproj/multi.sbt +++ b/sbt-app/src/sbt-test/dependency-management/cached-resolution-interproj/multi.sbt @@ -3,7 +3,7 @@ lazy val check = taskKey[Unit]("Runs the check") val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" val junit = "junit" % "junit" % "4.13.1" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" ThisBuild / csrCacheDirectory := (ThisBuild / baseDirectory).value / "coursier-cache" def commonSettings: Seq[Def.Setting[_]] = diff --git a/sbt-app/src/sbt-test/dependency-management/compiler-bridge-binary/build.sbt b/sbt-app/src/sbt-test/dependency-management/compiler-bridge-binary/build.sbt index 59aad4118c..f9cf8fddd8 100644 --- a/sbt-app/src/sbt-test/dependency-management/compiler-bridge-binary/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/compiler-bridge-binary/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val check = taskKey[Unit]("") diff --git a/sbt-app/src/sbt-test/dependency-management/conflict-coursier/build.sbt b/sbt-app/src/sbt-test/dependency-management/conflict-coursier/build.sbt index 436ed6e367..19d25ed0b1 100644 --- a/sbt-app/src/sbt-test/dependency-management/conflict-coursier/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/conflict-coursier/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" libraryDependencies ++= List( "org.webjars.npm" % "randomatic" % "1.1.7", "org.webjars.npm" % "is-odd" % "2.0.0", diff --git a/sbt-app/src/sbt-test/dependency-management/ext-pom-classifier/build.sbt b/sbt-app/src/sbt-test/dependency-management/ext-pom-classifier/build.sbt index 00bb5f7d57..9ac56bac55 100644 --- a/sbt-app/src/sbt-test/dependency-management/ext-pom-classifier/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/ext-pom-classifier/build.sbt @@ -2,6 +2,6 @@ ThisBuild / useCoursier := false lazy val root = (project in file(".")) .settings( - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", externalPom() ) diff --git a/sbt-app/src/sbt-test/dependency-management/force-update-period/build.sbt b/sbt-app/src/sbt-test/dependency-management/force-update-period/build.sbt index 23d58d7d1b..a6a4664652 100644 --- a/sbt-app/src/sbt-test/dependency-management/force-update-period/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/force-update-period/build.sbt @@ -1,7 +1,7 @@ ThisBuild / useCoursier := false name := "force-update-period" -scalaVersion := "2.12.18" +scalaVersion := "2.12.20" libraryDependencies += "log4j" % "log4j" % "1.2.16" % "compile" autoScalaLibrary := false diff --git a/sbt-app/src/sbt-test/dependency-management/global-plugins/build.sbt b/sbt-app/src/sbt-test/dependency-management/global-plugins/build.sbt index 8f50479761..76f36acc28 100644 --- a/sbt-app/src/sbt-test/dependency-management/global-plugins/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/global-plugins/build.sbt @@ -1 +1 @@ -scalaVersion := "2.12.19" +scalaVersion := "2.12.20" diff --git a/sbt-app/src/sbt-test/dependency-management/snapshot-local/build.sbt b/sbt-app/src/sbt-test/dependency-management/snapshot-local/build.sbt index 5b887b7d6a..15ac28821b 100644 --- a/sbt-app/src/sbt-test/dependency-management/snapshot-local/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/snapshot-local/build.sbt @@ -1,5 +1,5 @@ ThisBuild / organization := "com.example" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" ThisBuild / csrCacheDirectory := (ThisBuild / baseDirectory).value / "coursier-cache" def customIvyPaths: Seq[Def.Setting[_]] = Seq( diff --git a/sbt-app/src/sbt-test/dependency-management/snapshot-resolution/build.sbt b/sbt-app/src/sbt-test/dependency-management/snapshot-resolution/build.sbt index 4373ff66de..a129fcdf30 100644 --- a/sbt-app/src/sbt-test/dependency-management/snapshot-resolution/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/snapshot-resolution/build.sbt @@ -1,5 +1,5 @@ ThisBuild / organization := "com.example" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" // TTL is 24h so we can't detect the change ThisBuild / useCoursier := false diff --git a/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/a/A.scala b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/a/A.scala new file mode 100644 index 0000000000..c66551e1bd --- /dev/null +++ b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/a/A.scala @@ -0,0 +1,27 @@ +import scala.language.reflectiveCalls + + +package scala.collection.immutable { + object Exp { + // Access RedBlackTree.validate added in Scala 2.13.13 + def v = RedBlackTree.validate(null)(null) + } +} + + +object A extends App { + println(scala.util.Properties.versionString) +} + +object AMacro { + import scala.language.experimental.macros + import scala.reflect.macros.blackbox.Context + + def m(x: Int): Int = macro impl + + def impl(c: Context)(x: c.Expr[Int]): c.Expr[Int] = { + import c.universe._ + println(scala.collection.immutable.Exp.v) + c.Expr(q"2 + $x") + } +} diff --git a/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/b/B.scala b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/b/B.scala new file mode 100644 index 0000000000..f75b7905ef --- /dev/null +++ b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/b/B.scala @@ -0,0 +1,7 @@ +import java.nio.file.{Paths, Files} +import java.nio.charset.StandardCharsets + +object B extends App { + println(AMacro.m(33)) // fails + Files.write(Paths.get(s"s${scala.util.Properties.versionNumberString}.txt"), "nix".getBytes) +} diff --git a/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/build.sbt b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/build.sbt new file mode 100644 index 0000000000..c757f26481 --- /dev/null +++ b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/build.sbt @@ -0,0 +1,39 @@ +import sbt.librarymanagement.InclExclRule + +lazy val a = project.settings( + scalaVersion := "2.13.13", + libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value, + TaskKey[Unit]("checkLibs") := checkLibs("2.13.13", (Compile/dependencyClasspath).value, ".*scala-(library|reflect).*"), +) + +lazy val b = project.dependsOn(a).settings( + allowUnsafeScalaLibUpgrade := true, + scalaVersion := "2.13.12", + + // dependencies are upgraded to 2.13.13 + TaskKey[Unit]("checkLibs") := checkLibs("2.13.13", (Compile/dependencyClasspath).value, ".*scala-(library|reflect).*"), + + // check the compiler uses the 2.13.12 library on its runtime classpath + TaskKey[Unit]("checkScala") := { + val i = scalaInstance.value + i.libraryJars.filter(_.toString.contains("scala-library")).toList match { + case List(l) => assert(l.toString.contains("2.13.12"), i.toString) + } + assert(i.compilerJars.filter(_.toString.contains("scala-library")).isEmpty, i.toString) + assert(i.otherJars.filter(_.toString.contains("scala-library")).isEmpty, i.toString) + }, +) + +lazy val c = project.dependsOn(a).settings( + allowUnsafeScalaLibUpgrade := true, + scalaVersion := "2.13.12", + TaskKey[Unit]("checkLibs") := checkLibs("2.13.13", (Compile/dependencyClasspath).value, ".*scala-(library|reflect).*"), +) + +def checkLibs(v: String, cp: Classpath, filter: String): Unit = { + for (p <- cp) + if (p.toString.matches(filter)) { + println(s"$p -- $v") + assert(p.toString.contains(v), p) + } +} diff --git a/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/c/C.scala b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/c/C.scala new file mode 100644 index 0000000000..de0f7c0848 --- /dev/null +++ b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/c/C.scala @@ -0,0 +1,7 @@ +import java.nio.file.{Paths, Files} +import java.nio.charset.StandardCharsets + +object C extends App { + assert(scala.collection.immutable.Exp.v == null) + Files.write(Paths.get(s"s${scala.util.Properties.versionNumberString}.txt"), "nix".getBytes) +} diff --git a/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/test b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/test new file mode 100644 index 0000000000..f347b35342 --- /dev/null +++ b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze-warn/test @@ -0,0 +1,11 @@ +> a/checkLibs +> b/checkLibs +> b/checkScala +> c/checkLibs + +# macro expansion fails +-> b/compile + +> c/run +$ exists s2.13.13.txt +$ delete s2.13.13.txt diff --git a/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/a3/A.scala b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/a3/A.scala index e6f35a100d..600c113791 100644 --- a/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/a3/A.scala +++ b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/a3/A.scala @@ -1,16 +1,24 @@ import scala.quoted.* // imports Quotes, Expr -package scala.collection { - object Exp: - // added in 2.13.10, not available in 2.13.8 - def m(i: Int) = IterableOnce.checkArraySizeWithinVMLimit(i) +package scala.collection.immutable { + object Exp { + // Access RedBlackTree.validate and Tree class added in Scala 2.13.13 + // Scala 3.3.4 uses Scala 2.13.14 library + // Scala 3.3.2 uses Scala 2.13.12 library + // Hence RedBlackTree.validate is available in 3.3.4 but not in 3.3.2 + // c.c. https://mvnrepository.com/artifact/org.scala-lang/scala3-library_3/3.3.2 + // c.c. https://mvnrepository.com/artifact/org.scala-lang/scala3-library_3/3.3.4 + def validateTree[A](tree: RedBlackTree.Tree[A, _])(implicit ordering: Ordering[A]): tree.type = { + RedBlackTree.validate(tree) + } + } } object Mac: inline def inspect(inline x: Any): Any = ${ inspectCode('x) } def inspectCode(x: Expr[Any])(using Quotes): Expr[Any] = - scala.collection.Exp.m(42) + scala.collection.immutable.Exp.validateTree(null)(null) println(x.show) x diff --git a/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/build.sbt b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/build.sbt index 901101ceab..ab04ff427d 100644 --- a/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/build.sbt @@ -1,26 +1,26 @@ import sbt.librarymanagement.InclExclRule lazy val a = project.settings( - scalaVersion := "2.13.6", + scalaVersion := "2.13.11", libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value, - TaskKey[Unit]("checkLibs") := checkLibs("2.13.6", (Compile/dependencyClasspath).value, ".*scala-(library|reflect).*"), + TaskKey[Unit]("checkLibs") := checkLibs("2.13.11", (Compile/dependencyClasspath).value, ".*scala-(library|reflect).*"), ) lazy val b = project.dependsOn(a).settings( - scalaVersion := "2.13.8", - TaskKey[Unit]("checkLibs") := checkLibs("2.13.8", (Compile/dependencyClasspath).value, ".*scala-(library|reflect).*"), + scalaVersion := "2.13.12", + TaskKey[Unit]("checkLibs") := checkLibs("2.13.12", (Compile/dependencyClasspath).value, ".*scala-(library|reflect).*"), ) lazy val a3 = project.settings( - scalaVersion := "3.2.2", // 2.13.10 library + scalaVersion := "3.3.4", // 2.13.14 library ) lazy val b3 = project.dependsOn(a3).settings( - scalaVersion := "3.2.0", // 2.13.8 library + scalaVersion := "3.3.2", // 2.13.12 library TaskKey[Unit]("checkScala") := { val i = scalaInstance.value i.libraryJars.filter(_.toString.contains("scala-library")).toList match { - case List(l) => assert(l.toString.contains("2.13.10"), i.toString) + case List(l) => assert(l.toString.contains("2.13.14"), i.toString) } assert(i.compilerJars.filter(_.toString.contains("scala-library")).isEmpty, i.toString) assert(i.otherJars.filter(_.toString.contains("scala-library")).isEmpty, i.toString) diff --git a/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/test b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/test index 7df93ab6c4..8eb1734632 100644 --- a/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/test +++ b/sbt-app/src/sbt-test/dependency-management/stdlib-unfreeze/test @@ -2,17 +2,17 @@ > b/checkLibs > b/run -$ exists s2.13.8.txt -$ delete s2.13.8.txt +$ exists s2.13.12.txt +$ delete s2.13.12.txt # don't crash when expanding the macro > b3/run -$ exists s2.13.10.txt -$ delete s2.13.10.txt +$ exists s2.13.14.txt +$ delete s2.13.14.txt > b3/checkScala -# without the default `csrSameVersions`, scala-reflect in b stays at 2.13.6 +# without the default `csrSameVersions`, scala-reflect in b stays at 2.13.11 > set b/csrSameVersions := Nil > b/update -> b/checkLibs diff --git a/sbt-app/src/sbt-test/java/cross/build.sbt b/sbt-app/src/sbt-test/java/cross/build.sbt index b5f39d15e6..cbb55bd7df 100644 --- a/sbt-app/src/sbt-test/java/cross/build.sbt +++ b/sbt-app/src/sbt-test/java/cross/build.sbt @@ -4,7 +4,7 @@ val check = inputKey[Unit]("Runs the check") lazy val root = (project in file(".")) .settings( - ThisBuild / scalaVersion := "2.12.19", + ThisBuild / scalaVersion := "2.12.20", crossJavaVersions := List("1.8"), // read out.txt and see if it starts with the passed in number diff --git a/sbt-app/src/sbt-test/java/cross/changes/build.sbt b/sbt-app/src/sbt-test/java/cross/changes/build.sbt index 9facfdb8de..2d09de654d 100644 --- a/sbt-app/src/sbt-test/java/cross/changes/build.sbt +++ b/sbt-app/src/sbt-test/java/cross/changes/build.sbt @@ -4,7 +4,7 @@ val check = inputKey[Unit]("Runs the check") lazy val root = (project in file(".")) .settings( - ThisBuild / scalaVersion := "2.12.19", + ThisBuild / scalaVersion := "2.12.20", crossJavaVersions := List("1.8", "10"), // read out.txt and see if it starts with the passed in number diff --git a/sbt-app/src/sbt-test/plugins/doc-scala3-js/build.sbt b/sbt-app/src/sbt-test/plugins/doc-scala3-js/build.sbt index af0c707973..177518aa87 100644 --- a/sbt-app/src/sbt-test/plugins/doc-scala3-js/build.sbt +++ b/sbt-app/src/sbt-test/plugins/doc-scala3-js/build.sbt @@ -1,4 +1,4 @@ -val scala3Version = "3.0.1-RC1-bin-20210525-8f3fdf5-NIGHTLY" +val scala3Version = "3.3.4" enablePlugins(ScalaJSPlugin) diff --git a/sbt-app/src/sbt-test/plugins/doc-scala3-js/project/plugins.sbt b/sbt-app/src/sbt-test/plugins/doc-scala3-js/project/plugins.sbt index c16aefc537..a42ace5f7d 100644 --- a/sbt-app/src/sbt-test/plugins/doc-scala3-js/project/plugins.sbt +++ b/sbt-app/src/sbt-test/plugins/doc-scala3-js/project/plugins.sbt @@ -1 +1 @@ -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.5.1") \ No newline at end of file +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.17.0") \ No newline at end of file diff --git a/sbt-app/src/sbt-test/plugins/dotty-sandwich-sjs/build.sbt b/sbt-app/src/sbt-test/plugins/dotty-sandwich-sjs/build.sbt index 5fd5c06b81..aa25b680ea 100644 --- a/sbt-app/src/sbt-test/plugins/dotty-sandwich-sjs/build.sbt +++ b/sbt-app/src/sbt-test/plugins/dotty-sandwich-sjs/build.sbt @@ -1,15 +1,15 @@ -ThisBuild / scalaVersion := "2.13.12" +ThisBuild / scalaVersion := "2.13.15" ThisBuild / scalacOptions += "-Ytasty-reader" lazy val scala3code = project .enablePlugins(ScalaJSPlugin) - .settings(scalaVersion := "3.1.3") + .settings(scalaVersion := "3.3.4") lazy val app = project .enablePlugins(ScalaJSPlugin) .dependsOn(scala3code) .settings( libraryDependencies ~= (_.filterNot(_.name.contains("scalajs-compiler"))), - addCompilerPlugin("org.scala-js" % "scalajs-compiler_2.13.8" % scalaJSVersion), + addCompilerPlugin("org.scala-js" % "scalajs-compiler_2.13.15" % scalaJSVersion), scalaJSUseMainModuleInitializer := true, ) diff --git a/sbt-app/src/sbt-test/plugins/dotty-sandwich-sjs/project/plugins.sbt b/sbt-app/src/sbt-test/plugins/dotty-sandwich-sjs/project/plugins.sbt index 4c620dc0af..b3f269753d 100644 --- a/sbt-app/src/sbt-test/plugins/dotty-sandwich-sjs/project/plugins.sbt +++ b/sbt-app/src/sbt-test/plugins/dotty-sandwich-sjs/project/plugins.sbt @@ -1 +1 @@ -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.1") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.17.0") diff --git a/sbt-app/src/sbt-test/plugins/dotty-sandwich/build.sbt b/sbt-app/src/sbt-test/plugins/dotty-sandwich/build.sbt index a8e2060071..f3ee7e93e8 100644 --- a/sbt-app/src/sbt-test/plugins/dotty-sandwich/build.sbt +++ b/sbt-app/src/sbt-test/plugins/dotty-sandwich/build.sbt @@ -1,7 +1,7 @@ -ThisBuild / scalaVersion := "3.1.3" +ThisBuild / scalaVersion := "3.3.4" ThisBuild / scalacOptions += "-Ytasty-reader" -lazy val scala213 = "2.13.12" +lazy val scala213 = "2.13.15" lazy val root = (project in file(".")) .aggregate(fooApp, fooCore, barApp, barCore) diff --git a/sbt-app/src/sbt-test/plugins/dotty/build.sbt b/sbt-app/src/sbt-test/plugins/dotty/build.sbt index e46913668d..48a4f88fe0 100644 --- a/sbt-app/src/sbt-test/plugins/dotty/build.sbt +++ b/sbt-app/src/sbt-test/plugins/dotty/build.sbt @@ -1 +1 @@ -ThisBuild / scalaVersion := "3.1.3" +ThisBuild / scalaVersion := "3.3.4" diff --git a/sbt-app/src/sbt-test/plugins/hydra/build.sbt b/sbt-app/src/sbt-test/plugins/hydra/build.sbt index efc3b0a27d..9ee405caa0 100644 --- a/sbt-app/src/sbt-test/plugins/hydra/build.sbt +++ b/sbt-app/src/sbt-test/plugins/hydra/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val check = taskKey[Unit]("") diff --git a/sbt-app/src/sbt-test/plugins/sbt-native-packager/build.sbt b/sbt-app/src/sbt-test/plugins/sbt-native-packager/build.sbt index 202a48a915..7783ed396b 100644 --- a/sbt-app/src/sbt-test/plugins/sbt-native-packager/build.sbt +++ b/sbt-app/src/sbt-test/plugins/sbt-native-packager/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" name := "hello" enablePlugins(JavaAppPackaging) diff --git a/sbt-app/src/sbt-test/plugins/scala-js-macro/build.sbt b/sbt-app/src/sbt-test/plugins/scala-js-macro/build.sbt index ff4eb16f37..1039576e3e 100644 --- a/sbt-app/src/sbt-test/plugins/scala-js-macro/build.sbt +++ b/sbt-app/src/sbt-test/plugins/scala-js-macro/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.13.1" +ThisBuild / scalaVersion := "2.13.15" lazy val root = (project in file(".")) .aggregate(macroProvider, macroClient) diff --git a/sbt-app/src/sbt-test/plugins/scala-js-macro/project/plugins.sbt b/sbt-app/src/sbt-test/plugins/scala-js-macro/project/plugins.sbt index 8365c11cc3..b3f269753d 100644 --- a/sbt-app/src/sbt-test/plugins/scala-js-macro/project/plugins.sbt +++ b/sbt-app/src/sbt-test/plugins/scala-js-macro/project/plugins.sbt @@ -1 +1 @@ -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.0.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.17.0") diff --git a/sbt-app/src/sbt-test/plugins/unidoc/build.sbt b/sbt-app/src/sbt-test/plugins/unidoc/build.sbt index 2abb1992d7..afa976179c 100644 --- a/sbt-app/src/sbt-test/plugins/unidoc/build.sbt +++ b/sbt-app/src/sbt-test/plugins/unidoc/build.sbt @@ -1,4 +1,4 @@ -scalaVersion := "2.12.19" +scalaVersion := "2.12.20" scalacOptions += "-Xfatal-warnings" // required for the test enablePlugins(ScalaUnidocPlugin) diff --git a/sbt-app/src/sbt-test/project/aggregate/projA/build.sbt b/sbt-app/src/sbt-test/project/aggregate/projA/build.sbt index b12345076b..af30eb1d06 100644 --- a/sbt-app/src/sbt-test/project/aggregate/projA/build.sbt +++ b/sbt-app/src/sbt-test/project/aggregate/projA/build.sbt @@ -1,3 +1,3 @@ name := "projA" -scalaVersion := "2.12.19" +scalaVersion := "2.12.20" diff --git a/sbt-app/src/sbt-test/project/cross-plugins-defaults/build.sbt b/sbt-app/src/sbt-test/project/cross-plugins-defaults/build.sbt index 9ea6db60dd..d0b8f19125 100644 --- a/sbt-app/src/sbt-test/project/cross-plugins-defaults/build.sbt +++ b/sbt-app/src/sbt-test/project/cross-plugins-defaults/build.sbt @@ -1,7 +1,7 @@ val baseSbt = "1." -val buildCrossList = List("2.10.7", "2.11.12", "2.12.19") -scalaVersion in ThisBuild := "2.12.19" +val buildCrossList = List("2.10.7", "2.11.12", "2.12.20") +scalaVersion in ThisBuild := "2.12.20" crossScalaVersions in ThisBuild := buildCrossList addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.7.0") diff --git a/sbt-app/src/sbt-test/project/flatten/build.sbt b/sbt-app/src/sbt-test/project/flatten/build.sbt index 8f8e73e646..518c06e194 100644 --- a/sbt-app/src/sbt-test/project/flatten/build.sbt +++ b/sbt-app/src/sbt-test/project/flatten/build.sbt @@ -1,6 +1,6 @@ val unpackage = TaskKey[Unit]("unpackage") -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/project/internal-tracking/build.sbt b/sbt-app/src/sbt-test/project/internal-tracking/build.sbt index 711d9f88a4..c34f007b56 100644 --- a/sbt-app/src/sbt-test/project/internal-tracking/build.sbt +++ b/sbt-app/src/sbt-test/project/internal-tracking/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" ThisBuild / trackInternalDependencies := TrackLevel.NoTracking lazy val root = (project in file(".")) diff --git a/sbt-app/src/sbt-test/project/sbt-plugin/build.sbt b/sbt-app/src/sbt-test/project/sbt-plugin/build.sbt index 681686b5ad..3b1ec53286 100644 --- a/sbt-app/src/sbt-test/project/sbt-plugin/build.sbt +++ b/sbt-app/src/sbt-test/project/sbt-plugin/build.sbt @@ -1,6 +1,6 @@ lazy val root = project.in(file(".")) .enablePlugins(SbtPlugin) .settings( - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", scalacOptions ++= Seq("-Xfatal-warnings", "-Xlint") ) diff --git a/sbt-app/src/sbt-test/project/sbt-plugin/changes/oldSbtPlugin.sbt b/sbt-app/src/sbt-test/project/sbt-plugin/changes/oldSbtPlugin.sbt index 7b654c1964..1738ee9a5c 100644 --- a/sbt-app/src/sbt-test/project/sbt-plugin/changes/oldSbtPlugin.sbt +++ b/sbt-app/src/sbt-test/project/sbt-plugin/changes/oldSbtPlugin.sbt @@ -1,6 +1,6 @@ lazy val root = project.in(file(".")) .settings( - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", sbtPlugin := true, scalacOptions ++= Seq("-Xfatal-warnings", "-Xlint") ) diff --git a/sbt-app/src/sbt-test/project/scala3-cross-target/build.sbt b/sbt-app/src/sbt-test/project/scala3-cross-target/build.sbt index d87ccac1b6..4550b3c07a 100644 --- a/sbt-app/src/sbt-test/project/scala3-cross-target/build.sbt +++ b/sbt-app/src/sbt-test/project/scala3-cross-target/build.sbt @@ -1,3 +1,3 @@ -scalaVersion := "3.0.0-RC2-bin-20210328-cca5f8f-NIGHTLY" +scalaVersion := "3.3.4" name := "foo" version := "1.0.0" diff --git a/sbt-app/src/sbt-test/project/scala3-cross-target/test b/sbt-app/src/sbt-test/project/scala3-cross-target/test index ff09e0f19e..5509f79c25 100644 --- a/sbt-app/src/sbt-test/project/scala3-cross-target/test +++ b/sbt-app/src/sbt-test/project/scala3-cross-target/test @@ -1,7 +1,7 @@ > compile -$ exists target/scala-3.0.0-RC2-bin-20210328-cca5f8f-NIGHTLY/classes/Foo$.class +$ exists target/scala-3.3.4/classes/Foo$.class > package -$ exists target/scala-3.0.0-RC2-bin-20210328-cca5f8f-NIGHTLY/foo_3.0.0-RC2-1.0.0.jar +$ exists target/scala-3.3.4/foo_3-1.0.0.jar diff --git a/sbt-app/src/sbt-test/project/scala3-sandwich-sjs/build.sbt b/sbt-app/src/sbt-test/project/scala3-sandwich-sjs/build.sbt index 661ac82a1a..88ccf3d59f 100644 --- a/sbt-app/src/sbt-test/project/scala3-sandwich-sjs/build.sbt +++ b/sbt-app/src/sbt-test/project/scala3-sandwich-sjs/build.sbt @@ -1,15 +1,15 @@ -ThisBuild / scalaVersion := "2.13.6" +ThisBuild / scalaVersion := "2.13.15" ThisBuild / scalacOptions += "-Ytasty-reader" lazy val scala3code = project .enablePlugins(ScalaJSPlugin) - .settings(scalaVersion := "3.0.0") + .settings(scalaVersion := "3.3.4") lazy val app = project .enablePlugins(ScalaJSPlugin) .dependsOn(scala3code) .settings( - scalaVersion := "2.13.6", + scalaVersion := "2.13.15", scalacOptions += "-Ytasty-reader", scalaJSUseMainModuleInitializer := true ) diff --git a/sbt-app/src/sbt-test/project/scala3-sandwich-sjs/project/plugins.sbt b/sbt-app/src/sbt-test/project/scala3-sandwich-sjs/project/plugins.sbt index 56abd248d0..b3f269753d 100644 --- a/sbt-app/src/sbt-test/project/scala3-sandwich-sjs/project/plugins.sbt +++ b/sbt-app/src/sbt-test/project/scala3-sandwich-sjs/project/plugins.sbt @@ -1 +1 @@ -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.6.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.17.0") diff --git a/sbt-app/src/sbt-test/project/scala3-sandwich/build.sbt b/sbt-app/src/sbt-test/project/scala3-sandwich/build.sbt index 75988d69da..79f714e288 100644 --- a/sbt-app/src/sbt-test/project/scala3-sandwich/build.sbt +++ b/sbt-app/src/sbt-test/project/scala3-sandwich/build.sbt @@ -1,6 +1,6 @@ -ThisBuild / scalaVersion := "3.0.0" +ThisBuild / scalaVersion := "3.3.4" -lazy val scala213 = "2.13.6" +lazy val scala213 = "2.13.15" lazy val root = (project in file(".")) .aggregate(fooApp, fooCore, barApp, barCore) diff --git a/sbt-app/src/sbt-test/project/scripted13/test b/sbt-app/src/sbt-test/project/scripted13/test index 1617a03a4a..2fd6077fb1 100644 --- a/sbt-app/src/sbt-test/project/scripted13/test +++ b/sbt-app/src/sbt-test/project/scripted13/test @@ -1,6 +1,6 @@ # This tests that this sbt scripted plugin can launch the previous one -> ^^0.13.18 +> ^^1.10.7 $ copy-file changes/A.scala src/sbt-test/a/b/A.scala > scripted diff --git a/sbt-app/src/sbt-test/project/semanticdb/build.sbt b/sbt-app/src/sbt-test/project/semanticdb/build.sbt index fcc03b2ec0..03ad56d268 100644 --- a/sbt-app/src/sbt-test/project/semanticdb/build.sbt +++ b/sbt-app/src/sbt-test/project/semanticdb/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" ThisBuild / semanticdbEnabled := true ThisBuild / semanticdbIncludeInJar := true diff --git a/sbt-app/src/sbt-test/project/unified/build.sbt b/sbt-app/src/sbt-test/project/unified/build.sbt index 18ae6cfce6..cbb5585729 100644 --- a/sbt-app/src/sbt-test/project/unified/build.sbt +++ b/sbt-app/src/sbt-test/project/unified/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" import sbt.internal.CommandStrings.{ inspectBrief, inspectDetailed } import sbt.internal.Inspect diff --git a/sbt-app/src/sbt-test/run/fork-loader/build.sbt b/sbt-app/src/sbt-test/run/fork-loader/build.sbt index c5b8530f1b..b440e9f310 100644 --- a/sbt-app/src/sbt-test/run/fork-loader/build.sbt +++ b/sbt-app/src/sbt-test/run/fork-loader/build.sbt @@ -1,6 +1,6 @@ val scalcheck = "org.scalacheck" %% "scalacheck" % "1.14.0" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/source-dependencies/binary/build.sbt b/sbt-app/src/sbt-test/source-dependencies/binary/build.sbt index 4dc26da4a3..dbf8e86104 100644 --- a/sbt-app/src/sbt-test/source-dependencies/binary/build.sbt +++ b/sbt-app/src/sbt-test/source-dependencies/binary/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val dep = project diff --git a/sbt-app/src/sbt-test/source-dependencies/constants/test b/sbt-app/src/sbt-test/source-dependencies/constants/test index ff8815d859..8f027dbf23 100644 --- a/sbt-app/src/sbt-test/source-dependencies/constants/test +++ b/sbt-app/src/sbt-test/source-dependencies/constants/test @@ -1,4 +1,4 @@ -> ++2.12.19! +> ++2.12.20! $ copy-file changes/B.scala B.scala diff --git a/sbt-app/src/sbt-test/source-dependencies/cross-source/test b/sbt-app/src/sbt-test/source-dependencies/cross-source/test index 53348a66c3..21b560de7a 100644 --- a/sbt-app/src/sbt-test/source-dependencies/cross-source/test +++ b/sbt-app/src/sbt-test/source-dependencies/cross-source/test @@ -1,3 +1,3 @@ # A.scala needs B.scala, it would be in source list -> ++2.12.19! +> ++2.12.20! > compile diff --git a/sbt-app/src/sbt-test/source-dependencies/false-error/test b/sbt-app/src/sbt-test/source-dependencies/false-error/pending similarity index 100% rename from sbt-app/src/sbt-test/source-dependencies/false-error/test rename to sbt-app/src/sbt-test/source-dependencies/false-error/pending diff --git a/sbt-app/src/sbt-test/source-dependencies/macro-annotation/build.sbt b/sbt-app/src/sbt-test/source-dependencies/macro-annotation/build.sbt index 42ffe9799f..45d6045fe6 100644 --- a/sbt-app/src/sbt-test/source-dependencies/macro-annotation/build.sbt +++ b/sbt-app/src/sbt-test/source-dependencies/macro-annotation/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" val paradiseVersion = "2.1.1" val commonSettings = Seq( diff --git a/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep-nested/build.sbt b/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep-nested/build.sbt index 4e08091238..cd1f0fda46 100644 --- a/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep-nested/build.sbt +++ b/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep-nested/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" val defaultSettings = Seq( libraryDependencies += scalaVersion("org.scala-lang" % "scala-reflect" % _ ).value diff --git a/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep-stackoverflow/build.sbt b/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep-stackoverflow/build.sbt index 4e08091238..cd1f0fda46 100644 --- a/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep-stackoverflow/build.sbt +++ b/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep-stackoverflow/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" val defaultSettings = Seq( libraryDependencies += scalaVersion("org.scala-lang" % "scala-reflect" % _ ).value diff --git a/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep/build.sbt b/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep/build.sbt index 4e08091238..cd1f0fda46 100644 --- a/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep/build.sbt +++ b/sbt-app/src/sbt-test/source-dependencies/macro-arg-dep/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" val defaultSettings = Seq( libraryDependencies += scalaVersion("org.scala-lang" % "scala-reflect" % _ ).value diff --git a/sbt-app/src/sbt-test/source-dependencies/macro/build.sbt b/sbt-app/src/sbt-test/source-dependencies/macro/build.sbt index 4e08091238..cd1f0fda46 100644 --- a/sbt-app/src/sbt-test/source-dependencies/macro/build.sbt +++ b/sbt-app/src/sbt-test/source-dependencies/macro/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" val defaultSettings = Seq( libraryDependencies += scalaVersion("org.scala-lang" % "scala-reflect" % _ ).value diff --git a/sbt-app/src/sbt-test/source-dependencies/pipelining/build.sbt b/sbt-app/src/sbt-test/source-dependencies/pipelining/build.sbt index 96b5b5a17a..25dfae3964 100644 --- a/sbt-app/src/sbt-test/source-dependencies/pipelining/build.sbt +++ b/sbt-app/src/sbt-test/source-dependencies/pipelining/build.sbt @@ -17,6 +17,6 @@ lazy val use = project val x = (dep / Compile / compile).value val picklePath = (Compile / internalDependencyPicklePath).value assert(picklePath.size == 1 && - picklePath.head.data.name == "dep_2.13-0.1.0-SNAPSHOT.jar", s"picklePath = ${picklePath}") + picklePath.head.data.name == "early.jar", s"picklePath = ${picklePath}") }, ) diff --git a/sbt-app/src/sbt-test/tests/arguments/build.sbt b/sbt-app/src/sbt-test/tests/arguments/build.sbt index 83d73ec794..93cde9171d 100644 --- a/sbt-app/src/sbt-test/tests/arguments/build.sbt +++ b/sbt-app/src/sbt-test/tests/arguments/build.sbt @@ -1,6 +1,6 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" val foo = settingKey[Seq[String]]("foo") val checkFoo = inputKey[Unit]("check contents of foo") diff --git a/sbt-app/src/sbt-test/tests/do-not-discover/build.sbt b/sbt-app/src/sbt-test/tests/do-not-discover/build.sbt index 59179e4133..d05f234305 100644 --- a/sbt-app/src/sbt-test/tests/do-not-discover/build.sbt +++ b/sbt-app/src/sbt-test/tests/do-not-discover/build.sbt @@ -1,6 +1,6 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/tests/done/build.sbt b/sbt-app/src/sbt-test/tests/done/build.sbt index 59179e4133..d05f234305 100644 --- a/sbt-app/src/sbt-test/tests/done/build.sbt +++ b/sbt-app/src/sbt-test/tests/done/build.sbt @@ -1,6 +1,6 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/tests/filter-runners/build.sbt b/sbt-app/src/sbt-test/tests/filter-runners/build.sbt index bc17f844db..e1aba618ab 100644 --- a/sbt-app/src/sbt-test/tests/filter-runners/build.sbt +++ b/sbt-app/src/sbt-test/tests/filter-runners/build.sbt @@ -1,7 +1,7 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.2.2" val munit = "org.scalameta" %% "munit" % "0.7.22" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" libraryDependencies += scalatest % Test libraryDependencies += munit % Test diff --git a/sbt-app/src/sbt-test/tests/fork-async/build.sbt b/sbt-app/src/sbt-test/tests/fork-async/build.sbt index 1f765fdb1a..93256098a5 100644 --- a/sbt-app/src/sbt-test/tests/fork-async/build.sbt +++ b/sbt-app/src/sbt-test/tests/fork-async/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/tests/fork-parallel/build.sbt b/sbt-app/src/sbt-test/tests/fork-parallel/build.sbt index f6f82d54af..68c177d330 100644 --- a/sbt-app/src/sbt-test/tests/fork-parallel/build.sbt +++ b/sbt-app/src/sbt-test/tests/fork-parallel/build.sbt @@ -1,7 +1,7 @@ import Tests._ import Defaults._ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" val check = taskKey[Unit]("Check that tests are executed in parallel") lazy val root = (project in file(".")) diff --git a/sbt-app/src/sbt-test/tests/fork-test-group-parallel-custom-tags/build.sbt b/sbt-app/src/sbt-test/tests/fork-test-group-parallel-custom-tags/build.sbt index 059a130a2e..d1e4492cf5 100644 --- a/sbt-app/src/sbt-test/tests/fork-test-group-parallel-custom-tags/build.sbt +++ b/sbt-app/src/sbt-test/tests/fork-test-group-parallel-custom-tags/build.sbt @@ -1,5 +1,5 @@ val specs = "org.specs2" %% "specs2-core" % "4.3.4" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" val TestATypeTag = Tags.Tag("TestA") val TestBTypeTag = Tags.Tag("TestB") diff --git a/sbt-app/src/sbt-test/tests/fork-test-group-parallel/build.sbt b/sbt-app/src/sbt-test/tests/fork-test-group-parallel/build.sbt index a6b2aaf9d7..50f793d227 100644 --- a/sbt-app/src/sbt-test/tests/fork-test-group-parallel/build.sbt +++ b/sbt-app/src/sbt-test/tests/fork-test-group-parallel/build.sbt @@ -1,5 +1,5 @@ val specs = "org.specs2" %% "specs2-core" % "4.3.4" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" Global / concurrentRestrictions := Seq(Tags.limitAll(4)) libraryDependencies += specs % Test diff --git a/sbt-app/src/sbt-test/tests/fork-uncaught2/build.sbt b/sbt-app/src/sbt-test/tests/fork-uncaught2/build.sbt index 60ad261401..f13c4fbe62 100644 --- a/sbt-app/src/sbt-test/tests/fork-uncaught2/build.sbt +++ b/sbt-app/src/sbt-test/tests/fork-uncaught2/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" libraryDependencies += "org.scala-sbt" % "test-interface" % "1.0" diff --git a/sbt-app/src/sbt-test/tests/fork/build.sbt b/sbt-app/src/sbt-test/tests/fork/build.sbt index 8722b742d9..65f33a5776 100644 --- a/sbt-app/src/sbt-test/tests/fork/build.sbt +++ b/sbt-app/src/sbt-test/tests/fork/build.sbt @@ -11,7 +11,7 @@ val scalaxml = "org.scala-lang.modules" %% "scala-xml" % "1.1.1" def groupId(idx: Int) = "group_" + (idx + 1) def groupPrefix(idx: Int) = groupId(idx) + "_file_" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" ThisBuild / organization := "org.example" lazy val root = (project in file(".")) diff --git a/sbt-app/src/sbt-test/tests/fork2/build.sbt b/sbt-app/src/sbt-test/tests/fork2/build.sbt index 6c272bbde7..e70d963e1c 100644 --- a/sbt-app/src/sbt-test/tests/fork2/build.sbt +++ b/sbt-app/src/sbt-test/tests/fork2/build.sbt @@ -1,6 +1,6 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" fork := true libraryDependencies += scalatest % Test diff --git a/sbt-app/src/sbt-test/tests/it/build.sbt b/sbt-app/src/sbt-test/tests/it/build.sbt index f784e70a15..c3c2347735 100644 --- a/sbt-app/src/sbt-test/tests/it/build.sbt +++ b/sbt-app/src/sbt-test/tests/it/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" val specs = "org.specs2" %% "specs2-core" % "4.3.4" diff --git a/sbt-app/src/sbt-test/tests/junit-xml-report/build.sbt b/sbt-app/src/sbt-test/tests/junit-xml-report/build.sbt index 5da8566976..4d87f2ca2b 100644 --- a/sbt-app/src/sbt-test/tests/junit-xml-report/build.sbt +++ b/sbt-app/src/sbt-test/tests/junit-xml-report/build.sbt @@ -14,7 +14,7 @@ val nestedSuitesReportFile = "target/test-reports/TEST-my.scalatest.MyNestedSuit val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" val junitinterface = "com.novocode" % "junit-interface" % "0.11" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")). settings( diff --git a/sbt-app/src/sbt-test/tests/munit/build.sbt b/sbt-app/src/sbt-test/tests/munit/build.sbt index bc719880cf..e04350cbd4 100644 --- a/sbt-app/src/sbt-test/tests/munit/build.sbt +++ b/sbt-app/src/sbt-test/tests/munit/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val munit = "org.scalameta" %% "munit" % "0.7.22" diff --git a/sbt-app/src/sbt-test/tests/nested-inproc-par/build.sbt b/sbt-app/src/sbt-test/tests/nested-inproc-par/build.sbt index 5cbfb735e8..68ae9ccf74 100644 --- a/sbt-app/src/sbt-test/tests/nested-inproc-par/build.sbt +++ b/sbt-app/src/sbt-test/tests/nested-inproc-par/build.sbt @@ -1,6 +1,6 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/tests/nested-inproc-seq/build.sbt b/sbt-app/src/sbt-test/tests/nested-inproc-seq/build.sbt index a03155c8a3..20bdacb98e 100644 --- a/sbt-app/src/sbt-test/tests/nested-inproc-seq/build.sbt +++ b/sbt-app/src/sbt-test/tests/nested-inproc-seq/build.sbt @@ -1,6 +1,6 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/tests/nested-subproc/build.sbt b/sbt-app/src/sbt-test/tests/nested-subproc/build.sbt index 7b8de30100..bb06cb73f0 100644 --- a/sbt-app/src/sbt-test/tests/nested-subproc/build.sbt +++ b/sbt-app/src/sbt-test/tests/nested-subproc/build.sbt @@ -1,7 +1,7 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" val scalaxml = "org.scala-lang.modules" %% "scala-xml" % "1.1.1" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/tests/nested-tests/build.sbt b/sbt-app/src/sbt-test/tests/nested-tests/build.sbt index 6ae21f33fb..52030f3c9a 100644 --- a/sbt-app/src/sbt-test/tests/nested-tests/build.sbt +++ b/sbt-app/src/sbt-test/tests/nested-tests/build.sbt @@ -1,6 +1,6 @@ val scalcheck = "org.scalacheck" %% "scalacheck" % "1.14.0" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" ThisBuild / version := "0.0.1" ThisBuild / organization := "org.catastrophe" diff --git a/sbt-app/src/sbt-test/tests/one-class-multi-framework/build.sbt b/sbt-app/src/sbt-test/tests/one-class-multi-framework/build.sbt index 3fa69b6cf0..127d21076d 100644 --- a/sbt-app/src/sbt-test/tests/one-class-multi-framework/build.sbt +++ b/sbt-app/src/sbt-test/tests/one-class-multi-framework/build.sbt @@ -1,5 +1,5 @@ val specsJunit = "org.specs2" %% "specs2-junit" % "4.3.4" val junitinterface = "com.novocode" % "junit-interface" % "0.11" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" libraryDependencies += junitinterface % Test libraryDependencies += specsJunit % Test diff --git a/sbt-app/src/sbt-test/tests/order/build.sbt b/sbt-app/src/sbt-test/tests/order/build.sbt index fefa56d8e9..10db9515d4 100644 --- a/sbt-app/src/sbt-test/tests/order/build.sbt +++ b/sbt-app/src/sbt-test/tests/order/build.sbt @@ -1,5 +1,5 @@ val scalcheck = "org.scalacheck" %% "scalacheck" % "1.14.0" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" Test / parallelExecution := false libraryDependencies += scalcheck % Test diff --git a/sbt-app/src/sbt-test/tests/resources/build.sbt b/sbt-app/src/sbt-test/tests/resources/build.sbt index e6997605aa..5d64d55f45 100644 --- a/sbt-app/src/sbt-test/tests/resources/build.sbt +++ b/sbt-app/src/sbt-test/tests/resources/build.sbt @@ -1,3 +1,3 @@ val specs = "org.specs2" %% "specs2-core" % "4.3.4" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" libraryDependencies += specs % Test diff --git a/sbt-app/src/sbt-test/tests/scala-instance-classloader/build.sbt b/sbt-app/src/sbt-test/tests/scala-instance-classloader/build.sbt index 44c188f442..dcdf547a94 100644 --- a/sbt-app/src/sbt-test/tests/scala-instance-classloader/build.sbt +++ b/sbt-app/src/sbt-test/tests/scala-instance-classloader/build.sbt @@ -3,7 +3,7 @@ import sbt.internal.inc.ScalaInstance lazy val OtherScala = config("other-scala").hide lazy val junitinterface = "com.novocode" % "junit-interface" % "0.11" lazy val akkaActor = "com.typesafe.akka" %% "akka-actor" % "2.5.17" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .configs(OtherScala) diff --git a/sbt-app/src/sbt-test/tests/serial/build.sbt b/sbt-app/src/sbt-test/tests/serial/build.sbt index effd2fa66b..2d7abec582 100644 --- a/sbt-app/src/sbt-test/tests/serial/build.sbt +++ b/sbt-app/src/sbt-test/tests/serial/build.sbt @@ -1,6 +1,6 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" ThisBuild / organization := "com.example" ThisBuild / version := "0.0.1-SNAPSHOT" diff --git a/sbt-app/src/sbt-test/tests/setup-cleanup/base.sbt b/sbt-app/src/sbt-test/tests/setup-cleanup/base.sbt index ea0abf0e5d..d5d9b25526 100644 --- a/sbt-app/src/sbt-test/tests/setup-cleanup/base.sbt +++ b/sbt-app/src/sbt-test/tests/setup-cleanup/base.sbt @@ -1,3 +1,3 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" libraryDependencies += scalatest diff --git a/sbt-app/src/sbt-test/tests/single-runner/build.sbt b/sbt-app/src/sbt-test/tests/single-runner/build.sbt index 69ff2b7115..0547b74652 100644 --- a/sbt-app/src/sbt-test/tests/single-runner/build.sbt +++ b/sbt-app/src/sbt-test/tests/single-runner/build.sbt @@ -1,4 +1,4 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" libraryDependencies += scalatest Test / testOptions += Tests.Argument("-C", "custom.CustomReporter") diff --git a/sbt-app/src/sbt-test/tests/specs-run/build.sbt b/sbt-app/src/sbt-test/tests/specs-run/build.sbt index 7b2f632b63..47774f80b6 100644 --- a/sbt-app/src/sbt-test/tests/specs-run/build.sbt +++ b/sbt-app/src/sbt-test/tests/specs-run/build.sbt @@ -1,4 +1,4 @@ val specs = "org.specs2" %% "specs2-core" % "4.3.4" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" libraryDependencies += specs % Test diff --git a/sbt-app/src/sbt-test/tests/t543/build.sbt b/sbt-app/src/sbt-test/tests/t543/build.sbt index 3f885106ae..944e65e4e2 100644 --- a/sbt-app/src/sbt-test/tests/t543/build.sbt +++ b/sbt-app/src/sbt-test/tests/t543/build.sbt @@ -7,7 +7,7 @@ val check = TaskKey[Unit]("check", "Check correct error has been returned.") val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" val scalaxml = "org.scala-lang.modules" %% "scala-xml" % "1.1.1" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")). settings( diff --git a/sbt-app/src/sbt-test/tests/task/build.sbt b/sbt-app/src/sbt-test/tests/task/build.sbt index 69ff2b7115..0547b74652 100644 --- a/sbt-app/src/sbt-test/tests/task/build.sbt +++ b/sbt-app/src/sbt-test/tests/task/build.sbt @@ -1,4 +1,4 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" libraryDependencies += scalatest Test / testOptions += Tests.Argument("-C", "custom.CustomReporter") diff --git a/sbt-app/src/sbt-test/tests/test-exclude/build.sbt b/sbt-app/src/sbt-test/tests/test-exclude/build.sbt index c05ef3c0db..391cac0aef 100644 --- a/sbt-app/src/sbt-test/tests/test-exclude/build.sbt +++ b/sbt-app/src/sbt-test/tests/test-exclude/build.sbt @@ -1,5 +1,5 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/tests/test-quick/build.sbt b/sbt-app/src/sbt-test/tests/test-quick/build.sbt index c05ef3c0db..391cac0aef 100644 --- a/sbt-app/src/sbt-test/tests/test-quick/build.sbt +++ b/sbt-app/src/sbt-test/tests/test-quick/build.sbt @@ -1,5 +1,5 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" lazy val root = (project in file(".")) .settings( diff --git a/sbt-app/src/sbt-test/watch/commands/build.sbt b/sbt-app/src/sbt-test/watch/commands/build.sbt index b197a03950..1250a85677 100644 --- a/sbt-app/src/sbt-test/watch/commands/build.sbt +++ b/sbt-app/src/sbt-test/watch/commands/build.sbt @@ -53,4 +53,4 @@ expectFailure / watchOnFileInputEvent := { (_, e) => } -crossScalaVersions := Seq("2.11.12", "2.12.19") +crossScalaVersions := Seq("2.11.12", "2.12.20") diff --git a/server-test/src/server-test/client/build.sbt b/server-test/src/server-test/client/build.sbt index 3225bd76da..686d2a7a8d 100644 --- a/server-test/src/server-test/client/build.sbt +++ b/server-test/src/server-test/client/build.sbt @@ -1,7 +1,9 @@ +scalaVersion := "3.6.3" + TaskKey[Unit]("willSucceed") := println("success") TaskKey[Unit]("willFail") := { throw new Exception("failed") } -libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % "test" +libraryDependencies += "org.scalameta" %% "munit" % "1.0.4" % Test TaskKey[Unit]("fooBar") := { () } diff --git a/server-test/src/server-test/client/src/main/scala/A.scala b/server-test/src/server-test/client/src/main/scala/A.scala index 69c493db21..171b96e913 100644 --- a/server-test/src/server-test/client/src/main/scala/A.scala +++ b/server-test/src/server-test/client/src/main/scala/A.scala @@ -1 +1,3 @@ -object A +class A + +@main def hello() = println("Hello, World!") diff --git a/server-test/src/server-test/client/src/test/scala/FooSpec.scala b/server-test/src/server-test/client/src/test/scala/FooSpec.scala index 269be56244..fb5352fd9b 100644 --- a/server-test/src/server-test/client/src/test/scala/FooSpec.scala +++ b/server-test/src/server-test/client/src/test/scala/FooSpec.scala @@ -1,3 +1,3 @@ package test.pkg -class FooSpec extends org.scalatest.FlatSpec +class FooSpec extends munit.FunSuite diff --git a/server-test/src/server-test/response/build.sbt b/server-test/src/server-test/response/build.sbt index f3a2fac46e..5884663336 100644 --- a/server-test/src/server-test/response/build.sbt +++ b/server-test/src/server-test/response/build.sbt @@ -1,6 +1,6 @@ import sbt.internal.server.{ ServerHandler, ServerIntent } -ThisBuild / scalaVersion := "2.12.19" +ThisBuild / scalaVersion := "2.12.20" Global / serverLog / logLevel := Level.Debug // custom handler diff --git a/server-test/src/test/scala/testpkg/BuildServerTest.scala b/server-test/src/test/scala/testpkg/BuildServerTest.scala index fff085a943..0c0306fe9d 100644 --- a/server-test/src/test/scala/testpkg/BuildServerTest.scala +++ b/server-test/src/test/scala/testpkg/BuildServerTest.scala @@ -53,6 +53,16 @@ object BuildServerTest extends AbstractServerTest { result.targets.find(_.displayName.contains("buildserver-build")).get assert(buildServerBuildTarget.id.uri.toString.endsWith("#buildserver-build")) assert(!result.targets.exists(_.displayName.contains("badBuildTarget"))) + // Check for JVM based Scala Project, built target should contain Java version information + val scalaBuildTarget = + Converter.fromJsonOptionUnsafe[ScalaBuildTarget](utilTarget.data) + val javaTarget = scalaBuildTarget.jvmBuildTarget + (javaTarget.flatMap(_.javaVersion), javaTarget.flatMap(_.javaHome)) match { + case (Some(javaVersion), Some(javaHome)) => + assert(javaVersion.equals(sys.props("java.version"))) + assert(javaHome.equals(Paths.get(sys.props("java.home")).toUri)) + case _ => fail("JVM build target should contain javaVersion and javaHome") + } } test("buildTarget/sources") { _ => @@ -218,7 +228,6 @@ object BuildServerTest extends AbstractServerTest { val buildTarget = buildTargetUri("javaProj", "Compile") compile(buildTarget) - assertMessage( "build/publishDiagnostics", "Hello.java", @@ -236,6 +245,82 @@ object BuildServerTest extends AbstractServerTest { ) } + test("buildTarget/compile [Java diagnostics] clear stale warnings") { _ => + val buildTarget = buildTargetUri("javaProj", "Compile") + val testFile = new File(svr.baseDirectory, s"java-proj/src/main/java/example/Hello.java") + + val otherBuildFile = new File(svr.baseDirectory, "force-java-out-of-process-compiler.sbt") + // Setting `javaHome` will force sbt to shell out to an external Java compiler instead + // of using the local compilation service offered by the JVM running this SBT instance. + IO.write( + otherBuildFile, + """ + |def jdk: File = sbt.internal.util.Util.javaHome.toFile() + |lazy val javaProj = project + | .in(file("java-proj")) + | .settings( + | javacOptions += "-Xlint:all", + | javaHome := Some(jdk) + | ) + |""".stripMargin + ) + reloadWorkspace() + + compile(buildTarget) + + assertMessage( + "build/publishDiagnostics", + "Hello.java", + """"severity":2""", + """found raw type""" + )(message = "should send publishDiagnostics with severity 2 for Hello.java", debug = false) + + assertMessage( + "build/publishDiagnostics", + "Hello.java", + """"severity":1""", + """incompatible types: int cannot be converted""" + )( + message = "should send publishDiagnostics with severity 1 for Hello.java", + debug = true + ) + // Note the messages changed slightly in both cases. That's interesting… + + IO.write( + testFile, + """|package example; + | + |import java.util.List; + |import java.util.ArrayList; + | + |class Hello { + | public static void main(String[] args) { + | List list = new ArrayList<>(); + | String msg = "42"; + | System.out.println(msg); + | } + |} + |""".stripMargin + ) + + compile(buildTarget) + + /* + assertMessage( + "build/publishDiagnostics", + "Hello.java", + "\"diagnostics\":[]", + "\"reset\":true" + )( + message = "should send publishDiagnostics with empty diagnostics" + ) + */ + + IO.delete(otherBuildFile) + reloadWorkspace() + () + } + test("buildTarget/scalacOptions, buildTarget/javacOptions") { _ => val buildTargets = Seq( buildTargetUri("util", "Compile"), @@ -603,6 +688,11 @@ object BuildServerTest extends AbstractServerTest { def assertion = svr.waitForString(duration) { msg => if (debug) println(msg) + if (debug) + parts.foreach { p => + if (msg.contains(p)) println(s"> $msg contains $p") + else () + } parts.forall(msg.contains) } if (message.nonEmpty) assert.apply(assertion, message) else assert(assertion) diff --git a/server-test/src/test/scala/testpkg/ClientTest.scala b/server-test/src/test/scala/testpkg/ClientTest.scala index b4352062a0..628cbbda3b 100644 --- a/server-test/src/test/scala/testpkg/ClientTest.scala +++ b/server-test/src/test/scala/testpkg/ClientTest.scala @@ -57,7 +57,7 @@ object ClientTest extends AbstractServerTest { case r => r } } - private def client(args: String*): Int = { + private def client(args: String*): Int = background( NetworkClient.client( testPath.toFile, @@ -68,6 +68,19 @@ object ClientTest extends AbstractServerTest { false ) ) + def clientWithStdoutLines(args: String*): (Int, Seq[String]) = { + val out = new CachingPrintStream + val exitCode = background( + NetworkClient.client( + testPath.toFile, + args.toArray, + NullInputStream, + out, + NullPrintStream, + false + ) + ) + (exitCode, out.lines) } // This ensures that the completion command will send a tab that triggers // sbt to call definedTestNames or discoveredMainClasses if there hasn't diff --git a/server-test/src/test/scala/testpkg/TestServer.scala b/server-test/src/test/scala/testpkg/TestServer.scala index dac89ff79e..c3a78bc6ad 100644 --- a/server-test/src/test/scala/testpkg/TestServer.scala +++ b/server-test/src/test/scala/testpkg/TestServer.scala @@ -220,7 +220,7 @@ case class TestServer( // initiate handshake sendJsonRpc( - s"""{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "initializationOptions": { "skipAnalysis": true } } }""" + s"""{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "initializationOptions": { "skipAnalysis": true, "canWork": true } } }""" ) def test(f: TestServer => Future[Assertion]): Future[Assertion] = { diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemEventFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemEventFormats.scala index d6a8af553f..352ed5d8e9 100644 --- a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemEventFormats.scala +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestItemEventFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.protocol.testing.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait TestItemEventFormats { self: sbt.protocol.testing.codec.TestResultFormats with sbt.protocol.testing.codec.TestItemDetailFormats with sjsonnew.BasicJsonProtocol => +trait TestItemEventFormats { self: sbt.protocol.testing.codec.TestResultFormats with sjsonnew.BasicJsonProtocol with sbt.protocol.testing.codec.TestItemDetailFormats with sbt.internal.testing.StatusFormats => implicit lazy val TestItemEventFormat: JsonFormat[sbt.protocol.testing.TestItemEvent] = new JsonFormat[sbt.protocol.testing.TestItemEvent] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.testing.TestItemEvent = { __jsOpt match { diff --git a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestMessageFormats.scala b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestMessageFormats.scala index 13534855d6..ffeba09907 100644 --- a/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestMessageFormats.scala +++ b/testing/src/main/contraband-scala/sbt/protocol/testing/codec/TestMessageFormats.scala @@ -6,6 +6,6 @@ package sbt.protocol.testing.codec import _root_.sjsonnew.JsonFormat -trait TestMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.testing.codec.TestStringEventFormats with sbt.protocol.testing.codec.TestInitEventFormats with sbt.protocol.testing.codec.TestResultFormats with sbt.protocol.testing.codec.TestCompleteEventFormats with sbt.protocol.testing.codec.StartTestGroupEventFormats with sbt.protocol.testing.codec.EndTestGroupEventFormats with sbt.protocol.testing.codec.EndTestGroupErrorEventFormats with sbt.protocol.testing.codec.TestItemDetailFormats with sbt.protocol.testing.codec.TestItemEventFormats => +trait TestMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.testing.codec.TestStringEventFormats with sbt.protocol.testing.codec.TestInitEventFormats with sbt.protocol.testing.codec.TestResultFormats with sbt.protocol.testing.codec.TestCompleteEventFormats with sbt.protocol.testing.codec.StartTestGroupEventFormats with sbt.protocol.testing.codec.EndTestGroupEventFormats with sbt.protocol.testing.codec.EndTestGroupErrorEventFormats with sbt.protocol.testing.codec.TestItemDetailFormats with sbt.internal.testing.StatusFormats with sbt.protocol.testing.codec.TestItemEventFormats => implicit lazy val TestMessageFormat: JsonFormat[sbt.protocol.testing.TestMessage] = flatUnionFormat7[sbt.protocol.testing.TestMessage, sbt.protocol.testing.TestStringEvent, sbt.protocol.testing.TestInitEvent, sbt.protocol.testing.TestCompleteEvent, sbt.protocol.testing.StartTestGroupEvent, sbt.protocol.testing.EndTestGroupEvent, sbt.protocol.testing.EndTestGroupErrorEvent, sbt.protocol.testing.TestItemEvent]("type") } diff --git a/zinc-lm-integration/src/test/scala/sbt/internal/inc/ZincComponentCompilerSpec.scala b/zinc-lm-integration/src/test/scala/sbt/internal/inc/ZincComponentCompilerSpec.scala index bad241e515..7994581679 100644 --- a/zinc-lm-integration/src/test/scala/sbt/internal/inc/ZincComponentCompilerSpec.scala +++ b/zinc-lm-integration/src/test/scala/sbt/internal/inc/ZincComponentCompilerSpec.scala @@ -16,11 +16,8 @@ class ZincComponentCompilerSpec extends IvyBridgeProviderSpecification { val scala2106 = "2.10.6" val scala2118 = "2.11.8" val scala21111 = "2.11.11" - val scala2121 = "2.12.1" - val scala2122 = "2.12.2" - val scala2123 = "2.12.3" - val scala2130 = "2.13.0" - val scala2131 = "2.13.1" + val scala21220 = "2.12.20" + val scala21311 = "2.13.11" def isJava8: Boolean = sys.props("java.specification.version") == "1.8" @@ -40,14 +37,11 @@ class ZincComponentCompilerSpec extends IvyBridgeProviderSpecification { } else () } - it should "compile the bridge for Scala 2.12.2" in { implicit td => - IO.withTemporaryDirectory(t => getCompilerBridge(t, logger, scala2121) should exist) - IO.withTemporaryDirectory(t => getCompilerBridge(t, logger, scala2122) should exist) - IO.withTemporaryDirectory(t => getCompilerBridge(t, logger, scala2123) should exist) + it should "compile the bridge for Scala 2.12.20" in { implicit td => + IO.withTemporaryDirectory(t => getCompilerBridge(t, logger, scala21220) should exist) } - it should "compile the bridge for Scala 2.13" in { implicit td => - IO.withTemporaryDirectory(t => getCompilerBridge(t, logger, scala2130) should exist) - IO.withTemporaryDirectory(t => getCompilerBridge(t, logger, scala2131) should exist) + it should "compile the bridge for Scala 2.13.11" in { implicit td => + IO.withTemporaryDirectory(t => getCompilerBridge(t, logger, scala21311) should exist) } }