Merge branch '1.9.x' into wip/merge-1.9.x

This commit is contained in:
Eugene Yokota 2022-12-31 16:28:47 -05:00
commit bb40e1bc87
52 changed files with 222 additions and 66 deletions

View File

@ -7,4 +7,6 @@ assignees: ''
--- ---
Please use https://github.com/sbt/sbt/discussions 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".

View File

@ -3,6 +3,9 @@ on:
pull_request: pull_request:
push: push:
permissions:
contents: read # to fetch code (actions/checkout)
jobs: jobs:
test: test:
strategy: strategy:
@ -41,7 +44,7 @@ jobs:
java: 8 java: 8
distribution: adopt distribution: adopt
jobtype: 8 jobtype: 8
- os: windows-2019 - os: windows-latest
java: 8 java: 8
distribution: adopt distribution: adopt
jobtype: 9 jobtype: 9
@ -49,7 +52,7 @@ jobs:
env: env:
JAVA_OPTS: -Xms800M -Xmx2G -Xss6M -XX:ReservedCodeCacheSize=128M -server -Dsbt.io.virtual=false -Dfile.encoding=UTF-8 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 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_213: 2.13.8
SCALA_3: 3.1.0 SCALA_3: 3.1.0
UTIL_TESTS: "utilCache/test utilControl/test utilInterface/test utilLogging/test utilPosition/test utilRelation/test utilScripted/test utilTracking/test" UTIL_TESTS: "utilCache/test utilControl/test utilInterface/test utilLogging/test utilPosition/test utilRelation/test utilScripted/test utilTracking/test"
@ -97,11 +100,12 @@ jobs:
key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}
- name: Setup Windows C++ toolchain - name: Setup Windows C++ toolchain
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@v1
if: ${{ matrix.os == 'windows-2019' }} if: ${{ matrix.os == 'windows-latest' }}
- name: Build and test (1) - name: Build and test (1)
if: ${{ matrix.jobtype == 1 }} if: ${{ matrix.jobtype == 1 }}
shell: bash shell: bash
run: | run: |
rm -rf "$HOME/.sbt/boot/" || true
# ./sbt -v --client mimaReportBinaryIssues # ./sbt -v --client mimaReportBinaryIssues
./sbt -v --client javafmtCheck ./sbt -v --client javafmtCheck
./sbt -v --client "Test/javafmtCheck" ./sbt -v --client "Test/javafmtCheck"

View File

@ -3,8 +3,12 @@ name: Submit Dependency Graph
on: on:
push: push:
branches: [1.7.x] # default branch of the project branches: [1.7.x] # default branch of the project
permissions: {}
jobs: jobs:
submit-graph: submit-graph:
permissions:
contents: write # to submit the dependency graph
name: Submit Dependency Graph name: Submit Dependency Graph
runs-on: ubuntu-latest # or windows-latest, or macOS-latest runs-on: ubuntu-latest # or windows-latest, or macOS-latest
steps: steps:

View File

@ -5,6 +5,9 @@ on:
# # 08:00 UTC = 03:00 EST # # 08:00 UTC = 03:00 EST
# - cron: '0 8 * * *' # - cron: '0 8 * * *'
permissions:
contents: read # to fetch code (actions/checkout)
jobs: jobs:
deploy: deploy:
strategy: strategy:

1
.gitignore vendored
View File

@ -14,3 +14,4 @@ npm-debug.log
.vscode/ .vscode/
metals.sbt metals.sbt
launcher-package/citest/freshly-baked launcher-package/citest/freshly-baked
.vscode

View File

