diff --git a/build.sbt b/build.sbt index b6ed67172..c9fa87378 100644 --- a/build.sbt +++ b/build.sbt @@ -9,7 +9,7 @@ def buildLevelSettings: Seq[Setting[_]] = inThisBuild( Seq( organization := "org.scala-sbt", - version := "1.1.0-SNAPSHOT", + version := "1.1.2-SNAPSHOT", description := "sbt is an interactive build tool", bintrayOrganization := Some("sbt"), bintrayRepository := { diff --git a/launch/src/main/input_resources/sbt/sbt.boot.properties b/launch/src/main/input_resources/sbt/sbt.boot.properties index cd46ae8af..f13961dcf 100644 --- a/launch/src/main/input_resources/sbt/sbt.boot.properties +++ b/launch/src/main/input_resources/sbt/sbt.boot.properties @@ -22,6 +22,7 @@ [boot] directory: ${sbt.boot.directory-${sbt.global.base-${user.home}/.sbt}/boot/} + lock: ${sbt.boot.lock-true} [ivy] ivy-home: ${sbt.ivy.home-${user.home}/.ivy2/} diff --git a/main-command/src/main/scala/sbt/BasicKeys.scala b/main-command/src/main/scala/sbt/BasicKeys.scala index 86dd9343f..1570d392b 100644 --- a/main-command/src/main/scala/sbt/BasicKeys.scala +++ b/main-command/src/main/scala/sbt/BasicKeys.scala @@ -39,6 +39,12 @@ object BasicKeys { "The wire protocol for the server command.", 10000) + val autoStartServer = + AttributeKey[Boolean]( + "autoStartServer", + "If true, the sbt server will startup automatically during interactive sessions.", + 10000) + // Unlike other BasicKeys, this is not used directly as a setting key, // and severLog / logLevel is used instead. private[sbt] val serverLogLevel = diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 5c030829f..aba681b1a 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -268,6 +268,7 @@ object Defaults extends BuildCommon { .getOrElse(GCUtil.defaultForceGarbageCollection), minForcegcInterval :== GCUtil.defaultMinForcegcInterval, interactionService :== CommandLineUIService, + autoStartServer := true, serverHost := "127.0.0.1", serverPort := 5000 + (Hash .toHex(Hash(appConfiguration.value.baseDirectory.toString)) @@ -1362,12 +1363,13 @@ object Defaults extends BuildCommon { (compilers in task).value.scalac match { case ac: AnalyzingCompiler => ac.onArgs(exported(s, "scala")) } - (new Console(compiler))(cpFiles, - (scalacOptions in task).value, - loader, - (initialCommands in task).value, - (cleanupCommands in task).value)()(s.log).get - println() + val sc = (scalacOptions in task).value + val ic = (initialCommands in task).value + val cc = (cleanupCommands in task).value + JLine.usingTerminal { _ => + (new Console(compiler))(cpFiles, sc, loader, ic, cc)()(s.log).get + println() + } } private[this] def exported(w: PrintWriter, command: String): Seq[String] => Unit = diff --git a/main/src/main/scala/sbt/Extracted.scala b/main/src/main/scala/sbt/Extracted.scala index 01139d0dd..1cf02b8b7 100644 --- a/main/src/main/scala/sbt/Extracted.scala +++ b/main/src/main/scala/sbt/Extracted.scala @@ -122,10 +122,31 @@ final case class Extracted(structure: BuildStructure, ): T = getOrError(scope, key, structure.data.get(scope, key))(display) - def append(settings: Seq[Setting[_]], state: State): State = { + @deprecated( + "This discards session settings. Migrate to appendWithSession or appendWithoutSession.", + "1.2.0") + def append(settings: Seq[Setting[_]], state: State): State = + appendWithoutSession(settings, state) + + /** Appends the given settings to all the build state settings, including session settings. */ + def appendWithSession(settings: Seq[Setting[_]], state: State): State = + appendImpl(settings, state, session.mergeSettings) + + /** + * Appends the given settings to the original build state settings, discarding any settings + * appended to the session in the process. + */ + def appendWithoutSession(settings: Seq[Setting[_]], state: State): State = + appendImpl(settings, state, session.original) + + private[this] def appendImpl( + settings: Seq[Setting[_]], + state: State, + sessionSettings: Seq[Setting[_]], + ): State = { val appendSettings = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, settings) - val newStructure = Load.reapply(session.original ++ appendSettings, structure) + val newStructure = Load.reapply(sessionSettings ++ appendSettings, structure) Project.setProject(session, newStructure, state) } } diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 78cc96dfd..d90311607 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -131,6 +131,7 @@ object Keys { // Command keys val historyPath = SettingKey(BasicKeys.historyPath) val shellPrompt = SettingKey(BasicKeys.shellPrompt) + val autoStartServer = SettingKey(BasicKeys.autoStartServer) val serverPort = SettingKey(BasicKeys.serverPort) val serverHost = SettingKey(BasicKeys.serverHost) val serverAuthentication = SettingKey(BasicKeys.serverAuthentication) diff --git a/main/src/main/scala/sbt/PluginCross.scala b/main/src/main/scala/sbt/PluginCross.scala index bf6039c74..799c854f6 100644 --- a/main/src/main/scala/sbt/PluginCross.scala +++ b/main/src/main/scala/sbt/PluginCross.scala @@ -91,8 +91,8 @@ private[sbt] object PluginCross { def scalaVersionFromSbtBinaryVersion(sv: String): String = VersionNumber(sv) match { case VersionNumber(Seq(0, 12, _*), _, _) => "2.9.2" - case VersionNumber(Seq(0, 13, _*), _, _) => "2.10.6" - case VersionNumber(Seq(1, 0, _*), _, _) => "2.12.3" + case VersionNumber(Seq(0, 13, _*), _, _) => "2.10.7" + case VersionNumber(Seq(1, 0, _*), _, _) => "2.12.4" case _ => sys.error(s"Unsupported sbt binary version: $sv") } } diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index e2d99dac7..b3da0452a 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -21,6 +21,7 @@ import Keys.{ sessionSettings, shellPrompt, templateResolverInfos, + autoStartServer, serverHost, serverLog, serverPort, @@ -468,6 +469,7 @@ object Project extends ProjectExtra { val prompt = get(shellPrompt) val trs = (templateResolverInfos in Global get structure.data).toList.flatten val watched = get(watch) + val startSvr: Option[Boolean] = get(autoStartServer) val host: Option[String] = get(serverHost) val port: Option[Int] = get(serverPort) val authentication: Option[Set[ServerAuthentication]] = get(serverAuthentication) @@ -480,6 +482,7 @@ object Project extends ProjectExtra { s.attributes .setCond(Watched.Configuration, watched) .put(historyPath.key, history) + .setCond(autoStartServer.key, startSvr) .setCond(serverPort.key, port) .setCond(serverHost.key, host) .setCond(serverAuthentication.key, authentication) diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index 094491945..b09b488d0 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -14,6 +14,7 @@ import java.util.concurrent.atomic._ import scala.collection.mutable.ListBuffer import scala.annotation.tailrec import BasicKeys.{ + autoStartServer, serverHost, serverPort, serverAuthentication, @@ -43,9 +44,8 @@ import sbt.util.{ Level, Logger, LogExchange } * this exchange, which could serve command request from either of the channel. */ private[sbt] final class CommandExchange { - private val autoStartServer = + private val autoStartServerSysProp = sys.props get "sbt.server.autostart" forall (_.toLowerCase == "true") - private var server: Option[ServerInstance] = None private val firstInstance: AtomicBoolean = new AtomicBoolean(true) private var consoleChannel: Option[ConsoleChannel] = None @@ -82,7 +82,11 @@ private[sbt] final class CommandExchange { consoleChannel = Some(console0) subscribe(console0) } - if (autoStartServer) runServer(s) + val autoStartServerAttr = (s get autoStartServer) match { + case Some(bool) => bool + case None => true + } + if (autoStartServerSysProp && autoStartServerAttr) runServer(s) else s } diff --git a/main/src/main/scala/sbt/internal/ConsoleProject.scala b/main/src/main/scala/sbt/internal/ConsoleProject.scala index 866d4bd5e..f4b554c51 100644 --- a/main/src/main/scala/sbt/internal/ConsoleProject.scala +++ b/main/src/main/scala/sbt/internal/ConsoleProject.scala @@ -9,6 +9,7 @@ package sbt package internal import sbt.util.Logger +import sbt.internal.util.JLine import sbt.internal.inc.{ ScalaInstance, ZincUtil } import xsbti.compile.ClasspathOptionsUtil @@ -42,13 +43,17 @@ object ConsoleProject { val imports = BuildUtil.getImports(unit.unit) ++ BuildUtil.importAll(bindings.map(_._1)) val importString = imports.mkString("", ";\n", ";\n\n") val initCommands = importString + extra - // TODO - Hook up dsl classpath correctly... - (new Console(compiler))( - unit.classpath, - options, - initCommands, - cleanupCommands - )(Some(unit.loader), bindings).get + + JLine.usingTerminal { _ => + // TODO - Hook up dsl classpath correctly... + (new Console(compiler))( + unit.classpath, + options, + initCommands, + cleanupCommands + )(Some(unit.loader), bindings).get + } + () } /** Conveniences for consoleProject that shouldn't normally be used for builds. */ diff --git a/notes/1.1.1.markdown b/notes/1.1.1.markdown new file mode 100644 index 000000000..58cba0a73 --- /dev/null +++ b/notes/1.1.1.markdown @@ -0,0 +1,45 @@ +### Fixes + +- Fixes "Modified names for (class) is empty" error. [zinc#292][zinc292] / [zinc#484][zinc484] by [@jvican][@jvican] +- Fixes tab completion in `console` while running in batch mode as `sbt console`. [#3841][3841]/[#3876][3876] by [@eed3si9n][@eed3si9n] +- Fixes file timestamp retrieval of missing files on Windows. [#3871][3871] / [io#120][io120] by [@cunei][@cunei] +- Aligns the errors thrown by file timestamp implementations. Fixes [#3894][3894] / [io#121][io121] by [@j-keck][@j-keck] +- Adds file timestamps native support for FreeBSD. [#3894][3894] / [io#124][io124] by [@cunei][@cunei] +- Fixes JDK 10 version string parsing. [launcher#209][launcher209] by [@2m][@2m] + +### Improvements + +- Deprecates `Extracted#append` in favour of `appendWithSession` or `appendWithoutSession`. [#3865][3865] by [@dwijnand][@dwijnand] +- Adds a new global `Boolean` setting called `autoStartServer`. See below. +- Upgrades Scala versions used for sbt cross building `^^`. [#3923][3923] by [@dwijnand][@dwijnand] +- Many documentation maintenance changes by [@xuwei-k][@xuwei-k] + +### autoStartServer setting + +sbt 1.1.1 adds a new global `Boolean` setting called `autoStartServer`, which is set to `true` by default. +When set to `true`, sbt shell will automatically start sbt server. Otherwise, it will not start the server until `startSever` command is issued. This could be used to opt out of server for security reasons. + +[#3922][3922] by [@swaldman][@swaldman] + + [@eed3si9n]: https://github.com/eed3si9n + [@dwijnand]: http://github.com/dwijnand + [@cunei]: https://github.com/cunei + [@jvican]: https://github.com/jvican + [@Duhemm]: https://github.com/Duhemm + [@j-keck]: https://github.com/j-keck + [@swaldman]: https://github.com/swaldman + [@xuwei-k]: https://github.com/xuwei-k + [@2m]: https://github.com/2m + [3871]: https://github.com/sbt/sbt/issues/3871 + [io120]: https://github.com/sbt/io/pull/120 + [3894]: https://github.com/sbt/sbt/issues/3894 + [io121]: https://github.com/sbt/io/pull/121 + [io124]: https://github.com/sbt/io/pull/124 + [zinc292]: https://github.com/sbt/zinc/issues/292 + [zinc484]: https://github.com/sbt/zinc/pull/484 + [3865]: https://github.com/sbt/sbt/pull/3865 + [3841]: https://github.com/sbt/sbt/issues/3841 + [3876]: https://github.com/sbt/sbt/pull/3876 + [3923]: https://github.com/sbt/sbt/pull/3923 + [3922]: https://github.com/sbt/sbt/pull/3922 + [launcher209]: https://github.com/sbt/sbt-launcher-package/pull/209 diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 5ad8a4393..a8bb47140 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,19 +3,15 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala282 = "2.8.2" - val scala292 = "2.9.2" - val scala293 = "2.9.3" - val scala210 = "2.10.7" - val scala211 = "2.11.12" + // WARNING: Please Scala update versions in PluginCross.scala too val scala212 = "2.12.4" val baseScalaVersion = scala212 // sbt modules - private val ioVersion = "1.1.3" + private val ioVersion = "1.1.4" private val utilVersion = "1.1.2" - private val lmVersion = "1.1.2" - private val zincVersion = "1.1.0" + private val lmVersion = "1.1.3" + private val zincVersion = "1.1.1" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/sbt/src/sbt-test/tests/fork-parallel/build.sbt b/sbt/src/sbt-test/tests/fork-parallel/build.sbt index e28535d49..0647f55e9 100644 --- a/sbt/src/sbt-test/tests/fork-parallel/build.sbt +++ b/sbt/src/sbt-test/tests/fork-parallel/build.sbt @@ -13,6 +13,8 @@ lazy val root = (project in file(".")). val log = streams.value.log if( nbProc < 4 ) { log.warn("With fewer than 4 processors this test is meaningless") + // mimic behavior expected by scripted + if (!testForkedParallel.value) sys.error("Exiting with error (note: test not performed)") } else { // we've got at least 4 processors, we'll check the upper end but also 3 and 4 as the upper might not // be reached if the system is under heavy load. diff --git a/sbt/src/sbt-test/tests/fork-parallel/test b/sbt/src/sbt-test/tests/fork-parallel/test index 662328f42..70e542b98 100644 --- a/sbt/src/sbt-test/tests/fork-parallel/test +++ b/sbt/src/sbt-test/tests/fork-parallel/test @@ -1,18 +1,7 @@ -# The tests/fork-parallel test will currently always -# report success when run on less than four cores, -# rather than failing in one of the two cases as expected. -# TODO: Adjust this scripted test so that it works as -# intended on less than four cores as well. - -# To debug, it is possible to limit the number of cores -# reported to sbt, and run the test, by using: -# taskset 0x00000003 sbt 'scripted tests/fork-parallel' -# See: https://github.com/sbt/sbt/issues/3545 - -# This bit won't currently work when using less than four cores. -# > test -# -> check +# Note: this test is meaningless on less than four cores +> test +-> check > clean > set testForkedParallel := true > test diff --git a/sbt/src/test/scala/sbt/ServerSpec.scala b/sbt/src/test/scala/sbt/ServerSpec.scala index 9adeabcc8..7ad307fd8 100644 --- a/sbt/src/test/scala/sbt/ServerSpec.scala +++ b/sbt/src/test/scala/sbt/ServerSpec.scala @@ -108,7 +108,7 @@ object ServerSpec { val chunk0 = buffer.take(delimPos) buffer = buffer.drop(delimPos + 1) // remove \r at the end of line. - val chunk1 = if (chunk0.isEmpty || chunk0.last != RetByte) chunk0 else chunk0.dropRight(1) + val chunk1 = if (chunk0.lastOption contains RetByte) chunk0.dropRight(1) else chunk0 Some(new String(chunk1.toArray, "utf-8")) } else None // no EOL yet, so skip this turn. } diff --git a/src/main/conscript/scalas/launchconfig b/src/main/conscript/scalas/launchconfig index 98febc38c..61b9b5108 100644 --- a/src/main/conscript/scalas/launchconfig +++ b/src/main/conscript/scalas/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[1.1.0]} + version: ${sbt.version-read(sbt.version)[1.1.1]} class: sbt.ScriptMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false} diff --git a/src/main/conscript/screpl/launchconfig b/src/main/conscript/screpl/launchconfig index 17a32efb0..23a9a6a39 100644 --- a/src/main/conscript/screpl/launchconfig +++ b/src/main/conscript/screpl/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[1.1.0]} + version: ${sbt.version-read(sbt.version)[1.1.1]} class: sbt.ConsoleMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false} diff --git a/src/main/conscript/xsbt/launchconfig b/src/main/conscript/xsbt/launchconfig index 79ddd5ef7..ff2abceab 100644 --- a/src/main/conscript/xsbt/launchconfig +++ b/src/main/conscript/xsbt/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[1.1.0]} + version: ${sbt.version-read(sbt.version)[1.1.1]} class: sbt.xMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false}