Trying to modify sbt output to run it in Intellij

159 views
Skip to first unread message

Ben Jackman

unread,
Feb 3, 2010, 1:27:37 AM2/3/10
to simple-build-tool
Hi!

I think I might have an easy solution for getting sbt to run in
Intellij in a pretty usable way. Though I need a little help. I am
stuck with two issues both relating to needing to reformat sbt's
output.

I found a plugin for intellij called BashSupport:
http://plugins.intellij.net/plugin/?id=4230
I have managed to relatively quickly add a script to my project folder
that just calls out to intellij.
I added a file called run-sbt.sh to my projects folder (not the sbt
project folder, the one above it!)

#!/bin/sh
sbt

The bash support allows for running scripts in intellij very easily, I
can just right click on run-sbt.sh and select run (the bash support
plugin adds this) The sbt console then pops up in the run menu, and
it's great.

As was mentioned before: http://youtrack.jetbrains.net/issue/SCL-1724
Intellij seems to filter that window looking for java exception stack
traces
the pattern it matches on is
"at some.package.AClass(Filename.scala:line#)"
if that pattern occurs in the output and the some.package.AClass is a
valid name of anything in the intellij's project dependencies it will
highlight the Filename:line# as a clickable link.

(try running sbt in intellij as described then going into the scala
console and saying error("foo") you will notice several clickable
links you should be able to copy paste that back through the
interpreter as a string and notice that it will still be a clickable
link)

What's really exciting is that in that run window there are two arrows
on the right side that allow for 'navigating up/down the stack trace'.
However they will just navigate across any link. What's even cooler,
these can be bound to keys, and cooler yet these keys will work even
while in the editor editing code, quickly allowing jumping between
errors! (i have them bound to alt+, / alt+.) (settings > keymap > main
menu > goto > previous occurrence / next occurrence)

Finally sbt / scala console history works inside of the run window
with alt+up / alt+down (i had to remove the keymap from alt+down to
get it now to show the window content menu ... settings > keymap >
Main Menu > Window > Show Content)

So here are the two problems I mentioned at the start:
#1 the ANSI escape codes used by sbt are not recognized by idea, so i
need a way to suppress them, because they look pretty dreadful in
there.
#2 I need a way to reformat the output of compiler error messages that
sbt produces, to rephrase them into looking to intellij like a stack
trace element, by how their string is formatted. basically I need to
show the errors in the format of:
".*at com.package.AClass(AClass.scala:12).*" rather than:
/some/path/to/erroneous/AClass.scala:21

btw I am using sbt 0.5.6 as I am still developing against the 2.7.7
scala branch and will not be updating anytime soon and I cannot figure
out how to get scala-test + sbt 0.6.x + scala 2.7.7 to play nicely
together. I have managed to get the 2.8 series working. so I am hoping
that somehow I can hook in an action that can somehow get the error
list from sbt and re-express it.

Any help would be greating appreciated.
Thanks
Ben

Ben Jackman

unread,
Feb 3, 2010, 3:52:56 AM2/3/10
to simple-build-tool
Ok well I got something working pretty well (provided you have your
scala sources under /src/main/scala or /src/test/scala)

Basically I take the path of the name of the path and strip off parts
of it replace slashes with dots and remove the trailing .scala and use
that as my best guess as the canonical name of class in the same file
having an error. This seems good enough for intellij, as it will then
happily browse to correct spot in the source. Since I changed the way
the error messages are displayed this might hurt people that depend on
it in it's current format. I don't use emacs so I am not sure, but i
think maybe the way the error messages are displayed is to make them
friendly to them.

I had to hack the sbt source, specifically at Compile.scala to change
the way that it display errors and it is not perfect.

Now if I could just find a way to turn off the ANSI escape codes...

Ben

