Merge pull request #7950 from eed3si9n/wip/merge-1.10.x

[2.x] Merge 1.10.x
This commit is contained in:
eugene yokota 2024-12-17 12:55:59 -05:00 committed by GitHub
commit 8732d75a03
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
39 changed files with 200 additions and 148 deletions

View File

@ -4,3 +4,10 @@ updates:
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
target-branch: "develop"
commit-message:
prefix: "[2.x] "

View File

@ -1 +0,0 @@
1.8

View File

@ -48,12 +48,11 @@ ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml"
Global / semanticdbEnabled := !(Global / insideCI).value
// Change main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala too, if you change this.
Global / semanticdbVersion := "4.9.9"
Global / excludeLintKeys += Utils.componentID
Global / excludeLintKeys += scriptedBufferLog
Global / excludeLintKeys += checkPluginCross
Global / excludeLintKeys += nativeImageVersion
Global / excludeLintKeys += nativeImageJvm
ThisBuild / evictionErrorLevel := Level.Info
val excludeLint = SettingKey[Set[Def.KeyedInitialize[_]]]("excludeLintKeys")
Global / excludeLint := (Global / excludeLint).?.value.getOrElse(Set.empty)
Global / excludeLint += Utils.componentID
Global / excludeLint += scriptedBufferLog
Global / excludeLint += checkPluginCross
def commonSettings: Seq[Setting[_]] = Def.settings(
headerLicense := Some(
@ -67,6 +66,7 @@ def commonSettings: Seq[Setting[_]] = Def.settings(
)
),
scalaVersion := baseScalaVersion,
evictionErrorLevel := Level.Info,
Utils.componentID := None,
resolvers += Resolver.typesafeIvyRepo("releases").withName("typesafe-sbt-build-ivy-releases"),
resolvers ++= Resolver.sonatypeOssRepos("snapshots"),
@ -347,8 +347,8 @@ lazy val utilLogging = project
Seq(
jline,
jline3Terminal,
jline3JNA,
jline3Jansi,
jline3JNI,
jline3Native,
log4jApi,
log4jCore,
disruptor,
@ -1047,6 +1047,10 @@ lazy val sbtClientProj = (project in file("client"))
nativeImageOptions ++= Seq(
"--no-fallback",
s"--initialize-at-run-time=sbt.client",
// "The current machine does not support all of the following CPU features that are required by
// the image: [CX8, CMOV, FXSR, MMX, SSE, SSE2, SSE3, SSSE3, SSE4_1, SSE4_2, POPCNT, LZCNT, AVX,
// AVX2, BMI1, BMI2, FMA, F16C]."
"-march=compatibility",
// "--verbose",
"-H:IncludeResourceBundles=jline.console.completer.CandidateListCompletionHandler",
"-H:+ReportExceptionStackTraces",

View File

@ -11,11 +11,15 @@ package sbt.client;
import sbt.internal.client.NetworkClient;
public class Client {
public static void main(String[] args) {
public static void main(final String[] args) {
boolean hadError = false;
try {
NetworkClient.main(args);
} catch (final Throwable t) {
t.printStackTrace();
hadError = true;
} finally {
if (hadError) System.exit(1);
}
}
}

View File

@ -130,7 +130,7 @@ object LineReader {
}
catch {
case e: EndOfFileException =>
if (terminal == Terminal.console && System.console == null) None
if (terminal == Terminal.console && !Terminal.hasConsole) None
else Some("exit")
case _: IOError | _: ClosedException => Some("exit")
case _: UserInterruptException | _: ClosedByInterruptException |

View File

@ -19,51 +19,21 @@ import org.jline.terminal.{ Attributes, Size, Terminal => JTerminal }
import org.jline.terminal.Attributes.{ InputFlag, LocalFlag }
import org.jline.terminal.Terminal.SignalHandler
import org.jline.terminal.impl.{ AbstractTerminal, DumbTerminal }
import org.jline.terminal.impl.jansi.JansiTerminalProvider
import org.jline.terminal.spi.{ SystemStream, TerminalProvider }
import org.jline.utils.OSUtils
import sbt.internal.util.Terminal.hasConsole
import scala.jdk.CollectionConverters.*
import scala.util.Try
import java.util.concurrent.LinkedBlockingQueue
private[sbt] object JLine3 {
private[util] val initialAttributes = new AtomicReference[Attributes]
private val forceWindowsJansiHolder = new AtomicBoolean(false)
private[sbt] def forceWindowsJansi(): Unit = forceWindowsJansiHolder.set(true)
private def windowsJansi(): org.jline.terminal.Terminal = {
val provider = new JansiTerminalProvider
val termType = sys.props.get("org.jline.terminal.type").orElse(sys.env.get("TERM")).orNull
provider.winSysTerminal(
"console",
termType,
OSUtils.IS_CONEMU,
Charset.forName("UTF-8"),
false,
SignalHandler.SIG_DFL,
true,
SystemStream.Output
)
}
private val jansi = {
val (major, minor) =
(JansiTerminalProvider.getJansiMajorVersion, JansiTerminalProvider.getJansiMinorVersion)
(major > 1 || minor >= 18) && Util.isWindows
}
private[util] def system: org.jline.terminal.Terminal = {
val term =
if (forceWindowsJansiHolder.get) windowsJansi()
else {
// Only use jna on windows. Both jna and jansi use illegal reflective
// accesses on posix system.
org.jline.terminal.TerminalBuilder
.builder()
.system(System.console != null)
.jna(Util.isWindows && !jansi)
.jansi(jansi)
.paused(true)
.build()
}
org.jline.terminal.TerminalBuilder
.builder()
.system(hasConsole)
.paused(true)
.build()
initialAttributes.get match {
case null => initialAttributes.set(term.getAttributes)
case _ =>

View File

@ -289,7 +289,7 @@ object Terminal {
* the sbt client to detach from the server it launches.
*/
def close(): Unit = {
if (System.console == null) {
if (!hasConsole) {
originalOut.close()
originalIn.close()
originalErr.close()
@ -368,7 +368,17 @@ object Terminal {
private val isDumb = Some("dumb") == sys.env.get("TERM")
private def isDumbTerminal = isDumb || System.getProperty("jline.terminal", "") == "none"
private val hasConsole = Option(java.lang.System.console).isDefined
private[sbt] val hasConsole = {
System.console != null && {
try {
val isTerminal = System.console.getClass.getMethod("isTerminal")
isTerminal.invoke(System.console).asInstanceOf[Boolean]
} catch {
case _: NoSuchMethodException =>
true
}
}
}
private def useColorDefault: Boolean = {
// This approximates that both stdin and stdio are connected,
// so by default color will be turned off for pipes and redirects.
@ -717,7 +727,7 @@ object Terminal {
inputStream.read match {
case -1 =>
case `NO_BOOT_CLIENTS_CONNECTED` =>
if (System.console == null) {
if (!Terminal.hasConsole) {
result.put(-1)
running.set(false)
}

View File

@ -121,7 +121,7 @@ val root = (project in file(".")).
file
},
// update sbt.sh at root
sbtnVersion := "1.10.3",
sbtnVersion := "1.10.5",
sbtnJarsBaseUrl := "https://github.com/sbt/sbtn-dist/releases/download",
sbtnJarsMappings := {
val baseUrl = sbtnJarsBaseUrl.value

View File

@ -890,27 +890,27 @@ for /F "delims=.-_ tokens=1-2" %%v in ("!sbtV!") do (
set sbtBinaryV_1=%%v
set sbtBinaryV_2=%%w
)
set native_client_ready=
rem default to run_native_client=1 for sbt 2.x
if !sbtBinaryV_1! geq 2 (
set native_client_ready=1
if !sbt_args_client! equ 0 (
set run_native_client=
) else (
set run_native_client=1
)
) else (
if !sbtBinaryV_1! geq 1 (
if !sbtBinaryV_2! geq 4 (
set native_client_ready=1
if !sbt_args_client! equ 1 (
set run_native_client=1
)
)
)
)
if !native_client_ready! equ 1 (
if !sbt_args_client! equ 1 (
set run_native_client=1
)
)
set native_client_ready=
exit /B 0
:checkjava
set /a required_version=6
set /a required_version=8
if /I !JAVA_VERSION! GEQ !required_version! (
exit /B 0
)

View File

@ -17,6 +17,7 @@ import java.nio.file.Files
import java.util.UUID
import java.util.concurrent.atomic.{ AtomicBoolean, AtomicReference }
import java.util.concurrent.{ ConcurrentHashMap, LinkedBlockingQueue, TimeUnit }
import java.text.DateFormat
import sbt.BasicCommandStrings.{ DashDashDetachStdio, DashDashServer, Shutdown, TerminateAction }
import sbt.internal.langserver.{ LogMessageParams, MessageType, PublishDiagnosticsParams }
@ -534,7 +535,7 @@ class NetworkClient(
case null =>
case (q, startTime, name) =>
val now = System.currentTimeMillis
val message = timing(startTime, now)
val message = NetworkClient.timing(startTime, now)
val ec = exitCode
if (batchMode.get || !attached.get) {
if (ec == 0) console.success(message)
@ -1008,27 +1009,6 @@ class NetworkClient(
RawInputThread.this.interrupt()
}
}
// copied from Aggregation
private def timing(startTime: Long, endTime: Long): String = {
import java.text.DateFormat
val format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)
val nowString = format.format(new java.util.Date(endTime))
val total = math.max(0, (endTime - startTime + 500) / 1000)
val totalString = s"$total s" +
(if (total <= 60) ""
else {
val maybeHours = total / 3600 match {
case 0 => ""
case h => f"$h%02d:"
}
val mins = f"${total % 3600 / 60}%02d"
val secs = f"${total % 60}%02d"
s" ($maybeHours$mins:$secs)"
})
s"Total time: $totalString, completed $nowString"
}
}
object NetworkClient {
@ -1141,6 +1121,25 @@ object NetworkClient {
)
}
private[sbt] def timing(format: DateFormat, startTime: Long, endTime: Long): String =
val total = (endTime - startTime + 500) / 1000
val totalString = s"$total s" +
(if (total <= 60) ""
else {
val maybeHours = total / 3600 match
case 0 => ""
case h => f"$h%02d:"
val mins = f"${total % 3600 / 60}%02d"
val secs = f"${total % 60}%02d"
s" ($maybeHours$mins:$secs)"
})
s"elapsed time: $totalString"
private[sbt] def timing(startTime: Long, endTime: Long): String = {
val format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)
timing(format, startTime, endTime)
}
def client(
baseDirectory: File,
args: Array[String],
@ -1241,7 +1240,6 @@ object NetworkClient {
System.out.flush()
})
Runtime.getRuntime.addShutdownHook(hook)
if (Util.isNonCygwinWindows) sbt.internal.util.JLine3.forceWindowsJansi()
val parsed = parseArgs(restOfArgs)
System.exit(Terminal.withStreams(isServer = false, isSubProcess = false) {
val term = Terminal.console

View File

@ -17,6 +17,7 @@ import sbt.BasicKeys.{ historyPath, colorShellPrompt }
import sbt.State
import sbt.internal.CommandChannel
import sbt.internal.util.ConsoleAppender.{ ClearPromptLine, ClearScreenAfterCursor, DeleteLine }
import sbt.internal.util.Terminal.hasConsole
import sbt.internal.util._
import sbt.internal.util.complete.{ Parser }
@ -70,7 +71,7 @@ private[sbt] object UITask {
if (thread.isInterrupted || closed.get) throw interrupted
(try reader.readLine(clear + terminal.prompt.mkPrompt())
finally reader.close) match {
case None if terminal == Terminal.console && System.console == null =>
case None if terminal == Terminal.console && !hasConsole =>
// No stdin is attached to the process so just ignore the result and
// block until the thread is interrupted.
this.synchronized(this.wait())

View File

@ -14,6 +14,7 @@ import java.net.URL;
import java.net.URLClassLoader;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.Stack;
import java.util.regex.Pattern;
import xsbti.AppProvider;
import xsbti.ScalaProvider;
@ -65,21 +66,16 @@ public final class MetaBuildLoader extends URLClassLoader {
* library.
*/
public static MetaBuildLoader makeLoader(final AppProvider appProvider) throws IOException {
final String jlineJars = "jline-?[0-9.]+-sbt-.*|jline-terminal(-(jna|jansi))?-[0-9.]+";
final String jlineJars =
"jline-?[0-9.]+-sbt-.*|jline-terminal(-(jni))?-[0-9.]+|jline-native-[0-9.]+";
final String testInterfaceJars = "test-interface(-.*)?";
final String compilerInterfaceJars = "compiler-interface(-.*)?";
final String utilInterfaceJars = "util-interface(-.*)?";
final String jansiJars = "jansi-[0-9.]+";
final String jnaJars = "jna-(platform-)?[0-9.]+";
final String fullPattern =
String.format(
"^(%s|%s|%s|%s|%s|%s)\\.jar",
jlineJars,
testInterfaceJars,
compilerInterfaceJars,
utilInterfaceJars,
jansiJars,
jnaJars);
"^(%s|%s|%s|%s|%s)\\.jar",
jlineJars, testInterfaceJars, compilerInterfaceJars, utilInterfaceJars, jansiJars);
final Pattern pattern = Pattern.compile(fullPattern);
final File[] cp = appProvider.mainClasspath();
final Set<File> interfaceFiles = new LinkedHashSet<>();

View File

@ -109,6 +109,7 @@ abstract class JobHandle {
def id: Long
def humanReadableName: String
def spawningTask: ScopedKey[?]
def isAutoCancel: Boolean
}
/**

View File

@ -123,9 +123,10 @@ object Cross {
.map { case uri ~ seg1 ~ cmd => (uri, seg1, cmd) }
Parser.parse(command, parser) match {
case Right((uri, seg1, cmd)) =>
structure.allProjectRefs.find(p =>
uri.contains(p.build.toString) && seg1 == p.project
) match {
structure.allProjectRefs.find {
case p if uri.isDefined => seg1 == p.project && uri.contains(p.build.toString)
case p => seg1 == p.project
} match {
case Some(proj) => (Seq(proj), cmd)
case _ => (resolveAggregates(extracted), command)
}

View File

@ -714,6 +714,20 @@ object Defaults extends BuildCommon {
},
crossSbtVersions := Vector((pluginCrossBuild / sbtVersion).value),
crossTarget := target.value,
clean := {
try {
val store = AnalysisUtil.staticCachedStore(
analysisFile = (Compile / compileAnalysisFile).value.toPath,
useTextAnalysis = false,
useConsistent = true,
)
// TODO: Uncomment after Zinc update
// store.clearCache()
} catch {
case NonFatal(_) => ()
}
clean.value
},
scalaCompilerBridgeBinaryJar := {
val sv = scalaVersion.value
val managed = managedScalaInstance.value
@ -1943,6 +1957,10 @@ object Defaults extends BuildCommon {
def foregroundRunMainTask: Initialize[InputTask[EmulateForeground]] =
Def.inputTask {
val handle = bgRunMain.evaluated
handle match
case threadJobHandle: AbstractBackgroundJobService#ThreadJobHandle =>
threadJobHandle.isAutoCancel = true
case _ => ()
EmulateForeground(handle)
}
@ -1950,6 +1968,11 @@ object Defaults extends BuildCommon {
def foregroundRunTask: Initialize[InputTask[EmulateForeground]] =
Def.inputTask {
val handle = bgRun.evaluated
handle match {
case threadJobHandle: AbstractBackgroundJobService#ThreadJobHandle =>
threadJobHandle.isAutoCancel = true
case _ =>
}
EmulateForeground(handle)
}

View File

@ -547,6 +547,7 @@ object EvaluateTask {
log.warn("Canceling execution...")
RunningProcesses.killAll()
ConcurrentRestrictions.cancelAll()
DefaultBackgroundJobService.stop()
shutdownImpl(true)
}
}

View File

@ -26,6 +26,7 @@ import sbt.internal.inc.ScalaInstance
import sbt.internal.io.Retry
import sbt.internal.nio.{ CheckBuildSources, FileTreeRepository }
import sbt.internal.server.{ BuildServerProtocol, NetworkChannel }
import sbt.internal.util.Terminal.hasConsole
import sbt.internal.util.Types.{ const, idFun }
import sbt.internal.util.complete.{ Parser, SizeParser }
import sbt.internal.util.{ Terminal => ITerminal, _ }
@ -156,8 +157,7 @@ private[sbt] object xMain:
try Some(new BootServerSocket(configuration)) -> None
catch {
case e: ServerAlreadyBootingException
if System.console != null && !ITerminal.startedByRemoteClient =>
case e: ServerAlreadyBootingException if hasConsole && !ITerminal.startedByRemoteClient =>
printThrowable(e)
println("Create a new server? y/n (default y)")
val exit =

View File

@ -21,6 +21,7 @@ import sbt.librarymanagement._
import sbt.librarymanagement.ivy.{ IvyConfiguration, IvyDependencyResolution }
import sbt.internal.inc.classpath.ClasspathUtil
import BasicCommandStrings._, BasicKeys._
import sbt.internal.util.Terminal.hasConsole
import sbt.ProjectExtra.*
private[sbt] object TemplateCommandUtil {
@ -84,7 +85,9 @@ private[sbt] object TemplateCommandUtil {
hit
} match {
case Some(_) => // do nothing
case None => System.err.println("Template not found for: " + arguments.mkString(" "))
case None =>
val error = "Template not found for: " + arguments.mkString(" ")
throw new IllegalArgumentException(error)
}
private def tryTemplate(
@ -183,7 +186,7 @@ private[sbt] object TemplateCommandUtil {
"disneystreaming/smithy4s.g8" -> "A Smithy4s project",
)
private def fortifyArgs(templates: List[(String, String)]): List[String] =
if (System.console eq null) Nil
if (!hasConsole) Nil
else
ITerminal.withStreams(true, false) {
assert(templates.size <= 20, "template list cannot have more than 20 items")
@ -275,7 +278,8 @@ private[sbt] object TemplateCommandUtil {
case TypelevelToolkitSlug :: Nil => typelevelToolkitTemplate()
case SbtCrossPlatformSlug :: Nil => sbtCrossPlatformTemplate()
case _ =>
System.err.println("Local template not found for: " + arguments.mkString(" "))
val error = "Local template not found for: " + arguments.mkString(" ")
throw new IllegalArgumentException(error)
}
private final val defaultScalaV = "3.3.4"

View File

@ -18,6 +18,7 @@ import sbt.ScopeAxis.{ Select, Zero }
import sbt.internal.util.complete.Parser
import sbt.internal.util.complete.Parser.{ failure, seq, success }
import sbt.internal.util._
import sbt.internal.client.NetworkClient
import sbt.std.Transform.DummyTaskMap
import sbt.util.{ Logger, Show }
@ -165,18 +166,7 @@ object Aggregation {
}
def timing(format: java.text.DateFormat, startTime: Long, endTime: Long): String =
val total = (endTime - startTime + 500) / 1000
val totalString = s"$total s" +
(if total <= 60 then ""
else {
val maybeHours = total / 3600 match
case 0 => ""
case h => f"$h%02d:"
val mins = f"${total % 3600 / 60}%02d"
val secs = f"${total % 60}%02d"
s" ($maybeHours$mins:$secs)"
})
s"elapsed time: $totalString"
NetworkClient.timing(format, startTime, endTime)
def defaultFormat: DateFormat = {
import java.text.DateFormat

View File

@ -11,7 +11,6 @@ package internal
import java.nio.file.Path
import sbt.internal.inc.MixedAnalyzingCompiler
import scala.concurrent.ExecutionContext
import xsbti.compile.{ AnalysisStore => XAnalysisStore }
import xsbti.compile.analysis.ReadWriteMappers
@ -34,7 +33,7 @@ private[sbt] object AnalysisUtil {
useConsistent = useConsistent,
mappers = ReadWriteMappers.getEmptyMappers(),
sort = true,
ec = ExecutionContext.global,
ec = scala.concurrent.ExecutionContext.global,
parallelism = parallelism,
)
}

View File

@ -1138,7 +1138,7 @@ private[sbt] object Continuous extends DeprecatedContinuous {
val callbacks: Callbacks,
val dynamicInputs: mutable.Set[DynamicInput],
val pending: Boolean,
var failAction: Option[Watch.Action],
var terminationAction: Option[Watch.Action],
) {
def this(
count: Int,
@ -1171,7 +1171,8 @@ private[sbt] object Continuous extends DeprecatedContinuous {
afterWatch,
callbacks,
dynamicInputs,
p
p,
terminationAction,
)
private def withCount(c: Int): ContinuousState =
new ContinuousState(
@ -1182,7 +1183,8 @@ private[sbt] object Continuous extends DeprecatedContinuous {
afterWatch,
callbacks,
dynamicInputs,
pending
pending,
terminationAction,
)
}
}
@ -1350,12 +1352,13 @@ private[sbt] object ContinuousCommands {
case Watch.Trigger => Right(s"$runWatch ${channel.name}")
case Watch.Reload =>
val rewatch = s"$ContinuousExecutePrefix ${ws.count} ${cs.commands mkString "; "}"
cs.terminationAction = Some(Watch.Reload)
stop.map(_ :: "reload" :: rewatch :: Nil mkString "; ")
case Watch.Prompt => stop.map(_ :: s"$PromptChannel ${channel.name}" :: Nil mkString ";")
case Watch.Run(commands) =>
stop.map(_ +: commands.map(_.commandLine).filter(_.nonEmpty) mkString "; ")
case a @ Watch.HandleError(_) =>
cs.failAction = Some(a)
cs.terminationAction = Some(a)
stop.map(_ :: s"$failWatch ${channel.name}" :: Nil mkString "; ")
case _ => stop
}
@ -1403,7 +1406,7 @@ private[sbt] object ContinuousCommands {
}
val commands = cs.commands.mkString("; ")
val count = cs.count
val action = cs.failAction.getOrElse(Watch.CancelWatch)
val action = cs.terminationAction.getOrElse(Watch.CancelWatch)
val st = cs.callbacks.onTermination(action, commands, count, newState)
if (error) st.fail else st
case _ => if (error) state.fail else state

View File

@ -119,7 +119,8 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe
override val spawningTask: ScopedKey[?],
val logger: ManagedLogger,
val workingDirectory: File,
val job: BackgroundJob
val job: BackgroundJob,
@volatile var isAutoCancel: Boolean = false,
) extends AbstractJobHandle {
def humanReadableName: String = job.humanReadableName
@ -141,6 +142,7 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe
private final class DeadHandle(override val id: Long, override val humanReadableName: String)
extends AbstractJobHandle {
override val spawningTask: ScopedKey[?] = unknownTask
override val isAutoCancel = false
}
def doRunInBackground(
@ -537,6 +539,15 @@ private[sbt] object DefaultBackgroundJobService {
backgroundJobServices.values.forEach(_.shutdown())
backgroundJobServices.clear()
}
private[sbt] def stop(): Unit = {
backgroundJobServices
.values()
.forEach(jobService => {
jobService.jobs.filter(_.isAutoCancel).foreach(jobService.stop)
})
}
private[sbt] lazy val backgroundJobServiceSetting: Setting[?] =
(GlobalScope / Keys.bgJobService) := {
val path = (GlobalScope / sbt.Keys.bgJobServiceDirectory).value

View File

@ -11,6 +11,7 @@ package internal
import Def._
import Keys.{ sbtVersion, state, terminal }
import sbt.internal.util.Terminal.hasConsole
import java.io.{ File, FileInputStream, FileOutputStream, InputStream, IOException }
import java.net.URI
@ -37,7 +38,7 @@ private[sbt] object InstallSbtn {
Files.deleteIfExists(tmp)
()
}
val shell = if (System.console != null) getShell(term) else "none"
val shell = if (hasConsole) getShell(term) else "none"
shell match {
case "none" =>
case s =>

View File

@ -59,7 +59,7 @@ private[sbt] final class TaskTraceEvent extends AbstractTaskExecuteProgress with
def durationEvent(name: String, cat: String, t: Timer): String = {
val sb = new java.lang.StringBuilder(name.length + 2)
CompactPrinter.print(new JString(name), sb)
s"""{"name": ${sb.toString}, "cat": "$cat", "ph": "X", "ts": ${(t.startMicros)}, "dur": ${(t.durationMicros)}, "pid": 0, "tname": ${t.threadName}}"""
s"""{"name": ${sb.toString}, "cat": "$cat", "ph": "X", "ts": ${(t.startMicros)}, "dur": ${(t.durationMicros)}, "pid": 0, "tname": "${t.threadName}"}"""
}
val entryIterator = currentTimings
while (entryIterator.hasNext) {

View File

@ -148,8 +148,9 @@ object DependencyTreeSettings {
.asciiTree(GraphTransformations.reverseGraphStartingAt(graph, module), graphWidth)
}
.mkString("\n")
streams.value.log.info(output)
synchronized {
streams.value.log.info(output)
}
output
},
) ++
@ -172,7 +173,9 @@ object DependencyTreeSettings {
key := {
val s = streams.value
val str = (key / asString).value
s.log.info(str)
synchronized {
s.log.info(str)
}
},
(key / toFile) := {
val (targetFile, force) = targetFileAndForceParser.parsed
@ -199,7 +202,7 @@ object DependencyTreeSettings {
rendering.DOT.HTMLLabelRendering.AngleBrackets,
dependencyDotNodeColors.value
)
val link = DagreHTML.createLink(dotGraph, target.value)
val link = DagreHTML.createLink(dotGraph, dependencyBrowseGraphTarget.value)
streams.value.log.info(s"HTML graph written to $link")
link
}
@ -208,7 +211,7 @@ object DependencyTreeSettings {
Def.task {
val graph = dependencyTreeModuleGraph0.value
val renderedTree = TreeView.createJson(graph)
val link = TreeView.createLink(renderedTree, target.value)
val link = TreeView.createLink(renderedTree, dependencyBrowseTreeTarget.value)
streams.value.log.info(s"HTML tree written to $link")
link
}
@ -246,7 +249,10 @@ object DependencyTreeSettings {
Def.task {
val uri = uriKey.value
streams.value.log.info(s"Opening ${uri} in browser...")
java.awt.Desktop.getDesktop.browse(uri)
val desktop = java.awt.Desktop.getDesktop
desktop.synchronized {
desktop.browse(uri)
}
uri
}

View File

@ -18,7 +18,7 @@ object TagsTest extends Properties("Tags") {
def tagMap: Gen[TagMap] = for (ts <- listOf(tagAndFrequency)) yield ts.toMap
def tagAndFrequency: Gen[(Tag, Int)] =
for (t <- tag; count <- Arbitrary.arbitrary[Int]) yield (t, count)
for (t <- tag; count <- Gen.choose(0, Int.MaxValue)) yield (t, count)
def tag: Gen[Tag] = for (s <- Gen.alphaStr if !s.isEmpty) yield Tag(s)
def size: Gen[Size] =
for (i <- Arbitrary.arbitrary[Int] if i != Int.MinValue) yield Size(math.abs(i))

View File

@ -22,4 +22,8 @@ object AggregationSpec extends verify.BasicTestSuite {
assert(timing(6003099).startsWith("elapsed time: 6003 s (01:40:03)"))
assert(timing(96003099).startsWith("elapsed time: 96003 s (26:40:03)"))
}
test("timing should not emit special space characters") {
assert(!timing(96003099).contains("\u202F"))
}
}

View File

@ -80,10 +80,10 @@ object Dependencies {
// and the JLine 2 fork version, which uses the same JAnsi
val jline =
"org.scala-sbt.jline" % "jline" % "2.14.7-sbt-9c3b6aca11c57e339441442bbf58e550cdfecb79"
val jline3Version = "3.27.0"
val jline3Version = "3.27.1"
val jline3Terminal = "org.jline" % "jline-terminal" % jline3Version
val jline3Jansi = "org.jline" % "jline-terminal-jansi" % jline3Version
val jline3JNA = "org.jline" % "jline-terminal-jna" % jline3Version
val jline3JNI = "org.jline" % "jline-terminal-jni" % jline3Version
val jline3Native = "org.jline" % "jline-native" % jline3Version
val jline3Reader = "org.jline" % "jline-reader" % jline3Version
val jline3Builtins = "org.jline" % "jline-builtins" % jline3Version
val scalatest = "org.scalatest" %% "scalatest" % "3.2.19"
@ -121,7 +121,7 @@ object Dependencies {
// lm-coursier dependencies
val dataclassScalafixVersion = "0.1.0"
val coursierVersion = "2.1.13"
val coursierVersion = "2.1.19"
val coursier = ("io.get-coursier" %% "coursier" % coursierVersion)
.cross(CrossVersion.for3Use2_13)

View File

@ -1 +1 @@
sbt.version=1.10.3
sbt.version=1.10.5

17
sbt
View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
set +e
declare builtin_sbt_version="1.10.3"
declare builtin_sbt_version="1.10.6"
declare -a residual_args
declare -a java_args
declare -a scalac_args
@ -24,7 +24,7 @@ declare build_props_sbt_version=
declare use_sbtn=
declare no_server=
declare sbtn_command="$SBTN_CMD"
declare sbtn_version="1.10.3"
declare sbtn_version="1.10.5"
### ------------------------------- ###
### Helper methods for BASH scripts ###
@ -183,7 +183,7 @@ acquire_sbtn () {
local archive_target=
local url=
local arch="x86_64"
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if [[ "$OSTYPE" == "linux"* ]]; then
arch=$(uname -m)
if [[ "$arch" == "aarch64" ]] || [[ "$arch" == "x86_64" ]]; then
archive_target="$p/sbtn-${arch}-pc-linux-${sbtn_v}.tar.gz"
@ -496,7 +496,7 @@ run() {
}
# TODO - java check should be configurable...
checkJava "6"
checkJava "8"
# Java 9 support
copyRt
@ -752,7 +752,14 @@ isRunNativeClient() {
[[ "$sbtV" == "" ]] && sbtV="0.0.0"
sbtBinaryV_1=$(echo "$sbtV" | sed 's/^\([0-9]*\)\.\([0-9]*\).*$/\1/')
sbtBinaryV_2=$(echo "$sbtV" | sed 's/^\([0-9]*\)\.\([0-9]*\).*$/\2/')
if (( $sbtBinaryV_1 >= 2 )) || ( (( $sbtBinaryV_1 >= 1 )) && (( $sbtBinaryV_2 >= 4 )) ); then
# Default to true for sbt 2.x
if (( $sbtBinaryV_1 >= 2 )); then
if [[ "$use_sbtn" == "0" ]]; then
echo "false"
else
echo "true"
fi
elif ( (( $sbtBinaryV_1 >= 1 )) && (( $sbtBinaryV_2 >= 4 )) ); then
if [[ "$use_sbtn" == "1" ]]; then
echo "true"
else

View File

@ -1,4 +1,4 @@
> set scalaVersion := "2.13.12"
> check213
> set scalaVersion := "2.12.18"
> set scalaVersion := "2.12.20"
> check212

View File

@ -9,6 +9,18 @@ TaskKey[Unit]("check") := {
val report = updateFull.value
val graph = (Test / dependencyTree / asString).value
def sanitize(str: String): String = str.split('\n').drop(1).map(_.trim).mkString("\n")
/*
Started to return:
ch.qos.logback:logback-core:1.0.7
default:sbt_8ae1da13_2.12:0.1.0-SNAPSHOT [S]
+-ch.qos.logback:logback-classic:1.0.7
| +-org.slf4j:slf4j-api:1.6.6 (evicted by: 1.7.2)
|
+-org.slf4j:slf4j-api:1.7.2
*/
val expectedGraph =
"""default:default-e95e05_2.12:0.1-SNAPSHOT [S]
| +-ch.qos.logback:logback-classic:1.0.7

View File

@ -17,4 +17,4 @@ csrExtraCredentials += {
lmcoursier.credentials.FileCredentials(dest.toString)
}
libraryDependencies += "com.abc" % "test" % "0.1"
libraryDependencies += ("com.abc" % "test" % "0.1").intransitive()

View File

@ -2,4 +2,4 @@ scalaVersion := "2.12.8"
resolvers += "authenticated" at sys.env("TEST_REPOSITORY")
libraryDependencies += "com.abc" % "test" % "0.1"
libraryDependencies += ("com.abc" % "test" % "0.1").intransitive()

View File

@ -2,4 +2,4 @@ scalaVersion := "2.12.8"
resolvers += "authenticated" at sys.env("TEST_REPOSITORY")
libraryDependencies += "com.abc" % "test" % "0.1"
libraryDependencies += ("com.abc" % "test" % "0.1").intransitive()

View File

@ -9,4 +9,4 @@ credentials += Credentials(
sys.env("TEST_REPOSITORY_PASSWORD")
)
libraryDependencies += "com.abc" % "test" % "0.1"
libraryDependencies += ("com.abc" % "test" % "0.1").intransitive()

View File

@ -1,6 +1,6 @@
# This tests that this sbt scripted plugin can launch the previous one
> ^^1.10.3
> ^^1.10.5
$ copy-file changes/A.scala src/sbt-test/a/b/A.scala
> scripted

View File

@ -17,6 +17,6 @@ lazy val use = project
val x = (dep / Compile / compile).value
val picklePath = (Compile / internalDependencyPicklePath).value
assert(picklePath.size == 1 &&
picklePath.head.data.name == "dep_2.13-0.1.0-SNAPSHOT.jar", s"picklePath = ${picklePath}")
picklePath.head.data.name == "early.jar", s"picklePath = ${picklePath}")
},
)