From 020385d9174cd99ea4baad76838193b228e18731 Mon Sep 17 00:00:00 2001 From: Amina Adewusi Date: Fri, 18 Mar 2022 17:13:14 +0000 Subject: [PATCH 01/43] Attempts to fix sbt#6810 - deadlock issue --- .../src/main/scala/sbt/internal/util/Terminal.scala | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) 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 9fa61c02e..873a32871 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 @@ -189,6 +189,14 @@ object Terminal { try Terminal.console.printStream.println(s"[info] $string") catch { case _: IOException => } } + + private[this] val writeLock = new AnyRef + def withWriteLock[A](f: => A): A = { + writeLock.synchronized { + f + } + } + private[sbt] def set(terminal: Terminal): Terminal = activeTerminal.getAndSet(terminal) implicit class TerminalOps(private val term: Terminal) extends AnyVal { def ansi(richString: => String, string: => String): String = @@ -462,7 +470,7 @@ object Terminal { val sepBytes = System.lineSeparator.getBytes("UTF-8") private class LinePrintStream(outputStream: OutputStream) extends PrintStream(outputStream, true) { - override def println(s: String): Unit = synchronized { + override def println(s: String): Unit = withWriteLock { out.write(s.getBytes("UTF-8") ++ sepBytes) out.flush() } @@ -911,7 +919,6 @@ object Terminal { override def getWidth: Int = getSize._1 override def getHeight: Int = getSize._2 private[this] val rawMode = new AtomicBoolean(false) - private[this] val writeLock = new AnyRef def throwIfClosed[R](f: => R): R = if (isStopped.get) throw new ClosedChannelException else f override def getLastLine: Option[String] = progressState.currentLine override def getLines: Seq[String] = progressState.getLines @@ -939,7 +946,7 @@ object Terminal { write(Array((b & 0xFF).toByte)) } override def write(b: Array[Byte]): Unit = throwIfClosed { - writeLock.synchronized(doWrite(b)) + withWriteLock(doWrite(b)) } override def write(b: Array[Byte], offset: Int, length: Int): Unit = throwIfClosed { write(Arrays.copyOfRange(b, offset, offset + length)) From 4be80a8fa0461c4b3a52930bc0ae6f7e6cc7a14c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 06:08:33 +0000 Subject: [PATCH 02/43] Bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/nightly.yml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06c63b5af..886296b24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,21 +60,21 @@ jobs: SPARK_LOCAL_IP: "127.0.0.1" steps: - name: Checkout sbt/sbt - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout sbt/io - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: sbt/io ref: develop path: io - name: Checkout sbt/librarymanagement - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: sbt/librarymanagement ref: develop path: librarymanagement - name: Checkout sbt/zinc - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: sbt/zinc ref: develop diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 0593b63e9..4d98a29d8 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -16,21 +16,21 @@ jobs: JAVA_OPTS: -Xms800M -Xmx800M -Xss6M -XX:ReservedCodeCacheSize=128M -server -Dsbt.io.virtual=false -Dfile.encoding=UTF-8 steps: - name: Checkout sbt/sbt - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout sbt/io - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: sbt/io ref: develop path: io - name: Checkout sbt/librarymanagement - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: sbt/librarymanagement ref: develop path: librarymanagement - name: Checkout sbt/zinc - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: sbt/zinc ref: develop From 3376448701e8c329ceee51a491eac04ae580b1a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 06:08:36 +0000 Subject: [PATCH 03/43] Bump actions/setup-python from 2 to 4 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 4. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v2...v4) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06c63b5af..53bfc4e90 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,7 +85,7 @@ jobs: distribution: "${{ matrix.distribution }}" java-version: "${{ matrix.java }}" - name: Set up Python 3.7 - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.7 - name: Coursier cache From 913a4789f3130bfcb19a0e27e9009518f749453c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 06:08:38 +0000 Subject: [PATCH 04/43] Bump actions/setup-java from 2 to 3 Bumps [actions/setup-java](https://github.com/actions/setup-java) from 2 to 3. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06c63b5af..1c09d4733 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -80,7 +80,7 @@ jobs: ref: develop path: zinc - name: Setup JDK - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: distribution: "${{ matrix.distribution }}" java-version: "${{ matrix.java }}" From eb98dbf9c05ba3eb1043969c449491dd0973bc7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 06:08:40 +0000 Subject: [PATCH 05/43] Bump actions/cache from 2.1.6 to 3.0.4 Bumps [actions/cache](https://github.com/actions/cache) from 2.1.6 to 3.0.4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v2.1.6...v3.0.4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06c63b5af..85d12b72c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: - name: Coursier cache uses: coursier/cache-action@v6 - name: Cache sbt - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.4 with: path: ~/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} From 171383f2ad073847820beecb8ae244c1bb520734 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 13 Jun 2022 03:17:15 -0400 Subject: [PATCH 06/43] Fix javadoc --- build.sbt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.sbt b/build.sbt index 3168ba1dd..ea690b5b3 100644 --- a/build.sbt +++ b/build.sbt @@ -246,6 +246,7 @@ lazy val bundledLauncherProj = description := "sbt application launcher", autoScalaLibrary := false, crossPaths := false, + Compile / doc / javacOptions := Nil, Compile / packageBin := sbtLaunchJar.value, mimaSettings, mimaPreviousArtifacts := Set() @@ -340,6 +341,7 @@ lazy val utilInterface = (project in file("internal") / "util-interface").settin javaOnlySettings, crossPaths := false, autoScalaLibrary := false, + Compile / doc / javacOptions := Nil, name := "Util Interface", exportJars := true, utilMimaSettings, @@ -532,6 +534,7 @@ lazy val testAgentProj = (project in file("testing") / "agent") crossScalaVersions := Seq(baseScalaVersion), crossPaths := false, autoScalaLibrary := false, + Compile / doc / javacOptions := Nil, name := "Test Agent", libraryDependencies += testInterface, mimaSettings, From ac8a17d2a3b1f50a4cf16613c8a874658f421d88 Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Sun, 19 Jun 2022 21:09:49 -0400 Subject: [PATCH 07/43] Turn off Nightly --- .github/workflows/nightly.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 4d98a29d8..2897d641f 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,8 +1,9 @@ name: Nightly on: - schedule: - # 08:00 UTC = 03:00 EST - - cron: '0 8 * * *' + workflow_dispatch: +# schedule: +# # 08:00 UTC = 03:00 EST +# - cron: '0 8 * * *' jobs: deploy: From cd915845dbbd3893e2ec81de305f6b19cc4be2e2 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Mon, 9 May 2022 16:41:26 +0200 Subject: [PATCH 08/43] Add support for wildcards in Scala version switch Picking from the `crossScalaVersions` As discussed in https://github.com/sbt/sbt/discussions/6893 --- main/src/main/scala/sbt/Cross.scala | 96 +++++++++++++------ main/src/test/scala/sbt/CrossSpec.scala | 20 ++++ .../sbt-test/actions/cross-multiproject/test | 21 ++++ 3 files changed, 109 insertions(+), 28 deletions(-) create mode 100644 main/src/test/scala/sbt/CrossSpec.scala diff --git a/main/src/main/scala/sbt/Cross.scala b/main/src/main/scala/sbt/Cross.scala index 8bb001d04..9966c5eb9 100644 --- a/main/src/main/scala/sbt/Cross.scala +++ b/main/src/main/scala/sbt/Cross.scala @@ -8,7 +8,7 @@ package sbt import java.io.File - +import java.util.regex.Pattern import sbt.Def.{ ScopedKey, Setting } import sbt.Keys._ import sbt.SlashSyntax0._ @@ -284,8 +284,8 @@ object Cross { } def logSwitchInfo( - included: Seq[(ProjectRef, Seq[ScalaVersion])], - excluded: Seq[(ProjectRef, Seq[ScalaVersion])] + included: Seq[(ResolvedReference, ScalaVersion, Seq[ScalaVersion])], + excluded: Seq[(ResolvedReference, Seq[ScalaVersion])] ) = { instance.foreach { @@ -304,56 +304,96 @@ object Cross { def detailedLog(msg: => String) = if (switch.verbose) state.log.info(msg) else state.log.debug(msg) - def logProject: (ProjectRef, Seq[ScalaVersion]) => Unit = (proj, scalaVersions) => { - val current = if (proj == currentRef) "*" else " " - detailedLog(s" $current ${proj.project} ${scalaVersions.mkString("(", ", ", ")")}") + def logProject: (ResolvedReference, Seq[ScalaVersion]) => Unit = (ref, scalaVersions) => { + val current = if (ref == currentRef) "*" else " " + ref match { + case proj: ProjectRef => + detailedLog(s" $current ${proj.project} ${scalaVersions.mkString("(", ", ", ")")}") + case _ => // don't log BuildRefs + } } detailedLog("Switching Scala version on:") - included.foreach(logProject.tupled) + included.foreach { case (project, _, versions) => logProject(project, versions) } detailedLog("Excluding projects:") excluded.foreach(logProject.tupled) } - val projects: Seq[(ResolvedReference, Seq[ScalaVersion])] = { + val projects: Seq[(ResolvedReference, Option[ScalaVersion], Seq[ScalaVersion])] = { val projectScalaVersions = structure.allProjectRefs.map(proj => proj -> crossVersions(extracted, proj)) if (switch.version.force) { - logSwitchInfo(projectScalaVersions, Nil) - projectScalaVersions ++ structure.units.keys + projectScalaVersions.map { + case (ref, options) => (ref, Some(version), options) + } ++ structure.units.keys .map(BuildRef.apply) - .map(proj => proj -> crossVersions(extracted, proj)) + .map(proj => (proj, Some(version), crossVersions(extracted, proj))) + } else if (version.contains('*')) { + projectScalaVersions.map { + case (project, scalaVersions) => + globFilter(version, scalaVersions) match { + case Nil => (project, None, scalaVersions) + case Seq(version) => (project, Some(version), scalaVersions) + case multiple => + sys.error( + s"Multiple crossScalaVersions matched query '$version': ${multiple.mkString(", ")}" + ) + } + } } else { val binaryVersion = CrossVersion.binaryScalaVersion(version) - - val (included, excluded) = projectScalaVersions.partition { - case (_, scalaVersions) => - scalaVersions.exists(v => CrossVersion.binaryScalaVersion(v) == binaryVersion) + projectScalaVersions.map { + case (project, scalaVersions) => + if (scalaVersions.exists(v => CrossVersion.binaryScalaVersion(v) == binaryVersion)) + (project, Some(version), scalaVersions) + else + (project, None, scalaVersions) } - if (included.isEmpty) { - sys.error( - s"""Switch failed: no subprojects list "$version" (or compatible version) in crossScalaVersions setting. - |If you want to force it regardless, call ++ $version!""".stripMargin - ) - } - logSwitchInfo(included, excluded) - included } } - (setScalaVersionForProjects(version, instance, projects, state, extracted), projects.map(_._1)) + val included = projects.collect { + case (project, Some(version), scalaVersions) => (project, version, scalaVersions) + } + val excluded = projects.collect { + case (project, None, scalaVersions) => (project, scalaVersions) + } + + if (included.isEmpty) { + sys.error( + s"""Switch failed: no subprojects list "$version" (or compatible version) in crossScalaVersions setting. + |If you want to force it regardless, call ++ $version!""".stripMargin + ) + } + + logSwitchInfo(included, excluded) + + (setScalaVersionsForProjects(instance, included, state, extracted), included.map(_._1)) } - private def setScalaVersionForProjects( - version: String, + def globFilter(pattern: String, candidates: Seq[String]): Seq[String] = { + def createGlobRegex(remainingPattern: String): String = + remainingPattern.indexOf("*") match { + case -1 => Pattern.quote(remainingPattern) + case n => + val chunk = Pattern.quote(remainingPattern.substring(0, n)) + ".*" + if (remainingPattern.length > n) + chunk + createGlobRegex(remainingPattern.substring(n + 1)) + else chunk + } + val compiledPattern = Pattern.compile(createGlobRegex(pattern)) + candidates.filter(compiledPattern.matcher(_).matches()) + } + + private def setScalaVersionsForProjects( instance: Option[(File, ScalaInstance)], - projects: Seq[(ResolvedReference, Seq[String])], + projects: Seq[(ResolvedReference, String, Seq[String])], state: State, extracted: Extracted ): State = { import extracted._ val newSettings = projects.flatMap { - case (project, scalaVersions) => + case (project, version, scalaVersions) => val scope = Scope(Select(project), Zero, Zero, Zero) instance match { diff --git a/main/src/test/scala/sbt/CrossSpec.scala b/main/src/test/scala/sbt/CrossSpec.scala new file mode 100644 index 000000000..40673d548 --- /dev/null +++ b/main/src/test/scala/sbt/CrossSpec.scala @@ -0,0 +1,20 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt + +object CrossSpec extends verify.BasicTestSuite { + import Cross._ + + test("glob filter should work as expected") { + assert(globFilter("2.13.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Seq("2.13.16")) + assert(globFilter("3.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Seq("3.0.1")) + assert(globFilter("3.*", Seq("3.0.1", "30.1")) == Seq("3.0.1")) + assert(globFilter("2.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Seq("2.12.8", "2.13.16")) + assert(globFilter("4.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Nil) + } +} diff --git a/sbt-app/src/sbt-test/actions/cross-multiproject/test b/sbt-app/src/sbt-test/actions/cross-multiproject/test index 68b8383d5..baf4db9b8 100644 --- a/sbt-app/src/sbt-test/actions/cross-multiproject/test +++ b/sbt-app/src/sbt-test/actions/cross-multiproject/test @@ -41,3 +41,24 @@ $ exists lib/target/scala-2.13 -$ exists lib/target/scala-2.12 # -$ exists sbt-foo/target/scala-2.12 -$ exists sbt-foo/target/scala-2.13 + +# test wildcard switching (2.12) +> clean +> ++ 2.12.* -v compile +$ exists lib/target/scala-2.12 +-$ exists lib/target/scala-2.13 +$ exists sbt-foo/target/scala-2.12 +-$ exists sbt-foo/target/scala-2.13 + +# test wildcard switching (2.13) +> clean +> ++ 2.13.* -v compile +$ exists lib/target/scala-2.13 +-$ exists lib/target/scala-2.12 +# -$ exists sbt-foo/target/scala-2.12 +-$ exists sbt-foo/target/scala-2.13 + +# test wildcard switching (no matches) +-> ++ 3.* +# test wildcard switching (multiple matches) +-> ++ 2.* From 7921cab7e3bb252303b9e283cd40620fff322f19 Mon Sep 17 00:00:00 2001 From: Kamil Podsiadlo Date: Wed, 22 Jun 2022 00:00:31 +0200 Subject: [PATCH 09/43] fix: publishing bsp diagnostics * do not publish bsp diagnostics if there were and there are no problems * publish diagnostics if problems needs to be updated --- main/src/main/scala/sbt/Defaults.scala | 12 +- .../internal/server/BuildServerProtocol.scala | 48 +++-- .../internal/server/BuildServerReporter.scala | 69 ++++--- .../src/server-test/buildserver/build.sbt | 2 + .../src/main/scala/Diagnostics.scala | 3 + .../src/main/scala/PatternMatch.scala | 7 + .../test/scala/testpkg/BuildServerTest.scala | 182 +++++++++++++----- 7 files changed, 228 insertions(+), 95 deletions(-) create mode 100644 server-test/src/server-test/buildserver/diagnostics/src/main/scala/Diagnostics.scala create mode 100644 server-test/src/server-test/buildserver/diagnostics/src/main/scala/PatternMatch.scala diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 6e4746a53..efd856a67 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2308,11 +2308,10 @@ object Defaults extends BuildCommon { val ci = (compile / compileInputs).value val ping = earlyOutputPing.value val reporter = (compile / bspReporter).value - val prevAnalysis = previousCompile.value.analysis.toOption.getOrElse(Analysis.empty) BspCompileTask.compute(bspTargetIdentifier.value, thisProjectRef.value, configuration.value) { task => // TODO - Should readAnalysis + saveAnalysis be scoped by the compile task too? - compileIncrementalTaskImpl(task, s, ci, ping, reporter, prevAnalysis) + compileIncrementalTaskImpl(task, s, ci, ping, reporter) } } private val incCompiler = ZincUtil.defaultIncrementalCompiler @@ -2327,7 +2326,7 @@ object Defaults extends BuildCommon { val result0 = incCompiler .asInstanceOf[sbt.internal.inc.IncrementalCompilerImpl] .compileAllJava(in, s.log) - reporter.sendSuccessReport(result0.analysis(), Analysis.empty, false) + reporter.sendSuccessReport(result0.analysis()) result0.withHasModified(result0.hasModified || r.hasModified) } else r } catch { @@ -2342,7 +2341,6 @@ object Defaults extends BuildCommon { ci: Inputs, promise: PromiseWrap[Boolean], reporter: BuildServerReporter, - prev: CompileAnalysis ): CompileResult = { lazy val x = s.text(ExportStream) def onArgs(cs: Compilers) = { @@ -2364,11 +2362,7 @@ object Defaults extends BuildCommon { .withSetup(onProgress(setup)) try { val result = incCompiler.compile(i, s.log) - reporter.sendSuccessReport( - result.getAnalysis, - prev, - BuildServerProtocol.shouldReportAllPreviousProblems(task.targetId) - ) + reporter.sendSuccessReport(result.getAnalysis) result } catch { case e: Throwable => diff --git a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala index f288d05a3..4e2abdbe8 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala @@ -32,33 +32,20 @@ import sjsonnew.shaded.scalajson.ast.unsafe.{ JNull, JValue } import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter, Parser => JsonParser } import xsbti.CompileFailed +import java.nio.file.Path import java.io.File +import java.util.concurrent.atomic.AtomicBoolean import scala.collection.mutable // import scala.annotation.nowarn import scala.util.control.NonFatal import scala.util.{ Failure, Success, Try } import scala.annotation.nowarn -import scala.collection.concurrent.TrieMap import sbt.testing.Framework object BuildServerProtocol { import sbt.internal.bsp.codec.JsonProtocol._ - /** - * Keep track of those projects that were compiled at least once so that we can - * decide to enable fresh reporting for projects that are compiled for the first time. - * - * see: https://github.com/scalacenter/bloop/issues/726 - */ - private val compiledTargetsAtLeastOnce = new TrieMap[bsp.BuildTargetIdentifier, Boolean]() - def shouldReportAllPreviousProblems(id: bsp.BuildTargetIdentifier): Boolean = { - compiledTargetsAtLeastOnce.putIfAbsent(id, true) match { - case Some(_) => false - case None => true - } - } - private val capabilities = BuildServerCapabilities( CompileProvider(BuildServerConnection.languages), TestProvider(BuildServerConnection.languages), @@ -305,12 +292,20 @@ object BuildServerProtocol { bspScalaMainClassesItem := scalaMainClassesTask.value, Keys.compile / bspReporter := { val targetId = bspTargetIdentifier.value + val bspCompileStateInstance = bspCompileState.value val converter = fileConverter.value val underlying = (Keys.compile / compilerReporter).value val logger = streams.value.log val meta = isMetaBuild.value if (bspEnabled.value) { - new BuildServerReporterImpl(targetId, converter, meta, logger, underlying) + new BuildServerReporterImpl( + targetId, + bspCompileStateInstance, + converter, + meta, + logger, + underlying + ) } else { new BuildServerForwarder(meta, logger, underlying) } @@ -356,7 +351,6 @@ object BuildServerProtocol { case r if r.method == Method.Initialize => val params = Converter.fromJson[InitializeBuildParams](json(r)).get checkMetalsCompatibility(semanticdbEnabled, semanticdbVersion, params, callback.log) - compiledTargetsAtLeastOnce.clear() val response = InitializeBuildResult( "sbt", @@ -714,6 +708,10 @@ object BuildServerProtocol { DependencySourcesItem(targetId, sources.toVector.distinct) } + private def bspCompileState: Initialize[BuildServerProtocol.BspCompileState] = Def.setting { + new BuildServerProtocol.BspCompileState() + } + private def bspCompileTask: Def.Initialize[Task[Int]] = Def.task { Keys.compile.result.value match { case Value(_) => StatusCode.Success @@ -1000,4 +998,20 @@ object BuildServerProtocol { ) } } + + /** + * Additional information about compilation status for given build target. + * + * @param hasAnyProblems keeps track of problems in given file so BSP reporter + * can omit unnecessary diagnostics updates. + * @param compiledAtLeastOnce keeps track of those projects that were compiled at + * least once so that we can decide to enable fresh reporting for projects that + * are compiled for the first time. + * see: https://github.com/scalacenter/bloop/issues/726 + */ + private[server] final class BspCompileState { + val hasAnyProblems: java.util.Set[Path] = + java.util.concurrent.ConcurrentHashMap.newKeySet[Path] + val compiledAtLeastOnce: AtomicBoolean = new AtomicBoolean(false) + } } diff --git a/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala b/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala index 98d59d645..6e04053da 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala @@ -12,6 +12,7 @@ import java.nio.file.Path import sbt.StandardMain import sbt.internal.bsp._ import sbt.internal.util.ManagedLogger +import sbt.internal.server.BuildServerProtocol.BspCompileState import xsbti.compile.CompileAnalysis import xsbti.{ FileConverter, @@ -40,8 +41,6 @@ sealed trait BuildServerReporter extends Reporter { def sendSuccessReport( analysis: CompileAnalysis, - prev: CompileAnalysis, - reportAllPreviousProblems: Boolean ): Unit def sendFailureReport(sources: Array[VirtualFile]): Unit @@ -73,6 +72,7 @@ sealed trait BuildServerReporter extends Reporter { final class BuildServerReporterImpl( buildTarget: BuildTargetIdentifier, + bspCompileState: BspCompileState, converter: FileConverter, protected override val isMetaBuild: Boolean, protected override val logger: ManagedLogger, @@ -90,22 +90,38 @@ final class BuildServerReporterImpl( if (ref.id().contains("<")) None else Some(converter.toPath(ref)) + /** + * Send diagnostics from the compilation to the client. + * Do not send empty diagnostics if previous ones were also empty ones. + * + * @param analysis current compile analysis + */ override def sendSuccessReport( analysis: CompileAnalysis, - prev: CompileAnalysis, - reportAllPreviousProblems: Boolean ): Unit = { - val prevInfos = prev.readSourceInfos().getAllSourceInfos().asScala + val shouldReportAllProblems = !bspCompileState.compiledAtLeastOnce.getAndSet(true) for { (source, infos) <- analysis.readSourceInfos.getAllSourceInfos.asScala filePath <- toSafePath(source) } { - val prevProblems = prevInfos.get(source).map(_.getReportedProblems()).getOrElse(Array.empty) - val dontPublish = prevProblems.length == 0 && infos.getReportedProblems().length == 0 - val shouldPublish = reportAllPreviousProblems || !dontPublish + // clear problems for current file + val hadProblems = bspCompileState.hasAnyProblems.remove(filePath) + + val reportedProblems = infos.getReportedProblems.toVector + val diagnostics = reportedProblems.flatMap(toDiagnostic) + + // publish diagnostics if: + // 1. file had any problems previously - we might want to update them with new ones + // 2. file has fresh problems - we might want to update old ones + // 3. build project is compiled first time - shouldReportAllProblems is set + val shouldPublish = hadProblems || diagnostics.nonEmpty || shouldReportAllProblems + + // file can have some warnings + if (diagnostics.nonEmpty) { + bspCompileState.hasAnyProblems.add(filePath) + } if (shouldPublish) { - val diagnostics = infos.getReportedProblems.toSeq.flatMap(toDiagnostic) val params = PublishDiagnosticsParams( textDocument = TextDocumentIdentifier(filePath.toUri), buildTarget, @@ -117,21 +133,32 @@ final class BuildServerReporterImpl( } } } - override def sendFailureReport(sources: Array[VirtualFile]): Unit = { + val shouldReportAllProblems = !bspCompileState.compiledAtLeastOnce.get for { source <- sources filePath <- toSafePath(source) } { - val diagnostics = problemsByFile.getOrElse(filePath, Vector()) - val params = PublishDiagnosticsParams( - textDocument = TextDocumentIdentifier(filePath.toUri), - buildTarget, - originId = None, - diagnostics, - reset = true - ) - exchange.notifyEvent("build/publishDiagnostics", params) + val diagnostics = problemsByFile.getOrElse(filePath, Vector.empty) + + val hadProblems = bspCompileState.hasAnyProblems.remove(filePath) + val shouldPublish = hadProblems || diagnostics.nonEmpty || shouldReportAllProblems + + // mark file as file with problems + if (diagnostics.nonEmpty) { + bspCompileState.hasAnyProblems.add(filePath) + } + + if (shouldPublish) { + val params = PublishDiagnosticsParams( + textDocument = TextDocumentIdentifier(filePath.toUri), + buildTarget, + originId = None, + diagnostics, + reset = true + ) + exchange.notifyEvent("build/publishDiagnostics", params) + } } } @@ -141,7 +168,7 @@ final class BuildServerReporterImpl( diagnostic <- toDiagnostic(problem) filePath <- toSafePath(VirtualFileRef.of(id)) } { - problemsByFile(filePath) = problemsByFile.getOrElse(filePath, Vector()) :+ diagnostic + problemsByFile(filePath) = problemsByFile.getOrElse(filePath, Vector.empty) :+ diagnostic val params = PublishDiagnosticsParams( TextDocumentIdentifier(filePath.toUri), buildTarget, @@ -196,8 +223,6 @@ final class BuildServerForwarder( override def sendSuccessReport( analysis: CompileAnalysis, - prev: CompileAnalysis, - reportAllPreviousProblems: Boolean ): Unit = () override def sendFailureReport(sources: Array[VirtualFile]): Unit = () diff --git a/server-test/src/server-test/buildserver/build.sbt b/server-test/src/server-test/buildserver/build.sbt index 9d2de35fc..fe2cf4db5 100644 --- a/server-test/src/server-test/buildserver/build.sbt +++ b/server-test/src/server-test/buildserver/build.sbt @@ -32,6 +32,8 @@ lazy val respondError = project.in(file("respond-error")) lazy val util = project +lazy val diagnostics = project + def somethingBad = throw new MessageOnlyException("I am a bad build target") // other build targets should not be affected by this bad build target lazy val badBuildTarget = project.in(file("bad-build-target")) diff --git a/server-test/src/server-test/buildserver/diagnostics/src/main/scala/Diagnostics.scala b/server-test/src/server-test/buildserver/diagnostics/src/main/scala/Diagnostics.scala new file mode 100644 index 000000000..a74b3da77 --- /dev/null +++ b/server-test/src/server-test/buildserver/diagnostics/src/main/scala/Diagnostics.scala @@ -0,0 +1,3 @@ +object Diagnostics { + private val a: Int = 5 +} \ No newline at end of file diff --git a/server-test/src/server-test/buildserver/diagnostics/src/main/scala/PatternMatch.scala b/server-test/src/server-test/buildserver/diagnostics/src/main/scala/PatternMatch.scala new file mode 100644 index 000000000..626a59f8f --- /dev/null +++ b/server-test/src/server-test/buildserver/diagnostics/src/main/scala/PatternMatch.scala @@ -0,0 +1,7 @@ + +class PatternMatch { + val opt: Option[Int] = None + opt match { + case Some(value) => () + } +} diff --git a/server-test/src/test/scala/testpkg/BuildServerTest.scala b/server-test/src/test/scala/testpkg/BuildServerTest.scala index 817b0e6ad..1b8fd06fb 100644 --- a/server-test/src/test/scala/testpkg/BuildServerTest.scala +++ b/server-test/src/test/scala/testpkg/BuildServerTest.scala @@ -71,6 +71,7 @@ object BuildServerTest extends AbstractServerTest { ) assert(sources.contains(expectedSource)) } + test("buildTarget/sources: sbt") { _ => val x = new URI(s"${svr.baseDirectory.getAbsoluteFile.toURI}#buildserver-build") svr.sendJsonRpc(buildTargetSources(26, Seq(x))) @@ -89,13 +90,12 @@ object BuildServerTest extends AbstractServerTest { ).map(rel => new File(svr.baseDirectory.getAbsoluteFile, rel).toURI).sorted assert(sources == expectedSources) } + test("buildTarget/compile") { _ => val buildTarget = buildTargetUri("util", "Compile") - svr.sendJsonRpc( - s"""{ "jsonrpc": "2.0", "id": "32", "method": "buildTarget/compile", "params": { - | "targets": [{ "uri": "$buildTarget" }] - |} }""".stripMargin - ) + + compile(buildTarget, id = 32) + assert(processing("buildTarget/compile")) val res = svr.waitFor[BspCompileResult](10.seconds) assert(res.statusCode == StatusCode.Success) @@ -103,11 +103,8 @@ object BuildServerTest extends AbstractServerTest { test("buildTarget/compile - reports compilation progress") { _ => val buildTarget = buildTargetUri("runAndTest", "Compile") - svr.sendJsonRpc( - s"""{ "jsonrpc": "2.0", "id": "33", "method": "buildTarget/compile", "params": { - | "targets": [{ "uri": "$buildTarget" }] - |} }""".stripMargin - ) + + compile(buildTarget, id = 33) // This doesn't always come back in 10s on CI. assert(svr.waitForString(60.seconds) { s => @@ -134,16 +131,112 @@ object BuildServerTest extends AbstractServerTest { s.contains("build/taskFinish") && s.contains(""""message":"Compiled runAndTest"""") }) + } - svr.sendJsonRpc( - s"""{ "jsonrpc": "2.0", "id": "34", "method": "buildTarget/compile", "params": { - | "targets": [{ "uri": "$buildTarget" }] - |} }""".stripMargin + test( + "buildTarget/compile [diagnostics] don't publish unnecessary for successful compilation case" + ) { _ => + val buildTarget = buildTargetUri("diagnostics", "Compile") + val mainFile = new File(svr.baseDirectory, "diagnostics/src/main/scala/Diagnostics.scala") + + compile(buildTarget, id = 33) + + assert(svr.waitForString(30.seconds) { s => + s.contains("build/taskFinish") && + s.contains(""""message":"Compiled diagnostics"""") + }) + + // introduce compile error + IO.write( + mainFile, + """|object Diagnostics { + | private val a: Int = "" + |}""".stripMargin + ) + + reloadWorkspace(id = 55) + compile(buildTarget, id = 66) + + assert( + svr.waitForString(30.seconds) { s => + s.contains("build/publishDiagnostics") && + s.contains("Diagnostics.scala") && + s.contains("\"message\":\"type mismatch") + }, + "should send publishDiagnostics with type error for Main.scala" + ) + + // fix compilation error + IO.write( + mainFile, + """|object Diagnostics { + | private val a: Int = 5 + |}""".stripMargin + ) + + reloadWorkspace(id = 77) + compile(buildTarget, id = 88) + + assert( + svr.waitForString(30.seconds) { s => + s.contains("build/publishDiagnostics") && + s.contains("Diagnostics.scala") && + s.contains("\"diagnostics\":[]") + }, + "should send publishDiagnostics with empty diagnostics" + ) + + // trigger no-op compilation + compile(buildTarget, id = 99) + + assert( + !svr.waitForString(20.seconds) { s => + s.contains("build/publishDiagnostics") && + s.contains("Diagnostics.scala") + }, + "shouldn't send publishDiagnostics if there's no change in diagnostics (were empty, are empty)" + ) + } + + test("buildTarget/compile [diagnostics] clear stale warnings") { _ => + val buildTarget = buildTargetUri("diagnostics", "Compile") + val testFile = new File(svr.baseDirectory, s"diagnostics/src/main/scala/PatternMatch.scala") + + compile(buildTarget, id = 33) + + assert( + svr.waitForString(30.seconds) { s => + s.contains("build/publishDiagnostics") && + s.contains("PatternMatch.scala") && + s.contains(""""message":"match may not be exhaustive""") + }, + "should send publishDiagnostics with type error for PatternMatch.scala" + ) + + IO.write( + testFile, + """|class PatternMatch { + | val opt: Option[Int] = None + | opt match { + | case Some(value) => () + | case None => () + | } + |} + |""".stripMargin + ) + + reloadWorkspace(id = 55) + compile(buildTarget, id = 66) + + assert( + svr.waitForString(30.seconds) { s => + s.contains("build/publishDiagnostics") && + s.contains("PatternMatch.scala") && + s.contains("\"diagnostics\":[]") + }, + "should send publishDiagnostics with empty diagnostics" ) - assert(!svr.waitForString(30.seconds) { s => - s.contains("build/publishDiagnostics") - }, "shouldn't send publishDiagnostics if there's no change in diagnostics") } test("buildTarget/scalacOptions") { _ => @@ -171,11 +264,7 @@ object BuildServerTest extends AbstractServerTest { .toFile val buildTarget = buildTargetUri("runAndTest", "Compile") - svr.sendJsonRpc( - s"""{ "jsonrpc": "2.0", "id": "43", "method": "buildTarget/compile", "params": { - | "targets": [{ "uri": "$buildTarget" }] - |} }""".stripMargin - ) + compile(buildTarget, id = 43) svr.waitFor[BspCompileResult](10.seconds) assert(targetDir.list().contains("Main.class")) @@ -233,9 +322,7 @@ object BuildServerTest extends AbstractServerTest { |""".stripMargin ) // reload - svr.sendJsonRpc( - """{ "jsonrpc": "2.0", "id": "52", "method": "workspace/reload"}""" - ) + reloadWorkspace(id = 52) assert( svr.waitForString(10.seconds) { s => s.contains(s""""buildTarget":{"uri":"$metaBuildTarget"}""") && @@ -261,9 +348,7 @@ object BuildServerTest extends AbstractServerTest { |) |""".stripMargin ) - svr.sendJsonRpc( - """{ "jsonrpc": "2.0", "id": "52", "method": "workspace/reload"}""" - ) + reloadWorkspace(id = 52) // assert received an empty diagnostic assert( svr.waitForString(10.seconds) { s => @@ -335,10 +420,10 @@ object BuildServerTest extends AbstractServerTest { test("buildTarget/jvmTestEnvironment") { _ => val buildTarget = buildTargetUri("runAndTest", "Test") svr.sendJsonRpc( - s"""|{ "jsonrpc": "2.0", - | "id": "98", - | "method": "buildTarget/jvmTestEnvironment", - | "params": { "targets": [{ "uri": "$buildTarget" }] } + s"""|{ "jsonrpc": "2.0", + | "id": "98", + | "method": "buildTarget/jvmTestEnvironment", + | "params": { "targets": [{ "uri": "$buildTarget" }] } |}""".stripMargin ) assert(processing("buildTarget/jvmTestEnvironment")) @@ -410,11 +495,7 @@ object BuildServerTest extends AbstractServerTest { test("buildTarget/compile: report error") { _ => val buildTarget = buildTargetUri("reportError", "Compile") - svr.sendJsonRpc( - s"""{ "jsonrpc": "2.0", "id": "88", "method": "buildTarget/compile", "params": { - | "targets": [{ "uri": "$buildTarget" }] - |} }""".stripMargin - ) + compile(buildTarget, id = 88) assert(svr.waitForString(10.seconds) { s => (s contains s""""buildTarget":{"uri":"$buildTarget"}""") && (s contains """"severity":1""") && @@ -424,11 +505,7 @@ object BuildServerTest extends AbstractServerTest { test("buildTarget/compile: report warning") { _ => val buildTarget = buildTargetUri("reportWarning", "Compile") - svr.sendJsonRpc( - s"""{ "jsonrpc": "2.0", "id": "90", "method": "buildTarget/compile", "params": { - | "targets": [{ "uri": "$buildTarget" }] - |} }""".stripMargin - ) + compile(buildTarget, id = 90) assert(svr.waitForString(10.seconds) { s => (s contains s""""buildTarget":{"uri":"$buildTarget"}""") && (s contains """"severity":2""") && @@ -438,11 +515,7 @@ object BuildServerTest extends AbstractServerTest { test("buildTarget/compile: respond error") { _ => val buildTarget = buildTargetUri("respondError", "Compile") - svr.sendJsonRpc( - s"""{ "jsonrpc": "2.0", "id": "92", "method": "buildTarget/compile", "params": { - | "targets": [{ "uri": "$buildTarget" }] - |} }""".stripMargin - ) + compile(buildTarget, id = 92) assert(svr.waitForString(10.seconds) { s => s.contains(""""id":"92"""") && s.contains(""""error"""") && @@ -487,6 +560,21 @@ object BuildServerTest extends AbstractServerTest { } } + private def reloadWorkspace(id: Int): Unit = + svr.sendJsonRpc( + s"""{ "jsonrpc": "2.0", "id": "$id", "method": "workspace/reload"}""" + ) + + private def compile(buildTarget: URI, id: Int): Unit = + compile(buildTarget.toString, id) + + private def compile(buildTarget: String, id: Int): Unit = + svr.sendJsonRpc( + s"""{ "jsonrpc": "2.0", "id": "$id", "method": "buildTarget/compile", "params": { + | "targets": [{ "uri": "$buildTarget" }] + |} }""".stripMargin + ) + private def buildTargetSources(id: Int, buildTargets: Seq[URI]): String = { val targets = buildTargets.map(BuildTargetIdentifier.apply).toVector request(id, "buildTarget/sources", SourcesParams(targets)) From 87dc5da93a3b79d27501fc407911d2c7ec65b25e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 25 Jun 2022 18:55:36 -0400 Subject: [PATCH 10/43] Fix sbt trying to delete /tmp on ARM Macs Problem ------- There's a bug in ipcsocket cleanup logic that effectively tries to wipe out /tmp. Workaround ---------- We should fix the underlying bug, but we can start by explicitly configuring the temp directories ipcsocket uses. Ref https://github.com/sbt/sbt/issues/6931 --- .../java/sbt/internal/BootServerSocket.java | 2 +- main/src/main/scala/sbt/internal/Load.scala | 6 ++-- .../src/main/scala/sbt/internal/SysProp.scala | 30 +++++++++++++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/main-command/src/main/java/sbt/internal/BootServerSocket.java b/main-command/src/main/java/sbt/internal/BootServerSocket.java index 5cf91dc50..a64c18951 100644 --- a/main-command/src/main/java/sbt/internal/BootServerSocket.java +++ b/main-command/src/main/java/sbt/internal/BootServerSocket.java @@ -310,7 +310,7 @@ public class BootServerSocket implements AutoCloseable { return "sbt-load" + hash; } else { final String alternativeSocketLocation = - System.getenv().getOrDefault("XDG_RUNTIME_DIR", "/tmp"); + System.getenv().getOrDefault("XDG_RUNTIME_DIR", System.getProperty("java.io.tmpdir")); final Path alternativeSocketLocationRoot = Paths.get(alternativeSocketLocation).resolve(".sbt"); final Path locationForSocket = alternativeSocketLocationRoot.resolve("sbt-socket" + hash); diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index 08965b0ce..834257634 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -101,10 +101,8 @@ private[sbt] object Load { val delegates = defaultDelegates val pluginMgmt = PluginManagement(loader) val inject = InjectSettings(injectGlobal(state), Nil, const(Nil)) - System.setProperty( - "swoval.tmpdir", - System.getProperty("swoval.tmpdir", globalBase.getAbsolutePath.toString) - ) + SysProp.setSwovalTempDir() + SysProp.setIpcSocketTempDir() LoadBuildConfiguration( stagingDirectory, classpath, diff --git a/main/src/main/scala/sbt/internal/SysProp.scala b/main/src/main/scala/sbt/internal/SysProp.scala index 737b0b368..ce5760edd 100644 --- a/main/src/main/scala/sbt/internal/SysProp.scala +++ b/main/src/main/scala/sbt/internal/SysProp.scala @@ -9,6 +9,7 @@ package sbt package internal import java.io.File +import java.nio.file.{ Path, Paths } import java.util.Locale import scala.util.control.NonFatal @@ -220,4 +221,33 @@ object SysProp { lazy val sbtCredentialsEnv: Option[Credentials] = sys.env.get("SBT_CREDENTIALS").map(raw => new FileCredentials(new File(raw))) + + private[sbt] def setSwovalTempDir(): Unit = { + val _ = getOrUpdateSwovalTmpDir( + runtimeDirectory.resolve("swoval").toString + ) + } + private[sbt] def setIpcSocketTempDir(): Unit = { + val _ = getOrUpdateIpcSocketTmpDir( + runtimeDirectory.resolve("ipcsocket").toString + ) + } + private[this] lazy val getOrUpdateSwovalTmpDir: String => String = + getOrUpdateSysProp("swoval.tmpdir")(_) + private[this] lazy val getOrUpdateIpcSocketTmpDir: String => String = + getOrUpdateSysProp("sbt.ipcsocket.tmpdir")(_) + private[this] def getOrUpdateSysProp(key: String)(value: String): String = { + val newVal = sys.props.getOrElse(key, value) + sys.props += (key -> newVal) + newVal + } + + /** + * This returns a temporary directory that is friendly to macOS, Linux, + * Windows, and Docker environment. + * Mostly these directories will be used as throw-away location to extract + * native files etc. + */ + private[this] def runtimeDirectory: Path = + Paths.get(sys.env.getOrElse("XDG_RUNTIME_DIR", sys.props("java.io.tmpdir"))).resolve(".sbt") } From 8973fce1fabca1e50cecc4feda5ddde1f864e2a2 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Sun, 26 Jun 2022 12:31:22 +0200 Subject: [PATCH 11/43] More flexible Scala version switch By using SemanticSelector instead of custom globbing. Follow-up on https://github.com/sbt/sbt/pull/6894, fixes https://github.com/sbt/sbt/issues/6934 --- main/src/main/scala/sbt/Cross.scala | 28 ++++++++----------- main/src/test/scala/sbt/CrossSpec.scala | 20 ------------- .../sbt-test/actions/cross-multiproject/test | 2 +- 3 files changed, 12 insertions(+), 38 deletions(-) delete mode 100644 main/src/test/scala/sbt/CrossSpec.scala diff --git a/main/src/main/scala/sbt/Cross.scala b/main/src/main/scala/sbt/Cross.scala index 9966c5eb9..73b4cadec 100644 --- a/main/src/main/scala/sbt/Cross.scala +++ b/main/src/main/scala/sbt/Cross.scala @@ -8,7 +8,6 @@ package sbt import java.io.File -import java.util.regex.Pattern import sbt.Def.{ ScopedKey, Setting } import sbt.Keys._ import sbt.SlashSyntax0._ @@ -19,7 +18,7 @@ import sbt.internal.util.AttributeKey import sbt.internal.util.complete.DefaultParsers._ import sbt.internal.util.complete.{ DefaultParsers, Parser } import sbt.io.IO -import sbt.librarymanagement.CrossVersion +import sbt.librarymanagement.{ CrossVersion, SemanticSelector, VersionNumber } /** * Cross implements the Scala cross building commands: @@ -327,10 +326,11 @@ object Cross { } ++ structure.units.keys .map(BuildRef.apply) .map(proj => (proj, Some(version), crossVersions(extracted, proj))) - } else if (version.contains('*')) { + } else if (isSelector(version)) { + val selector = SemanticSelector(version) projectScalaVersions.map { case (project, scalaVersions) => - globFilter(version, scalaVersions) match { + scalaVersions.filter(v => selector.matches(VersionNumber(v))) match { case Nil => (project, None, scalaVersions) case Seq(version) => (project, Some(version), scalaVersions) case multiple => @@ -370,19 +370,13 @@ object Cross { (setScalaVersionsForProjects(instance, included, state, extracted), included.map(_._1)) } - def globFilter(pattern: String, candidates: Seq[String]): Seq[String] = { - def createGlobRegex(remainingPattern: String): String = - remainingPattern.indexOf("*") match { - case -1 => Pattern.quote(remainingPattern) - case n => - val chunk = Pattern.quote(remainingPattern.substring(0, n)) + ".*" - if (remainingPattern.length > n) - chunk + createGlobRegex(remainingPattern.substring(n + 1)) - else chunk - } - val compiledPattern = Pattern.compile(createGlobRegex(pattern)) - candidates.filter(compiledPattern.matcher(_).matches()) - } + // determine whether this is a 'specific' version or a selector + // to be passed to SemanticSelector + private def isSelector(version: String): Boolean = + version.contains('*') || version.contains('x') || version.contains('X') || version.contains(' ') || + version.contains('<') || version.contains('>') || version.contains('|') || version.contains( + '=' + ) private def setScalaVersionsForProjects( instance: Option[(File, ScalaInstance)], diff --git a/main/src/test/scala/sbt/CrossSpec.scala b/main/src/test/scala/sbt/CrossSpec.scala deleted file mode 100644 index 40673d548..000000000 --- a/main/src/test/scala/sbt/CrossSpec.scala +++ /dev/null @@ -1,20 +0,0 @@ -/* - * sbt - * Copyright 2011 - 2018, Lightbend, Inc. - * Copyright 2008 - 2010, Mark Harrah - * Licensed under Apache License 2.0 (see LICENSE) - */ - -package sbt - -object CrossSpec extends verify.BasicTestSuite { - import Cross._ - - test("glob filter should work as expected") { - assert(globFilter("2.13.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Seq("2.13.16")) - assert(globFilter("3.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Seq("3.0.1")) - assert(globFilter("3.*", Seq("3.0.1", "30.1")) == Seq("3.0.1")) - assert(globFilter("2.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Seq("2.12.8", "2.13.16")) - assert(globFilter("4.*", Seq("2.12.8", "2.13.16", "3.0.1")) == Nil) - } -} diff --git a/sbt-app/src/sbt-test/actions/cross-multiproject/test b/sbt-app/src/sbt-test/actions/cross-multiproject/test index baf4db9b8..b464e9cb3 100644 --- a/sbt-app/src/sbt-test/actions/cross-multiproject/test +++ b/sbt-app/src/sbt-test/actions/cross-multiproject/test @@ -52,7 +52,7 @@ $ exists sbt-foo/target/scala-2.12 # test wildcard switching (2.13) > clean -> ++ 2.13.* -v compile +> ++ 2.13.x -v compile $ exists lib/target/scala-2.13 -$ exists lib/target/scala-2.12 # -$ exists sbt-foo/target/scala-2.12 From 21e5838cfd3e3fe987a1bd6e7dadfd9201e516ce Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 26 Jun 2022 13:15:50 -0400 Subject: [PATCH 12/43] Build Graal native image using sbt-native-image --- .appveyor.yml | 162 --------------------------------------- .github/workflows/ci.yml | 6 ++ build.sbt | 76 +++--------------- project/plugins.sbt | 1 + 4 files changed, 18 insertions(+), 227 deletions(-) delete mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index a58675259..000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,162 +0,0 @@ -image: - - MacOS - - Visual Studio 2015 - - Visual Studio 2019 - - Ubuntu - -build: off - -init: - - git config --global core.autocrlf input - -for: -- - matrix: - only: - - image: Ubuntu - - branches: - only: - - build-graal - artifacts: - - path: client/target/bin/sbtn - name: sbtn - - install: - - curl -sL https://github.com/sbt/sbt/releases/download/v1.3.10/sbt-1.3.10.tgz > ~/sbt-bin.tgz - - mkdir ~/sbt - - tar -xf ~/sbt-bin.tgz --directory ~/sbt - - curl -sL https://raw.githubusercontent.com/shyiko/jabba/0.11.0/install.sh | bash && . ~/.jabba/jabba.sh - - jabba install adopt@1.8.0-275 - - jabba use adopt@1.8.0-275 - - curl -sL https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.1.0/graalvm-ce-java8-linux-amd64-20.1.0.tar.gz > graalvm.tar.gz - - tar -xf graalvm.tar.gz - - export PATH="~/sbt/sbt/bin:$PATH" - - export PATH="$PATH:~/.jabba/jdk/adopt@1.8.0-275/bin" - - export JAVA_HOME="~/.jabba/jdk/adopt@1.8.0-275" - - test_script: - - export PATH="$PATH:~/.jabba/jdk/adopt@1.8.0-275/bin" - - export PATH="$PATH:graalvm-ce-java8-20.1.0/bin" - - gu install native-image - - sbt "-Dsbt.io.virtual=false" "-Dsbt.native-image=$(pwd)/graalvm-ce-java8-20.1.0/bin/native-image" "sbtClientProj/buildNativeThinClient" - -- - matrix: - only: - - image: MacOS - - branches: - only: - - build-graal - artifacts: - - path: client/target/bin/sbtn - name: mac-native-sbt-client - - install: - - curl -sL https://github.com/sbt/sbt/releases/download/v1.3.10/sbt-1.3.10.tgz > ~/sbt-bin.tgz - - mkdir ~/sbt - - tar -xf ~/sbt-bin.tgz --directory ~/sbt - - curl -sL https://raw.githubusercontent.com/shyiko/jabba/0.11.0/install.sh | bash && . ~/.jabba/jabba.sh - - jabba install adopt@1.8.0-222 - - jabba use adopt@1.8.0-222 - - curl -sL https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.1.0/graalvm-ce-java8-darwin-amd64-20.1.0.tar.gz > graalvm.tar.gz - - tar -xf graalvm.tar.gz - - export PATH="~/sbt/sbt/bin:$PATH" - - export PATH="$PATH:~/.jabba/jdk/adopt@1.8.0-222/bin" - - export JAVA_HOME="~/.jabba/jdk/adopt@1.8.0-222" - - test_script: - - export PATH="$PATH:~/.jabba/jdk/adopt@1.8.0-222/Contents/Home/bin" - - export PATH="$PATH:graalvm-ce-java8-20.1.0/Contents/Home/bin" - - gu install native-image - - sbt "-Dsbt.io.virtual=false" "-Dsbt.native-image=$(pwd)/graalvm-ce-java8-20.1.0/Contents/Home/bin/native-image" "sbtClientProj/buildNativeThinClient" - -- - matrix: - only: - - image: Visual Studio 2015 - branches: - only: - - build-graal - - artifacts: - - path: client\target\bin\sbtn.exe - name: sbtn.exe - install: - - cinst adoptopenjdk8 -params 'installdir=C:\\jdk8' - - SET CI=true - #- choco install windows-sdk-7.1 kb2519277 - - call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" - - - ps: | - Add-Type -AssemblyName System.IO.Compression.FileSystem - if (!(Test-Path -Path "C:\sbt" )) { - (new-object System.Net.WebClient).DownloadFile( - 'https://github.com/sbt/sbt/releases/download/v1.3.10/sbt-1.3.10.zip', - 'C:\sbt-bin.zip' - ) - [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\sbt-bin.zip", "C:\sbt") - } - if (!(Test-Path -Path "C:\graalvm-ce-java8-20.2.0-dev" )) { - (new-object System.Net.WebClient).DownloadFile( - 'https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.1.0/graalvm-ce-java8-windows-amd64-20.1.0.zip', - 'C:\graalvm-ce-java8-20.1.0.zip' - ) - [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\graalvm-ce-java8-20.1.0.zip", "C:\") - } - if (!(Test-Path -Path "C:\zulu-jdk7" )) { - (new-object System.Net.WebClient).DownloadFile( - 'https://cdn.azul.com/zulu/bin/zulu7.38.0.11-ca-jdk7.0.262-win_x64.zip', - 'C:\zulu-jdk7.zip' - ) - [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\zulu-jdk7.zip", "C:\") - } - - SET PATH=C:\graalvm-ce-java8-20.1.0\bin;%PATH% - - SET PATH=C:\sbt\sbt\bin;%PATH% - - SET JAVA_HOME=C:\jdk8 - - gu install native-image - - rm .sbtopts - - cache: - - '%USERPROFILE%\.ivy2\cache' - - '%LOCALAPPDATA%\Coursier\Cache\v1' - - '%USERPROFILE%\.sbt' - - test_script: - - sbt "-Dsbt.io.virtual=false" "-Dsbt.native-image=C:\graalvm-ce-java8-20.1.0\bin\native-image.cmd" "sbtClientProj/buildNativeThinClient" -- - matrix: - only: - - image: Visual Studio 2019 - branches: - except: - - build-graal - install: - - cinst adoptopenjdk8 -params 'installdir=C:\\jdk8' - - SET JAVA_HOME=C:\jdk8 - - SET PATH=C:\jdk8\bin;%PATH% - - SET CI=true - - - ps: | - Add-Type -AssemblyName System.IO.Compression.FileSystem - if (!(Test-Path -Path "C:\sbt" )) { - (new-object System.Net.WebClient).DownloadFile( - 'https://github.com/sbt/sbt/releases/download/v1.3.10/sbt-1.3.10.zip', - 'C:\sbt-bin.zip' - ) - [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\sbt-bin.zip", "C:\sbt") - } - - SET PATH=C:\sbt\sbt\bin;%PATH% - - SET SBT_OPTS=-Xmx4g -Dsbt.supershell=never -Dfile.encoding=UTF8 - - rm .sbtopts - - cache: - - '%USERPROFILE%\.ivy2\cache' - - '%LOCALAPPDATA%\Coursier\Cache\v1' - - '%USERPROFILE%\.sbt' - - test_script: - # The server tests often fail in CI when run together so just run a single test to ensure - # that the thin client works on windows - - sbt "-Dsbt.io.virtual=false" "scripted actions/* reporter/source-mapper classloader-cache/* nio/* watch/*" "serverTestProj/testOnly testpkg.ClientTest" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d09fa04f6..f3ab86d21 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,6 +152,8 @@ jobs: if: ${{ matrix.jobtype == 7 }} shell: bash run: | + # test building sbtn on Linux + sbt "-Dsbt.io.virtual=false" nativeImage # test launcher script echo build using JDK 8 test using JDK 8 and JDK 11 cd launcher-package @@ -165,6 +167,8 @@ jobs: if: ${{ matrix.jobtype == 8 }} shell: bash run: | + # test building sbtn on macOS + sbt "-Dsbt.io.virtual=false" nativeImage # test launcher script echo build using JDK 8, test using JDK 8, on macOS cd launcher-package @@ -175,6 +179,8 @@ jobs: if: ${{ matrix.jobtype == 9 }} shell: bash run: | + # test building sbtn on Windows + sbt "-Dsbt.io.virtual=false" nativeImage # test launcher script echo build using JDK 8, test using JDK 8, on Windows cd launcher-package diff --git a/build.sbt b/build.sbt index ea690b5b3..2fc3ae23e 100644 --- a/build.sbt +++ b/build.sbt @@ -211,7 +211,7 @@ lazy val sbtRoot: Project = (project in file(".")) mimaSettings, mimaPreviousArtifacts := Set.empty, buildThinClient := (sbtClientProj / buildThinClient).evaluated, - buildNativeThinClient := (sbtClientProj / buildNativeThinClient).value, + nativeImage := (sbtClientProj / nativeImage).value, installNativeThinClient := { // nativeInstallDirectory can be set globally or in a gitignored local file val dir = nativeInstallDirectory.?.value @@ -226,7 +226,7 @@ lazy val sbtRoot: Project = (project in file(".")) } } val base = baseDirectory.value.toPath - val exec = (sbtClientProj / buildNativeThinClient).value + val exec = (sbtClientProj / nativeImage).value.toPath streams.value.log.info(s"installing thin client ${base.relativize(exec)} to ${target}") Files.copy(exec, target, java.nio.file.StandardCopyOption.REPLACE_EXISTING) } @@ -1143,17 +1143,11 @@ lazy val serverTestProj = (project in file("server-test")) val isWin = scala.util.Properties.isWin val buildThinClient = inputKey[JPath]("generate a java implementation of the thin client") -val thinClientClasspath = - taskKey[Seq[JPath]]("Generate the classpath for thin client (compacted for windows)") -val thinClientNativeImageCommand = taskKey[String]("The native image command") -val thinClientNativeImageOptions = settingKey[Seq[String]]("The native image options") -val thinClientNativeImageClass = settingKey[String]("The class for the native image") -val buildNativeThinClient = taskKey[JPath]("Generate a native executable") // Use a TaskKey rather than SettingKey for nativeInstallDirectory so it can left unset by default val nativeInstallDirectory = taskKey[JPath]("The install directory for the native executable") val installNativeThinClient = inputKey[JPath]("Install the native executable") -val nativeThinClientPath = settingKey[JPath]("The location of the native executable") lazy val sbtClientProj = (project in file("client")) + .enablePlugins(NativeImagePlugin) .dependsOn(commandProj) .settings( commonBaseSettings, @@ -1164,65 +1158,17 @@ lazy val sbtClientProj = (project in file("client")) crossPaths := false, exportJars := true, libraryDependencies += jansi, - libraryDependencies += scalatest % "test", - /* - * On windows, the raw classpath is too large to be a command argument to an - * external process so we create symbolic links with short names to get the - * classpath length under the limit. - */ - thinClientClasspath := { - val original = (Compile / fullClasspathAsJars).value.map(_.data) - val outputDir = target.value / "thinclientcp" - IO.createDirectory(outputDir) - Files.walk(outputDir.toPath).forEach { - case f if f.getFileName.toString.endsWith(".jar") => Files.deleteIfExists(f) - case _ => - } - original.zipWithIndex.map { - case (f, i) => Files.createSymbolicLink(outputDir.toPath / s"$i.jar", f.toPath) - } + libraryDependencies += scalatest % Test, + Compile / mainClass := Some("sbt.client.Client"), + nativeImageReady := { () => + () }, - thinClientNativeImageCommand := System.getProperty("sbt.native-image", "native-image").toString, - buildNativeThinClient / name := s"sbtn${if (isWin) ".exe" else ""}", - nativeThinClientPath := target.value.toPath / "bin" / (buildNativeThinClient / name).value, - thinClientNativeImageClass := "sbt.client.Client", - buildNativeThinClient := { - val hasChanges = thinClientClasspath.outputFileChanges.hasChanges - val cpString = - thinClientClasspath.value.map(_.getFileName).mkString(java.io.File.pathSeparator) - val prefix = Seq(thinClientNativeImageCommand.value, "-cp", cpString) - val full = prefix ++ thinClientNativeImageOptions.value :+ thinClientNativeImageClass.value - val dir = target.value - if (hasChanges || !Files.exists(nativeThinClientPath.value)) { - val pb = new java.lang.ProcessBuilder(full: _*) - pb.directory(dir / "thinclientcp") - val proc = pb.start() - val thread = new Thread { - setDaemon(true) - val is = proc.getInputStream - val es = proc.getErrorStream - - override def run(): Unit = { - Thread.sleep(100) - while (proc.isAlive) { - if (is.available > 0 || es.available > 0) { - while (is.available > 0) System.out.print(is.read.toChar) - while (es.available > 0) System.err.print(es.read.toChar) - } - if (proc.isAlive) Thread.sleep(10) - } - } - } - thread.start() - proc.waitFor(5, java.util.concurrent.TimeUnit.MINUTES) - assert(proc.exitValue == 0, s"Exit value ${proc.exitValue} was nonzero") - } - nativeThinClientPath.value - }, - thinClientNativeImageOptions := Seq( + nativeImage / name := s"sbtn${if (isWin) ".exe" else ""}", + nativeImageOutput := target.value / "bin" / (nativeImage / name).value, + nativeImageOptions ++= Seq( "--no-fallback", s"--initialize-at-run-time=sbt.client", - "--verbose", + // "--verbose", "-H:IncludeResourceBundles=jline.console.completer.CandidateListCompletionHandler", "-H:+ReportExceptionStackTraces", "-H:-ParseRuntimeOptions", diff --git a/project/plugins.sbt b/project/plugins.sbt index 00c24984e..7f677b694 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -11,4 +11,5 @@ addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1") addSbtPlugin("com.swoval" % "sbt-java-format" % "0.3.1") +addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.1") addDependencyTreePlugin From 0598c9fdc10c65dc1129f1158b07dff4f594360a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 26 Jun 2022 14:37:12 -0400 Subject: [PATCH 13/43] ipcsocket 1.5.0 This bumps to ipcsocket 1.5.0, which fixes the temp directory cleanup bug. Fixes https://github.com/sbt/sbt/issues/6931 Fixes https://github.com/sbt/sbt/issues/6173 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 368646ed4..991e96b03 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -26,7 +26,7 @@ object Dependencies { 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.3.1" + val ipcSocket = "org.scala-sbt.ipcsocket" % "ipcsocket" % "1.5.0" private val compilerInterface = "org.scala-sbt" % "compiler-interface" % zincVersion private val compilerClasspath = "org.scala-sbt" %% "zinc-classpath" % zincVersion From 705d3d58ce16176f107770cb6c998e814251eec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Gonc=CC=A7alves?= Date: Tue, 14 Jun 2022 21:13:25 +0100 Subject: [PATCH 14/43] Filter incompatible Scala 3 projects in cross switch commands --- main/src/main/scala/sbt/Cross.scala | 10 ++++++---- notes/1.7.0/cross-strict-aggregation-scala-3.md | 8 ++++++++ project/Dependencies.scala | 2 +- .../cross-strict-aggregation-scala-3/build.sbt | 14 ++++++++++++++ .../subproj/src/main/scala/A.scala | 6 ++++++ .../actions/cross-strict-aggregation-scala-3/test | 14 ++++++++++++++ 6 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 notes/1.7.0/cross-strict-aggregation-scala-3.md create mode 100644 sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt create mode 100644 sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/subproj/src/main/scala/A.scala create mode 100644 sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/test diff --git a/main/src/main/scala/sbt/Cross.scala b/main/src/main/scala/sbt/Cross.scala index 73b4cadec..86b31ff59 100644 --- a/main/src/main/scala/sbt/Cross.scala +++ b/main/src/main/scala/sbt/Cross.scala @@ -339,16 +339,18 @@ object Cross { ) } } - } else { - val binaryVersion = CrossVersion.binaryScalaVersion(version) + } else + // This is the default implementation for ++ + // It checks that is backward compatible with one of the Scala versions listed + // in crossScalaVersions setting. Note this must account for the fact that in Scala 3.x + // 3.1.0 is not compatible with 3.0.0. projectScalaVersions.map { case (project, scalaVersions) => - if (scalaVersions.exists(v => CrossVersion.binaryScalaVersion(v) == binaryVersion)) + if (scalaVersions.exists(CrossVersion.isScalaBinaryCompatibleWith(version, _))) (project, Some(version), scalaVersions) else (project, None, scalaVersions) } - } } val included = projects.collect { diff --git a/notes/1.7.0/cross-strict-aggregation-scala-3.md b/notes/1.7.0/cross-strict-aggregation-scala-3.md new file mode 100644 index 000000000..8e00c2422 --- /dev/null +++ b/notes/1.7.0/cross-strict-aggregation-scala-3.md @@ -0,0 +1,8 @@ +[@ruippeixotog]: https://github.com/ruippeixotog + +[#6915]: https://github.com/sbt/sbt/issues/6915 +[#6926]: https://github.com/sbt/sbt/pull/6926 + +### Bug Fixes + +- Make `++ ` run `` only on compatible Scala 3 subprojects. [#6915][]/[#6926][] by [@ruippeixotog][] diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 368646ed4..7c7ed6663 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -14,7 +14,7 @@ object Dependencies { // sbt modules private val ioVersion = nightlyVersion.getOrElse("1.6.0") private val lmVersion = - sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.7.0-M1") + sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.7.0-M3") val zincVersion = nightlyVersion.getOrElse("1.7.0-M2") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion 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 new file mode 100644 index 000000000..d5cf2f898 --- /dev/null +++ b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt @@ -0,0 +1,14 @@ +scalaVersion := "2.12.16" + +lazy val core = project + .settings( + crossScalaVersions := Seq("2.12.16", "3.0.2", "3.1.2") + ) + +lazy val subproj = project + .dependsOn(core) + .settings( + crossScalaVersions := Seq("2.12.16", "3.1.2"), + // a random library compiled against Scala 3.1 + libraryDependencies += "org.http4s" %% "http4s-core" % "0.23.12" + ) diff --git a/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/subproj/src/main/scala/A.scala b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/subproj/src/main/scala/A.scala new file mode 100644 index 000000000..da95b9fc4 --- /dev/null +++ b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/subproj/src/main/scala/A.scala @@ -0,0 +1,6 @@ +import org.http4s.Uri + +object A { + // Just using something from http4s + Uri.fromString("example.com") +} 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 new file mode 100644 index 000000000..ea7afbf93 --- /dev/null +++ b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/test @@ -0,0 +1,14 @@ +> ++3.0.2 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 + +> clean +> ++3.1.2 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 From bec2be707ab8f73c83769fcc8b2846d84bd05e4f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 27 Jun 2022 03:09:43 -0400 Subject: [PATCH 15/43] Fix sbtn building --- build.sbt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 2fc3ae23e..42a77a8a3 100644 --- a/build.sbt +++ b/build.sbt @@ -1163,8 +1163,7 @@ lazy val sbtClientProj = (project in file("client")) nativeImageReady := { () => () }, - nativeImage / name := s"sbtn${if (isWin) ".exe" else ""}", - nativeImageOutput := target.value / "bin" / (nativeImage / name).value, + nativeImageOutput := target.value / "bin" / "sbtn", nativeImageOptions ++= Seq( "--no-fallback", s"--initialize-at-run-time=sbt.client", From 498493599f0c080c8da508b11621505f4e2ce287 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 27 Jun 2022 04:08:31 -0400 Subject: [PATCH 16/43] 1.7.0-RC1 --- .github/workflows/ci.yml | 5 ++++- launcher-package/build.sbt | 2 +- sbt | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3ab86d21..40b17cf4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: java: 8 distribution: adopt jobtype: 8 - - os: windows-latest + - os: windows-2019 java: 8 distribution: adopt jobtype: 9 @@ -95,6 +95,9 @@ jobs: with: path: ~/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} + - name: Setup Windows C++ toolchain + uses: ilammy/msvc-dev-cmd@v1 + if: ${{ matrix.os == 'windows-2019' }} - name: Build and test (1) if: ${{ matrix.jobtype == 1 }} shell: bash diff --git a/launcher-package/build.sbt b/launcher-package/build.sbt index ddfdb1f9f..aee72cdaf 100755 --- a/launcher-package/build.sbt +++ b/launcher-package/build.sbt @@ -119,7 +119,7 @@ val root = (project in file(".")). file }, // update sbt.sh at root - sbtnVersion := "1.4.7", + sbtnVersion := "1.7.0-RC1", sbtnJarsBaseUrl := "https://github.com/sbt/sbtn-dist/releases/download", sbtnJarsMappings := { val baseUrl = sbtnJarsBaseUrl.value diff --git a/sbt b/sbt index c7c45a3a2..8fdadc5a1 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.6.2" +declare builtin_sbt_version="1.7.0-RC1" declare -a residual_args declare -a java_args declare -a scalac_args @@ -24,7 +24,7 @@ declare build_props_sbt_version= declare use_sbtn= declare no_server= declare sbtn_command="$SBTN_CMD" -declare sbtn_version="1.4.7" +declare sbtn_version="1.7.0-RC1" ### ------------------------------- ### ### Helper methods for BASH scripts ### From 6a79bdb461944fc7c3b3bbf2015eba96ef542794 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Tue, 28 Jun 2022 07:55:53 +0200 Subject: [PATCH 17/43] Show a more useful log message when doing a flexible version switch Suggested by @SethTisue in https://github.com/sbt/sbt/pull/6894#issuecomment-1168042209 Will show multiple lines when different versions are selected for different subprojects. When no subprojects have a matching Scala version you will get a 'Switch failed' exception anyway, so in that case there is no change in behavior. --- main/src/main/scala/sbt/Cross.scala | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/Cross.scala b/main/src/main/scala/sbt/Cross.scala index 86b31ff59..30ca8a3ee 100644 --- a/main/src/main/scala/sbt/Cross.scala +++ b/main/src/main/scala/sbt/Cross.scala @@ -294,7 +294,14 @@ object Cross { if (switch.version.force) { state.log.info(s"Forcing Scala version to $version on all projects.") } else { - state.log.info(s"Setting Scala version to $version on ${included.size} projects.") + included + .groupBy(_._2) + .foreach { + case (selectedVersion, projects) => + state.log.info( + s"Setting Scala version to $selectedVersion on ${projects.size} projects." + ) + } } if (excluded.nonEmpty && !switch.verbose) { state.log.info(s"Excluded ${excluded.size} projects, run ++ $version -v for more details.") From 697e3bce5182796c57c03fc157f9c05ab3333f2f Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Tue, 28 Jun 2022 08:08:04 +0200 Subject: [PATCH 18/43] Show a more appropriate message when no Scala versions matches When switching scala versions with a wildcard, and no subproject has a matching version to switch to, show a more appropriate error message --- main/src/main/scala/sbt/Cross.scala | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/main/src/main/scala/sbt/Cross.scala b/main/src/main/scala/sbt/Cross.scala index 86b31ff59..103a4568e 100644 --- a/main/src/main/scala/sbt/Cross.scala +++ b/main/src/main/scala/sbt/Cross.scala @@ -15,6 +15,7 @@ import sbt.internal.Act import sbt.internal.CommandStrings._ import sbt.internal.inc.ScalaInstance import sbt.internal.util.AttributeKey +import sbt.internal.util.MessageOnlyException import sbt.internal.util.complete.DefaultParsers._ import sbt.internal.util.complete.{ DefaultParsers, Parser } import sbt.io.IO @@ -361,10 +362,15 @@ object Cross { } if (included.isEmpty) { - sys.error( - s"""Switch failed: no subprojects list "$version" (or compatible version) in crossScalaVersions setting. - |If you want to force it regardless, call ++ $version!""".stripMargin - ) + if (isSelector(version)) + throw new MessageOnlyException( + s"""Switch failed: no subprojects have a version matching "$version" in the crossScalaVersions setting.""" + ) + else + throw new MessageOnlyException( + s"""Switch failed: no subprojects list "$version" (or compatible version) in crossScalaVersions setting. + |If you want to force it regardless, call ++ $version!""".stripMargin + ) } logSwitchInfo(included, excluded) From 05d3d8689bd645ba1507edc5f6fa598610d5409e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 2 Jul 2022 18:19:42 -0400 Subject: [PATCH 19/43] Remove compatibility check from ++ Problem ------- Since sbt-doge merger `++ ` has used binary compatibility as a test to select subproject, but it causes surprising situations like sbt/sbt#6915, and it blurs the responsibility of YAML file and build file as the version specified in the version can override the Scala version test on local laptop. Solution -------- This removes the compatibiliy check (backward-only or otherwise), and require that `` match one of `crossScalaVersions` using the new Semantic Version selector pattern. --- main/src/main/scala/sbt/Cross.scala | 19 ++++--------------- .../scala/sbt/internal/CommandStrings.scala | 12 +++++++++--- .../cross-strict-aggregation/build.sbt | 2 +- .../actions/cross-strict-aggregation/test | 2 ++ 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/main/src/main/scala/sbt/Cross.scala b/main/src/main/scala/sbt/Cross.scala index e56503e05..b6f8447d4 100644 --- a/main/src/main/scala/sbt/Cross.scala +++ b/main/src/main/scala/sbt/Cross.scala @@ -19,7 +19,7 @@ import sbt.internal.util.MessageOnlyException import sbt.internal.util.complete.DefaultParsers._ import sbt.internal.util.complete.{ DefaultParsers, Parser } import sbt.io.IO -import sbt.librarymanagement.{ CrossVersion, SemanticSelector, VersionNumber } +import sbt.librarymanagement.{ SemanticSelector, VersionNumber } /** * Cross implements the Scala cross building commands: @@ -334,10 +334,10 @@ object Cross { } ++ structure.units.keys .map(BuildRef.apply) .map(proj => (proj, Some(version), crossVersions(extracted, proj))) - } else if (isSelector(version)) { - val selector = SemanticSelector(version) + } else { projectScalaVersions.map { case (project, scalaVersions) => + val selector = SemanticSelector(version) scalaVersions.filter(v => selector.matches(VersionNumber(v))) match { case Nil => (project, None, scalaVersions) case Seq(version) => (project, Some(version), scalaVersions) @@ -347,18 +347,7 @@ object Cross { ) } } - } else - // This is the default implementation for ++ - // It checks that is backward compatible with one of the Scala versions listed - // in crossScalaVersions setting. Note this must account for the fact that in Scala 3.x - // 3.1.0 is not compatible with 3.0.0. - projectScalaVersions.map { - case (project, scalaVersions) => - if (scalaVersions.exists(CrossVersion.isScalaBinaryCompatibleWith(version, _))) - (project, Some(version), scalaVersions) - else - (project, None, scalaVersions) - } + } } val included = projects.collect { diff --git a/main/src/main/scala/sbt/internal/CommandStrings.scala b/main/src/main/scala/sbt/internal/CommandStrings.scala index 7c50f506e..78ed93104 100644 --- a/main/src/main/scala/sbt/internal/CommandStrings.scala +++ b/main/src/main/scala/sbt/internal/CommandStrings.scala @@ -387,17 +387,23 @@ $SwitchCommand [=][!] [-v] [] Uses the Scala installation at by configuring the scalaHome setting for all projects. - If is specified, it is used as the value of the scalaVersion setting. + If is specified, it is used to select the value of the scalaVersion setting + from one of the values of crossScalaVersions setting. This is important when using managed dependencies. This version will determine the cross-version used as well as transitive dependencies. - Only projects that are listed to be binary compatible with the selected Scala version + may be an actual Scala version such as 3.1.3, or a Semantic Version selector + pattern such as 2.13.x. Only subprojects that are listed to match the version pattern have their Scala version switched. If ! is supplied, then all projects projects have their Scala version switched. If -v is supplied, verbose logging of the Scala version switching is done. - If is provided, it is then executed. + If is provided, it is then executed. For example: + + ++ 2.13.x test + + The above will run test on all subprojects that contain a 2.13 Scala version. See also `help $CrossCommand` """ 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 b7cb3b5c2..1ffbc3b59 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.12" +lazy val scala212 = "2.12.16" lazy val scala213 = "2.13.1" ThisBuild / scalaVersion := scala212 diff --git a/sbt-app/src/sbt-test/actions/cross-strict-aggregation/test b/sbt-app/src/sbt-test/actions/cross-strict-aggregation/test index 8767e4e22..996094f8e 100644 --- a/sbt-app/src/sbt-test/actions/cross-strict-aggregation/test +++ b/sbt-app/src/sbt-test/actions/cross-strict-aggregation/test @@ -1,5 +1,7 @@ -> ++2.12.0-magic +-> ++2.12.12 + > ++2.13.1 compile $ exists core/target/scala-2.13 From 31a6c60df3698b72bc7dbd8f929ced48cd6be24f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 2 Jul 2022 19:07:34 -0400 Subject: [PATCH 20/43] Banner --- main/src/main/scala/sbt/internal/Banner.scala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main/src/main/scala/sbt/internal/Banner.scala b/main/src/main/scala/sbt/internal/Banner.scala index 0b5a25e71..24e3a9f6b 100644 --- a/main/src/main/scala/sbt/internal/Banner.scala +++ b/main/src/main/scala/sbt/internal/Banner.scala @@ -10,6 +10,15 @@ package sbt.internal private[sbt] object Banner { def apply(version: String): Option[String] = version match { + case v if v.startsWith("1.7.0") => + Some(s""" + |Here are some highlights of this release: + | - `++ ` updates + | - Scala 3 compiler error improvements + | - Improved Build Server Protocol (BSP) support + |See https://eed3si9n.com/sbt-1.7.0 for full release notes. + |Hide the banner for this release by running `skipBanner`. + |""".stripMargin.linesIterator.mkString("\n")) case v if v.startsWith("1.6.0") => Some(s""" |Here are some highlights of this release: From d1ea1f27e64ff7133441c0f313a590acb8b7789d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 2 Jul 2022 19:59:55 -0400 Subject: [PATCH 21/43] 1.7.0-RC2 --- sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt b/sbt index 8fdadc5a1..92f5d8dc3 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.7.0-RC1" +declare builtin_sbt_version="1.7.0-RC2" declare -a residual_args declare -a java_args declare -a scalac_args From d98074e358e99c1edf206f35d8c89382995ae259 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sun, 3 Jul 2022 12:54:56 +0900 Subject: [PATCH 22/43] enable project/source-plugins test --- sbt-app/src/sbt-test/project/source-plugins/build.sbt | 2 +- .../src/sbt-test/project/source-plugins/project/plugin.sbt | 4 ++-- .../sbt-test/project/source-plugins/project/plugins.sbt | 7 ------- .../src/sbt-test/project/source-plugins/{pending => test} | 0 4 files changed, 3 insertions(+), 10 deletions(-) delete mode 100644 sbt-app/src/sbt-test/project/source-plugins/project/plugins.sbt rename sbt-app/src/sbt-test/project/source-plugins/{pending => test} (100%) diff --git a/sbt-app/src/sbt-test/project/source-plugins/build.sbt b/sbt-app/src/sbt-test/project/source-plugins/build.sbt index 0b5906837..c9d463090 100644 --- a/sbt-app/src/sbt-test/project/source-plugins/build.sbt +++ b/sbt-app/src/sbt-test/project/source-plugins/build.sbt @@ -2,6 +2,6 @@ name := "source-plugins" organization := "org.example" -proguardSettings +enablePlugins(SbtProguard) useJGit diff --git a/sbt-app/src/sbt-test/project/source-plugins/project/plugin.sbt b/sbt-app/src/sbt-test/project/source-plugins/project/plugin.sbt index 381215651..e5a6a1f84 100644 --- a/sbt-app/src/sbt-test/project/source-plugins/project/plugin.sbt +++ b/sbt-app/src/sbt-test/project/source-plugins/project/plugin.sbt @@ -1,5 +1,5 @@ -lazy val proguard = uri("git://github.com/sbt/sbt-proguard.git#e7b4732969c137db1b5") -lazy val git = uri("git://github.com/sbt/sbt-git.git#2e7c2503850698d60bb") +lazy val proguard = RootProject(uri("https://github.com/sbt/sbt-proguard.git#95b27788a5b00ab89e8ae7c05ef5bfe538129280")) +lazy val git = RootProject(uri("https://github.com/sbt/sbt-git.git#a81a110af1c5693cd3fd0204248f5c529a43a112")) lazy val root = (project in file(".")). dependsOn(proguard, git) diff --git a/sbt-app/src/sbt-test/project/source-plugins/project/plugins.sbt b/sbt-app/src/sbt-test/project/source-plugins/project/plugins.sbt deleted file mode 100644 index 6dc6ae42e..000000000 --- a/sbt-app/src/sbt-test/project/source-plugins/project/plugins.sbt +++ /dev/null @@ -1,7 +0,0 @@ -lazy val plugins = (project in file(".")) - .dependsOn(proguard, git) - -// e7b4732969c137db1b5 -// d4974f7362bf55d3f52 -lazy val proguard = uri("git://github.com/sbt/sbt-proguard.git#e7b4732969c137db1b5") -lazy val git = uri("git://github.com/sbt/sbt-git.git#2e7c2503850698d60bb") diff --git a/sbt-app/src/sbt-test/project/source-plugins/pending b/sbt-app/src/sbt-test/project/source-plugins/test similarity index 100% rename from sbt-app/src/sbt-test/project/source-plugins/pending rename to sbt-app/src/sbt-test/project/source-plugins/test From 72bfa5e3c87ecb91d2de1326c1ea859f017088b8 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sun, 3 Jul 2022 14:26:18 +0900 Subject: [PATCH 23/43] enable some scripted tests --- .../dependency-management/dynamic-revision/{disabled => test} | 0 sbt-app/src/sbt-test/tests/t543/{disabled => test} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename sbt-app/src/sbt-test/dependency-management/dynamic-revision/{disabled => test} (100%) rename sbt-app/src/sbt-test/tests/t543/{disabled => test} (100%) diff --git a/sbt-app/src/sbt-test/dependency-management/dynamic-revision/disabled b/sbt-app/src/sbt-test/dependency-management/dynamic-revision/test similarity index 100% rename from sbt-app/src/sbt-test/dependency-management/dynamic-revision/disabled rename to sbt-app/src/sbt-test/dependency-management/dynamic-revision/test diff --git a/sbt-app/src/sbt-test/tests/t543/disabled b/sbt-app/src/sbt-test/tests/t543/test similarity index 100% rename from sbt-app/src/sbt-test/tests/t543/disabled rename to sbt-app/src/sbt-test/tests/t543/test From 9c8e99c39080ff6955d655ffed6d5d63fd7a51b3 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sun, 3 Jul 2022 14:45:23 +0900 Subject: [PATCH 24/43] remove sbt-whitesource --- .github/workflows/ci.yml | 1 - build.sbt | 31 ------------------------------- project/plugins.sbt | 1 - 3 files changed, 33 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 40b17cf4d..cf09702f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -110,7 +110,6 @@ jobs: ./sbt -v --client serverTestProj/scalafmtCheckAll ./sbt -v --client headerCheck ./sbt -v --client "Test/headerCheck" - ./sbt -v --client whitesourceOnPush ./sbt -v --client "Test/compile" ./sbt -v --client publishLocal ./sbt -v --client test diff --git a/build.sbt b/build.sbt index 42a77a8a3..138910013 100644 --- a/build.sbt +++ b/build.sbt @@ -50,7 +50,6 @@ Global / semanticdbVersion := "4.5.9" val excludeLint = SettingKey[Set[Def.KeyedInitialize[_]]]("excludeLintKeys") Global / excludeLint := (Global / excludeLint).?.value.getOrElse(Set.empty) Global / excludeLint += componentID -Global / excludeLint += whitesourceIgnoredScopes Global / excludeLint += scriptedBufferLog Global / excludeLint += checkPluginCross @@ -1454,15 +1453,6 @@ def customCommands: Seq[Setting[_]] = Seq( s"""set scalaVersion in ThisBuild := "$scala212" """ :: state }, - commands += Command.command("whitesourceOnPush") { state => - sys.env.get("TRAVIS_EVENT_TYPE") match { - case Some("push") => - "whitesourceCheckPolicies" :: - "whitesourceUpdate" :: - state - case _ => state - } - }, commands += Command.command("release-sbt-local") { state => "clean" :: "so compile" :: @@ -1519,24 +1509,3 @@ ThisBuild / publishTo := { Some("releases" at nexus + "service/local/staging/deploy/maven2") } ThisBuild / publishMavenStyle := true -ThisBuild / whitesourceProduct := "Lightbend Reactive Platform" -ThisBuild / whitesourceAggregateProjectName := { - // note this can get detached on tag build etc - val b = sys.process.Process("git rev-parse --abbrev-ref HEAD").!!.trim - val Stable = """1\.([0-9]+)\.x""".r - b match { - case Stable(y) => "sbt-1." + y.toString + "-stable" - case _ => "sbt-master" - } -} -ThisBuild / whitesourceAggregateProjectToken := { - (ThisBuild / whitesourceAggregateProjectName).value match { - case "sbt-master" => "e7a1e55518c0489a98e9c7430c8b2ccd53d9f97c12ed46148b592ebe4c8bf128" - case "sbt-1.3-stable" => "7e38cbb4d2fc4599835cd5d2cfb41b150597a4147b15424bb65841664ab2ec0d" - case "sbt-1.2-stable" => "54f2313767aa47198971e65595670ee16e1ad0000d20458588e72d3ac2c34763" - case _ => "" // it's ok to fail here - } -} -ThisBuild / whitesourceIgnoredScopes ++= Seq("plugin", "scalafmt", "sxr") -ThisBuild / whitesourceFailOnError := sys.env.contains("WHITESOURCE_PASSWORD") // fail if pwd is present -ThisBuild / whitesourceForceCheckAllDependencies := true diff --git a/project/plugins.sbt b/project/plugins.sbt index 7f677b694..28508259b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -7,7 +7,6 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.3.0") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.1") addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.6.5") -addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1") addSbtPlugin("com.swoval" % "sbt-java-format" % "0.3.1") From 7e68572b10def2f6ee98b71b7de7bc9d218d581d Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Mon, 4 Jul 2022 13:06:08 +0900 Subject: [PATCH 25/43] enable some scripted tests --- .../sbt-test/actions/eval-is-safe-and-sound/{disabled => test} | 0 .../source-dependencies/repeated-parameters/{disabled => test} | 0 .../sbt-test/tests/fork-test-group-parallel/{disabled => test} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename sbt-app/src/sbt-test/actions/eval-is-safe-and-sound/{disabled => test} (100%) rename sbt-app/src/sbt-test/source-dependencies/repeated-parameters/{disabled => test} (100%) rename sbt-app/src/sbt-test/tests/fork-test-group-parallel/{disabled => test} (100%) diff --git a/sbt-app/src/sbt-test/actions/eval-is-safe-and-sound/disabled b/sbt-app/src/sbt-test/actions/eval-is-safe-and-sound/test similarity index 100% rename from sbt-app/src/sbt-test/actions/eval-is-safe-and-sound/disabled rename to sbt-app/src/sbt-test/actions/eval-is-safe-and-sound/test diff --git a/sbt-app/src/sbt-test/source-dependencies/repeated-parameters/disabled b/sbt-app/src/sbt-test/source-dependencies/repeated-parameters/test similarity index 100% rename from sbt-app/src/sbt-test/source-dependencies/repeated-parameters/disabled rename to sbt-app/src/sbt-test/source-dependencies/repeated-parameters/test diff --git a/sbt-app/src/sbt-test/tests/fork-test-group-parallel/disabled b/sbt-app/src/sbt-test/tests/fork-test-group-parallel/test similarity index 100% rename from sbt-app/src/sbt-test/tests/fork-test-group-parallel/disabled rename to sbt-app/src/sbt-test/tests/fork-test-group-parallel/test From c36145fccdfd0298b28b340b26341644562f43cf Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Mon, 4 Jul 2022 11:11:49 -0400 Subject: [PATCH 26/43] Update badges --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4224db130..b169ba27d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -[![Build Status](https://travis-ci.com/sbt/sbt.svg?branch=develop)](https://travis-ci.com/github/sbt/sbt) +[![CI](https://github.com/sbt/sbt/actions/workflows/ci.yml/badge.svg)](https://github.com/sbt/sbt/actions/workflows/ci.yml) [![Latest version](https://img.shields.io/github/tag/sbt/sbt.svg)](https://index.scala-lang.org/sbt/sbt) -[![Gitter Chat](https://badges.gitter.im/sbt/sbt.svg)](https://gitter.im/sbt/sbt) +[![Discord](https://img.shields.io/discord/632150470000902164?label=Discord%20%23sbt)](https://discord.com/channels/632150470000902164/922600050989875282) [sbt/sbt-zero-seven]: https://github.com/sbt/sbt-zero-seven [CONTRIBUTING]: CONTRIBUTING.md From 321ae968471e1fa6ebbded10535bf51a1219726b Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 7 Jul 2022 10:50:17 +0200 Subject: [PATCH 27/43] Add dependency-graph workflow --- .github/workflows/dependency-graph.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/dependency-graph.yml diff --git a/.github/workflows/dependency-graph.yml b/.github/workflows/dependency-graph.yml new file mode 100644 index 000000000..3a865c1d4 --- /dev/null +++ b/.github/workflows/dependency-graph.yml @@ -0,0 +1,14 @@ +# .github/workflows/dependency-graph.yml +name: Submit Dependency Graph +on: + push: + branches: [1.7.x] # default branch of the project +jobs: + submit-graph: + name: Submit Dependency Graph + runs-on: ubuntu-latest # or windows-latest, or macOS-latest + steps: + - uses: actions/checkout@v3 + - uses: scalacenter/sbt-dependency-graph-action@v1 + with: + scala-versions: 2.12.16 From 87bd79e538fc9e3510331d94f296f8c2fbf44593 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Fri, 8 Jul 2022 14:45:43 +0900 Subject: [PATCH 28/43] remove sbt-dotty --- .../src/sbt-test/plugins/dotty-compiler-plugin/build.sbt | 4 ++-- .../plugins/dotty-compiler-plugin/changes/build.sbt | 6 +----- .../plugins/dotty-compiler-plugin/project/plugins.sbt | 1 - sbt-app/src/sbt-test/plugins/dotty-sandwich-sjs/build.sbt | 6 +++--- .../sbt-test/plugins/dotty-sandwich-sjs/project/plugins.sbt | 3 +-- sbt-app/src/sbt-test/plugins/dotty-sandwich/build.sbt | 4 ++-- .../src/sbt-test/plugins/dotty-sandwich/project/plugins.sbt | 1 - sbt-app/src/sbt-test/plugins/dotty/build.sbt | 2 +- sbt-app/src/sbt-test/plugins/dotty/project/build.properties | 3 --- sbt-app/src/sbt-test/plugins/dotty/project/plugins.sbt | 1 - 10 files changed, 10 insertions(+), 21 deletions(-) delete mode 100644 sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/project/plugins.sbt delete mode 100644 sbt-app/src/sbt-test/plugins/dotty-sandwich/project/plugins.sbt delete mode 100644 sbt-app/src/sbt-test/plugins/dotty/project/build.properties delete mode 100644 sbt-app/src/sbt-test/plugins/dotty/project/plugins.sbt diff --git a/sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/build.sbt b/sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/build.sbt index 8aabedac8..8da13c7ec 100644 --- a/sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/build.sbt +++ b/sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "3.0.0-M1" +ThisBuild / scalaVersion := "3.1.3" lazy val plugin = project .in(file("plugin")) @@ -12,7 +12,7 @@ lazy val plugin = project ), libraryDependencies ++= Seq( - "ch.epfl.lamp" %% "dotty-compiler" % scalaVersion.value % "provided" + "org.scala-lang" %% "scala3-compiler" % scalaVersion.value % "provided" ) ) diff --git a/sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/changes/build.sbt b/sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/changes/build.sbt index 584adf234..3c716e1bb 100644 --- a/sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/changes/build.sbt +++ b/sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/changes/build.sbt @@ -1,4 +1,4 @@ -lazy val dottyVersion = "3.0.0-M1" +lazy val dottyVersion = "3.1.3" lazy val plugin = project .in(file("plugin")) @@ -7,10 +7,6 @@ lazy val plugin = project version := "0.0.1", organization := "ch.epfl.lamp", scalaVersion := dottyVersion, - - libraryDependencies ++= Seq( - "ch.epfl.lamp" %% "dotty" % scalaVersion.value % "provided" - ) ) lazy val app = project diff --git a/sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/project/plugins.sbt b/sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/project/plugins.sbt deleted file mode 100644 index 83a3da10f..000000000 --- a/sbt-app/src/sbt-test/plugins/dotty-compiler-plugin/project/plugins.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.4.6") 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 9e2883f48..f28325922 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.4" +ThisBuild / scalaVersion := "2.13.8" ThisBuild / scalacOptions += "-Ytasty-reader" lazy val scala3code = project .enablePlugins(ScalaJSPlugin) - .settings(scalaVersion := "3.0.0-M1") + .settings(scalaVersion := "3.1.3") lazy val app = project .enablePlugins(ScalaJSPlugin) .dependsOn(scala3code) .settings( libraryDependencies ~= (_.filterNot(_.name.contains("scalajs-compiler"))), - addCompilerPlugin("org.scala-js" % "scalajs-compiler_2.13.4" % scalaJSVersion), + addCompilerPlugin("org.scala-js" % "scalajs-compiler_2.13.8" % 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 f0dfae12d..4c620dc0a 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,2 +1 @@ -addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.4.6") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.3.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.1") 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 d6b4a9a34..fe7f9dd1f 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.0.0-M1" +ThisBuild / scalaVersion := "3.1.3" ThisBuild / scalacOptions += "-Ytasty-reader" -lazy val scala213 = "2.13.4" +lazy val scala213 = "2.13.8" lazy val root = (project in file(".")) .aggregate(fooApp, fooCore, barApp, barCore) diff --git a/sbt-app/src/sbt-test/plugins/dotty-sandwich/project/plugins.sbt b/sbt-app/src/sbt-test/plugins/dotty-sandwich/project/plugins.sbt deleted file mode 100644 index 83a3da10f..000000000 --- a/sbt-app/src/sbt-test/plugins/dotty-sandwich/project/plugins.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.4.6") diff --git a/sbt-app/src/sbt-test/plugins/dotty/build.sbt b/sbt-app/src/sbt-test/plugins/dotty/build.sbt index e80bfb07c..e46913668 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.0.0-M1" +ThisBuild / scalaVersion := "3.1.3" diff --git a/sbt-app/src/sbt-test/plugins/dotty/project/build.properties b/sbt-app/src/sbt-test/plugins/dotty/project/build.properties deleted file mode 100644 index 16dc090c5..000000000 --- a/sbt-app/src/sbt-test/plugins/dotty/project/build.properties +++ /dev/null @@ -1,3 +0,0 @@ -# sbt-coursier scripted tests: required, as we default to sbt 1.0.3, -# but sbt-dotty requires sbt >= 1.2.7 -sbt.version=1.2.7 diff --git a/sbt-app/src/sbt-test/plugins/dotty/project/plugins.sbt b/sbt-app/src/sbt-test/plugins/dotty/project/plugins.sbt deleted file mode 100644 index 83a3da10f..000000000 --- a/sbt-app/src/sbt-test/plugins/dotty/project/plugins.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.4.6") From 6788c2e1ca17572bb11ad735c7ed7c783463f9d4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jul 2022 03:40:58 -0400 Subject: [PATCH 29/43] IO 1.7.0 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 6d3e3f63a..3c6f033b8 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -12,7 +12,7 @@ object Dependencies { sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") // sbt modules - private val ioVersion = nightlyVersion.getOrElse("1.6.0") + private val ioVersion = nightlyVersion.getOrElse("1.7.0") private val lmVersion = sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.7.0-M3") val zincVersion = nightlyVersion.getOrElse("1.7.0-M2") From 2462d5fbcf7bf33c75157bb6ff3e4064350f3164 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jul 2022 04:35:57 -0400 Subject: [PATCH 30/43] Fix proxyInputStream#available proxyInputStream does not override available, which broke sbt-site previewSite. This fixes that. --- .../src/main/scala/sbt/internal/util/Terminal.scala | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 873a32871..0019b04e9 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 @@ -675,7 +675,7 @@ object Terminal { } override def close(): Unit = if (running.compareAndSet(true, false)) this.interrupt() } - def read(): Int = { + override def read(): Int = { if (isScripted) -1 else if (bootInputStreamHolder.get == null) activeTerminal.get().inputStream.read() else { @@ -689,6 +689,13 @@ object Terminal { poll() } } + override def available(): Int = + if (isScripted) 0 + else + bootInputStreamHolder.get match { + case null => activeTerminal.get().inputStream.available() + case stream => stream.available() + activeTerminal.get().inputStream.available() + } } private[this] object proxyOutputStream extends OutputStream { private[this] def os: OutputStream = activeTerminal.get().outputStream From 2d27e6deeaf4963333a7f5d5eafd30111b6bc5e2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jul 2022 13:55:14 -0400 Subject: [PATCH 31/43] Update Zinc to 1.7.0 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 3c6f033b8..4826b3cd0 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -14,8 +14,8 @@ object Dependencies { // sbt modules private val ioVersion = nightlyVersion.getOrElse("1.7.0") private val lmVersion = - sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.7.0-M3") - val zincVersion = nightlyVersion.getOrElse("1.7.0-M2") + sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.7.0") + val zincVersion = nightlyVersion.getOrElse("1.7.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 4f38bcbd033536e964da880677b4ea36bad72906 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jul 2022 15:21:21 -0400 Subject: [PATCH 32/43] sbt 1.7.0 --- sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt b/sbt index 92f5d8dc3..9d0690cd5 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.7.0-RC2" +declare builtin_sbt_version="1.7.0" declare -a residual_args declare -a java_args declare -a scalac_args From 79ea2bdaf29dac6fb1ae455bb380d6fefcec7701 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jul 2022 15:43:25 -0400 Subject: [PATCH 33/43] sbtn 1.7.0 --- launcher-package/build.sbt | 2 +- sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher-package/build.sbt b/launcher-package/build.sbt index aee72cdaf..cceaebd16 100755 --- a/launcher-package/build.sbt +++ b/launcher-package/build.sbt @@ -119,7 +119,7 @@ val root = (project in file(".")). file }, // update sbt.sh at root - sbtnVersion := "1.7.0-RC1", + sbtnVersion := "1.7.0", sbtnJarsBaseUrl := "https://github.com/sbt/sbtn-dist/releases/download", sbtnJarsMappings := { val baseUrl = sbtnJarsBaseUrl.value diff --git a/sbt b/sbt index 9d0690cd5..821fc9cbf 100755 --- a/sbt +++ b/sbt @@ -24,7 +24,7 @@ declare build_props_sbt_version= declare use_sbtn= declare no_server= declare sbtn_command="$SBTN_CMD" -declare sbtn_version="1.7.0-RC1" +declare sbtn_version="1.7.0" ### ------------------------------- ### ### Helper methods for BASH scripts ### From fcee055a8c9ea9b447a81b14a1b45098d390b529 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jul 2022 23:50:06 -0400 Subject: [PATCH 34/43] Use sbt 1.7.0 --- build.sbt | 2 ++ project/build.properties | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 138910013..e28e7cca2 100644 --- a/build.sbt +++ b/build.sbt @@ -128,6 +128,8 @@ val sbt13Plus = "1.3.0", "1.4.0", "1.5.0", + "1.6.0", + "1.7.0", ) val sbt10Plus = Seq( diff --git a/project/build.properties b/project/build.properties index c8fcab543..5b12c1dc6 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.6.2 +sbt.version=1.7.0 From 106bc89e0620175aa107bfed3e371bbb160a5dd1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 11 Jul 2022 22:54:42 -0400 Subject: [PATCH 35/43] Update Zinc to 1.7.1 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 4826b3cd0..86df2e8ef 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -15,7 +15,7 @@ object Dependencies { private val ioVersion = nightlyVersion.getOrElse("1.7.0") private val lmVersion = sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.7.0") - val zincVersion = nightlyVersion.getOrElse("1.7.0") + val zincVersion = nightlyVersion.getOrElse("1.7.1") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 38125c534747d4cad12895e64ea1dc4b3f680aa5 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 11 Jul 2022 23:43:06 -0400 Subject: [PATCH 36/43] sbt 1.7.1 --- build.sbt | 2 +- sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index e28e7cca2..7dbc9482c 100644 --- a/build.sbt +++ b/build.sbt @@ -10,7 +10,7 @@ import scala.util.Try // ThisBuild settings take lower precedence, // but can be shared across the multi projects. ThisBuild / version := { - val v = "1.7.0-SNAPSHOT" + val v = "1.7.2-SNAPSHOT" nightlyVersion.getOrElse(v) } ThisBuild / version2_13 := "2.0.0-SNAPSHOT" diff --git a/sbt b/sbt index 821fc9cbf..0becdebc6 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.7.0" +declare builtin_sbt_version="1.7.1" declare -a residual_args declare -a java_args declare -a scalac_args From 8dba607ed85d408467f39c329e7adc864d439c0f Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 15 Jul 2022 11:07:33 +0200 Subject: [PATCH 37/43] Bump sbt-dependency-submission Fix the build on 2.13.8 to submit the corresponding graphs: Remove 2.13.8 in the crossScalaVersions of sbt-dependency-graph scripted-sbt-redux and scripted-sbt because they depend on sbtProj. --- .github/workflows/dependency-graph.yml | 4 +--- build.sbt | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dependency-graph.yml b/.github/workflows/dependency-graph.yml index 3a865c1d4..7caea8278 100644 --- a/.github/workflows/dependency-graph.yml +++ b/.github/workflows/dependency-graph.yml @@ -9,6 +9,4 @@ jobs: runs-on: ubuntu-latest # or windows-latest, or macOS-latest steps: - uses: actions/checkout@v3 - - uses: scalacenter/sbt-dependency-graph-action@v1 - with: - scala-versions: 2.12.16 + - uses: scalacenter/sbt-dependency-submission@v2 diff --git a/build.sbt b/build.sbt index 7dbc9482c..8ffea7edc 100644 --- a/build.sbt +++ b/build.sbt @@ -622,6 +622,7 @@ lazy val scriptedSbtReduxProj = (project in file("scripted-sbt-redux")) .dependsOn(sbtProj % "compile;test->test", commandProj, utilLogging, utilScripted) .settings( baseSettings, + crossScalaVersions := Seq(baseScalaVersion), name := "Scripted sbt Redux", libraryDependencies ++= Seq(launcherInterface % "provided"), mimaSettings, @@ -633,6 +634,7 @@ lazy val scriptedSbtOldProj = (project in file("scripted-sbt-old")) .dependsOn(scriptedSbtReduxProj) .settings( baseSettings, + crossScalaVersions := Seq(baseScalaVersion), name := "Scripted sbt", mimaSettings, mimaBinaryIssueFilters ++= Seq( @@ -660,6 +662,7 @@ lazy val dependencyTreeProj = (project in file("dependency-tree")) .settings( sbtPlugin := true, baseSettings, + crossScalaVersions := Seq(baseScalaVersion), name := "sbt-dependency-tree", publishMavenStyle := true, // mimaSettings, From 683f2e929149a52fc2237d2c832ab5116274fe5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Jul 2022 04:02:58 +0000 Subject: [PATCH 38/43] Bump actions/cache from 3.0.4 to 3.0.5 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.4 to 3.0.5. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.4...v3.0.5) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf09702f8..c252d6598 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: - name: Coursier cache uses: coursier/cache-action@v6 - name: Cache sbt - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.5 with: path: ~/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} From 5c933679faee776e36a435d6657191ec7af60f58 Mon Sep 17 00:00:00 2001 From: Jason Pickens Date: Wed, 27 Jul 2022 11:56:27 +1200 Subject: [PATCH 39/43] fix: change BSP JVM environment working directory to be a path --- .../main/scala/sbt/internal/server/BuildServerProtocol.scala | 2 +- server-test/src/test/scala/testpkg/BuildServerTest.scala | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala index 4e2abdbe8..831902d55 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala @@ -661,7 +661,7 @@ object BuildServerProtocol { val target = Keys.bspTargetIdentifier.value val classpath = Keys.fullClasspath.value.map(_.data.toURI).toVector val jvmOptions = Keys.javaOptions.value.toVector - val baseDir = Keys.baseDirectory.value.toURI().toString() + val baseDir = Keys.baseDirectory.value.getAbsolutePath val env = envVars.value JvmEnvironmentItem( diff --git a/server-test/src/test/scala/testpkg/BuildServerTest.scala b/server-test/src/test/scala/testpkg/BuildServerTest.scala index 1b8fd06fb..da4659fe1 100644 --- a/server-test/src/test/scala/testpkg/BuildServerTest.scala +++ b/server-test/src/test/scala/testpkg/BuildServerTest.scala @@ -412,7 +412,7 @@ object BuildServerTest extends AbstractServerTest { (s contains "jsoniter-scala-core_2.13-2.13.11.jar") && // compile dependency (s contains "\"jvmOptions\":[\"Xmx256M\"]") && (s contains "\"environmentVariables\":{\"KEY\":\"VALUE\"}") && - (s contains "/buildserver/run-and-test/") // working directory + (s contains s""""workingDirectory":"${svr.baseDirectory.getAbsolutePath}/run-and-test"""") } } } @@ -434,7 +434,8 @@ object BuildServerTest extends AbstractServerTest { (s contains "jsoniter-scala-core_2.13-2.13.11.jar") && // compile dependency (s contains "scalatest_2.13-3.0.8.jar") && // test dependency (s contains "\"jvmOptions\":[\"Xmx512M\"]") && - (s contains "\"environmentVariables\":{\"KEY_TEST\":\"VALUE_TEST\"}") + (s contains "\"environmentVariables\":{\"KEY_TEST\":\"VALUE_TEST\"}") && + (s contains s""""workingDirectory":"${svr.baseDirectory.getAbsolutePath}/run-and-test"""") } } } From 58f0ff612c2e3bfd9ef7b9c991efb2a73c1b248c Mon Sep 17 00:00:00 2001 From: Krzysztof Pado Date: Wed, 27 Jul 2022 19:40:18 -0700 Subject: [PATCH 40/43] Add support for BSP's buildTarget/outputPaths method --- main/src/main/scala/sbt/Keys.scala | 2 ++ .../internal/server/BuildServerProtocol.scala | 22 ++++++++++++ notes/1.8.0/bsp-output-paths.md | 4 +++ .../bsp/BuildServerCapabilities.scala | 21 +++++++---- .../sbt/internal/bsp/OutputPathItem.scala | 36 +++++++++++++++++++ .../sbt/internal/bsp/OutputPathsItem.scala | 36 +++++++++++++++++++ .../sbt/internal/bsp/OutputPathsParams.scala | 33 +++++++++++++++++ .../sbt/internal/bsp/OutputPathsResult.scala | 33 +++++++++++++++++ .../BuildServerCapabilitiesFormats.scala | 4 ++- .../bsp/codec/ExcludeItemFormats.scala | 29 +++++++++++++++ .../bsp/codec/ExcludesItemFormats.scala | 29 +++++++++++++++ .../bsp/codec/ExcludesParamsFormats.scala | 27 ++++++++++++++ .../bsp/codec/ExcludesResultFormats.scala | 27 ++++++++++++++ .../sbt/internal/bsp/codec/JsonProtocol.scala | 4 +++ .../bsp/codec/OutputPathItemFormats.scala | 29 +++++++++++++++ .../bsp/codec/OutputPathsItemFormats.scala | 29 +++++++++++++++ .../bsp/codec/OutputPathsParamsFormats.scala | 27 ++++++++++++++ .../bsp/codec/OutputPathsResultFormats.scala | 27 ++++++++++++++ protocol/src/main/contraband/bsp.contra | 24 +++++++++++++ .../internal/bsp/BuildServerConnection.scala | 2 +- .../sbt/internal/bsp/OutputPathItemKind.scala | 17 +++++++++ .../src/server-test/buildserver/build.sbt | 5 ++- .../test/scala/testpkg/BuildServerTest.scala | 31 ++++++++++++++-- 23 files changed, 486 insertions(+), 12 deletions(-) create mode 100644 notes/1.8.0/bsp-output-paths.md create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathItem.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsItem.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsParams.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsResult.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludeItemFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesItemFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesParamsFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesResultFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathItemFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsItemFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsParamsFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsResultFormats.scala create mode 100644 protocol/src/main/scala/sbt/internal/bsp/OutputPathItemKind.scala diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 392812271..10ae7f1b1 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -412,6 +412,8 @@ object Keys { val bspBuildTargetResourcesItem = taskKey[ResourcesItem]("").withRank(DTask) val bspBuildTargetDependencySources = inputKey[Unit]("").withRank(DTask) val bspBuildTargetDependencySourcesItem = taskKey[DependencySourcesItem]("").withRank(DTask) + val bspBuildTargetOutputPaths = inputKey[Unit]("").withRank(DTask) + val bspBuildTargetOutputPathsItem = taskKey[OutputPathsItem]("").withRank(DTask) val bspBuildTargetCompile = inputKey[Unit]("").withRank(DTask) val bspBuildTargetCompileItem = taskKey[Int]("").withRank(DTask) val bspBuildTargetTest = inputKey[Unit]("Corresponds to buildTarget/test request").withRank(DTask) diff --git a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala index 831902d55..b9aaff3a5 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala @@ -52,6 +52,7 @@ object BuildServerProtocol { RunProvider(BuildServerConnection.languages), dependencySourcesProvider = true, resourcesProvider = true, + outputPathsProvider = true, canReload = true, jvmRunEnvironmentProvider = true, jvmTestEnvironmentProvider = true, @@ -158,6 +159,16 @@ object BuildServerProtocol { } }.evaluated, bspBuildTargetDependencySources / aggregate := false, + bspBuildTargetOutputPaths := bspInputTask { (state, _, workspace, filter) => + Def.task { + import sbt.internal.bsp.codec.JsonProtocol._ + val items = bspBuildTargetOutputPathsItem.result.all(filter).value + val successfulItems = anyOrThrow(items) + val result = OutputPathsResult(successfulItems.toVector) + state.respondEvent(result) + } + }.evaluated, + bspBuildTargetOutputPaths / aggregate := false, bspBuildTargetCompile := bspInputTask { (state, _, workspace, filter) => workspace.warnIfBuildsNonEmpty(Method.Compile, state.log) Def.task { @@ -267,6 +278,10 @@ object BuildServerProtocol { ResourcesItem(id, uris) }, bspBuildTargetDependencySourcesItem := dependencySourcesItemTask.value, + bspBuildTargetOutputPathsItem := { + val id = bspTargetIdentifier.value + OutputPathsItem(id, Vector(OutputPathItem(target.value.toURI, OutputPathItemKind.Directory))) + }, bspBuildTargetCompileItem := bspCompileTask.value, bspBuildTargetRun := bspRunTask.evaluated, bspBuildTargetScalacOptionsItem := scalacOptionsTask.value, @@ -318,6 +333,7 @@ object BuildServerProtocol { final val Shutdown = "build/shutdown" final val Sources = "buildTarget/sources" final val Resources = "buildTarget/resources" + final val OutputPaths = "buildTarget/outputPaths" final val DependencySources = "buildTarget/dependencySources" final val Compile = "buildTarget/compile" final val Test = "buildTarget/test" @@ -453,6 +469,12 @@ object BuildServerProtocol { val targets = param.targets.map(_.uri).mkString(" ") val command = Keys.bspBuildTargetResources.key val _ = callback.appendExec(s"$command $targets", Some(r.id)) + + case r if r.method == Method.OutputPaths => + val param = Converter.fromJson[OutputPathsParams](json(r)).get + val targets = param.targets.map(_.uri).mkString(" ") + val command = Keys.bspBuildTargetOutputPaths.key + val _ = callback.appendExec(s"$command $targets", Some(r.id)) }, onResponse = PartialFunction.empty, onNotification = { diff --git a/notes/1.8.0/bsp-output-paths.md b/notes/1.8.0/bsp-output-paths.md new file mode 100644 index 000000000..a59adde1c --- /dev/null +++ b/notes/1.8.0/bsp-output-paths.md @@ -0,0 +1,4 @@ +[@povder]: https://github.com/povder + +### Improvements +- Add support for newly introduced `buildTarget/outputPaths` method of BSP protocol. See [bsp#269](https://github.com/build-server-protocol/build-server-protocol/pull/269) pull request and [bsp#205](https://github.com/build-server-protocol/build-server-protocol/issues/205) issue. diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/BuildServerCapabilities.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/BuildServerCapabilities.scala index 82f88a090..4d625cce9 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/BuildServerCapabilities.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/BuildServerCapabilities.scala @@ -17,6 +17,7 @@ final class BuildServerCapabilities private ( val runProvider: Option[sbt.internal.bsp.RunProvider], val dependencySourcesProvider: Option[Boolean], val resourcesProvider: Option[Boolean], + val outputPathsProvider: Option[Boolean], val canReload: Option[Boolean], val jvmRunEnvironmentProvider: Option[Boolean], val jvmTestEnvironmentProvider: Option[Boolean]) extends Serializable { @@ -24,17 +25,17 @@ final class BuildServerCapabilities private ( override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { - case x: BuildServerCapabilities => (this.compileProvider == x.compileProvider) && (this.testProvider == x.testProvider) && (this.runProvider == x.runProvider) && (this.dependencySourcesProvider == x.dependencySourcesProvider) && (this.resourcesProvider == x.resourcesProvider) && (this.canReload == x.canReload) && (this.jvmRunEnvironmentProvider == x.jvmRunEnvironmentProvider) && (this.jvmTestEnvironmentProvider == x.jvmTestEnvironmentProvider) + case x: BuildServerCapabilities => (this.compileProvider == x.compileProvider) && (this.testProvider == x.testProvider) && (this.runProvider == x.runProvider) && (this.dependencySourcesProvider == x.dependencySourcesProvider) && (this.resourcesProvider == x.resourcesProvider) && (this.outputPathsProvider == x.outputPathsProvider) && (this.canReload == x.canReload) && (this.jvmRunEnvironmentProvider == x.jvmRunEnvironmentProvider) && (this.jvmTestEnvironmentProvider == x.jvmTestEnvironmentProvider) case _ => false }) override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.BuildServerCapabilities".##) + compileProvider.##) + testProvider.##) + runProvider.##) + dependencySourcesProvider.##) + resourcesProvider.##) + canReload.##) + jvmRunEnvironmentProvider.##) + jvmTestEnvironmentProvider.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.BuildServerCapabilities".##) + compileProvider.##) + testProvider.##) + runProvider.##) + dependencySourcesProvider.##) + resourcesProvider.##) + outputPathsProvider.##) + canReload.##) + jvmRunEnvironmentProvider.##) + jvmTestEnvironmentProvider.##) } override def toString: String = { - "BuildServerCapabilities(" + compileProvider + ", " + testProvider + ", " + runProvider + ", " + dependencySourcesProvider + ", " + resourcesProvider + ", " + canReload + ", " + jvmRunEnvironmentProvider + ", " + jvmTestEnvironmentProvider + ")" + "BuildServerCapabilities(" + compileProvider + ", " + testProvider + ", " + runProvider + ", " + dependencySourcesProvider + ", " + resourcesProvider + ", " + outputPathsProvider + ", " + canReload + ", " + jvmRunEnvironmentProvider + ", " + jvmTestEnvironmentProvider + ")" } - private[this] def copy(compileProvider: Option[sbt.internal.bsp.CompileProvider] = compileProvider, testProvider: Option[sbt.internal.bsp.TestProvider] = testProvider, runProvider: Option[sbt.internal.bsp.RunProvider] = runProvider, dependencySourcesProvider: Option[Boolean] = dependencySourcesProvider, resourcesProvider: Option[Boolean] = resourcesProvider, canReload: Option[Boolean] = canReload, jvmRunEnvironmentProvider: Option[Boolean] = jvmRunEnvironmentProvider, jvmTestEnvironmentProvider: Option[Boolean] = jvmTestEnvironmentProvider): BuildServerCapabilities = { - new BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider) + private[this] def copy(compileProvider: Option[sbt.internal.bsp.CompileProvider] = compileProvider, testProvider: Option[sbt.internal.bsp.TestProvider] = testProvider, runProvider: Option[sbt.internal.bsp.RunProvider] = runProvider, dependencySourcesProvider: Option[Boolean] = dependencySourcesProvider, resourcesProvider: Option[Boolean] = resourcesProvider, outputPathsProvider: Option[Boolean] = outputPathsProvider, canReload: Option[Boolean] = canReload, jvmRunEnvironmentProvider: Option[Boolean] = jvmRunEnvironmentProvider, jvmTestEnvironmentProvider: Option[Boolean] = jvmTestEnvironmentProvider): BuildServerCapabilities = { + new BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, outputPathsProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider) } def withCompileProvider(compileProvider: Option[sbt.internal.bsp.CompileProvider]): BuildServerCapabilities = { copy(compileProvider = compileProvider) @@ -66,6 +67,12 @@ final class BuildServerCapabilities private ( def withResourcesProvider(resourcesProvider: Boolean): BuildServerCapabilities = { copy(resourcesProvider = Option(resourcesProvider)) } + def withOutputPathsProvider(outputPathsProvider: Option[Boolean]): BuildServerCapabilities = { + copy(outputPathsProvider = outputPathsProvider) + } + def withOutputPathsProvider(outputPathsProvider: Boolean): BuildServerCapabilities = { + copy(outputPathsProvider = Option(outputPathsProvider)) + } def withCanReload(canReload: Option[Boolean]): BuildServerCapabilities = { copy(canReload = canReload) } @@ -87,6 +94,6 @@ final class BuildServerCapabilities private ( } object BuildServerCapabilities { - def apply(compileProvider: Option[sbt.internal.bsp.CompileProvider], testProvider: Option[sbt.internal.bsp.TestProvider], runProvider: Option[sbt.internal.bsp.RunProvider], dependencySourcesProvider: Option[Boolean], resourcesProvider: Option[Boolean], canReload: Option[Boolean], jvmRunEnvironmentProvider: Option[Boolean], jvmTestEnvironmentProvider: Option[Boolean]): BuildServerCapabilities = new BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider) - def apply(compileProvider: sbt.internal.bsp.CompileProvider, testProvider: sbt.internal.bsp.TestProvider, runProvider: sbt.internal.bsp.RunProvider, dependencySourcesProvider: Boolean, resourcesProvider: Boolean, canReload: Boolean, jvmRunEnvironmentProvider: Boolean, jvmTestEnvironmentProvider: Boolean): BuildServerCapabilities = new BuildServerCapabilities(Option(compileProvider), Option(testProvider), Option(runProvider), Option(dependencySourcesProvider), Option(resourcesProvider), Option(canReload), Option(jvmRunEnvironmentProvider), Option(jvmTestEnvironmentProvider)) + def apply(compileProvider: Option[sbt.internal.bsp.CompileProvider], testProvider: Option[sbt.internal.bsp.TestProvider], runProvider: Option[sbt.internal.bsp.RunProvider], dependencySourcesProvider: Option[Boolean], resourcesProvider: Option[Boolean], outputPathsProvider: Option[Boolean], canReload: Option[Boolean], jvmRunEnvironmentProvider: Option[Boolean], jvmTestEnvironmentProvider: Option[Boolean]): BuildServerCapabilities = new BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, outputPathsProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider) + def apply(compileProvider: sbt.internal.bsp.CompileProvider, testProvider: sbt.internal.bsp.TestProvider, runProvider: sbt.internal.bsp.RunProvider, dependencySourcesProvider: Boolean, resourcesProvider: Boolean, outputPathsProvider: Boolean, canReload: Boolean, jvmRunEnvironmentProvider: Boolean, jvmTestEnvironmentProvider: Boolean): BuildServerCapabilities = new BuildServerCapabilities(Option(compileProvider), Option(testProvider), Option(runProvider), Option(dependencySourcesProvider), Option(resourcesProvider), Option(outputPathsProvider), Option(canReload), Option(jvmRunEnvironmentProvider), Option(jvmTestEnvironmentProvider)) } diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathItem.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathItem.scala new file mode 100644 index 000000000..da00ff79c --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathItem.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.bsp +final class OutputPathItem private ( + val uri: java.net.URI, + val kind: Int) extends Serializable { + + + + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { + case x: OutputPathItem => (this.uri == x.uri) && (this.kind == x.kind) + case _ => false + }) + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.internal.bsp.OutputPathItem".##) + uri.##) + kind.##) + } + override def toString: String = { + "OutputPathItem(" + uri + ", " + kind + ")" + } + private[this] def copy(uri: java.net.URI = uri, kind: Int = kind): OutputPathItem = { + new OutputPathItem(uri, kind) + } + def withUri(uri: java.net.URI): OutputPathItem = { + copy(uri = uri) + } + def withKind(kind: Int): OutputPathItem = { + copy(kind = kind) + } +} +object OutputPathItem { + + def apply(uri: java.net.URI, kind: Int): OutputPathItem = new OutputPathItem(uri, kind) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsItem.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsItem.scala new file mode 100644 index 000000000..f101d7555 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsItem.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.bsp +final class OutputPathsItem private ( + val target: sbt.internal.bsp.BuildTargetIdentifier, + val outputPaths: Vector[sbt.internal.bsp.OutputPathItem]) extends Serializable { + + + + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { + case x: OutputPathsItem => (this.target == x.target) && (this.outputPaths == x.outputPaths) + case _ => false + }) + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.internal.bsp.OutputPathsItem".##) + target.##) + outputPaths.##) + } + override def toString: String = { + "OutputPathsItem(" + target + ", " + outputPaths + ")" + } + private[this] def copy(target: sbt.internal.bsp.BuildTargetIdentifier = target, outputPaths: Vector[sbt.internal.bsp.OutputPathItem] = outputPaths): OutputPathsItem = { + new OutputPathsItem(target, outputPaths) + } + def withTarget(target: sbt.internal.bsp.BuildTargetIdentifier): OutputPathsItem = { + copy(target = target) + } + def withOutputPaths(outputPaths: Vector[sbt.internal.bsp.OutputPathItem]): OutputPathsItem = { + copy(outputPaths = outputPaths) + } +} +object OutputPathsItem { + + def apply(target: sbt.internal.bsp.BuildTargetIdentifier, outputPaths: Vector[sbt.internal.bsp.OutputPathItem]): OutputPathsItem = new OutputPathsItem(target, outputPaths) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsParams.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsParams.scala new file mode 100644 index 000000000..4a1d97c43 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsParams.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.bsp +/** Build Target OutputPaths Request */ +final class OutputPathsParams private ( + val targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]) extends Serializable { + + + + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { + case x: OutputPathsParams => (this.targets == x.targets) + case _ => false + }) + override def hashCode: Int = { + 37 * (37 * (17 + "sbt.internal.bsp.OutputPathsParams".##) + targets.##) + } + override def toString: String = { + "OutputPathsParams(" + targets + ")" + } + private[this] def copy(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier] = targets): OutputPathsParams = { + new OutputPathsParams(targets) + } + def withTargets(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]): OutputPathsParams = { + copy(targets = targets) + } +} +object OutputPathsParams { + + def apply(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]): OutputPathsParams = new OutputPathsParams(targets) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsResult.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsResult.scala new file mode 100644 index 000000000..50e2062bd --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/OutputPathsResult.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.bsp +/** Build Target OutputPaths response */ +final class OutputPathsResult private ( + val items: Vector[sbt.internal.bsp.OutputPathsItem]) extends Serializable { + + + + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { + case x: OutputPathsResult => (this.items == x.items) + case _ => false + }) + override def hashCode: Int = { + 37 * (37 * (17 + "sbt.internal.bsp.OutputPathsResult".##) + items.##) + } + override def toString: String = { + "OutputPathsResult(" + items + ")" + } + private[this] def copy(items: Vector[sbt.internal.bsp.OutputPathsItem] = items): OutputPathsResult = { + new OutputPathsResult(items) + } + def withItems(items: Vector[sbt.internal.bsp.OutputPathsItem]): OutputPathsResult = { + copy(items = items) + } +} +object OutputPathsResult { + + def apply(items: Vector[sbt.internal.bsp.OutputPathsItem]): OutputPathsResult = new OutputPathsResult(items) +} 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 c23b3db80..9c8684ba3 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 @@ -16,11 +16,12 @@ implicit lazy val BuildServerCapabilitiesFormat: JsonFormat[sbt.internal.bsp.Bui val runProvider = unbuilder.readField[Option[sbt.internal.bsp.RunProvider]]("runProvider") val dependencySourcesProvider = unbuilder.readField[Option[Boolean]]("dependencySourcesProvider") val resourcesProvider = unbuilder.readField[Option[Boolean]]("resourcesProvider") + val outputPathsProvider = unbuilder.readField[Option[Boolean]]("outputPathsProvider") val canReload = unbuilder.readField[Option[Boolean]]("canReload") val jvmRunEnvironmentProvider = unbuilder.readField[Option[Boolean]]("jvmRunEnvironmentProvider") val jvmTestEnvironmentProvider = unbuilder.readField[Option[Boolean]]("jvmTestEnvironmentProvider") unbuilder.endObject() - sbt.internal.bsp.BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider) + sbt.internal.bsp.BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, outputPathsProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider) case None => deserializationError("Expected JsObject but found None") } @@ -32,6 +33,7 @@ implicit lazy val BuildServerCapabilitiesFormat: JsonFormat[sbt.internal.bsp.Bui builder.addField("runProvider", obj.runProvider) builder.addField("dependencySourcesProvider", obj.dependencySourcesProvider) builder.addField("resourcesProvider", obj.resourcesProvider) + builder.addField("outputPathsProvider", obj.outputPathsProvider) builder.addField("canReload", obj.canReload) builder.addField("jvmRunEnvironmentProvider", obj.jvmRunEnvironmentProvider) builder.addField("jvmTestEnvironmentProvider", obj.jvmTestEnvironmentProvider) diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludeItemFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludeItemFormats.scala new file mode 100644 index 000000000..6e65b8630 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludeItemFormats.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 ExcludeItemFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val ExcludeItemFormat: JsonFormat[sbt.internal.bsp.ExcludeItem] = new JsonFormat[sbt.internal.bsp.ExcludeItem] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ExcludeItem = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val uri = unbuilder.readField[java.net.URI]("uri") + val kind = unbuilder.readField[Int]("kind") + unbuilder.endObject() + sbt.internal.bsp.ExcludeItem(uri, kind) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.bsp.ExcludeItem, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("uri", obj.uri) + builder.addField("kind", obj.kind) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesItemFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesItemFormats.scala new file mode 100644 index 000000000..cc324552f --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesItemFormats.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 ExcludesItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.bsp.codec.ExcludeItemFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ExcludesItemFormat: JsonFormat[sbt.internal.bsp.ExcludesItem] = new JsonFormat[sbt.internal.bsp.ExcludesItem] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ExcludesItem = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val target = unbuilder.readField[sbt.internal.bsp.BuildTargetIdentifier]("target") + val excludes = unbuilder.readField[Vector[sbt.internal.bsp.ExcludeItem]]("excludes") + unbuilder.endObject() + sbt.internal.bsp.ExcludesItem(target, excludes) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.bsp.ExcludesItem, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("target", obj.target) + builder.addField("excludes", obj.excludes) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesParamsFormats.scala new file mode 100644 index 000000000..f43a536c3 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesParamsFormats.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.bsp.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ExcludesParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ExcludesParamsFormat: JsonFormat[sbt.internal.bsp.ExcludesParams] = new JsonFormat[sbt.internal.bsp.ExcludesParams] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ExcludesParams = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val targets = unbuilder.readField[Vector[sbt.internal.bsp.BuildTargetIdentifier]]("targets") + unbuilder.endObject() + sbt.internal.bsp.ExcludesParams(targets) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.bsp.ExcludesParams, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("targets", obj.targets) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesResultFormats.scala new file mode 100644 index 000000000..a167af41e --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ExcludesResultFormats.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.bsp.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ExcludesResultFormats { self: sbt.internal.bsp.codec.ExcludesItemFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ExcludesResultFormat: JsonFormat[sbt.internal.bsp.ExcludesResult] = new JsonFormat[sbt.internal.bsp.ExcludesResult] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ExcludesResult = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val items = unbuilder.readField[Vector[sbt.internal.bsp.ExcludesItem]]("items") + unbuilder.endObject() + sbt.internal.bsp.ExcludesResult(items) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.bsp.ExcludesResult, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("items", obj.items) + builder.endObject() + } +} +} 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 7d26ae037..5c087e4b4 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 @@ -29,6 +29,10 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.SourceItemFormats with sbt.internal.bsp.codec.SourcesItemFormats with sbt.internal.bsp.codec.SourcesResultFormats + with sbt.internal.bsp.codec.OutputPathsParamsFormats + with sbt.internal.bsp.codec.OutputPathItemFormats + with sbt.internal.bsp.codec.OutputPathsItemFormats + with sbt.internal.bsp.codec.OutputPathsResultFormats with sbt.internal.bsp.codec.DependencySourcesParamsFormats with sbt.internal.bsp.codec.DependencySourcesItemFormats with sbt.internal.bsp.codec.DependencySourcesResultFormats diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathItemFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathItemFormats.scala new file mode 100644 index 000000000..e9eba8f0e --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathItemFormats.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 OutputPathItemFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val OutputPathItemFormat: JsonFormat[sbt.internal.bsp.OutputPathItem] = new JsonFormat[sbt.internal.bsp.OutputPathItem] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.OutputPathItem = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val uri = unbuilder.readField[java.net.URI]("uri") + val kind = unbuilder.readField[Int]("kind") + unbuilder.endObject() + sbt.internal.bsp.OutputPathItem(uri, kind) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.bsp.OutputPathItem, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("uri", obj.uri) + builder.addField("kind", obj.kind) + builder.endObject() + } +} +} 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 new file mode 100644 index 000000000..f3c0795ee --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsItemFormats.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 OutputPathsItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.bsp.codec.OutputPathItemFormats with sjsonnew.BasicJsonProtocol => +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 { + case Some(__js) => + unbuilder.beginObject(__js) + val target = unbuilder.readField[sbt.internal.bsp.BuildTargetIdentifier]("target") + val outputPaths = unbuilder.readField[Vector[sbt.internal.bsp.OutputPathItem]]("outputPaths") + unbuilder.endObject() + sbt.internal.bsp.OutputPathsItem(target, outputPaths) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.bsp.OutputPathsItem, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("target", obj.target) + builder.addField("outputPaths", obj.outputPaths) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsParamsFormats.scala new file mode 100644 index 000000000..b984eeeb2 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsParamsFormats.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.bsp.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait OutputPathsParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val OutputPathsParamsFormat: JsonFormat[sbt.internal.bsp.OutputPathsParams] = new JsonFormat[sbt.internal.bsp.OutputPathsParams] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.OutputPathsParams = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val targets = unbuilder.readField[Vector[sbt.internal.bsp.BuildTargetIdentifier]]("targets") + unbuilder.endObject() + sbt.internal.bsp.OutputPathsParams(targets) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.bsp.OutputPathsParams, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("targets", obj.targets) + builder.endObject() + } +} +} 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 new file mode 100644 index 000000000..0aa475097 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/OutputPathsResultFormats.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.bsp.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait OutputPathsResultFormats { self: sbt.internal.bsp.codec.OutputPathsItemFormats with sjsonnew.BasicJsonProtocol => +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 { + case Some(__js) => + unbuilder.beginObject(__js) + val items = unbuilder.readField[Vector[sbt.internal.bsp.OutputPathsItem]]("items") + unbuilder.endObject() + sbt.internal.bsp.OutputPathsResult(items) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.bsp.OutputPathsResult, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("items", obj.items) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband/bsp.contra b/protocol/src/main/contraband/bsp.contra index 79734b10f..d5f0beec5 100644 --- a/protocol/src/main/contraband/bsp.contra +++ b/protocol/src/main/contraband/bsp.contra @@ -202,6 +202,10 @@ type BuildServerCapabilities { # via method buildTarget/resources resourcesProvider: Boolean + # The server provides output paths + # via method buildTarget/outputPaths + outputPathsProvider: Boolean + ## Reloading the workspace state through workspace/reload is supported canReload: Boolean @@ -290,6 +294,26 @@ type SourceItem { generated: Boolean! } +## Build Target OutputPaths Request +type OutputPathsParams { + targets: [sbt.internal.bsp.BuildTargetIdentifier] +} + +## Build Target OutputPaths response +type OutputPathsResult { + items: [sbt.internal.bsp.OutputPathsItem] +} + +type OutputPathsItem { + target: sbt.internal.bsp.BuildTargetIdentifier! + outputPaths: [sbt.internal.bsp.OutputPathItem] +} + +type OutputPathItem { + uri: java.net.URI! + kind: Int! +} + ## Dependency Sources Request type DependencySourcesParams { targets: [sbt.internal.bsp.BuildTargetIdentifier] diff --git a/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala b/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala index fa7fce354..bdc850cd2 100644 --- a/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala +++ b/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala @@ -17,7 +17,7 @@ import scala.util.Properties object BuildServerConnection { final val name = "sbt" - final val bspVersion = "2.0.0-M5" + final val bspVersion = "2.1.0-M1" final val languages = Vector("scala") private final val SbtLaunchJar = "sbt-launch(-.*)?\\.jar".r diff --git a/protocol/src/main/scala/sbt/internal/bsp/OutputPathItemKind.scala b/protocol/src/main/scala/sbt/internal/bsp/OutputPathItemKind.scala new file mode 100644 index 000000000..aaee48e65 --- /dev/null +++ b/protocol/src/main/scala/sbt/internal/bsp/OutputPathItemKind.scala @@ -0,0 +1,17 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt.internal.bsp + +object OutputPathItemKind { + + /** The output path item references a normal file. */ + val File: Int = 1 + + /** The output path item references a directory. */ + val Directory: Int = 2 +} diff --git a/server-test/src/server-test/buildserver/build.sbt b/server-test/src/server-test/buildserver/build.sbt index fe2cf4db5..e41e0192b 100644 --- a/server-test/src/server-test/buildserver/build.sbt +++ b/server-test/src/server-test/buildserver/build.sbt @@ -30,7 +30,9 @@ lazy val respondError = project.in(file("respond-error")) } ) -lazy val util = project +lazy val util = project.settings( + Compile / target := baseDirectory.value / "custom-target", +) lazy val diagnostics = project @@ -44,6 +46,7 @@ lazy val badBuildTarget = project.in(file("bad-build-target")) Compile / bspBuildTargetDependencySourcesItem := somethingBad, Compile / bspBuildTargetScalacOptionsItem := somethingBad, Compile / bspBuildTargetCompileItem := somethingBad, + Compile / bspBuildTargetOutputPathsItem := somethingBad, Compile / bspScalaMainClasses := somethingBad, Test / bspBuildTarget := somethingBad, Test / bspScalaTestClasses := somethingBad, diff --git a/server-test/src/test/scala/testpkg/BuildServerTest.scala b/server-test/src/test/scala/testpkg/BuildServerTest.scala index da4659fe1..5765e1649 100644 --- a/server-test/src/test/scala/testpkg/BuildServerTest.scala +++ b/server-test/src/test/scala/testpkg/BuildServerTest.scala @@ -31,7 +31,8 @@ object BuildServerTest extends AbstractServerTest { initializeRequest() assert(svr.waitForString(10.seconds) { s => (s contains """"id":"8"""") && - (s contains """"resourcesProvider":true""") + (s contains """"resourcesProvider":true""") && + (s contains """"outputPathsProvider":true""") }) } @@ -539,13 +540,39 @@ object BuildServerTest extends AbstractServerTest { }) } + test("buildTarget/outputPaths") { _ => + val buildTarget = buildTargetUri("util", "Compile") + val badBuildTarget = buildTargetUri("badBuildTarget", "Compile") + svr.sendJsonRpc( + s"""{ "jsonrpc": "2.0", "id": "97", "method": "buildTarget/outputPaths", "params": { + | "targets": [{ "uri": "$buildTarget" }, { "uri": "$badBuildTarget" }] + |} }""".stripMargin + ) + assert(processing("buildTarget/outputPaths")) + val actualResult = svr.waitFor[OutputPathsResult](10.seconds) + val expectedResult = OutputPathsResult( + items = Vector( + OutputPathsItem( + target = BuildTargetIdentifier(buildTarget), + outputPaths = Vector( + OutputPathItem( + uri = new File(svr.baseDirectory, "util/custom-target").toURI, + kind = OutputPathItemKind.Directory + ) + ) + ) + ) + ) + assert(actualResult == expectedResult) + } + private def initializeRequest(): Unit = { svr.sendJsonRpc( """{ "jsonrpc": "2.0", "id": "8", "method": "build/initialize", | "params": { | "displayName": "test client", | "version": "1.0.0", - | "bspVersion": "2.0.0-M5", + | "bspVersion": "2.1.0-M1", | "rootUri": "file://root/", | "capabilities": { "languageIds": ["scala"] } | } From 0d37a9eae24a18b02b1bd38c0d854656026e6c04 Mon Sep 17 00:00:00 2001 From: Devin Fisher Date: Fri, 5 Aug 2022 09:57:22 -0600 Subject: [PATCH 41/43] add output when book server socket fails to create --- main/src/main/scala/sbt/Main.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 4d30a9920..1dcde1001 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -153,9 +153,13 @@ private[sbt] object xMain { if (ITerminal.get.withRawInput(System.in.read) == 'n'.toInt) Some(Exit(1)) else None (None, exit) - case _: ServerAlreadyBootingException => + case e: ServerAlreadyBootingException => if (SysProp.forceServerStart) (None, None) - else (None, Some(Exit(2))) + else { + println("Boot server failed to create socket") + e.printStackTrace() + (None, Some(Exit(2))) + } case _: UnsatisfiedLinkError => (None, None) } } From 157030212ac331fbe9fbd8f295c444328fc39c5d Mon Sep 17 00:00:00 2001 From: Devin Fisher Date: Mon, 8 Aug 2022 11:21:43 -0600 Subject: [PATCH 42/43] refactor printing error to an in-function function --- main/src/main/scala/sbt/Main.scala | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 1dcde1001..c2cbb74f9 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -141,13 +141,17 @@ private[sbt] object xMain { private def getSocketOrExit( configuration: xsbti.AppConfiguration - ): (Option[BootServerSocket], Option[Exit]) = - try (Some(new BootServerSocket(configuration)) -> None) + ): (Option[BootServerSocket], Option[Exit]) = { + def printThrowable(e: Throwable): Unit = { + println("sbt thinks that server is already booting because of this exception:") + e.printStackTrace() + } + + try Some(new BootServerSocket(configuration)) -> None catch { case e: ServerAlreadyBootingException if System.console != null && !ITerminal.startedByRemoteClient => - println("sbt thinks that server is already booting because of this exception:") - e.printStackTrace() + printThrowable(e) println("Create a new server? y/n (default y)") val exit = if (ITerminal.get.withRawInput(System.in.read) == 'n'.toInt) Some(Exit(1)) @@ -156,12 +160,12 @@ private[sbt] object xMain { case e: ServerAlreadyBootingException => if (SysProp.forceServerStart) (None, None) else { - println("Boot server failed to create socket") - e.printStackTrace() + printThrowable(e) (None, Some(Exit(2))) } case _: UnsatisfiedLinkError => (None, None) } + } } final class ScriptMain extends xsbti.AppMain { From 77673eef55d0cb749b4156b4071512b7448688dd Mon Sep 17 00:00:00 2001 From: Chris Kipp Date: Sun, 21 Aug 2022 14:01:47 +0200 Subject: [PATCH 43/43] fix: also include diagnosticCode and related info in InterfaceUtil Looks like I missed this in https://github.com/sbt/sbt/pull/6874 and I hit on it in Mill when I couldn't figure out why it was also empty, and thanks to @adpi realized it was because of the `LoggedReporter` in zinc not taking it into account. However before I can bump that this needs to be bumped as well. refs: https://github.com/lampepfl/dotty/issues/14904 --- .../main/scala/sbt/util/InterfaceUtil.scala | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/internal/util-logging/src/main/scala/sbt/util/InterfaceUtil.scala b/internal/util-logging/src/main/scala/sbt/util/InterfaceUtil.scala index 40fecbae1..e7f2d33cc 100644 --- a/internal/util-logging/src/main/scala/sbt/util/InterfaceUtil.scala +++ b/internal/util-logging/src/main/scala/sbt/util/InterfaceUtil.scala @@ -7,10 +7,14 @@ package sbt.util -import xsbti.{ Position, Problem, Severity, T2 } import java.io.File import java.util.Optional import java.util.function.Supplier +import java.{ util => ju } + +import xsbti.{ DiagnosticCode, DiagnosticRelatedInformation, Position, Problem, Severity, T2 } + +import scala.collection.mutable.ListBuffer object InterfaceUtil { def toSupplier[A](a: => A): Supplier[A] = new Supplier[A] { @@ -43,6 +47,18 @@ object InterfaceUtil { case None => Optional.empty[A]() } + def l2jl[A](l: List[A]): ju.List[A] = { + val jl = new ju.ArrayList[A](l.size) + l.foreach(jl.add(_)) + jl + } + + def jl2l[A](jl: ju.List[A]): List[A] = { + val l = ListBuffer[A]() + jl.forEach(l += _) + l.toList + } + @deprecated("Use the overload of this method with more arguments", "1.2.2") def position( line0: Option[Integer], @@ -104,6 +120,7 @@ object InterfaceUtil { def problem(cat: String, pos: Position, msg: String, sev: Severity): Problem = problem(cat, pos, msg, sev, None) + @deprecated("Use the overload of this method with more arguments", "1.7.2") def problem( cat: String, pos: Position, @@ -111,7 +128,18 @@ object InterfaceUtil { sev: Severity, rendered: Option[String] ): Problem = - new ConcreteProblem(cat, pos, msg, sev, rendered) + problem(cat, pos, msg, sev, rendered, None, List.empty[DiagnosticRelatedInformation]) + + def problem( + cat: String, + pos: Position, + msg: String, + sev: Severity, + rendered: Option[String], + diagnosticCode: Option[DiagnosticCode], + diagnosticRelatedInforamation: List[DiagnosticRelatedInformation] + ): Problem = + new ConcreteProblem(cat, pos, msg, sev, rendered, diagnosticCode, diagnosticRelatedInforamation) private final class ConcreteT2[A1, A2](a1: A1, a2: A2) extends T2[A1, A2] { val get1: A1 = a1 @@ -166,13 +194,18 @@ object InterfaceUtil { pos: Position, msg: String, sev: Severity, - rendered0: Option[String] + rendered0: Option[String], + diagnosticCode0: Option[DiagnosticCode], + diagnosticRelatedInformation0: List[DiagnosticRelatedInformation] ) extends Problem { val category = cat val position = pos val message = msg val severity = sev override val rendered = o2jo(rendered0) + override def diagnosticCode: Optional[DiagnosticCode] = o2jo(diagnosticCode0) + override def diagnosticRelatedInforamation(): ju.List[DiagnosticRelatedInformation] = + l2jl(diagnosticRelatedInformation0) override def toString = s"[$severity] $pos: $message" } }