@ -7,12 +7,15 @@ Create a [fork](https://docs.github.com/en/github/getting-started-with-github/fo
### Branch to work against ### 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") - Next minor branch: `1.$MINOR.x`, where `$MINOR` is next minor version (e.g. `1.9.x` during 1.8.x series)
- Stable branch: `1.$MINOR.x`, where `$MINOR` is current minor version (e.g. `1.1.x` during 1.1.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. The `stable` branch represents the current stable sbt release. Only bug fixes are back-ported to the stable branch.
### Instruction to build just sbt ### Instruction to build just sbt

View File

@ -10,7 +10,7 @@ import scala.util.Try
// ThisBuild settings take lower precedence, // ThisBuild settings take lower precedence,
// but can be shared across the multi projects. // but can be shared across the multi projects.
ThisBuild / version := { ThisBuild / version := {
val v = "1.7.2-SNAPSHOT" val v = "1.8.1-SNAPSHOT"
nightlyVersion.getOrElse(v) nightlyVersion.getOrElse(v)
} }
ThisBuild / version2_13 := "2.0.0-SNAPSHOT" ThisBuild / version2_13 := "2.0.0-SNAPSHOT"
@ -43,10 +43,11 @@ ThisBuild / scmInfo := Some(
ScmInfo(url("https://github.com/sbt/sbt"), "git@github.com:sbt/sbt.git") ScmInfo(url("https://github.com/sbt/sbt"), "git@github.com:sbt/sbt.git")
) )
ThisBuild / resolvers += Resolver.mavenLocal ThisBuild / resolvers += Resolver.mavenLocal
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
Global / semanticdbEnabled := !(Global / insideCI).value Global / semanticdbEnabled := !(Global / insideCI).value
// Change main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala too, if you change this. // 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") val excludeLint = SettingKey[Set[Def.KeyedInitialize[_]]]("excludeLintKeys")
Global / excludeLint := (Global / excludeLint).?.value.getOrElse(Set.empty) Global / excludeLint := (Global / excludeLint).?.value.getOrElse(Set.empty)
Global / excludeLint += componentID Global / excludeLint += componentID

View File

@ -126,11 +126,12 @@ object ConsoleAppender {
def out: ConsoleOut def out: ConsoleOut
} }
private[sbt] object Properties { private[sbt] object Properties {
def from(terminal: Terminal): Properties = new Properties { def from(terminal: Terminal): Properties =
override def isAnsiSupported: Boolean = terminal.isAnsiSupported from(ConsoleOut.terminalOut(terminal), terminal.isAnsiSupported, terminal.isColorEnabled)
override def isColorEnabled: Boolean = terminal.isColorEnabled
override def out = ConsoleOut.terminalOut(terminal) def safelyFrom(terminal: Terminal): Properties =
} from(ConsoleOut.safeTerminalOut(terminal), terminal.isAnsiSupported, terminal.isColorEnabled)
def from(o: ConsoleOut, ansi: Boolean, color: Boolean): Properties = new Properties { def from(o: ConsoleOut, ansi: Boolean, color: Boolean): Properties = new Properties {
override def isAnsiSupported: Boolean = ansi override def isAnsiSupported: Boolean = ansi
override def isColorEnabled: Boolean = color override def isColorEnabled: Boolean = color
@ -246,6 +247,18 @@ object ConsoleAppender {
new ConsoleAppender(name, Properties.from(terminal), noSuppressedMessage) 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`. * A new `ConsoleAppender` identified by `name`, and that writes to `out`.
* *

View File

@ -8,6 +8,7 @@
package sbt.internal.util package sbt.internal.util
import java.io.{ BufferedWriter, PrintStream, PrintWriter } import java.io.{ BufferedWriter, PrintStream, PrintWriter }
import java.nio.channels.ClosedChannelException
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
@ -90,6 +91,26 @@ object ConsoleOut {
override def toString: String = s"TerminalOut" 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] private[this] val consoleOutPerTerminal = new ConcurrentHashMap[Terminal, ConsoleOut]
def terminalOut(terminal: Terminal): ConsoleOut = consoleOutPerTerminal.get(terminal) match { def terminalOut(terminal: Terminal): ConsoleOut = consoleOutPerTerminal.get(terminal) match {
case null => case null =>

View File

@ -438,6 +438,7 @@ object Terminal {
override def toString: String = s"ProxyTerminal(current = $t)" override def toString: String = s"ProxyTerminal(current = $t)"
} }
private[sbt] def get: Terminal = ProxyTerminal private[sbt] def get: Terminal = ProxyTerminal
private[sbt] def current: Terminal = activeTerminal.get
private[sbt] def withIn[T](in: InputStream)(f: => T): T = { private[sbt] def withIn[T](in: InputStream)(f: => T): T = {
val original = inputStream.get val original = inputStream.get

View File

@ -103,7 +103,8 @@ object LoggerContext {
} }
} }
def close(): Unit = { def close(): Unit = {
loggers.forEach((name, l) => l.clearAppenders()) closed.set(true)
loggers.forEach((_, l) => l.clearAppenders())
loggers.clear() loggers.clear()
} }
} }

View File

@ -1217,7 +1217,7 @@ object Defaults extends BuildCommon {
Seq( Seq(
testFrameworks :== { testFrameworks :== {
import sbt.TestFrameworks._ import sbt.TestFrameworks._
Seq(ScalaCheck, Specs2, Specs, ScalaTest, JUnit, MUnit) Seq(ScalaCheck, Specs2, Specs, ScalaTest, JUnit, MUnit, ZIOTest)
}, },
testListeners :== Nil, testListeners :== Nil,
testOptions :== Nil, testOptions :== Nil,

View File

@ -99,7 +99,7 @@ private[sbt] object PluginCross {
VersionNumber(sv) match { VersionNumber(sv) match {
case VersionNumber(Seq(0, 12, _*), _, _) => "2.9.2" case VersionNumber(Seq(0, 12, _*), _, _) => "2.9.2"
case VersionNumber(Seq(0, 13, _*), _, _) => "2.10.7" 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") case _ => sys.error(s"Unsupported sbt binary version: $sv")
} }
} }

View File

@ -20,6 +20,7 @@ import lmcoursier.definitions.{
Strict => CStrict, Strict => CStrict,
} }
import lmcoursier._ import lmcoursier._
import lmcoursier.syntax._
import lmcoursier.credentials.Credentials import lmcoursier.credentials.Credentials
import Keys._ import Keys._
import sbt.internal.util.Util import sbt.internal.util.Util

View File

@ -74,6 +74,7 @@ private[sbt] abstract class AbstractJobHandle extends JobHandle {
private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobService { private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobService {
private val nextId = new AtomicLong(1) private val nextId = new AtomicLong(1)
private val pool = new BackgroundThreadPool() private val pool = new BackgroundThreadPool()
private val context = LoggerContext()
private[sbt] def serviceTempDirBase: File private[sbt] def serviceTempDirBase: File
private[sbt] def useLog4J: Boolean private[sbt] def useLog4J: Boolean
@ -90,7 +91,6 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe
// hooks for sending start/stop events // hooks for sending start/stop events
protected def onAddJob(@deprecated("unused", "") job: JobHandle): Unit = () protected def onAddJob(@deprecated("unused", "") job: JobHandle): Unit = ()
protected def onRemoveJob(@deprecated("unused", "") job: JobHandle): Unit = () protected def onRemoveJob(@deprecated("unused", "") job: JobHandle): Unit = ()
private val context = LoggerContext()
// this mutable state could conceptually go on State except // this mutable state could conceptually go on State except
// that then every task that runs a background job would have // 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 def humanReadableName: String = job.humanReadableName
job.onStop { () => job.onStop { () =>
// TODO: Fix this
// logger.close()
removeJob(this) removeJob(this)
IO.delete(workingDirectory) IO.delete(workingDirectory)
context.clearAppenders(logger.name) context.clearAppenders(logger.name)
context.close()
} }
addJob(this) addJob(this)
override final def equals(other: Any): Boolean = other match { 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 override val spawningTask: ScopedKey[_] = unknownTask
} }
protected def makeContext(id: Long, spawningTask: ScopedKey[_], state: State): ManagedLogger
def doRunInBackground( def doRunInBackground(
spawningTask: ScopedKey[_], spawningTask: ScopedKey[_],
state: State, state: State,
start: (Logger, File) => BackgroundJob start: (Logger, File) => BackgroundJob
): JobHandle = { ): JobHandle = {
val id = nextId.getAndIncrement() 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" val workingDir = serviceTempDir / s"job-$id"
IO.createDirectory(workingDir) IO.createDirectory(workingDir)
val job = try { val job = try {
@ -502,10 +499,6 @@ private[sbt] class DefaultBackgroundJobService(
) extends AbstractBackgroundJobService { ) extends AbstractBackgroundJobService {
@deprecated("Use the constructor that specifies the background job temporary directory", "1.4.0") @deprecated("Use the constructor that specifies the background job temporary directory", "1.4.0")
def this() = this(IO.createTemporaryDirectory, false) 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 { private[sbt] object DefaultBackgroundJobService {

View File

@ -72,15 +72,23 @@ object LogManager {
manager(data, state, task, to, context) manager(data, state, task, to, context)
} }
@nowarn @deprecated("Use alternate constructBackgroundLog that provides a LoggerContext", "1.8.0")
def constructBackgroundLog( def constructBackgroundLog(
data: Settings[Scope], data: Settings[Scope],
state: State 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 = ): (ScopedKey[_]) => ManagedLogger =
(task: ScopedKey[_]) => { (task: ScopedKey[_]) => {
val manager: LogManager = val manager: LogManager =
(logManager in task.scope).get(data) getOrElse defaultManager(state.globalLogging.console) (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) manager.backgroundLog(data, state, task, context)
} }
@ -134,7 +142,7 @@ object LogManager {
task: ScopedKey[_], task: ScopedKey[_],
context: LoggerContext context: LoggerContext
): ManagedLogger = { ): ManagedLogger = {
val console = screen(task, state) val console = ConsoleAppender.safe("bg-" + ConsoleAppender.generateName(), ITerminal.current)
LogManager.backgroundLog(data, state, task, console, relay(()), context) LogManager.backgroundLog(data, state, task, console, relay(()), context)
} }
} }

View File

@ -14,6 +14,7 @@ import java.util.Locale
import scala.util.control.NonFatal import scala.util.control.NonFatal
import scala.concurrent.duration._ import scala.concurrent.duration._
import sbt.internal.inc.HashUtil
import sbt.internal.util.{ Terminal => ITerminal, Util } import sbt.internal.util.{ Terminal => ITerminal, Util }
import sbt.internal.util.complete.SizeParser import sbt.internal.util.complete.SizeParser
import sbt.io.syntax._ import sbt.io.syntax._
@ -247,7 +248,15 @@ object SysProp {
* Windows, and Docker environment. * Windows, and Docker environment.
* Mostly these directories will be used as throw-away location to extract * Mostly these directories will be used as throw-away location to extract
* native files etc. * 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 = private[this] def runtimeDirectory: Path = {
Paths.get(sys.env.getOrElse("XDG_RUNTIME_DIR", sys.props("java.io.tmpdir"))).resolve(".sbt") 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")
}
} }

View File

@ -201,7 +201,7 @@ final class BuildServerReporterImpl(
Diagnostic( Diagnostic(
range, range,
Option(toDiagnosticSeverity(problem.severity)), Option(toDiagnosticSeverity(problem.severity)),
None, problem.diagnosticCode().toOption.map(_.code),
Option("sbt"), Option("sbt"),
problem.message problem.message
) )

View File

@ -26,7 +26,7 @@ object Giter8TemplatePlugin extends AutoPlugin {
ModuleID( ModuleID(
"org.scala-sbt.sbt-giter8-resolver", "org.scala-sbt.sbt-giter8-resolver",
"sbt-giter8-resolver", "sbt-giter8-resolver",
"0.13.1" "0.15.0"
) cross CrossVersion.binary, ) cross CrossVersion.binary,
"sbtgiter8resolver.Giter8TemplateResolver" "sbtgiter8resolver.Giter8TemplateResolver"
) )

View File

@ -26,7 +26,7 @@ object SemanticdbPlugin extends AutoPlugin {
semanticdbEnabled := SysProp.semanticdb, semanticdbEnabled := SysProp.semanticdb,
semanticdbIncludeInJar := false, semanticdbIncludeInJar := false,
semanticdbOptions := List(), semanticdbOptions := List(),
semanticdbVersion := "4.5.9" semanticdbVersion := "4.5.13"
) )
override lazy val projectSettings: Seq[Def.Setting[_]] = Seq( override lazy val projectSettings: Seq[Def.Setting[_]] = Seq(

View File

@ -4,7 +4,7 @@ import sbt.contraband.ContrabandPlugin.autoImport._
object Dependencies { object Dependencies {
// WARNING: Please Scala update versions in PluginCross.scala too // 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 scala213 = "2.13.8"
val checkPluginCross = settingKey[Unit]("Make sure scalaVersion match up") val checkPluginCross = settingKey[Unit]("Make sure scalaVersion match up")
val baseScalaVersion = scala212 val baseScalaVersion = scala212
@ -12,17 +12,17 @@ object Dependencies {
sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version")
// sbt modules // sbt modules
private val ioVersion = nightlyVersion.getOrElse("1.7.0") private val ioVersion = nightlyVersion.getOrElse("1.8.0")
private val lmVersion = private val lmVersion =
sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.7.0") sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.8.0")
val zincVersion = nightlyVersion.getOrElse("1.7.1") val zincVersion = nightlyVersion.getOrElse("1.8.0")
private val sbtIO = "org.scala-sbt" %% "io" % ioVersion private val sbtIO = "org.scala-sbt" %% "io" % ioVersion
private val libraryManagementCore = "org.scala-sbt" %% "librarymanagement-core" % lmVersion private val libraryManagementCore = "org.scala-sbt" %% "librarymanagement-core" % lmVersion
private val libraryManagementIvy = "org.scala-sbt" %% "librarymanagement-ivy" % 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 launcherInterface = "org.scala-sbt" % "launcher-interface" % launcherVersion
val rawLauncher = "org.scala-sbt" % "launcher" % launcherVersion val rawLauncher = "org.scala-sbt" % "launcher" % launcherVersion
val testInterface = "org.scala-sbt" % "test-interface" % "1.0" val testInterface = "org.scala-sbt" % "test-interface" % "1.0"
@ -77,7 +77,7 @@ object Dependencies {
def addSbtZincCompile = addSbtModule(sbtZincPath, "zincCompile", zincCompile) def addSbtZincCompile = addSbtModule(sbtZincPath, "zincCompile", zincCompile)
def addSbtZincCompileCore = addSbtModule(sbtZincPath, "zincCompileCore", zincCompileCore) 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.13"
def sjsonNew(n: String) = def sjsonNew(n: String) =
Def.setting("com.eed3si9n" %% n % "0.9.1") // contrabandSjsonNewVersion.value Def.setting("com.eed3si9n" %% n % "0.9.1") // contrabandSjsonNewVersion.value
@ -102,9 +102,9 @@ object Dependencies {
val scalaXml = Def.setting( val scalaXml = Def.setting(
if (scalaBinaryVersion.value == "3") { if (scalaBinaryVersion.value == "3") {
"org.scala-lang.modules" %% "scala-xml" % "2.0.1" "org.scala-lang.modules" %% "scala-xml" % "2.1.0"
} else { } else {
"org.scala-lang.modules" %% "scala-xml" % "1.3.0" "org.scala-lang.modules" %% "scala-xml" % "2.1.0"
} }
) )
val scalaParsers = Def.setting( val scalaParsers = Def.setting(

View File

@ -1 +1 @@
sbt.version=1.7.0 sbt.version=1.7.2

View File

@ -63,8 +63,10 @@ object BuildServerConnection {
// For those who use an old sbt script, the -Dsbt.script is not set // 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 // As a fallback we try to find the sbt script in $PATH
val fileName = if (Properties.isWin) "sbt.bat" else "sbt" val fileName = if (Properties.isWin) "sbt.bat" else "sbt"
val envPath = sys.env.getOrElse("PATH", "") val envPath = sys.env.collectFirst {
val allPaths = envPath.split(File.pathSeparator).map(Paths.get(_)) case (k, v) if k.toUpperCase() == "PATH" => v
}
val allPaths = envPath.map(_.split(File.pathSeparator).map(Paths.get(_))).getOrElse(Array.empty)
allPaths allPaths
.map(_.resolve(fileName)) .map(_.resolve(fileName))
.find(file => Files.exists(file) && Files.isExecutable(file)) .find(file => Files.exists(file) && Files.isExecutable(file))

View File

@ -8,6 +8,7 @@
package sbt package sbt
import java.io.File import java.io.File
import java.io.PrintWriter
import java.lang.ProcessBuilder.Redirect import java.lang.ProcessBuilder.Redirect
import scala.sys.process.Process import scala.sys.process.Process
import OutputStrategy._ import OutputStrategy._
@ -15,6 +16,7 @@ import sbt.internal.util.{ RunningProcesses, Util }
import Util.{ AnyOps, none } import Util.{ AnyOps, none }
import java.lang.{ ProcessBuilder => JProcessBuilder } import java.lang.{ ProcessBuilder => JProcessBuilder }
import java.util.Locale
/** /**
* Represents a command that can be forked. * Represents a command that can be forked.
@ -57,7 +59,11 @@ final class Fork(val commandName: String, val runnerClass: Option[String]) {
(classpathEnv map { value => (classpathEnv map { value =>
Fork.ClasspathEnvKey -> 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 _) workingDirectory foreach (jpb directory _)
environment foreach { case (k, v) => jpb.environment.put(k, v) } environment foreach { case (k, v) => jpb.environment.put(k, v) }
if (connectInput) { if (connectInput) {
@ -125,4 +131,57 @@ object Fork {
val home = javaHome.getOrElse(new File(System.getProperty("java.home"))) val home = javaHome.getOrElse(new File(System.getProperty("java.home")))
new File(new File(home, "bin"), name) 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}"
}
} }

2
sbt
View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set +e set +e
declare builtin_sbt_version="1.7.1" declare builtin_sbt_version="1.8.0"
declare -a residual_args declare -a residual_args
declare -a java_args declare -a java_args
declare -a scalac_args declare -a scalac_args

View File

@ -1,3 +1,3 @@
[repositories] [repositories]
local local
jcenter: https://jcenter.bintray.com/ sonatype-releases: https://oss.sonatype.org/content/repositories/releases

View File

@ -1,3 +1,5 @@
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
libraryDependencies += "org.scala-sbt" % "sbt" % sbtVersion.value libraryDependencies += "org.scala-sbt" % "sbt" % sbtVersion.value

View File

@ -1,6 +1,6 @@
lazy val check = taskKey[Unit]("") lazy val check = taskKey[Unit]("")
lazy val compile2 = 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(".")) lazy val root = (project in file("."))
.aggregate(foo, bar, client) .aggregate(foo, bar, client)

View File

@ -17,7 +17,7 @@
## test + with command or alias ## test + with command or alias
> clean > clean
## for command cross building you do need crossScalaVerions on root ## 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 > + build
$ exists foo/target/scala-2.12 $ exists foo/target/scala-2.12
$ exists foo/target/scala-2.13 $ exists foo/target/scala-2.13

View File

@ -1,14 +1,14 @@
scalaVersion := "2.12.16" scalaVersion := "2.12.17"
lazy val core = project lazy val core = project
.settings( .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 lazy val subproj = project
.dependsOn(core) .dependsOn(core)
.settings( .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 // a random library compiled against Scala 3.1
libraryDependencies += "org.http4s" %% "http4s-core" % "0.23.12" libraryDependencies += "org.http4s" %% "http4s-core" % "0.23.12"
) )

View File

@ -1,4 +1,4 @@
lazy val scala212 = "2.12.16" lazy val scala212 = "2.12.17"
lazy val scala213 = "2.13.1" lazy val scala213 = "2.13.1"
ThisBuild / scalaVersion := scala212 ThisBuild / scalaVersion := scala212

View File

@ -1,4 +1,4 @@
ThisBuild / scalaVersion := "2.12.16" ThisBuild / scalaVersion := "2.12.17"
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"com.novocode" % "junit-interface" % "0.5" % Test, "com.novocode" % "junit-interface" % "0.5" % Test,

View File

@ -1,4 +1,4 @@
ThisBuild / scalaVersion := "2.12.16" ThisBuild / scalaVersion := "2.12.17"
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"org.slf4j" % "slf4j-api" % "1.7.2", "org.slf4j" % "slf4j-api" % "1.7.2",

View File

@ -1,5 +1,5 @@
// ThisBuild / useCoursier := false // ThisBuild / useCoursier := false
ThisBuild / scalaVersion := "2.12.16" ThisBuild / scalaVersion := "2.12.17"
ThisBuild / organization := "org.example" ThisBuild / organization := "org.example"
ThisBuild / version := "0.1" ThisBuild / version := "0.1"

View File

@ -1,3 +1,5 @@
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
import scala.concurrent.duration._ import scala.concurrent.duration._
val foo = inputKey[Unit]("working task") val foo = inputKey[Unit]("working task")

View File

@ -1,3 +1,5 @@
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
import scala.concurrent.duration._ import scala.concurrent.duration._
libraryDependencies += "org.scala-sbt" % "sbt" % "1.3.0" libraryDependencies += "org.scala-sbt" % "sbt" % "1.3.0"

View File

@ -1,3 +1,5 @@
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
libraryDependencies ++= { libraryDependencies ++= {
if (ScalafmtVersion.value == "2.0.4") { if (ScalafmtVersion.value == "2.0.4") {
val sbtV = (sbtBinaryVersion in pluginCrossBuild).value val sbtV = (sbtBinaryVersion in pluginCrossBuild).value

View File

@ -1 +1,2 @@
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.3") addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.3")

View File

@ -1 +1,3 @@
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.20") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.20")

View File

@ -1,6 +1,6 @@
lazy val root = project.in(file(".")) lazy val root = project.in(file("."))
.enablePlugins(SbtPlugin) .enablePlugins(SbtPlugin)
.settings( .settings(
scalaVersion := "2.12.16", scalaVersion := "2.12.17",
scalacOptions ++= Seq("-Xfatal-warnings", "-Xlint") scalacOptions ++= Seq("-Xfatal-warnings", "-Xlint")
) )

View File

@ -1,6 +1,6 @@
lazy val root = project.in(file(".")) lazy val root = project.in(file("."))
.settings( .settings(
scalaVersion := "2.12.16", scalaVersion := "2.12.17",
sbtPlugin := true, sbtPlugin := true,
scalacOptions ++= Seq("-Xfatal-warnings", "-Xlint") scalacOptions ++= Seq("-Xfatal-warnings", "-Xlint")
) )

View File

@ -1,2 +1,4 @@
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
lazy val root = (project in file(".")). lazy val root = (project in file(".")).
dependsOn(RootProject(file("../plugin"))) dependsOn(RootProject(file("../plugin")))

View File

@ -1,4 +1,4 @@
ThisBuild / scalaVersion := "2.12.16" ThisBuild / scalaVersion := "2.12.17"
import sbt.internal.CommandStrings.{ inspectBrief, inspectDetailed } import sbt.internal.CommandStrings.{ inspectBrief, inspectDetailed }
import sbt.internal.Inspect import sbt.internal.Inspect

View File

@ -1,4 +1,4 @@
> ++2.12.16! > ++2.12.17!
$ copy-file changes/B.scala B.scala $ copy-file changes/B.scala B.scala

View File

@ -3,7 +3,7 @@ import sbt.internal.inc.ScalaInstance
lazy val OtherScala = config("other-scala").hide lazy val OtherScala = config("other-scala").hide
lazy val junitinterface = "com.novocode" % "junit-interface" % "0.11" lazy val junitinterface = "com.novocode" % "junit-interface" % "0.11"
lazy val akkaActor = "com.typesafe.akka" %% "akka-actor" % "2.5.17" 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(".")) lazy val root = (project in file("."))
.configs(OtherScala) .configs(OtherScala)

View File

@ -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

View File

@ -0,0 +1,11 @@
package spec
import zio.test._
object Spec extends ZIOSpecDefault {
def spec = suite("Spec")(
test("test") {
assertTrue(1 == 1)
}
)
}

View File

@ -0,0 +1 @@
> test

View File

@ -1,6 +1,6 @@
import sbt.internal.server.{ ServerHandler, ServerIntent } import sbt.internal.server.{ ServerHandler, ServerIntent }
ThisBuild / scalaVersion := "2.12.16" ThisBuild / scalaVersion := "2.12.17"
Global / serverLog / logLevel := Level.Debug Global / serverLog / logLevel := Level.Debug
// custom handler // custom handler

View File

@ -27,6 +27,7 @@ object TestFrameworks {
TestFramework("org.specs2.runner.Specs2Framework", "org.specs2.runner.SpecsFramework") TestFramework("org.specs2.runner.Specs2Framework", "org.specs2.runner.SpecsFramework")
val JUnit = TestFramework("com.novocode.junit.JUnitFramework") val JUnit = TestFramework("com.novocode.junit.JUnitFramework")
val MUnit = TestFramework("munit.Framework") val MUnit = TestFramework("munit.Framework")
val ZIOTest = TestFramework("zio.test.sbt.ZTestFramework")
} }
final class TestFramework(val implClassNames: String*) extends Serializable { final class TestFramework(val implClassNames: String*) extends Serializable {