sbt 1.1.0-RC1 with sbt server and slash syntax

By Eugene Yokota (@eed3si9n) November 30, 2017

Hi everyone. Lightbend Tooling team is happy to announce sbt 1.1.0-RC1. This is the first feature release of sbt 1, a binary compatible release focusing on new features. sbt 1 is released under Semantic Versioning, and the plugins are expected to work for sbt 1.x series. If no serious issues are found by Thursday, December 14th 2017, 1.1.0-RC1 will become 1.1.0 final.

The headline features of sbt 1.1 are unified slash syntax and sbt server. They are both features that I have been involved in for a while, but ultimately had to postpone for sbt 1.0. This makes it all the more exciting to see these finally come out.

Unified slash syntax of setting keys

As a user of sbt, I’ve long thought having different notations for setting/task keys, one for sbt shell and another for build.sbt made the tool harder to learn. After lots of discussions with the community, and a few prototypes, sbt 1.1.0-RC1 will support unified slash syntax (the sbt 0.13 notations will continue to work, so don’t worry).

Both in build.sbt and in sbt shell, the settings can be written like this, scope axis delimited by slashes:

ref / Config / intask / key

In the above, ref typically is subproject name or ThisBuild, and Config is the Scala identifier for configurations such as Compile and Test. Each axis might be omitted and can also be substituted with a special Zero value, so it’s actually:

((ref | "Zero") "/") ((Config | "Zero") "/") ((intask | "Zero") "/") key