patch (against google-code trunk) below:
diff --git a/src/main/scala/sbt/Compile.scala b/src/main/scala/sbt/
Compile.scala
index aaaab2d..21f5ef6 100644
--- a/src/main/scala/sbt/Compile.scala
+++ b/src/main/scala/sbt/Compile.scala
@@ -261,9 +261,28 @@ final class LoggerReporter(maximumErrors: Int,
log: Logger) extends scala.tools.
case NoPosition => log.log(level, msg)
case FakePos(fmsg) => log.log(level, fmsg+"
"+msg)
case _ =>
- val sourcePrefix = pos.source.map
(_.file.path).getOrElse("")
- val lineNumberString = pos.line.map
(line => ":" + line + ":").getOrElse(":") + " "
- log.log(level, sourcePrefix +
lineNumberString + msg)
+ //Attempts to turn a path into a guesstimated canonical class
name
+ def canonicalClassName(path: String): String =
+ path.replaceAll("""/""", ".").replaceAll("""\\""", ".").
+ replaceAll(""".*src\.(main|test)\.scala\.*""",
"").replaceAll("""\.scala""", "")
+
+ val fullPath = pos.source.map(_.file.path).getOrElse("")
+ val fileName = pos.source.map(_.file.name).getOrElse("")
+ val lineNumStr = pos.line.map(_.toString).getOrElse("0")
+ val fileLineStr = "(" + fileName + ":" + lineNumStr + ")"
+ //Here we essentially fake a bad method name for the time
+ //being this will allow programs that highlight on stacktrace
+ //elements to hopefully highlight on this entry...
+ val badMethod = canonicalClassName(fullPath) match {
+ case "" => ""
+ case canClass => {
+ //start with newline to preserve horizontal space
+ "\n" + " at " + canClass + ".unknown"
+ }
+ }
+
+ //probably should make the format of this output fully
customizable
+ log.log(level, "[" + fullPath + "]" + badMethod + fileLineStr
+ "\n" + msg)
if (!pos.line.isEmpty)
{
val lineContent =
pos.lineContent.stripLineEnd

Ben Jackman

unread,
Feb 3, 2010, 4:19:19 AM2/3/10
to simple-build-tool
Ok figured out how to turn off the ansi escapes, i made a script very
similar to the sbt one called sbt-intj and added this property
-Dsbt.log.noformat=true

Ben

Ben Jackman

unread,
Feb 3, 2010, 4:30:20 AM2/3/10
to simple-build-tool
btw here is a link to my blog which has better link to the patch via
gist
http://scalide.blogspot.com/2010/02/pot-of-coffee-gone-intellij-scala-sbt.html
sooo tired

Mark Harrah

unread,
Feb 3, 2010, 8:00:36 AM2/3/10
to simple-b...@googlegroups.com
Hi Ben,

The current format is the same as scalac's, just sent to a logger instead of
directly to the screen. Note that scalac's format is the same as javac's. I
think the right solution is for IntelliJ to detect <path>:<line> instead of
trying to make it look like a stack trace.

What I would consider for sbt is making the warnings/errors available to a
project definition in some data structure. You could process this to spit out
a list of quasi-stack traces to satisfy Intellij.

-Mark

Mark Harrah

unread,
Feb 3, 2010, 8:00:41 AM2/3/10
to simple-b...@googlegroups.com
Hi Ben,

On Wednesday 03 February 2010, Ben Jackman wrote:

...


> btw I am using sbt 0.5.6 as I am still developing against the 2.7.7
> scala branch and will not be updating anytime soon and I cannot figure
> out how to get scala-test + sbt 0.6.x + scala 2.7.7 to play nicely
> together. I have managed to get the 2.8 series working. so I am hoping
> that somehow I can hook in an action that can somehow get the error
> list from sbt and re-express it.

Whenever I finish updating the documentation, 0.7 should be out as a stable
release. It will still support back to Scala 2.7.2. You should be able to
drop in ScalaTest 1.0 with Scala 2.7.7 and have it work as before.

-Mark

James Strachan

unread,
Feb 3, 2010, 8:20:21 AM2/3/10
to simple-build-tool
Interesting stuff Ben! :). I saw somewhere there was a system property
you could set to disable the colour of sbt though cant seem to find it
right now...

I experimented the other day with a different approach; I really like
the command line console with tab completion and colour, so wondered
about generating a HTML document whenever tests run which can then
show the results nicely - which then you can click on the stack trace
to open them in your IDE. Ideally we could then plug this renderer
into SBT itself.

I made some progress - I chucked the code up here...

http://github.com/jstrachan/webbytest

there's a little bit of docs on that page together with steps to use
sbt to generate the HTML report with clickable stack traces.

It'd be awesome to reuse this Renderer as an option in sbt by default;
so whenever it runs tests, it regenerates the HTML report which then
has a nice summary of failed tests and clickable links to stack traces

Randall R Schulz

unread,
Feb 3, 2010, 9:45:16 AM2/3/10
to simple-b...@googlegroups.com
On Tuesday February 2 2010, Ben Jackman wrote:
> Hi!
>
> I think I might have an easy solution for getting sbt to run in
> Intellij in a pretty usable way. ...

>
> I found a plugin for intellij called BashSupport:
> http://plugins.intellij.net/plugin/?id=4230

I should point out that BashSupport has a problem in certain
circumstances:

1) Its "Accept files without extension" mode / option is enabled.
2) There are files within the project scope with no extension that are
_not_ BASH scripts

