/* sbt -- Simple Build Tool * Copyright 2010 Tony Sloane */ package sbt object StackTrace { def isSbtClass(name: String) = name.startsWith("sbt") || name.startsWith("xsbt") /** * Return a printable representation of the stack trace associated * with t. Information about t and its Throwable causes is included. * The number of lines to be included for each Throwable is configured * via d which should be greater than or equal to zero. If d is zero, * then all elements are included up to (but not including) the first * element that comes from sbt. If d is greater than zero, then up to * that many lines are included, where the line for the Throwable is * counted plus one line for each stack element. Less lines will be * included if there are not enough stack elements. */ def trimmed(t : Throwable, d : Int) : String = { require(d >= 0) val b = new StringBuilder () def appendStackTrace (t : Throwable, first : Boolean) { val include : StackTraceElement => Boolean = if (d == 0) element => !isSbtClass(element.getClassName) else { var count = d - 1 (_ => { count -= 1; count >= 0 }) } def appendElement (e : StackTraceElement) { b.append ("\tat ") b.append (e) b.append ('\n') } if (!first) b.append ("Caused by: ") b.append (t) b.append ('\n') val els = t.getStackTrace () var i = 0 while ((i < els.size) && include (els (i))) { appendElement (els (i)) i += 1 } } appendStackTrace (t, true) var c = t while (c.getCause () != null) { c = c.getCause () appendStackTrace (c, false) } b.toString () } }