For example, in sbt 0.13:

  • to compile just the Test configuration, in sbt 0.13 you’d write (compile in Test).value in build.sbt and test:compile in the sbt shell.
  • cancelable setting at the Global level is written as (cancelable in Global).value in build.sbt and */*:cancelable in the sbt shell.

In sbt 1.1.0-RC1:

  • compile task scoped to Test is written as (Test / compile).value in build.sbt, and Test / compile in the sbt shell.
  • cancelable setting scoped to Global is written as (Global / cancelable).value in build.sbt and Global / cancelable in the sbt shell.

Here is a demo:

slash

For more details, see Migrating to slash syntax and Scopes docs.

Note: One caveat to the plugin authors is that if you use the new syntax in your plugin it will push the minimum required sbt version to 1.1.0-RC for your users.

#1812/#3434/#3617/#3620 by @eed3si9n and @dwijnand

sbt server

When people hear the name “sbt server”, they might imagine it to be something that runs on remote servers, and does great things. But, sbt server is not that for now. Instead, sbt server just adds network access to the sbt shell. sbt 1.1 reworked this feature to use Language Server Protocol 3.0 (LSP) as the wire protocol, a protocol created by Microsoft for Visual Studio Code.

To discover a running server, sbt 1.1.0 creates a port file at ./project/target/active.json relative to a build:

{"uri":"local:///Users/foo/.sbt/1.0/server/0845deda85cb41abcdef/sock"}

local: indicates a UNIX domain socket. Here’s how we can say hello to the server using nc. (^M can be sent Ctrl-V then Return):

$ nc -U /Users/foo/.sbt/1.0/server/0845deda85cb41abcdef/sock
Content-Length: 99^M
^M
{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "initializationOptions": { } } }^M

Here’s how we can call compile:

Content-Length: 93^M
^M
{ "jsonrpc": "2.0", "id": 2, "method": "sbt/exec", "params": { "commandLine": "compile" } }^M

The running sbt session should now queue compile, and return back with compiler warnings and errors, if any:

Content-Length: 296
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:/Users/foo/work/hellotest/Hello.scala","diagnostics":[{"range":{"start":{"line":2,"character":26},"end":{"line":2,"character":27}},"severity":1,"source":"sbt","message":"object X is not a member of package foo"}]}}

This allows multiple clients to connect to a single session of sbt. The primary use case we have in mind for the client is tooling integration such as editors and IDEs. For more details, see sbt server docs.

#3524/#3556 by @eed3si9n

VS Code extension

As a proof of concept for editor integration, we created a Visual Studio Code extension called Scala (sbt). To try it out, install Visual Studio Code, search for “Scala (sbt)” in Extensions tab, run sbt 1.1.0-RC1 on some project, and open it using VS Code.

Currently this extension is able to:

  • Run compile at the root project when *.scala files are saved. #3524 by Eugene Yokota (@eed3si9n)
  • Display compiler errors.
  • Display log messages. #3740 by Alexey Alekhin (@laughedelic)
  • Jump to class definitions. #3660 by Wiesław Popielarski at VirtusLab (@wpopielarski)

Here is a demo:

vscode-scala-sbt

Other bug fixes and improvements

  • Changes version setting default to 0.1.0-SNAPSHOT for compatibility with Semantic Versioning. #3577 by @laughedelic
  • Fixes over-compilation bug with Java 9. zinc#450 by @retronym
  • Fixes handling of deeply nested Java classes. zinc#423 by @romanowski
  • Fixes JavaDoc not printing all errors. zinc#415 by @raboof
  • Preserves JAR order in ScalaInstance.otherJars. zinc#411 by @dwijnand
  • Fixes used name when it contains NL. zinc#449 by @jilen
  • Fixes handling of ThisProject. #3609 by @dwijnand
  • Escapes imports from sbt files, so if user creates a backquoted definition then task evalution will not fail. #3635 by @panaeon
  • Removes reference to version 0.14.0 from a warning message. #3693 by @saniyatech
  • Fixes screpl throwing “Not a valid key: console-quick”. #3762 by @xuwei-k
  • Filters scripted tests based on optional project/build.properties. #3564/#3566 by @jonas
  • Adds Project#withId to change a project’s id. #3601 by @dwijnand
  • Adds reboot dev command, which deletes the current artifact from the boot directory. This is useful when working with development versions of sbt. #3659 by @eed3si9n
  • Adds a check for a change in sbt version before reload. #1055/#3673 by @RomanIakovlev
  • Adds a new setting insideCI, which indicates that sbt is likely running in an Continuous Integration environment. #3672 by @RomanIakovlev
  • Adds nameOption to Command trait. #3671 by @miklos-martin
  • Adds POSIX persmission operations in IO, such as IO.chmod(..). io#76 by @eed3si9n
  • Treat sbt 1 modules using Semantic Versioning in the eviction warning. lm#188 by @eed3si9n
  • Uses kind-projector in the code. #3650 by @dwijnand
  • Make displayOnly etc methods strict in Completions. #3763 by @xuwei-k

Participation

Thanks again to everyone who’s helped improve sbt and Zinc 1 by using them, reporting bugs, improving our documentation, porting builds, porting plugins, and submitting and reviewing pull requests.

sbt 1.1.0-RC1 was brought to you by 32 contributors, according to git shortlog -sn --no-merges v1.0.4..v1.1.0-RC on sbt, zinc, librarymanagement, util, io, and website: Eugene Yokota, Dale Wijnand, Kenji Yoshida (xuwei-k), Alexey Alekhin, Simon Schäfer, Jorge Vicente Cantero (jvican), Miklos Martin, Jeffrey Olchovy, Jonas Fonseca, Andrey Artemov, Arnout Engelen, Dominik Winter, Krzysztof Romanowski, Roman Iakovlev, Wiesław Popielarski, Age Mooij, Allan Timothy Leong, Antonio Cunei, Jason Zaugg, Jilen Zhang, Long Jinwei, Martin Duhem, Michael Stringer, Michael Wizner, Nud Teeraworamongkol, OlegYch, PanAeon, Philippus Baalman, Pierre Dal-Pra, Saniya Tech, Tom Walford, and many others who contributed ideas. Thank you!

For anyone interested in helping sbt, there are many avenues you could help, depending on your interest.

  • Migrate library builds to sbt 1, or update plugins.
  • Report bugs when you see them.
  • Send in fixes to bugs.
  • Update documentation.

If you’re interested in other ideas, come talk to us on sbt-contrib.