What can happen in this case is that Global Find Usages can (but does
not always) lead to an exception thrown by BashSupport. After this
happens, the Find in Path, Replace and non-in-place rename refactorings
stop working until IDEA is restarted.

I've reported this to the BashSupport author who is investigating ways
to be more discerning about which suffix-free files are deemed BASH
scripts.


> ...
> Thanks
> Ben


Randall Schulz

Mark Harrah

unread,
Feb 3, 2010, 12:18:20 PM2/3/10
to simple-b...@googlegroups.com
James,

On 2/3/10, James Strachan <james.s...@gmail.com> wrote:
> Interesting stuff Ben! :). I saw somewhere there was a system property
> you could set to disable the colour of sbt though cant seem to find it
> right now...
>
> I experimented the other day with a different approach; I really like
> the command line console with tab completion and colour, so wondered
> about generating a HTML document whenever tests run which can then
> show the results nicely - which then you can click on the stack trace
> to open them in your IDE. Ideally we could then plug this renderer
> into SBT itself.
>
> I made some progress - I chucked the code up here...
>
> http://github.com/jstrachan/webbytest
>
> there's a little bit of docs on that page together with steps to use
> sbt to generate the HTML report with clickable stack traces.
>
> It'd be awesome to reuse this Renderer as an option in sbt by default;
> so whenever it runs tests, it regenerates the HTML report which then
> has a nice summary of failed tests and clickable links to stack traces

You can skip parsing the output and get the results, exceptions, and
logged output per test directly by implementing a TestsListener. You
can see the sources below for details for now. If you are interested,
I'll be sure to document it for 0.7. Reports of various kinds have
been requested before and it would be great to see them as options in
sbt.

-Mark

http://github.com/harrah/sbt/blob/using-xsbt/src/main/scala/sbt/TestReportListener.scala

http://github.com/harrah/sbt/blob/using-xsbt/src/main/scala/sbt/impl/TestStatusReporter.scala

http://github.com/harrah/test-interface/tree/master/src/org/scalatools/testing/

> --
> You received this message because you are subscribed to the Google Groups
> "simple-build-tool" group.
> To post to this group, send email to simple-b...@googlegroups.com.
> To unsubscribe from this group, send email to
> simple-build-t...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/simple-build-tool?hl=en.
>
>

James Strachan

unread,
Feb 3, 2010, 12:29:20 PM2/3/10
to simple-build-tool
On Feb 3, 5:18 pm, Mark Harrah <dmhar...@gmail.com> wrote:
> James,
>
> On 2/3/10, James Strachan <james.strac...@gmail.com> wrote:
>
> > Interesting stuff Ben! :). I saw somewhere there was a system property
> > you could set to disable the colour of sbt though cant seem to find it
> > right now...
>
> > I experimented the other day with a different approach; I really like
> > the command line console with tab completion and colour, so wondered
> > about generating a HTML document whenever tests run which can then
> > show the results nicely - which then you can click on the stack trace
> > to open them in your IDE. Ideally we could then plug this renderer
> > into SBT itself.
>
> > I made some progress - I chucked the code up here...
>
> >http://github.com/jstrachan/webbytest
>
> > there's a little bit of docs on that page together with steps to use
> > sbt to generate the HTML report with clickable stack traces.
>
> > It'd be awesome to reuse this Renderer as an option in sbt by default;
> > so whenever it runs tests, it regenerates the HTML report which then
> > has a nice summary of failed tests and clickable links to stack traces
>
> You can skip parsing the output and get the results, exceptions, and
> logged output per test directly by implementing a TestsListener.  You
> can see the sources below for details for now.  If you are interested,
> I'll be sure to document it for 0.7.  Reports of various kinds have
> been requested before and it would be great to see them as options in
> sbt.
>
> -Mark
>
> http://github.com/harrah/sbt/blob/using-xsbt/src/main/scala/sbt/TestR...
>
> http://github.com/harrah/sbt/blob/using-xsbt/src/main/scala/sbt/impl/...
>
> http://github.com/harrah/test-interface/tree/master/src/org/scalatool...

