From 2bffb2731e85f0bd8a0040d26e42958295ff564d Mon Sep 17 00:00:00 2001 From: Krzysztof Pado Date: Wed, 27 Jul 2022 19:40:18 -0700 Subject: [PATCH 01/42] 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 4e2abdbe8..adc0004a5 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 1b8fd06fb..aa08914f1 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""") }) } @@ -538,13 +539,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 6bcda6684add413956bc0d28bfb6b94a64f7feeb Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 4 Aug 2022 10:54:43 +0200 Subject: [PATCH 02/42] Use BackgroundJobService context instead of MainLoop context A new context is created and closed for each state of the MainLoop. But the context of the backgroundJob must stay alive. So we use a context that is owned by the BackgroundJobService. It creates a new logger for each background job and cleans it when the job stops. --- .../src/main/scala/sbt/util/LoggerContext.scala | 3 ++- .../internal/DefaultBackgroundJobService.scala | 15 ++++----------- main/src/main/scala/sbt/internal/LogManager.scala | 12 ++++++++++-- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/internal/util-logging/src/main/scala/sbt/util/LoggerContext.scala b/internal/util-logging/src/main/scala/sbt/util/LoggerContext.scala index ee1069061..0435793dd 100644 --- a/internal/util-logging/src/main/scala/sbt/util/LoggerContext.scala +++ b/internal/util-logging/src/main/scala/sbt/util/LoggerContext.scala @@ -182,7 +182,8 @@ object LoggerContext { } } def close(): Unit = { - loggers.forEach((name, l) => l.clearAppenders()) + closed.set(true) + loggers.forEach((_, l) => l.clearAppenders()) loggers.clear() } } diff --git a/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala b/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala index b9effa8a9..79d431ebd 100644 --- a/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala +++ b/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala @@ -74,6 +74,7 @@ private[sbt] abstract class AbstractJobHandle extends JobHandle { private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobService { private val nextId = new AtomicLong(1) private val pool = new BackgroundThreadPool() + private val context = LoggerContext(useLog4J) private[sbt] def serviceTempDirBase: File private[sbt] def useLog4J: Boolean @@ -90,7 +91,6 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe // hooks for sending start/stop events protected def onAddJob(@deprecated("unused", "") job: JobHandle): Unit = () protected def onRemoveJob(@deprecated("unused", "") job: JobHandle): Unit = () - private val context = LoggerContext(useLog4J) // this mutable state could conceptually go on State except // that then every task that runs a background job would have @@ -122,12 +122,9 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe def humanReadableName: String = job.humanReadableName job.onStop { () => - // TODO: Fix this - // logger.close() removeJob(this) IO.delete(workingDirectory) context.clearAppenders(logger.name) - context.close() } addJob(this) override final def equals(other: Any): Boolean = other match { @@ -144,15 +141,15 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe override val spawningTask: ScopedKey[_] = unknownTask } - protected def makeContext(id: Long, spawningTask: ScopedKey[_], state: State): ManagedLogger - def doRunInBackground( spawningTask: ScopedKey[_], state: State, start: (Logger, File) => BackgroundJob ): JobHandle = { val id = nextId.getAndIncrement() - val logger = makeContext(id, spawningTask, state) + val extracted = Project.extract(state) + val logger = + LogManager.constructBackgroundLog(extracted.structure.data, state, context)(spawningTask) val workingDir = serviceTempDir / s"job-$id" IO.createDirectory(workingDir) val job = try { @@ -502,10 +499,6 @@ private[sbt] class DefaultBackgroundJobService( ) extends AbstractBackgroundJobService { @deprecated("Use the constructor that specifies the background job temporary directory", "1.4.0") def this() = this(IO.createTemporaryDirectory, false) - override def makeContext(id: Long, spawningTask: ScopedKey[_], state: State): ManagedLogger = { - val extracted = Project.extract(state) - LogManager.constructBackgroundLog(extracted.structure.data, state)(spawningTask) - } } private[sbt] object DefaultBackgroundJobService { diff --git a/main/src/main/scala/sbt/internal/LogManager.scala b/main/src/main/scala/sbt/internal/LogManager.scala index e28fd91ee..7029cde2e 100644 --- a/main/src/main/scala/sbt/internal/LogManager.scala +++ b/main/src/main/scala/sbt/internal/LogManager.scala @@ -73,15 +73,23 @@ object LogManager { manager(data, state, task, to, context) } - @nowarn + @deprecated("Use alternate constructBackgroundLog that provides a LoggerContext", "1.8.0") def constructBackgroundLog( data: Settings[Scope], state: State + ): ScopedKey[_] => ManagedLogger = { + val context = state.get(Keys.loggerContext).getOrElse(LoggerContext.globalContext) + constructBackgroundLog(data, state, context) + } + + def constructBackgroundLog( + data: Settings[Scope], + state: State, + context: LoggerContext ): (ScopedKey[_]) => ManagedLogger = (task: ScopedKey[_]) => { val manager: LogManager = (logManager in task.scope).get(data) getOrElse defaultManager(state.globalLogging.console) - val context = state.get(Keys.loggerContext).getOrElse(LoggerContext.globalContext) manager.backgroundLog(data, state, task, context) } From 592086b889fa998abc436139c3ffb52153049db9 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 4 Aug 2022 15:59:25 +0200 Subject: [PATCH 03/42] Don't use ProxyTerminal in background job If we use the ProxyTerminal in the background jobs, the logs would be spread across different terminals, switching from active client to active client. We want the logs to stick to the client that started the job. --- .../src/main/scala/sbt/internal/util/Terminal.scala | 1 + main/src/main/scala/sbt/internal/LogManager.scala | 2 +- 2 files changed, 2 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 0019b04e9..27b1e29c4 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 @@ -438,6 +438,7 @@ object Terminal { override def toString: String = s"ProxyTerminal(current = $t)" } private[sbt] def get: Terminal = ProxyTerminal + private[sbt] def current: Terminal = activeTerminal.get private[sbt] def withIn[T](in: InputStream)(f: => T): T = { val original = inputStream.get diff --git a/main/src/main/scala/sbt/internal/LogManager.scala b/main/src/main/scala/sbt/internal/LogManager.scala index 7029cde2e..8612c692b 100644 --- a/main/src/main/scala/sbt/internal/LogManager.scala +++ b/main/src/main/scala/sbt/internal/LogManager.scala @@ -149,7 +149,7 @@ object LogManager { task: ScopedKey[_], context: LoggerContext ): ManagedLogger = { - val console = screen(task, state) + val console = ConsoleAppender("bg-" + ConsoleAppender.generateName(), ITerminal.current) LogManager.backgroundLog(data, state, task, console, relay(()), context) } } From 634e8799e76395f7bb280ea7f5f910f9cce21838 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 5 Aug 2022 14:45:38 +0200 Subject: [PATCH 04/42] Catch ClosedChannelException in background job logger We want the background job to stay alive even if its terminal has been closed and we cannot write to it anymore --- .../sbt/internal/util/ConsoleAppender.scala | 23 +++++++++++++++---- .../scala/sbt/internal/util/ConsoleOut.scala | 21 +++++++++++++++++ .../main/scala/sbt/internal/LogManager.scala | 2 +- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleAppender.scala b/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleAppender.scala index 7cfed50e6..2b1700572 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleAppender.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleAppender.scala @@ -126,11 +126,12 @@ object ConsoleAppender { def out: ConsoleOut } private[sbt] object Properties { - def from(terminal: Terminal): Properties = new Properties { - override def isAnsiSupported: Boolean = terminal.isAnsiSupported - override def isColorEnabled: Boolean = terminal.isColorEnabled - override def out = ConsoleOut.terminalOut(terminal) - } + def from(terminal: Terminal): Properties = + from(ConsoleOut.terminalOut(terminal), terminal.isAnsiSupported, terminal.isColorEnabled) + + def safelyFrom(terminal: Terminal): Properties = + from(ConsoleOut.safeTerminalOut(terminal), terminal.isAnsiSupported, terminal.isColorEnabled) + def from(o: ConsoleOut, ansi: Boolean, color: Boolean): Properties = new Properties { override def isAnsiSupported: Boolean = ansi override def isColorEnabled: Boolean = color @@ -246,6 +247,18 @@ object ConsoleAppender { new ConsoleAppender(name, Properties.from(terminal), noSuppressedMessage) } + /** + * A new `ConsoleAppender` identified by `name`, and that writes to `terminal`. + * Printing to this Appender will not throw if the Terminal has been closed. + * + * @param name An identifier for the `ConsoleAppender`. + * @param terminal The terminal to which this appender corresponds + * @return A new `ConsoleAppender` that writes to `terminal`. + */ + def safe(name: String, terminal: Terminal): Appender = { + new ConsoleAppender(name, Properties.safelyFrom(terminal), noSuppressedMessage) + } + /** * A new `ConsoleAppender` identified by `name`, and that writes to `out`. * diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleOut.scala b/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleOut.scala index b946a0cc8..0f6a089bf 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleOut.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleOut.scala @@ -8,6 +8,7 @@ package sbt.internal.util import java.io.{ BufferedWriter, PrintStream, PrintWriter } +import java.nio.channels.ClosedChannelException import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicReference @@ -90,6 +91,26 @@ object ConsoleOut { override def toString: String = s"TerminalOut" } + /** Same as terminalOut but it catches and ignores the ClosedChannelException + */ + def safeTerminalOut(terminal: Terminal): ConsoleOut = { + val out = terminalOut(terminal) + new ConsoleOut { + override val lockObject: AnyRef = terminal + override def print(s: String): Unit = catchException(out.print(s)) + override def println(s: String): Unit = catchException(out.println(s)) + override def println(): Unit = catchException(out.println()) + override def flush(): Unit = catchException(out.flush) + override def toString: String = s"SafeTerminalOut($terminal)" + private def catchException(f: => Unit): Unit = { + try f + catch { + case _: ClosedChannelException => () + } + } + } + } + private[this] val consoleOutPerTerminal = new ConcurrentHashMap[Terminal, ConsoleOut] def terminalOut(terminal: Terminal): ConsoleOut = consoleOutPerTerminal.get(terminal) match { case null => diff --git a/main/src/main/scala/sbt/internal/LogManager.scala b/main/src/main/scala/sbt/internal/LogManager.scala index 8612c692b..9feb065d1 100644 --- a/main/src/main/scala/sbt/internal/LogManager.scala +++ b/main/src/main/scala/sbt/internal/LogManager.scala @@ -149,7 +149,7 @@ object LogManager { task: ScopedKey[_], context: LoggerContext ): ManagedLogger = { - val console = ConsoleAppender("bg-" + ConsoleAppender.generateName(), ITerminal.current) + val console = ConsoleAppender.safe("bg-" + ConsoleAppender.generateName(), ITerminal.current) LogManager.backgroundLog(data, state, task, console, relay(()), context) } } From 5b09ba03a356fc71139ac55c1c2028229dd5e823 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Aug 2022 04:04:59 +0000 Subject: [PATCH 05/42] Bump actions/cache from 3.0.5 to 3.0.6 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.5 to 3.0.6. - [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.5...v3.0.6) --- 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 c252d6598..9bba79c8e 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.5 + uses: actions/cache@v3.0.6 with: path: ~/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} From 15a45cb3c0a480b8d19d693cb94811ca5d515afa Mon Sep 17 00:00:00 2001 From: Chris Kipp Date: Tue, 9 Aug 2022 19:02:52 +0200 Subject: [PATCH 06/42] feat: start forwarding diagnosticCode via BSP This change is a continuation of the work that was done in https://github.com/sbt/sbt/pull/6874 to allow the Scala 3 compiler to forward the `diagnosticCode` of an error as well as the other normal things. This change in dotty was merged in https://github.com/lampepfl/dotty/pull/15565 and also backported so it will be in the 3.2.x series release. This change captures the `diagnosticCode` and forwards it on via BSP so that tools like Metals can can use this code. You can see this in the BSP trace now for a diagnostic: For example with some code that contains the following: ```scala val x: Int = "hi" ``` You'll see the code in the BSP diagnostic: ``` "diagnostics": [ { "range": { "start": { "line": 9, "character": 15 }, "end": { "line": 9, "character": 19 } }, "severity": 1, "code": "7", "source": "sbt", "message": "Found: (\u001b[32m\"hi\"\u001b[0m : String)\nRequired: Int\n\nThe following import might make progress towards fixing the problem:\n\n import sourcecode.Text.generate\n\n" } ] ``` Co-authored-by: Adrien Piquerez Refs: https://github.com/lampepfl/dotty/issues/14904 --- .../main/scala/sbt/internal/server/BuildServerReporter.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala b/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala index 98d59d645..3c8c8bb0c 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala @@ -174,7 +174,7 @@ final class BuildServerReporterImpl( Diagnostic( range, Option(toDiagnosticSeverity(problem.severity)), - None, + problem.diagnosticCode().toOption.map(_.code), Option("sbt"), problem.message ) From 5874ad920efb48deba8b57056d2f32550aca646d Mon Sep 17 00:00:00 2001 From: Devin Fisher Date: Fri, 5 Aug 2022 09:57:22 -0600 Subject: [PATCH 07/42] 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 6bb147f7d..d8f5d2eb2 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 9f9b08edbd49d1b48aa9e544999cfe225efac935 Mon Sep 17 00:00:00 2001 From: Devin Fisher Date: Mon, 8 Aug 2022 11:21:43 -0600 Subject: [PATCH 08/42] 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 d8f5d2eb2..88babfe0b 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 92a9f0e583bc1968cf07e9de02a5359f835efd27 Mon Sep 17 00:00:00 2001 From: Chris Kipp Date: Tue, 9 Aug 2022 19:02:52 +0200 Subject: [PATCH 09/42] feat: start forwarding diagnosticCode via BSP This change is a continuation of the work that was done in https://github.com/sbt/sbt/pull/6874 to allow the Scala 3 compiler to forward the `diagnosticCode` of an error as well as the other normal things. This change in dotty was merged in https://github.com/lampepfl/dotty/pull/15565 and also backported so it will be in the 3.2.x series release. This change captures the `diagnosticCode` and forwards it on via BSP so that tools like Metals can can use this code. You can see this in the BSP trace now for a diagnostic: For example with some code that contains the following: ```scala val x: Int = "hi" ``` You'll see the code in the BSP diagnostic: ``` "diagnostics": [ { "range": { "start": { "line": 9, "character": 15 }, "end": { "line": 9, "character": 19 } }, "severity": 1, "code": "7", "source": "sbt", "message": "Found: (\u001b[32m\"hi\"\u001b[0m : String)\nRequired: Int\n\nThe following import might make progress towards fixing the problem:\n\n import sourcecode.Text.generate\n\n" } ] ``` Co-authored-by: Adrien Piquerez Refs: https://github.com/lampepfl/dotty/issues/14904 --- .../main/scala/sbt/internal/server/BuildServerReporter.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala b/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala index 6e04053da..3963da325 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerReporter.scala @@ -201,7 +201,7 @@ final class BuildServerReporterImpl( Diagnostic( range, Option(toDiagnosticSeverity(problem.severity)), - None, + problem.diagnosticCode().toOption.map(_.code), Option("sbt"), problem.message ) From 6cafc895743d7936ab61b63226ec3d7a0f5e3914 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Aug 2022 04:02:16 +0000 Subject: [PATCH 10/42] Bump actions/cache from 3.0.6 to 3.0.7 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.6 to 3.0.7. - [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.6...v3.0.7) --- 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 9bba79c8e..8e0e67967 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.6 + uses: actions/cache@v3.0.7 with: path: ~/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} From 6ef9d5d244ca4a47dcc39ef2e94216f002b23fb2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Aug 2022 04:07:24 +0000 Subject: [PATCH 11/42] Bump actions/cache from 3.0.7 to 3.0.8 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.7 to 3.0.8. - [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.7...v3.0.8) --- 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 8e0e67967..b277baa50 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.7 + uses: actions/cache@v3.0.8 with: path: ~/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} From 5bd44058ef6a96171cfa7cb2779b725fa40633a7 Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Wed, 31 Aug 2022 16:07:11 -0400 Subject: [PATCH 12/42] Update --feature-request.md --- .github/ISSUE_TEMPLATE/--feature-request.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/--feature-request.md b/.github/ISSUE_TEMPLATE/--feature-request.md index 5ef8d3776..bbce6fbc7 100644 --- a/.github/ISSUE_TEMPLATE/--feature-request.md +++ b/.github/ISSUE_TEMPLATE/--feature-request.md @@ -7,4 +7,6 @@ assignees: '' --- -Please use https://discuss.lightbend.com/c/tooling including a specific user story instead of posting them to the issue tracker. +If you have new ideas about sbt or an open-ended discussion, please use https://github.com/sbt/sbt/discussions instead of posting them to the issue tracker, which we use to track bugs and (internal) todo list. + +Please note that sbt is mostly maintained by community effort, so one of the questions that we'd ask might be "would like to contribute it if we help you where the relevant code is". From ca45370ea18463c27135293f35856ea6f070c0d0 Mon Sep 17 00:00:00 2001 From: Erik LaBianca Date: Thu, 8 Sep 2022 15:05:47 -0400 Subject: [PATCH 13/42] Add sbt.argsfile option There are a number of scenarios, including long classpaths, that can cause linux and other systems to fail to fork a jvm. We can work around this on JDK9 and above by using an "arguments file" [1]. This patch adds an "sbt.argsfile" property and SBT_ARGSFILE environment variable. This option defaults to true. When active on Java 9+, long command lines are translated to an arguments file by adding all command line arguments to the arguments file format at [1] and java is invoked using the arguments file instead of passing the arguments on the command line. 1. https://docs.oracle.com/javase/9/tools/java.htm# Fixes: #2974 --- run/src/main/scala/sbt/Fork.scala | 61 ++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/run/src/main/scala/sbt/Fork.scala b/run/src/main/scala/sbt/Fork.scala index c7e74c0f7..7cbf1c7ad 100644 --- a/run/src/main/scala/sbt/Fork.scala +++ b/run/src/main/scala/sbt/Fork.scala @@ -8,6 +8,7 @@ package sbt import java.io.File +import java.io.PrintWriter import java.lang.ProcessBuilder.Redirect import scala.sys.process.Process import OutputStrategy._ @@ -15,6 +16,7 @@ import sbt.internal.util.{ RunningProcesses, Util } import Util.{ AnyOps, none } import java.lang.{ ProcessBuilder => JProcessBuilder } +import java.util.Locale /** * Represents a command that can be forked. @@ -57,7 +59,11 @@ final class Fork(val commandName: String, val runnerClass: Option[String]) { (classpathEnv map { value => Fork.ClasspathEnvKey -> value }) - val jpb = new JProcessBuilder(command.toArray: _*) + val jpb = + if (Fork.shouldUseArgumentsFile(options)) + new JProcessBuilder(executable, Fork.createArgumentsFile(options)) + else + new JProcessBuilder(command.toArray: _*) workingDirectory foreach (jpb directory _) environment foreach { case (k, v) => jpb.environment.put(k, v) } if (connectInput) { @@ -125,4 +131,57 @@ object Fork { val home = javaHome.getOrElse(new File(System.getProperty("java.home"))) new File(new File(home, "bin"), name) } + + /* copied from SysProp.scala for consistency while avoiding + * introducing a circular dependency + */ + private def parseBoolean(value: String): Option[Boolean] = + value.toLowerCase(Locale.ENGLISH) match { + case "1" | "always" | "true" => Some(true) + case "0" | "never" | "false" => Some(false) + case "auto" => None + case _ => None + } + private def booleanOpt(name: String): Option[Boolean] = + sys.props.get(name) match { + case Some(x) => parseBoolean(x) + case _ => + sys.env.get(name.toUpperCase(Locale.ENGLISH).replace('.', '_')) match { + case Some(x) => parseBoolean(x) + case _ => None + } + } + + /** Use an arguments file if: + * - we are on jdk >= 9 + * - sbt.argfile is unset or not falsy + * - the command line length would exceed MaxConcatenatedOptionLength + */ + private def shouldUseArgumentsFile(options: Seq[String]): Boolean = + (sys.props.getOrElse("java.vm.specification.version", "1").toFloat >= 9.0) && + booleanOpt("sbt.argsfile").getOrElse(true) && + (options.mkString.length > MaxConcatenatedOptionLength) + + /** + * Create an arguments file from a sequence of command line arguments + * by quoting each argument to a line with escaped backslashes + * + * @param options command line options to write to the args file + * @return + */ + private def createArgumentsFile(options: Seq[String]): String = { + val file = File.createTempFile(s"sbt-args", ".tmp") + file.deleteOnExit() + + val pw = new PrintWriter(file) + options.foreach { option => + pw.write("\"") + pw.write(option.replace("\\", "\\\\")) + pw.write("\"") + pw.write(System.lineSeparator()) + } + pw.flush() + pw.close() + s"@${file.getAbsolutePath}" + } } From 0f70950ccd59d96111ee6360102f6229b417bfa9 Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Sun, 11 Sep 2022 02:42:14 -0400 Subject: [PATCH 14/42] Try windows-latest --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b277baa50..cbd26b8c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: java: 8 distribution: adopt jobtype: 8 - - os: windows-2019 + - os: windows-latest java: 8 distribution: adopt jobtype: 9 @@ -97,7 +97,7 @@ jobs: 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' }} + if: ${{ matrix.os == 'windows-latest' }} - name: Build and test (1) if: ${{ matrix.jobtype == 1 }} shell: bash From 573cd2de81986e1e1bf8ccd988192d1c8d0e179d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 11 Sep 2022 02:05:41 -0400 Subject: [PATCH 15/42] Giter8 0.15.0 by default --- main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala b/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala index a5cc5efce..26d901d2e 100644 --- a/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala +++ b/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala @@ -26,7 +26,7 @@ object Giter8TemplatePlugin extends AutoPlugin { ModuleID( "org.scala-sbt.sbt-giter8-resolver", "sbt-giter8-resolver", - "0.13.1" + "0.15.0" ) cross CrossVersion.binary, "sbtgiter8resolver.Giter8TemplateResolver" ) From b00792a3a74d7cc87d417426689f397798eae403 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 17 Sep 2022 02:23:56 -0400 Subject: [PATCH 16/42] Scala 2.12.17 This bumps up scala-xml to 2.x. --- .github/workflows/ci.yml | 2 +- build.sbt | 3 ++- main/src/main/scala/sbt/PluginCross.scala | 2 +- main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala | 2 +- project/Dependencies.scala | 6 +++--- sbt-app/src/sbt-test/actions/compile-time-only/build.sbt | 2 ++ sbt-app/src/sbt-test/actions/cross-advanced/build.sbt | 2 +- sbt-app/src/sbt-test/actions/cross-advanced/test | 2 +- .../actions/cross-strict-aggregation-scala-3/build.sbt | 6 +++--- .../src/sbt-test/actions/cross-strict-aggregation/build.sbt | 2 +- sbt-app/src/sbt-test/compiler-project/run-test/build.sbt | 2 +- .../sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt | 2 +- .../src/sbt-test/dependency-graph/toFileSubTask/build.sbt | 2 +- sbt-app/src/sbt-test/nio/reload/build.sbt | 2 ++ sbt-app/src/sbt-test/nio/reload/changes/sub.sbt | 2 ++ sbt-app/src/sbt-test/nio/reload/project/plugins.sbt | 2 ++ sbt-app/src/sbt-test/plugins/play-watch/project/plugins.sbt | 1 + .../plugins/sbt-native-packager/project/plugins.sbt | 2 ++ sbt-app/src/sbt-test/project/sbt-plugin/build.sbt | 2 +- .../sbt-test/project/sbt-plugin/changes/oldSbtPlugin.sbt | 2 +- .../src/sbt-test/project/source-plugins/{test => pending} | 0 sbt-app/src/sbt-test/project/src-plugins/{test => pending} | 0 sbt-app/src/sbt-test/project/src-plugins/project/p.sbt | 2 ++ sbt-app/src/sbt-test/project/unified/build.sbt | 2 +- sbt-app/src/sbt-test/source-dependencies/constants/test | 2 +- .../src/sbt-test/tests/scala-instance-classloader/build.sbt | 2 +- server-test/src/server-test/response/build.sbt | 2 +- 27 files changed, 36 insertions(+), 22 deletions(-) rename sbt-app/src/sbt-test/project/source-plugins/{test => pending} (100%) rename sbt-app/src/sbt-test/project/src-plugins/{test => pending} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cbd26b8c2..d717c8d25 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: env: JAVA_OPTS: -Xms800M -Xmx2G -Xss6M -XX:ReservedCodeCacheSize=128M -server -Dsbt.io.virtual=false -Dfile.encoding=UTF-8 JVM_OPTS: -Xms800M -Xmx2G -Xss6M -XX:ReservedCodeCacheSize=128M -server -Dsbt.io.virtual=false -Dfile.encoding=UTF-8 - SCALA_212: 2.12.16 + SCALA_212: 2.12.17 SCALA_213: 2.13.8 SCALA_3: 3.1.0 UTIL_TESTS: "utilCache/test utilControl/test utilInterface/test utilLogging/test utilPosition/test utilRelation/test utilScripted/test utilTracking/test" diff --git a/build.sbt b/build.sbt index 8ffea7edc..791ea39ae 100644 --- a/build.sbt +++ b/build.sbt @@ -43,10 +43,11 @@ ThisBuild / scmInfo := Some( ScmInfo(url("https://github.com/sbt/sbt"), "git@github.com:sbt/sbt.git") ) ThisBuild / resolvers += Resolver.mavenLocal +ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always Global / semanticdbEnabled := !(Global / insideCI).value // Change main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala too, if you change this. -Global / semanticdbVersion := "4.5.9" +Global / semanticdbVersion := "4.5.13" val excludeLint = SettingKey[Set[Def.KeyedInitialize[_]]]("excludeLintKeys") Global / excludeLint := (Global / excludeLint).?.value.getOrElse(Set.empty) Global / excludeLint += componentID diff --git a/main/src/main/scala/sbt/PluginCross.scala b/main/src/main/scala/sbt/PluginCross.scala index 740709b98..dbadb542a 100644 --- a/main/src/main/scala/sbt/PluginCross.scala +++ b/main/src/main/scala/sbt/PluginCross.scala @@ -99,7 +99,7 @@ private[sbt] object PluginCross { VersionNumber(sv) match { case VersionNumber(Seq(0, 12, _*), _, _) => "2.9.2" case VersionNumber(Seq(0, 13, _*), _, _) => "2.10.7" - case VersionNumber(Seq(1, 0, _*), _, _) => "2.12.16" + case VersionNumber(Seq(1, 0, _*), _, _) => "2.12.17" case _ => sys.error(s"Unsupported sbt binary version: $sv") } } diff --git a/main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala b/main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala index c1563c60d..b7a558d6d 100644 --- a/main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala +++ b/main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala @@ -26,7 +26,7 @@ object SemanticdbPlugin extends AutoPlugin { semanticdbEnabled := SysProp.semanticdb, semanticdbIncludeInJar := false, semanticdbOptions := List(), - semanticdbVersion := "4.5.9" + semanticdbVersion := "4.5.13" ) override lazy val projectSettings: Seq[Def.Setting[_]] = Seq( diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 86df2e8ef..de4c5e44c 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,7 +4,7 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { // WARNING: Please Scala update versions in PluginCross.scala too - val scala212 = "2.12.16" + val scala212 = "2.12.17" val scala213 = "2.13.8" val checkPluginCross = settingKey[Unit]("Make sure scalaVersion match up") val baseScalaVersion = scala212 @@ -102,9 +102,9 @@ object Dependencies { val scalaXml = Def.setting( if (scalaBinaryVersion.value == "3") { - "org.scala-lang.modules" %% "scala-xml" % "2.0.1" + "org.scala-lang.modules" %% "scala-xml" % "2.1.0" } else { - "org.scala-lang.modules" %% "scala-xml" % "1.3.0" + "org.scala-lang.modules" %% "scala-xml" % "2.1.0" } ) val scalaParsers = Def.setting( diff --git a/sbt-app/src/sbt-test/actions/compile-time-only/build.sbt b/sbt-app/src/sbt-test/actions/compile-time-only/build.sbt index 5baf27554..f8d308a29 100644 --- a/sbt-app/src/sbt-test/actions/compile-time-only/build.sbt +++ b/sbt-app/src/sbt-test/actions/compile-time-only/build.sbt @@ -1,3 +1,5 @@ +ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always + libraryDependencies += "org.scala-sbt" % "sbt" % sbtVersion.value diff --git a/sbt-app/src/sbt-test/actions/cross-advanced/build.sbt b/sbt-app/src/sbt-test/actions/cross-advanced/build.sbt index 91460f0e3..1a8fa296a 100644 --- a/sbt-app/src/sbt-test/actions/cross-advanced/build.sbt +++ b/sbt-app/src/sbt-test/actions/cross-advanced/build.sbt @@ -1,6 +1,6 @@ lazy val check = taskKey[Unit]("") lazy val compile2 = taskKey[Unit]("") -lazy val scala212 = "2.12.16" +lazy val scala212 = "2.12.17" lazy val root = (project in file(".")) .aggregate(foo, bar, client) diff --git a/sbt-app/src/sbt-test/actions/cross-advanced/test b/sbt-app/src/sbt-test/actions/cross-advanced/test index 5ee486310..3b074490d 100644 --- a/sbt-app/src/sbt-test/actions/cross-advanced/test +++ b/sbt-app/src/sbt-test/actions/cross-advanced/test @@ -17,7 +17,7 @@ ## test + with command or alias > clean ## for command cross building you do need crossScalaVerions on root -> set root/crossScalaVersions := Seq("2.12.16", "2.13.1") +> set root/crossScalaVersions := Seq("2.12.17", "2.13.1") > + build $ exists foo/target/scala-2.12 $ exists foo/target/scala-2.13 diff --git a/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt index d5cf2f898..aca345c51 100644 --- a/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt +++ b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt @@ -1,14 +1,14 @@ -scalaVersion := "2.12.16" +scalaVersion := "2.12.17" lazy val core = project .settings( - crossScalaVersions := Seq("2.12.16", "3.0.2", "3.1.2") + crossScalaVersions := Seq("2.12.17", "3.0.2", "3.1.2") ) lazy val subproj = project .dependsOn(core) .settings( - crossScalaVersions := Seq("2.12.16", "3.1.2"), + crossScalaVersions := Seq("2.12.17", "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/build.sbt b/sbt-app/src/sbt-test/actions/cross-strict-aggregation/build.sbt index 1ffbc3b59..f65bc2364 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.16" +lazy val scala212 = "2.12.17" lazy val scala213 = "2.13.1" ThisBuild / scalaVersion := scala212 diff --git a/sbt-app/src/sbt-test/compiler-project/run-test/build.sbt b/sbt-app/src/sbt-test/compiler-project/run-test/build.sbt index f424c2d91..1019be51a 100644 --- a/sbt-app/src/sbt-test/compiler-project/run-test/build.sbt +++ b/sbt-app/src/sbt-test/compiler-project/run-test/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.16" +ThisBuild / scalaVersion := "2.12.17" libraryDependencies ++= Seq( "com.novocode" % "junit-interface" % "0.5" % Test, diff --git a/sbt-app/src/sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt b/sbt-app/src/sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt index f67a2c7ee..5ba1d09ce 100644 --- a/sbt-app/src/sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt +++ b/sbt-app/src/sbt-test/dependency-graph/ignoreScalaLibrary/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.16" +ThisBuild / scalaVersion := "2.12.17" libraryDependencies ++= Seq( "org.slf4j" % "slf4j-api" % "1.7.2", diff --git a/sbt-app/src/sbt-test/dependency-graph/toFileSubTask/build.sbt b/sbt-app/src/sbt-test/dependency-graph/toFileSubTask/build.sbt index b8c0e1620..85fd38f7f 100644 --- a/sbt-app/src/sbt-test/dependency-graph/toFileSubTask/build.sbt +++ b/sbt-app/src/sbt-test/dependency-graph/toFileSubTask/build.sbt @@ -1,5 +1,5 @@ // ThisBuild / useCoursier := false -ThisBuild / scalaVersion := "2.12.16" +ThisBuild / scalaVersion := "2.12.17" ThisBuild / organization := "org.example" ThisBuild / version := "0.1" diff --git a/sbt-app/src/sbt-test/nio/reload/build.sbt b/sbt-app/src/sbt-test/nio/reload/build.sbt index 910bfa622..509d4f3f8 100644 --- a/sbt-app/src/sbt-test/nio/reload/build.sbt +++ b/sbt-app/src/sbt-test/nio/reload/build.sbt @@ -1,3 +1,5 @@ +ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always + import scala.concurrent.duration._ val foo = inputKey[Unit]("working task") diff --git a/sbt-app/src/sbt-test/nio/reload/changes/sub.sbt b/sbt-app/src/sbt-test/nio/reload/changes/sub.sbt index 4797974c4..2a374e9b3 100644 --- a/sbt-app/src/sbt-test/nio/reload/changes/sub.sbt +++ b/sbt-app/src/sbt-test/nio/reload/changes/sub.sbt @@ -1,3 +1,5 @@ +ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always + import scala.concurrent.duration._ libraryDependencies += "org.scala-sbt" % "sbt" % "1.3.0" diff --git a/sbt-app/src/sbt-test/nio/reload/project/plugins.sbt b/sbt-app/src/sbt-test/nio/reload/project/plugins.sbt index 99c853f12..1ed25683c 100644 --- a/sbt-app/src/sbt-test/nio/reload/project/plugins.sbt +++ b/sbt-app/src/sbt-test/nio/reload/project/plugins.sbt @@ -1,3 +1,5 @@ +ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always + libraryDependencies ++= { if (ScalafmtVersion.value == "2.0.4") { val sbtV = (sbtBinaryVersion in pluginCrossBuild).value diff --git a/sbt-app/src/sbt-test/plugins/play-watch/project/plugins.sbt b/sbt-app/src/sbt-test/plugins/play-watch/project/plugins.sbt index 05e01d6e5..c8882f94b 100644 --- a/sbt-app/src/sbt-test/plugins/play-watch/project/plugins.sbt +++ b/sbt-app/src/sbt-test/plugins/play-watch/project/plugins.sbt @@ -1 +1,2 @@ +ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.3") \ No newline at end of file diff --git a/sbt-app/src/sbt-test/plugins/sbt-native-packager/project/plugins.sbt b/sbt-app/src/sbt-test/plugins/sbt-native-packager/project/plugins.sbt index 414d83d34..c3e04c903 100644 --- a/sbt-app/src/sbt-test/plugins/sbt-native-packager/project/plugins.sbt +++ b/sbt-app/src/sbt-test/plugins/sbt-native-packager/project/plugins.sbt @@ -1 +1,3 @@ +ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always + addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.20") diff --git a/sbt-app/src/sbt-test/project/sbt-plugin/build.sbt b/sbt-app/src/sbt-test/project/sbt-plugin/build.sbt index 1831f255c..d0943ff9d 100644 --- a/sbt-app/src/sbt-test/project/sbt-plugin/build.sbt +++ b/sbt-app/src/sbt-test/project/sbt-plugin/build.sbt @@ -1,6 +1,6 @@ lazy val root = project.in(file(".")) .enablePlugins(SbtPlugin) .settings( - scalaVersion := "2.12.16", + scalaVersion := "2.12.17", scalacOptions ++= Seq("-Xfatal-warnings", "-Xlint") ) diff --git a/sbt-app/src/sbt-test/project/sbt-plugin/changes/oldSbtPlugin.sbt b/sbt-app/src/sbt-test/project/sbt-plugin/changes/oldSbtPlugin.sbt index 03437f9da..61199e931 100644 --- a/sbt-app/src/sbt-test/project/sbt-plugin/changes/oldSbtPlugin.sbt +++ b/sbt-app/src/sbt-test/project/sbt-plugin/changes/oldSbtPlugin.sbt @@ -1,6 +1,6 @@ lazy val root = project.in(file(".")) .settings( - scalaVersion := "2.12.16", + scalaVersion := "2.12.17", sbtPlugin := true, scalacOptions ++= Seq("-Xfatal-warnings", "-Xlint") ) diff --git a/sbt-app/src/sbt-test/project/source-plugins/test b/sbt-app/src/sbt-test/project/source-plugins/pending similarity index 100% rename from sbt-app/src/sbt-test/project/source-plugins/test rename to sbt-app/src/sbt-test/project/source-plugins/pending diff --git a/sbt-app/src/sbt-test/project/src-plugins/test b/sbt-app/src/sbt-test/project/src-plugins/pending similarity index 100% rename from sbt-app/src/sbt-test/project/src-plugins/test rename to sbt-app/src/sbt-test/project/src-plugins/pending diff --git a/sbt-app/src/sbt-test/project/src-plugins/project/p.sbt b/sbt-app/src/sbt-test/project/src-plugins/project/p.sbt index 8d6251248..84a62c711 100644 --- a/sbt-app/src/sbt-test/project/src-plugins/project/p.sbt +++ b/sbt-app/src/sbt-test/project/src-plugins/project/p.sbt @@ -1,2 +1,4 @@ +ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always + lazy val root = (project in file(".")). dependsOn(RootProject(file("../plugin"))) diff --git a/sbt-app/src/sbt-test/project/unified/build.sbt b/sbt-app/src/sbt-test/project/unified/build.sbt index 8210ad038..fe6b1a94a 100644 --- a/sbt-app/src/sbt-test/project/unified/build.sbt +++ b/sbt-app/src/sbt-test/project/unified/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / scalaVersion := "2.12.16" +ThisBuild / scalaVersion := "2.12.17" import sbt.internal.CommandStrings.{ inspectBrief, inspectDetailed } import sbt.internal.Inspect diff --git a/sbt-app/src/sbt-test/source-dependencies/constants/test b/sbt-app/src/sbt-test/source-dependencies/constants/test index b1e725f26..eeebe3599 100644 --- a/sbt-app/src/sbt-test/source-dependencies/constants/test +++ b/sbt-app/src/sbt-test/source-dependencies/constants/test @@ -1,4 +1,4 @@ -> ++2.12.16! +> ++2.12.17! $ copy-file changes/B.scala B.scala diff --git a/sbt-app/src/sbt-test/tests/scala-instance-classloader/build.sbt b/sbt-app/src/sbt-test/tests/scala-instance-classloader/build.sbt index 1f8431d46..7dcf87b1e 100644 --- a/sbt-app/src/sbt-test/tests/scala-instance-classloader/build.sbt +++ b/sbt-app/src/sbt-test/tests/scala-instance-classloader/build.sbt @@ -3,7 +3,7 @@ import sbt.internal.inc.ScalaInstance lazy val OtherScala = config("other-scala").hide lazy val junitinterface = "com.novocode" % "junit-interface" % "0.11" lazy val akkaActor = "com.typesafe.akka" %% "akka-actor" % "2.5.17" -ThisBuild / scalaVersion := "2.12.16" +ThisBuild / scalaVersion := "2.12.17" lazy val root = (project in file(".")) .configs(OtherScala) diff --git a/server-test/src/server-test/response/build.sbt b/server-test/src/server-test/response/build.sbt index 90f7f9f8d..9bf691e56 100644 --- a/server-test/src/server-test/response/build.sbt +++ b/server-test/src/server-test/response/build.sbt @@ -1,6 +1,6 @@ import sbt.internal.server.{ ServerHandler, ServerIntent } -ThisBuild / scalaVersion := "2.12.16" +ThisBuild / scalaVersion := "2.12.17" Global / serverLog / logLevel := Level.Debug // custom handler From 9d9e9e5c53e2fcf340cc5f1d1889e9561c30daa7 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 25 Sep 2022 19:13:42 +0200 Subject: [PATCH 17/42] build: harden dependency-graph.yml permissions Signed-off-by: Alex --- .github/workflows/dependency-graph.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/dependency-graph.yml b/.github/workflows/dependency-graph.yml index 7caea8278..0ab49c9b3 100644 --- a/.github/workflows/dependency-graph.yml +++ b/.github/workflows/dependency-graph.yml @@ -3,8 +3,12 @@ name: Submit Dependency Graph on: push: branches: [1.7.x] # default branch of the project +permissions: {} jobs: submit-graph: + permissions: + contents: write # to submit the dependency graph + name: Submit Dependency Graph runs-on: ubuntu-latest # or windows-latest, or macOS-latest steps: From 459310bc9b95720db647fb99ee0b57d1c83da95a Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 25 Sep 2022 19:14:47 +0200 Subject: [PATCH 18/42] build: harden ci.yml permissions Signed-off-by: Alex --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d717c8d25..6f74b063d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,9 @@ on: pull_request: push: +permissions: + contents: read # to fetch code (actions/checkout) + jobs: test: strategy: From 39d9a8fa180a53c15fc629d5c9e5b16a62a18bec Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 25 Sep 2022 19:15:26 +0200 Subject: [PATCH 19/42] build: harden nightly.yml permissions Signed-off-by: Alex --- .github/workflows/nightly.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 2897d641f..b7664a12f 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -5,6 +5,9 @@ on: # # 08:00 UTC = 03:00 EST # - cron: '0 8 * * *' +permissions: + contents: read # to fetch code (actions/checkout) + jobs: deploy: strategy: From 89acd3eed112d2a41480c53f28c961dee436ebb2 Mon Sep 17 00:00:00 2001 From: gontard Date: Fri, 25 Feb 2022 16:14:43 +0100 Subject: [PATCH 20/42] Improve log for not found remote cache artifact Before remote cache not found for 0.0.0-7c40144bd1c774e6 After remote cache artifact not found for org.gontard:sbt-test:0.0.0-7c40144bd1c774e6 Some(cached-compile) --- main/src/main/scala/sbt/internal/RemoteCache.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/internal/RemoteCache.scala b/main/src/main/scala/sbt/internal/RemoteCache.scala index 58e7b4b9c..c3838243b 100644 --- a/main/src/main/scala/sbt/internal/RemoteCache.scala +++ b/main/src/main/scala/sbt/internal/RemoteCache.scala @@ -303,7 +303,8 @@ object RemoteCache { } found = true case Left(e) => - log.info(s"remote cache not found for ${v}") + val classifier = seqa.map(_.classifier).mkString(" ") + log.info(s"remote cache artifact not found for $p $classifier") log.debug(e.getMessage) } } From 7f55e3acbd79149bae1d551c00b8a854154fc4eb Mon Sep 17 00:00:00 2001 From: gontard Date: Mon, 23 May 2022 20:54:11 +0200 Subject: [PATCH 21/42] Fix scripted tests doc --- DEVELOPING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DEVELOPING.md b/DEVELOPING.md index 8b1db7b09..40cbfda3a 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -151,14 +151,14 @@ suite with `sbt testOnly` #### Integration tests -Scripted integration tests reside in `sbt/src/sbt-test` and are +Scripted integration tests reside in `sbt-app/src/sbt-test` and are written using the same testing infrastructure sbt plugin authors can use to test their own plugins with sbt. You can read more about this style of tests [here](https://www.scala-sbt.org/1.0/docs/Testing-sbt-plugins). You can run the integration tests with the `sbt scripted` sbt command. To run a single test, such as the test in -`sbt/src/sbt-test/project/global-plugin`, simply run: +`sbt-app/src/sbt-test/project/global-plugin`, simply run: sbt "scripted project/global-plugin" From 68e2ec872dc9fb4121f6999139b93f8882c12ca9 Mon Sep 17 00:00:00 2001 From: gontard Date: Mon, 23 May 2022 21:31:26 +0200 Subject: [PATCH 22/42] Activate test-quick scripted test --- sbt-app/src/sbt-test/tests/test-quick/build.sbt | 3 +-- .../sbt-test/tests/test-quick/src/test/scala/Create.scala | 7 +++---- .../sbt-test/tests/test-quick/src/test/scala/Delete.scala | 5 ++--- sbt-app/src/sbt-test/tests/test-quick/{disabled => test} | 0 4 files changed, 6 insertions(+), 9 deletions(-) rename sbt-app/src/sbt-test/tests/test-quick/{disabled => test} (100%) diff --git a/sbt-app/src/sbt-test/tests/test-quick/build.sbt b/sbt-app/src/sbt-test/tests/test-quick/build.sbt index 0fb62b441..9fd396d27 100644 --- a/sbt-app/src/sbt-test/tests/test-quick/build.sbt +++ b/sbt-app/src/sbt-test/tests/test-quick/build.sbt @@ -1,9 +1,8 @@ val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" -val scalaxml = "org.scala-lang.modules" %% "scala-xml" % "1.1.1" ThisBuild / scalaVersion := "2.12.12" lazy val root = (project in file(".")) .settings( - libraryDependencies ++= List(scalaxml, scalatest), + libraryDependencies += scalatest % Test, Test / parallelExecution := false ) diff --git a/sbt-app/src/sbt-test/tests/test-quick/src/test/scala/Create.scala b/sbt-app/src/sbt-test/tests/test-quick/src/test/scala/Create.scala index 121de95b0..651807d8d 100644 --- a/sbt-app/src/sbt-test/tests/test-quick/src/test/scala/Create.scala +++ b/sbt-app/src/sbt-test/tests/test-quick/src/test/scala/Create.scala @@ -1,11 +1,10 @@ import org.scalatest.FlatSpec -import org.scalatest.matchers.ShouldMatchers -class Create extends FlatSpec with ShouldMatchers with Base { +class Create extends FlatSpec with Base { "a file" should "not exist" in { A(new B).foo - marker.exists should equal(false) - marker.createNewFile() should equal (true) + assert(marker.exists == false) + assert(marker.createNewFile() == true) } } diff --git a/sbt-app/src/sbt-test/tests/test-quick/src/test/scala/Delete.scala b/sbt-app/src/sbt-test/tests/test-quick/src/test/scala/Delete.scala index cd2eb6617..ff1caacb1 100644 --- a/sbt-app/src/sbt-test/tests/test-quick/src/test/scala/Delete.scala +++ b/sbt-app/src/sbt-test/tests/test-quick/src/test/scala/Delete.scala @@ -1,9 +1,8 @@ import org.scalatest.FlatSpec -import org.scalatest.matchers.ShouldMatchers -class Delete extends FlatSpec with ShouldMatchers with Base { +class Delete extends FlatSpec with Base { "a file" should "exist" in { - marker.exists should equal(true) + assert(marker.exists == true) marker.delete() } diff --git a/sbt-app/src/sbt-test/tests/test-quick/disabled b/sbt-app/src/sbt-test/tests/test-quick/test similarity index 100% rename from sbt-app/src/sbt-test/tests/test-quick/disabled rename to sbt-app/src/sbt-test/tests/test-quick/test From 11a7ab3ef70e4de85a5094b7714c43e2ca803ae0 Mon Sep 17 00:00:00 2001 From: gontard Date: Tue, 24 May 2022 06:44:26 +0200 Subject: [PATCH 23/42] Reproduce issue #5504 in scripted test --- .../sbt-test/tests/test-quick/changed/MathFunction.scala | 3 +++ .../tests/test-quick/src/main/scala/MathFunction.scala | 3 +++ .../tests/test-quick/src/test/scala/MathFunctionSpec.scala | 7 +++++++ sbt-app/src/sbt-test/tests/test-quick/test | 6 ++++++ 4 files changed, 19 insertions(+) create mode 100644 sbt-app/src/sbt-test/tests/test-quick/changed/MathFunction.scala create mode 100644 sbt-app/src/sbt-test/tests/test-quick/src/main/scala/MathFunction.scala create mode 100644 sbt-app/src/sbt-test/tests/test-quick/src/test/scala/MathFunctionSpec.scala diff --git a/sbt-app/src/sbt-test/tests/test-quick/changed/MathFunction.scala b/sbt-app/src/sbt-test/tests/test-quick/changed/MathFunction.scala new file mode 100644 index 000000000..1be75e613 --- /dev/null +++ b/sbt-app/src/sbt-test/tests/test-quick/changed/MathFunction.scala @@ -0,0 +1,3 @@ +object MathFunction { + def times2(i: Int): Int = 2 * 2 +} diff --git a/sbt-app/src/sbt-test/tests/test-quick/src/main/scala/MathFunction.scala b/sbt-app/src/sbt-test/tests/test-quick/src/main/scala/MathFunction.scala new file mode 100644 index 000000000..08d0ec501 --- /dev/null +++ b/sbt-app/src/sbt-test/tests/test-quick/src/main/scala/MathFunction.scala @@ -0,0 +1,3 @@ +object MathFunction { + def times2(i: Int): Int = i * 2 +} diff --git a/sbt-app/src/sbt-test/tests/test-quick/src/test/scala/MathFunctionSpec.scala b/sbt-app/src/sbt-test/tests/test-quick/src/test/scala/MathFunctionSpec.scala new file mode 100644 index 000000000..7ee6336da --- /dev/null +++ b/sbt-app/src/sbt-test/tests/test-quick/src/test/scala/MathFunctionSpec.scala @@ -0,0 +1,7 @@ +import org.scalatest.FlatSpec + +class MathFunctionTest extends FlatSpec { + "times2" should "double the input" in { + assert(MathFunction.times2(4) == 8) + } +} diff --git a/sbt-app/src/sbt-test/tests/test-quick/test b/sbt-app/src/sbt-test/tests/test-quick/test index d88f8a185..c86f0276f 100644 --- a/sbt-app/src/sbt-test/tests/test-quick/test +++ b/sbt-app/src/sbt-test/tests/test-quick/test @@ -32,3 +32,9 @@ $ sleep 2000 -> testQuick Create > testQuick Delete > testQuick Create + +# https://github.com/sbt/sbt/issues/5504 +$ copy-file changed/MathFunction.scala src/test/scala/MathFunction.scala +> compile +$ sleep 2000 +-> testQuick MathFunctionTest From cc44169fe092e0d2bfb113906e07615b1ed5152b Mon Sep 17 00:00:00 2001 From: gontard Date: Tue, 24 May 2022 10:54:11 +0200 Subject: [PATCH 24/42] Fix testQuick on changed function in object Fix https://github.com/sbt/sbt/issues/5504 --- main/src/main/scala/sbt/Defaults.scala | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index efd856a67..c199329f4 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1393,11 +1393,10 @@ object Defaults extends BuildCommon { val x = { import analysis.{ apis, relations => rel } rel.internalClassDeps(c).map(intlStamp(_, analysis, s + c)) ++ - rel.externalDeps(c).map(stamp) + - (apis.internal.get(c) match { - case Some(x) => x.compilationTimestamp - case _ => Long.MinValue - }) + rel.externalDeps(c).map(stamp) ++ + rel.productClassName.reverse(c).flatMap { pc => + apis.internal.get(pc).map(_.compilationTimestamp) + } + Long.MinValue }.max if (x != Long.MinValue) { stamps(c) = x From a775fb8f1da68cf35559345eae54a48c2a2b754d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 2 Oct 2022 04:07:49 -0400 Subject: [PATCH 25/42] Launcher 1.4.1 Launcher 1.4.1 is capable of launching Scala 3 apps. In other words, launchers prior to 1.4.1 are not capable of launching Scala 3 apps, including tests for sbt 2.x. --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index de4c5e44c..31b342e59 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -22,7 +22,7 @@ object Dependencies { private val libraryManagementCore = "org.scala-sbt" %% "librarymanagement-core" % lmVersion private val libraryManagementIvy = "org.scala-sbt" %% "librarymanagement-ivy" % lmVersion - val launcherVersion = "1.3.3" + val launcherVersion = "1.4.1" val launcherInterface = "org.scala-sbt" % "launcher-interface" % launcherVersion val rawLauncher = "org.scala-sbt" % "launcher" % launcherVersion val testInterface = "org.scala-sbt" % "test-interface" % "1.0" From dadfee584643a03a8bc1f7d3081f50753f80dd4d Mon Sep 17 00:00:00 2001 From: Chris Kipp Date: Sun, 21 Aug 2022 14:01:47 +0200 Subject: [PATCH 26/42] 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" } } From 2a61fb35f99557537df7f5a34d0f8cc0c6fec079 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 2 Oct 2022 12:45:30 -0400 Subject: [PATCH 27/42] Fix /tmp/.sbt/ collision for domain socket Problem ------- Fixes https://github.com/sbt/sbt/issues/7013 In a shared environment, multiple users will try to create `/tmp/.sbt/` directory, and fail. Solution -------- Append a deterministic hash like `/tmp/.sbt1234ABCD` based on the user home, so the same directory is used for the given user, but each user would have a unique runtime directory. --- main/src/main/scala/sbt/internal/SysProp.scala | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/main/src/main/scala/sbt/internal/SysProp.scala b/main/src/main/scala/sbt/internal/SysProp.scala index ce5760edd..b2846a1b7 100644 --- a/main/src/main/scala/sbt/internal/SysProp.scala +++ b/main/src/main/scala/sbt/internal/SysProp.scala @@ -14,6 +14,7 @@ import java.util.Locale import scala.util.control.NonFatal import scala.concurrent.duration._ +import sbt.internal.inc.HashUtil import sbt.internal.util.{ Terminal => ITerminal, Util } import sbt.internal.util.complete.SizeParser import sbt.io.syntax._ @@ -247,7 +248,15 @@ object SysProp { * Windows, and Docker environment. * Mostly these directories will be used as throw-away location to extract * native files etc. + * A deterministic hash is appended in the directory name as "/tmp/.sbt1234ABCD/" + * to avoid collision between multiple users in a shared server environment. */ - private[this] def runtimeDirectory: Path = - Paths.get(sys.env.getOrElse("XDG_RUNTIME_DIR", sys.props("java.io.tmpdir"))).resolve(".sbt") + private[this] def runtimeDirectory: Path = { + val hashValue = + java.lang.Long.toHexString(HashUtil.farmHash(home.toString.getBytes("UTF-8"))) + val halfhash = hashValue.take(8) + Paths + .get(sys.env.getOrElse("XDG_RUNTIME_DIR", sys.props("java.io.tmpdir"))) + .resolve(s".sbt$halfhash") + } } From d366b77b2361eab4decf2b999e3f9baee2da9e74 Mon Sep 17 00:00:00 2001 From: frosforever Date: Tue, 19 Jul 2022 09:55:45 -0400 Subject: [PATCH 28/42] Protect against missing edges in graph by using map get vs apply --- .../internal/graph/GraphTransformations.scala | 2 +- .../main/scala/sbt/internal/graph/model.scala | 4 ++-- .../sbt/internal/graph/rendering/DOT.scala | 18 ++++++++---------- .../internal/graph/rendering/Statistics.scala | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/main/src/main/scala/sbt/internal/graph/GraphTransformations.scala b/main/src/main/scala/sbt/internal/graph/GraphTransformations.scala index c7385383d..816fe2624 100644 --- a/main/src/main/scala/sbt/internal/graph/GraphTransformations.scala +++ b/main/src/main/scala/sbt/internal/graph/GraphTransformations.scala @@ -32,7 +32,7 @@ object GraphTransformations { val nodes = edges .foldLeft(Set.empty[GraphModuleId])((set, edge) => set + edge._1 + edge._2) - .map(graph.module) + .flatMap(graph.module) ModuleGraph(nodes.toSeq, edges) } diff --git a/main/src/main/scala/sbt/internal/graph/model.scala b/main/src/main/scala/sbt/internal/graph/model.scala index 219e8b4f6..5bedafcc4 100644 --- a/main/src/main/scala/sbt/internal/graph/model.scala +++ b/main/src/main/scala/sbt/internal/graph/model.scala @@ -67,7 +67,7 @@ private[sbt] case class ModuleGraph(nodes: Seq[Module], edges: Seq[Edge]) { lazy val modules: Map[GraphModuleId, Module] = nodes.map(n => (n.id, n)).toMap - def module(id: GraphModuleId): Module = modules(id) + def module(id: GraphModuleId): Option[Module] = modules.get(id) lazy val dependencyMap: Map[GraphModuleId, Seq[Module]] = createMap(identity) @@ -81,7 +81,7 @@ private[sbt] case class ModuleGraph(nodes: Seq[Module], edges: Seq[Edge]) { val m = new HashMap[GraphModuleId, Set[Module]] with MultiMap[GraphModuleId, Module] edges.foreach { entry => val (f, t) = bindingFor(entry) - m.addBinding(f, module(t)) + module(t).foreach(m.addBinding(f, _)) } m.toMap.mapValues(_.toSeq.sortBy(_.id.idString)).toMap.withDefaultValue(Nil) } diff --git a/main/src/main/scala/sbt/internal/graph/rendering/DOT.scala b/main/src/main/scala/sbt/internal/graph/rendering/DOT.scala index b7e347d63..d53fb1023 100644 --- a/main/src/main/scala/sbt/internal/graph/rendering/DOT.scala +++ b/main/src/main/scala/sbt/internal/graph/rendering/DOT.scala @@ -31,8 +31,8 @@ object DOT { } }.sorted.mkString("\n") - def originWasEvicted(edge: Edge): Boolean = graph.module(edge._1).isEvicted - def targetWasEvicted(edge: Edge): Boolean = graph.module(edge._2).isEvicted + def originWasEvicted(edge: Edge): Boolean = graph.module(edge._1).exists(_.isEvicted) + def targetWasEvicted(edge: Edge): Boolean = graph.module(edge._2).exists(_.isEvicted) // add extra edges from evicted to evicted-by module val evictedByEdges: Seq[Edge] = @@ -43,13 +43,11 @@ object DOT { // remove edges to new evicted-by module which is now replaced by a chain // dependend -> [evicted] -> dependee val evictionTargetEdges = - graph.edges - .filter(targetWasEvicted) - .map { - case (from, evicted) => - (from, evicted.copy(version = graph.module(evicted).evictedByVersion.get)) - } - .toSet + graph.edges.collect { + case edge @ (from, evicted) if targetWasEvicted(edge) => + // Can safely call `get` as `targetWasEvicted` already proves evicted exists in the graph + (from, evicted.copy(version = graph.module(evicted).flatMap(_.evictedByVersion).get)) + }.toSet val filteredEdges = graph.edges @@ -58,7 +56,7 @@ object DOT { val edges = { for (e <- filteredEdges) yield { val extra = - if (graph.module(e._1).isEvicted) + if (graph.module(e._1).exists(_.isEvicted)) s""" [label="Evicted By" style="$EvictedStyle"]""" else "" """ "%s" -> "%s"%s""".format(e._1.idString, e._2.idString, extra) diff --git a/main/src/main/scala/sbt/internal/graph/rendering/Statistics.scala b/main/src/main/scala/sbt/internal/graph/rendering/Statistics.scala index a52d4d387..15c922992 100644 --- a/main/src/main/scala/sbt/internal/graph/rendering/Statistics.scala +++ b/main/src/main/scala/sbt/internal/graph/rendering/Statistics.scala @@ -28,7 +28,7 @@ object Statistics { val directDependencies = graph.dependencyMap(moduleId).filterNot(_.isEvicted).map(_.id) val dependencyStats = directDependencies.map(statsFor).flatMap(_.transitiveStatsWithSelf).toMap - val selfSize = graph.module(moduleId).jarFile.filter(_.exists).map(_.length) + val selfSize = graph.module(moduleId).flatMap(_.jarFile).filter(_.exists).map(_.length) val numDirectDependencies = directDependencies.size val numTransitiveDependencies = dependencyStats.size val transitiveSize = selfSize.getOrElse(0L) + dependencyStats From 4e7fefa70cda0cac2683991c33abbc9da9c62bf9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 04:02:29 +0000 Subject: [PATCH 29/42] Bump actions/cache from 3.0.8 to 3.0.9 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.8 to 3.0.9. - [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.8...v3.0.9) --- 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 6f74b063d..50f68146f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,7 +94,7 @@ jobs: - name: Coursier cache uses: coursier/cache-action@v6 - name: Cache sbt - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: ~/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} From e7a847615a30692a032438ff880e1ecf0dfcc88e Mon Sep 17 00:00:00 2001 From: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> Date: Sun, 16 Oct 2022 22:42:53 +0200 Subject: [PATCH 30/42] Add zio-test TestFramework to default test frameworks --- main/src/main/scala/sbt/Defaults.scala | 2 +- sbt-app/src/sbt-test/tests/zio-test/build.sbt | 4 ++++ .../tests/zio-test/src/test/scala/spec/Spec.scala | 11 +++++++++++ sbt-app/src/sbt-test/tests/zio-test/test | 1 + testing/src/main/scala/sbt/TestFramework.scala | 1 + 5 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 sbt-app/src/sbt-test/tests/zio-test/build.sbt create mode 100644 sbt-app/src/sbt-test/tests/zio-test/src/test/scala/spec/Spec.scala create mode 100644 sbt-app/src/sbt-test/tests/zio-test/test diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index c199329f4..81aa5e509 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1217,7 +1217,7 @@ object Defaults extends BuildCommon { Seq( testFrameworks :== { import sbt.TestFrameworks._ - Seq(ScalaCheck, Specs2, Specs, ScalaTest, JUnit, MUnit) + Seq(ScalaCheck, Specs2, Specs, ScalaTest, JUnit, MUnit, ZIOTest) }, testListeners :== Nil, testOptions :== Nil, diff --git a/sbt-app/src/sbt-test/tests/zio-test/build.sbt b/sbt-app/src/sbt-test/tests/zio-test/build.sbt new file mode 100644 index 000000000..a2ddfa655 --- /dev/null +++ b/sbt-app/src/sbt-test/tests/zio-test/build.sbt @@ -0,0 +1,4 @@ +ThisBuild / scalaVersion := "2.13.10" + +libraryDependencies += "dev.zio" %% "zio-test" % "2.0.2" % Test +libraryDependencies += "dev.zio" %% "zio-test-sbt" % "2.0.2" % Test diff --git a/sbt-app/src/sbt-test/tests/zio-test/src/test/scala/spec/Spec.scala b/sbt-app/src/sbt-test/tests/zio-test/src/test/scala/spec/Spec.scala new file mode 100644 index 000000000..f95610899 --- /dev/null +++ b/sbt-app/src/sbt-test/tests/zio-test/src/test/scala/spec/Spec.scala @@ -0,0 +1,11 @@ +package spec + +import zio.test._ + +object Spec extends ZIOSpecDefault { + def spec = suite("Spec")( + test("test") { + assertTrue(1 == 1) + } + ) +} \ No newline at end of file diff --git a/sbt-app/src/sbt-test/tests/zio-test/test b/sbt-app/src/sbt-test/tests/zio-test/test new file mode 100644 index 000000000..a270b7b48 --- /dev/null +++ b/sbt-app/src/sbt-test/tests/zio-test/test @@ -0,0 +1 @@ +> test \ No newline at end of file diff --git a/testing/src/main/scala/sbt/TestFramework.scala b/testing/src/main/scala/sbt/TestFramework.scala index cb89dd5f4..bd20829ed 100644 --- a/testing/src/main/scala/sbt/TestFramework.scala +++ b/testing/src/main/scala/sbt/TestFramework.scala @@ -27,6 +27,7 @@ object TestFrameworks { TestFramework("org.specs2.runner.Specs2Framework", "org.specs2.runner.SpecsFramework") val JUnit = TestFramework("com.novocode.junit.JUnitFramework") val MUnit = TestFramework("munit.Framework") + val ZIOTest = TestFramework("zio.test.sbt.ZTestFramework") } final class TestFramework(val implClassNames: String*) extends Serializable { From 4ec2f7b7946304978bc3e97d3cd8a96113464122 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Oct 2022 04:02:28 +0000 Subject: [PATCH 31/42] Bump actions/cache from 3.0.9 to 3.0.11 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.9 to 3.0.11. - [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.9...v3.0.11) --- 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 50f68146f..1f45e1f38 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,7 +94,7 @@ jobs: - name: Coursier cache uses: coursier/cache-action@v6 - name: Cache sbt - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.11 with: path: ~/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} From 39dc13668f0e55d3fa46125fac7414268e922d5d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 30 Oct 2022 16:33:20 -0400 Subject: [PATCH 32/42] lm-coursier-shaded 2.0.12 https://github.com/coursier/sbt-coursier/releases/tag/v2.0.12 --- build.sbt | 2 +- main/src/main/scala/sbt/coursierint/LMCoursier.scala | 1 + project/Dependencies.scala | 2 +- project/build.properties | 2 +- sbt-app/src/repo-override-test/repo.config | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index 791ea39ae..c9d90f51f 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.2-SNAPSHOT" + val v = "1.7.3-SNAPSHOT" nightlyVersion.getOrElse(v) } ThisBuild / version2_13 := "2.0.0-SNAPSHOT" diff --git a/main/src/main/scala/sbt/coursierint/LMCoursier.scala b/main/src/main/scala/sbt/coursierint/LMCoursier.scala index 36d7cf524..ebdf02d78 100644 --- a/main/src/main/scala/sbt/coursierint/LMCoursier.scala +++ b/main/src/main/scala/sbt/coursierint/LMCoursier.scala @@ -20,6 +20,7 @@ import lmcoursier.definitions.{ Strict => CStrict, } import lmcoursier._ +import lmcoursier.syntax._ import lmcoursier.credentials.Credentials import Keys._ import sbt.internal.util.Util diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 31b342e59..486b32564 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -77,7 +77,7 @@ object Dependencies { def addSbtZincCompile = addSbtModule(sbtZincPath, "zincCompile", zincCompile) def addSbtZincCompileCore = addSbtModule(sbtZincPath, "zincCompileCore", zincCompileCore) - val lmCoursierShaded = "io.get-coursier" %% "lm-coursier-shaded" % "2.0.10" + val lmCoursierShaded = "io.get-coursier" %% "lm-coursier-shaded" % "2.0.12" def sjsonNew(n: String) = Def.setting("com.eed3si9n" %% n % "0.9.1") // contrabandSjsonNewVersion.value diff --git a/project/build.properties b/project/build.properties index 5b12c1dc6..563a014da 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.7.0 +sbt.version=1.7.2 diff --git a/sbt-app/src/repo-override-test/repo.config b/sbt-app/src/repo-override-test/repo.config index 68dbabf81..49770caeb 100644 --- a/sbt-app/src/repo-override-test/repo.config +++ b/sbt-app/src/repo-override-test/repo.config @@ -1,3 +1,3 @@ [repositories] local - jcenter: https://jcenter.bintray.com/ + sonatype-releases: https://oss.sonatype.org/content/repositories/releases From 92c6903ec57d9dc36842a926d70a9ac6c6c0683a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 6 Nov 2022 21:35:26 -0500 Subject: [PATCH 33/42] Bump lm and zinc --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 486b32564..ceb44a859 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") - val zincVersion = nightlyVersion.getOrElse("1.7.1") + sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.7.1") + val zincVersion = nightlyVersion.getOrElse("1.7.2") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From f974cd3bab0b8d09d031414c0741035ceba221b2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 6 Nov 2022 23:25:22 -0500 Subject: [PATCH 34/42] sbt 1.8.0-RC1 --- build.sbt | 2 +- sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index c9d90f51f..51994de34 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.3-SNAPSHOT" + val v = "1.8.0-SNAPSHOT" nightlyVersion.getOrElse(v) } ThisBuild / version2_13 := "2.0.0-SNAPSHOT" diff --git a/sbt b/sbt index 0becdebc6..bdd9a421c 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.7.1" +declare builtin_sbt_version="1.8.0-RC1" declare -a residual_args declare -a java_args declare -a scalac_args From e55955d918ac0269a461e1cc7c7c78d40cc65c41 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 10 Nov 2022 11:01:32 -0500 Subject: [PATCH 35/42] lm-coursier-shaded 2.0.13 --- project/Dependencies.scala | 4 ++-- .../conflict-manager-with-org/{test => pending} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename sbt-app/src/sbt-test/dependency-management/conflict-manager-with-org/{test => pending} (100%) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index ceb44a859..a06f57624 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.7.0") + private val ioVersion = nightlyVersion.getOrElse("1.8.0") private val lmVersion = sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.7.1") val zincVersion = nightlyVersion.getOrElse("1.7.2") @@ -77,7 +77,7 @@ object Dependencies { def addSbtZincCompile = addSbtModule(sbtZincPath, "zincCompile", zincCompile) def addSbtZincCompileCore = addSbtModule(sbtZincPath, "zincCompileCore", zincCompileCore) - val lmCoursierShaded = "io.get-coursier" %% "lm-coursier-shaded" % "2.0.12" + val lmCoursierShaded = "io.get-coursier" %% "lm-coursier-shaded" % "2.0.13" def sjsonNew(n: String) = Def.setting("com.eed3si9n" %% n % "0.9.1") // contrabandSjsonNewVersion.value diff --git a/sbt-app/src/sbt-test/dependency-management/conflict-manager-with-org/test b/sbt-app/src/sbt-test/dependency-management/conflict-manager-with-org/pending similarity index 100% rename from sbt-app/src/sbt-test/dependency-management/conflict-manager-with-org/test rename to sbt-app/src/sbt-test/dependency-management/conflict-manager-with-org/pending From 03e1b3cadcad4189aeb01d3934b6a869da3bb6df Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 10 Nov 2022 12:02:37 -0500 Subject: [PATCH 36/42] Wipe out boot directory --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f45e1f38..6c2cc30a4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,6 +105,7 @@ jobs: if: ${{ matrix.jobtype == 1 }} shell: bash run: | + rm -rf "$HOME/.sbt/boot/" || true ./sbt -v --client mimaReportBinaryIssues ./sbt -v --client javafmtCheck ./sbt -v --client "Test/javafmtCheck" From 05fe27226eee44a59487e0e333dc51bf3e884712 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 10 Nov 2022 15:24:00 -0500 Subject: [PATCH 37/42] Zinc 1.8.0, lm 1.8.0 --- project/Dependencies.scala | 4 ++-- sbt-app/src/sbt-test/project/src-plugins/{pending => test} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename sbt-app/src/sbt-test/project/src-plugins/{pending => test} (100%) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index a06f57624..33941806c 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -14,8 +14,8 @@ object Dependencies { // sbt modules private val ioVersion = nightlyVersion.getOrElse("1.8.0") private val lmVersion = - sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.7.1") - val zincVersion = nightlyVersion.getOrElse("1.7.2") + sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.8.0") + val zincVersion = nightlyVersion.getOrElse("1.8.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/sbt-app/src/sbt-test/project/src-plugins/pending b/sbt-app/src/sbt-test/project/src-plugins/test similarity index 100% rename from sbt-app/src/sbt-test/project/src-plugins/pending rename to sbt-app/src/sbt-test/project/src-plugins/test From 09e06c45f01a72ed1010873a3ba89c0b70689fca Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 10 Nov 2022 16:30:41 -0500 Subject: [PATCH 38/42] sbt 1.8.0 --- build.sbt | 2 +- sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 51994de34..46681bca6 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.8.0-SNAPSHOT" + val v = "1.8.1-SNAPSHOT" nightlyVersion.getOrElse(v) } ThisBuild / version2_13 := "2.0.0-SNAPSHOT" diff --git a/sbt b/sbt index bdd9a421c..6d4d96c4e 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.8.0-RC1" +declare builtin_sbt_version="1.8.0" declare -a residual_args declare -a java_args declare -a scalac_args From a2de0643a60284dd8274228abdc17f814939fe6b Mon Sep 17 00:00:00 2001 From: Vadim Chelyshov Date: Tue, 6 Dec 2022 15:59:27 +0300 Subject: [PATCH 39/42] fix: bspConfig sbt.script - use `Path` env variable as a fallback for Windows Originally reported in https://github.com/scalameta/metals/issues/4702#issuecomment-1339137772 --- .gitignore | 1 + .../main/scala/sbt/internal/bsp/BuildServerConnection.scala | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 322179c4a..b36926580 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ npm-debug.log .bsp/ metals.sbt launcher-package/citest/freshly-baked +.vscode diff --git a/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala b/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala index bdc850cd2..4317f893d 100644 --- a/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala +++ b/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala @@ -63,8 +63,10 @@ object BuildServerConnection { // For those who use an old sbt script, the -Dsbt.script is not set // As a fallback we try to find the sbt script in $PATH val fileName = if (Properties.isWin) "sbt.bat" else "sbt" - val envPath = sys.env.getOrElse("PATH", "") - val allPaths = envPath.split(File.pathSeparator).map(Paths.get(_)) + val envPath = sys.env.collectFirst { + case (k, v) if k.toUpperCase() == "PATH" => v + } + val allPaths = envPath.map(_.split(File.pathSeparator).map(Paths.get(_))).getOrElse(Array.empty) allPaths .map(_.resolve(fileName)) .find(file => Files.exists(file) && Files.isExecutable(file)) From 0067bec2138000692f70db068449d566087b829e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Dec 2022 04:00:43 +0000 Subject: [PATCH 40/42] Bump actions/cache from 3.0.11 to 3.2.1 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.11 to 3.2.1. - [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.11...v3.2.1) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-minor ... 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 6c2cc30a4..5a8c530bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,7 +94,7 @@ jobs: - name: Coursier cache uses: coursier/cache-action@v6 - name: Cache sbt - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.2.1 with: path: ~/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} From 9afd3200f4c7674972b8433785e3f075c4ad5c15 Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Mon, 26 Dec 2022 19:03:20 -0500 Subject: [PATCH 41/42] Update ci.yml --- .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 5a8c530bd..5d302c00f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,7 +94,7 @@ jobs: - name: Coursier cache uses: coursier/cache-action@v6 - name: Cache sbt - uses: actions/cache@v3.2.1 + uses: actions/cache@v3 with: path: ~/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} From ff56e88532a1fb0fb32a633638a08c5d36d5202b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 31 Dec 2022 13:38:17 -0500 Subject: [PATCH 42/42] Note on developing --- DEVELOPING.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/DEVELOPING.md b/DEVELOPING.md index 40cbfda3a..909fb566a 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -7,12 +7,15 @@ Create a [fork](https://docs.github.com/en/github/getting-started-with-github/fo ### Branch to work against -sbt uses two branches for development: +sbt uses **two or three** branches for development: +Generally the default branch set on Github is what we recommend as the base line for PRs. -- Development branch: `develop` (this is also called "master") -- Stable branch: `1.$MINOR.x`, where `$MINOR` is current minor version (e.g. `1.1.x` during 1.1.x series) +- Next minor branch: `1.$MINOR.x`, where `$MINOR` is next minor version (e.g. `1.9.x` during 1.8.x series) +- Development branch: `develop` +- Stable branch: `1.$MINOR.x`, where `$MINOR` is current minor version (e.g. `1.8.x` during 1.8.x series) -The `develop` branch represents the next major version of sbt. Only new features are pushed to the `develop` branch. This is the branch that you will branch off of to make your changes. +Currently `develop` branch represents the next major version of sbt, i.e. sbt 2. +Next minor branch is where new features can be added as long as it is binary compatible with sbt 1.0. The `stable` branch represents the current stable sbt release. Only bug fixes are back-ported to the stable branch. ### Instruction to build just sbt