cb372 / sbt-client

A thin client for sbt
92 stars 8 forks source link

Seems as though addCommandAlias confuses sbt-client #5

Open blast-hardcheese opened 5 years ago

blast-hardcheese commented 5 years ago

1) Set up environment:

dir=$(mktemp -d)

cd "$dir"
mkdir -p src/test/scala project

cat >project/build.properties<<!
sbt.version=1.2.8
!

cat >build.sbt <<!
addCommandAlias("foo", "test")
!

cat >src/test/scala/Test.scala <<!
bogus
!

2) Launch sbt

brick:tmp.7n30pDvX7u blast$ sbt
[info] Loading project definition from /private/var/folders/mm/g56v4k7n6dv5qfg0gf4hllx8kjwmvc/T/tmp.7n30pDvX7u/project
[info] Updating ProjectRef(uri("file:/private/var/folders/mm/g56v4k7n6dv5qfg0gf4hllx8kjwmvc/T/tmp.7n30pDvX7u/project/"), "tmp-7n30pdvx7u-build")...
[info] Done updating.
[info] Loading settings for project tmp-7n30pdvx7u from build.sbt ...
[info] Set current project to tmp-7n30pdvx7u (in build file:/private/var/folders/mm/g56v4k7n6dv5qfg0gf4hllx8kjwmvc/T/tmp.7n30pDvX7u/)
[info] sbt server started at local:///Users/blast/.sbt/1.0/server/6b0fd817c0a02f522edb/sock
sbt:tmp-7n30pdvx7u>

3) Confirm that test in the primary sbt shell results in an error:

sbt:tmp-7n30pdvx7u> test
[info] Updating ...
[info] Done updating.
[info] Compiling 1 Scala source to /private/var/folders/mm/g56v4k7n6dv5qfg0gf4hllx8kjwmvc/T/tmp.7n30pDvX7u/target/scala-2.12/test-classes ...
[error] /private/var/folders/mm/g56v4k7n6dv5qfg0gf4hllx8kjwmvc/T/tmp.7n30pDvX7u/src/test/scala/Test.scala:1:1: expected class or object definition
[error] bogus
[error] ^
[error] one error found
[error] (Test / compileIncremental) Compilation failed
[error] Total time: 1 s, completed Jan 7, 2019 12:42:11 AM
sbt:tmp-7n30pdvx7u>

4) sbt-client to run test, confirming the expected output:

brick:tmp.7n30pDvX7u blast$ sbt-client test
[info] Processing
[info] Compiling 1 Scala source to /private/var/folders/mm/g56v4k7n6dv5qfg0gf4hllx8kjwmvc/T/tmp.7n30pDvX7u/target/scala-2.12/test-classes ...
[error] /private/var/folders/mm/g56v4k7n6dv5qfg0gf4hllx8kjwmvc/T/tmp.7n30pDvX7u/src/test/scala/Test.scala:1:1: expected class or object definition
[error] bogus
[error] ^
[error] one error found
[error] (Test / compileIncremental) Compilation failed
[error] Error from sbt

5) Now, use the same sbt client to run the foo alias, notice that the output is lost to the aether:

brick:tmp.7n30pDvX7u blast$ sbt-client foo
[info] Processing
[success] Done
brick:tmp.7n30pDvX7u blast$

6) To confirm this isn't a bug in sbt, use socat as a raw jsonrpc client:

brick:tmp.7n30pDvX7u blast$ socat - UNIX-CLIENT:/Users/blast/.sbt/1.0/server/6b0fd817c0a02f522edb/sock
{"jsonrpc": "2.0", "id": 1, "method": "sbt/exec", "params": { "commandLine": "foo" } }
Content-Length: 89
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"Processing"}}Content-Length: 133
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"jsonrpc":"2.0","id":1,"result":{"status":"Done","channelName":"network-4","execId":1,"commandQueue":["test","shell"],"exitCode":0}}Content-Length: 89
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"Processing"}}Content-Length: 213
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"jsonrpc":"2.0","method":"window/logMessage","params":{"type":3,"message":"Compiling 1 Scala source to /private/var/folders/mm/g56v4k7n6dv5qfg0gf4hllx8kjwmvc/T/tmp.7n30pDvX7u/target/scala-2.12/test-classes ..."}}Content-Length: 352
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///private/var/folders/mm/g56v4k7n6dv5qfg0gf4hllx8kjwmvc/T/tmp.7n30pDvX7u/src/test/scala/Test.scala","diagnostics":[{"range":{"start":{"line":0,"character":0},"end":{"line":0,"character":1}},"severity":1,"source":"sbt","message":"expected class or object definition"}]}}Content-Length: 94
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"jsonrpc":"2.0","method":"window/logMessage","params":{"type":1,"message":"one error found"}}Content-Length: 144
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"jsonrpc":"2.0","method":"window/logMessage","params":{"type":1,"message":"(Test / \u001b[31mcompileIncremental\u001b[0m) Compilation failed"}}Content-Length: 83
Content-Type: application/vscode-jsonrpc; charset=utf-8

{"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"Done"}}
blast-hardcheese commented 5 years ago

I wonder if this is actually an sbt issue, emitting

{"jsonrpc":"2.0","id":1,"result":{"status":"Done","channelName":"network-4","execId":1,"commandQueue":["test","shell"],"exitCode":0}}

too soon, as there's no followup Done after the commands are executed

cb372 commented 5 years ago

Yes, it looks like sbt is returning the responses in a strange order. It returns the "result" response before the log messages.

While that's totally fine in terms of LSP, sbt-client doesn't like it. sbt-client needs some way to decide that it's finished communicating with sbt and it's time to exit the process. It uses the "result" response for this, with the implicit assumption that this is the final message it will receive.

I'm not really sure what to do about this. sbt-client can't hang around forever on the off chance sbt might want to send it some more messages.

Might be worth opening an sbt issue? This behaviour does seem strange to me.