I did try hacking an SBT build to add a custom test listener but
struggled to get anything working; I couldn't seem to be able to
import anything properly into the SBT project class. Is there some
magic thats required? Or is there an example SBT build which
customises test reporting? How does the SBT project reuse new
dependencies for the build itself other than sbt? (i.e. to compile the
project class rather than build the project)?

Maybe its easier if I fork sbt and add reporting into the core of sbt
(then once thats working submit it as a patch)? (We're talking a
couple of fairly trivial classes to render nicely in HTML). BTW when I
last looked at the test events, there was no output available - so its
hard to spot stack traces to transform them.

Mark Harrah

unread,
Feb 3, 2010, 12:49:07 PM2/3/10
to simple-b...@googlegroups.com
On 2/3/10, James Strachan <james.s...@gmail.com> wrote:
> On Feb 3, 5:18 pm, Mark Harrah <dmhar...@gmail.com> wrote:
>> On 2/3/10, James Strachan <james.strac...@gmail.com> wrote:
>>
>> > I experimented the other day with a different approach; I really like
>> > the command line console with tab completion and colour, so wondered
>> > about generating a HTML document whenever tests run which can then
>> > show the results nicely - which then you can click on the stack trace
>> > to open them in your IDE. Ideally we could then plug this renderer
>> > into SBT itself.
>>
>> > I made some progress - I chucked the code up here...
>>
>> >http://github.com/jstrachan/webbytest
>>
>> > there's a little bit of docs on that page together with steps to use
>> > sbt to generate the HTML report with clickable stack traces.
>>
>> > It'd be awesome to reuse this Renderer as an option in sbt by default;
>> > so whenever it runs tests, it regenerates the HTML report which then
>> > has a nice summary of failed tests and clickable links to stack traces
>>
>> You can skip parsing the output and get the results, exceptions, and
>> logged output per test directly by implementing a TestsListener. You
>> can see the sources below for details for now. If you are interested,
>> I'll be sure to document it for 0.7. Reports of various kinds have
>> been requested before and it would be great to see them as options in
>> sbt.
>>
>> -Mark
>
> I did try hacking an SBT build to add a custom test listener but
> struggled to get anything working; I couldn't seem to be able to
> import anything properly into the SBT project class. Is there some
> magic thats required? Or is there an example SBT build which
> customises test reporting? How does the SBT project reuse new
> dependencies for the build itself other than sbt? (i.e. to compile the
> project class rather than build the project)?

You can add jars to be used by your project definition in
project/build/lib or by declaring them as a plugin [1]. Is this what
you are asking?

> Maybe its easier if I fork sbt and add reporting into the core of sbt
> (then once thats working submit it as a patch)? (We're talking a
> couple of fairly trivial classes to render nicely in HTML). BTW when I
> last looked at the test events, there was no output available - so its
> hard to spot stack traces to transform them.

In cases like this where you can implement the functionality in a
project definition, the turnaround is faster to do it that way- just
'reload'.

TestEvent contains the name of the test, a description, and the result
of the test- success, failure, error and any associated exception. If
you want logged output, you specify a logger instance. I'll try to
get an example in the documentation for 0.7.

-Mark

[1] http://code.google.com/p/simple-build-tool/wiki/SbtPlugins

Reply all
Reply to author
Forward
0 new messages