summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/io/AbstractFile.scala54
-rw-r--r--src/compiler/scala/tools/nsc/io/Directory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/io/File.scala36
-rw-r--r--src/compiler/scala/tools/nsc/io/Path.scala19
-rw-r--r--src/compiler/scala/tools/nsc/io/PlainFile.scala30
-rw-r--r--src/compiler/scala/tools/nsc/io/Streamable.scala78
-rw-r--r--src/compiler/scala/tools/nsc/io/package.scala9
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala35
-rw-r--r--src/partest/scala/tools/partest/nest/FileManager.scala2
-rw-r--r--src/partest/scala/tools/partest/nest/Worker.scala4
10 files changed, 134 insertions, 135 deletions
diff --git a/src/compiler/scala/tools/nsc/io/AbstractFile.scala b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
index 4b196877a3..059ca9bd9e 100644
--- a/src/compiler/scala/tools/nsc/io/AbstractFile.scala
+++ b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
@@ -10,7 +10,7 @@ package io
import java.io.{ FileOutputStream, IOException, InputStream, OutputStream, BufferedOutputStream }
import java.net.URL
import PartialFunction._
-import java.io.File.{ separatorChar => separator }
+
import scala.collection.mutable.ArrayBuffer
/**
@@ -84,6 +84,7 @@ object AbstractFile {
* </p>
*/
abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
+
/** Returns the name of this abstract file. */
def name: String
@@ -136,8 +137,6 @@ abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
/** size of this file if it is a concrete file. */
def sizeOption: Option[Int] = None
- def toURL: URL = if (file == null) null else file.toURI.toURL
-
/** Returns contents of file (if applicable) in a Char array.
* warning: use <code>Global.getSourceFile()</code> to use the proper
* encoding when converting to the char array.
@@ -187,47 +186,43 @@ abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
* @return ...
*/
def lookupPath(path: String, directory: Boolean): AbstractFile = {
- lookupPathInternal(path, directory, false)
+ lookup((f, p, dir) => f.lookupName(p, dir), path, directory)
}
/** Return an abstract file that does not check that `path' denotes
* an existing file.
*/
def lookupPathUnchecked(path: String, directory: Boolean): AbstractFile = {
- lookupPathInternal(path, directory, true)
+ lookup((f, p, dir) => f.lookupNameUnchecked(p, dir), path, directory)
}
- private def lookupPathInternal(path0: String, directory: Boolean, unchecked: Boolean): AbstractFile = {
+ private def lookup(getFile: (AbstractFile, String, Boolean) => AbstractFile,
+ path0: String,
+ directory: Boolean): AbstractFile = {
+ val separator = JFile.separatorChar
// trim trailing '/'s
- val path = (
- if (path0.charAt(path0.length - 1) != separator) path0
- else path0.substring(0, path0.length - 1)
- )
- def loop(file: AbstractFile, start: Int): AbstractFile = {
+ val path: String = if (path0.last == separator) path0 dropRight 1 else path0
+ val length = path.length()
+ assert(length > 0 && !(path.last == separator), path)
+ var file = this
+ var start = 0
+ while (true) {
val index = path.indexOf(separator, start)
- if (index < 0) {
- if (unchecked) file.lookupNameUnchecked(path, directory)
- else file.lookupName(path, directory)
- }
- else {
- val name = path.substring(start, index)
- val next = (
- if (unchecked) file.lookupNameUnchecked(name, true)
- else file.lookupName(name, true)
- )
- if (next == null) null
- else loop(next, index + 1)
- }
+ assert(index < 0 || start < index)
+ val name = path.substring(start, if (index < 0) length else index)
+ file = getFile(file, name, if (index < 0) directory else true)
+ if ((file eq null) || index < 0) return file
+ start = index + 1
}
- loop(this, 0)
+ file
}
- private def fileOrSubdirectoryNamed(name: String, directory: Boolean): AbstractFile = {
- val lookup = lookupName(name, directory)
+ private def fileOrSubdirectoryNamed(name: String, isDir: Boolean): AbstractFile = {
+ val lookup = lookupName(name, isDir)
if (lookup != null) lookup
else {
val jfile = new JFile(file, name)
- if (directory) jfile.mkdirs() else jfile.createNewFile()
+ if (isDir) jfile.mkdirs() else jfile.createNewFile()
new PlainFile(jfile)
}
}
@@ -254,5 +249,6 @@ abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
protected def unsupported(msg: String): Nothing = throw new UnsupportedOperationException(msg)
/** Returns the path of this abstract file. */
- override def toString = path
+ override def toString() = path
+
}
diff --git a/src/compiler/scala/tools/nsc/io/Directory.scala b/src/compiler/scala/tools/nsc/io/Directory.scala
index 64b7711686..b4ceba682a 100644
--- a/src/compiler/scala/tools/nsc/io/Directory.scala
+++ b/src/compiler/scala/tools/nsc/io/Directory.scala
@@ -12,7 +12,7 @@ package io
object Directory {
import scala.util.Properties.{ tmpDir, userHome, userDir }
- private def normalizePath(s: String) = Some(Directory(s).toAbsolute)
+ private def normalizePath(s: String) = Some(apply(Path(s).normalize))
def Current: Option[Directory] = if (userDir == "") None else normalizePath(userDir)
def Home: Option[Directory] = if (userHome == "") None else normalizePath(userHome)
def TmpDir: Option[Directory] = if (tmpDir == "") None else normalizePath(tmpDir)
diff --git a/src/compiler/scala/tools/nsc/io/File.scala b/src/compiler/scala/tools/nsc/io/File.scala
index e5969f318e..b11151ab7e 100644
--- a/src/compiler/scala/tools/nsc/io/File.scala
+++ b/src/compiler/scala/tools/nsc/io/File.scala
@@ -17,14 +17,14 @@ import java.nio.channels.{ Channel, FileChannel }
import scala.io.Codec
object File {
- def pathSeparator = java.io.File.pathSeparator
- def separator = java.io.File.separator
+ def pathSeparator = JFile.pathSeparator
+ def separator = JFile.separator
def apply(path: Path)(implicit codec: Codec) = new File(path.jfile)(codec)
// Create a temporary file, which will be deleted upon jvm exit.
def makeTemp(prefix: String = Path.randomPrefix, suffix: String = null, dir: JFile = null) = {
- val jfile = java.io.File.createTempFile(prefix, suffix, dir)
+ val jfile = JFile.createTempFile(prefix, suffix, dir)
jfile.deleteOnExit()
apply(jfile)
}
@@ -43,20 +43,20 @@ object File {
// trigger java.lang.InternalErrors later when using it concurrently. We ignore all
// the exceptions so as not to cause spurious failures when no write access is available,
// e.g. google app engine.
- // try {
- // import Streamable.closing
- // val tmp = java.io.File.createTempFile("bug6503430", null, null)
- // try closing(new FileInputStream(tmp)) { in =>
- // val inc = in.getChannel()
- // closing(new FileOutputStream(tmp, true)) { out =>
- // out.getChannel().transferFrom(inc, 0, 0)
- // }
- // }
- // finally tmp.delete()
- // }
- // catch {
- // case _: IllegalArgumentException | _: IllegalStateException | _: IOException | _: SecurityException => ()
- // }
+ try {
+ import Streamable.closing
+ val tmp = JFile.createTempFile("bug6503430", null, null)
+ try closing(new FileInputStream(tmp)) { in =>
+ val inc = in.getChannel()
+ closing(new FileOutputStream(tmp, true)) { out =>
+ out.getChannel().transferFrom(inc, 0, 0)
+ }
+ }
+ finally tmp.delete()
+ }
+ catch {
+ case _: IllegalArgumentException | _: IllegalStateException | _: IOException | _: SecurityException => ()
+ }
}
import File._
import Path._
@@ -145,7 +145,7 @@ class File(jfile: JFile)(implicit constructorCodec: Codec) extends Path(jfile) w
val CHUNK = 1024 * 1024 * 16 // 16 MB
val dest = destPath.toFile
if (!isValid) fail("Source %s is not a valid file." format name)
- if (this isSame dest) fail("Source and destination are the same.")
+ if (this.normalize == dest.normalize) fail("Source and destination are the same.")
if (!dest.parent.exists) fail("Destination cannot be created.")
if (dest.exists && !dest.canWrite) fail("Destination exists but is not writable.")
if (dest.isDirectory) fail("Destination exists but is a directory.")
diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala
index f95790785c..86839437f4 100644
--- a/src/compiler/scala/tools/nsc/io/Path.scala
+++ b/src/compiler/scala/tools/nsc/io/Path.scala
@@ -11,7 +11,6 @@ import java.io.{
BufferedInputStream, BufferedOutputStream, RandomAccessFile }
import java.net.{ URI, URL }
import scala.util.Random.alphanumeric
-import java.io.File.{ separatorChar, separator => separatorStr }
/** An abstraction for filesystem paths. The differences between
* Path, File, and Directory are primarily to communicate intent.
@@ -66,9 +65,9 @@ object Path {
def onlyFiles(xs: Iterator[Path]): Iterator[File] = xs filter (_.isFile) map (_.toFile)
def onlyFiles(xs: List[Path]): List[File] = xs filter (_.isFile) map (_.toFile)
- def roots: List[Path] = java.io.File.listRoots().toList map Path.apply
+ def roots: List[Path] = JFile.listRoots().toList map Path.apply
- def apply(segments: Seq[String]): Path = apply(segments mkString separatorStr)
+ def apply(segments: Seq[String]): Path = apply(segments mkString JFile.separator)
def apply(path: String): Path = apply(new JFile(path))
def apply(jfile: JFile): Path =
if (jfile.isFile) new File(jfile)
@@ -85,6 +84,9 @@ import Path._
* semantics regarding how a Path might relate to the world.
*/
class Path private[io] (val jfile: JFile) {
+ val separator = JFile.separatorChar
+ val separatorStr = JFile.separator
+
// Validation: this verifies that the type of this object and the
// contents of the filesystem are in agreement. All objects are
// valid except File objects whose path points to a directory and
@@ -95,7 +97,6 @@ class Path private[io] (val jfile: JFile) {
def toFile: File = new File(jfile)
def toDirectory: Directory = new Directory(jfile)
def toAbsolute: Path = if (isAbsolute) this else Path(jfile.getAbsolutePath())
- def toCanonical: Path = Path(jfile.getCanonicalPath())
def toURI: URI = jfile.toURI()
def toURL: URL = toURI.toURL()
/** If this path is absolute, returns it: otherwise, returns an absolute
@@ -129,7 +130,7 @@ class Path private[io] (val jfile: JFile) {
// identity
def name: String = jfile.getName()
def path: String = jfile.getPath()
- def normalize: Path = toCanonical
+ def normalize: Path = Path(jfile.getCanonicalPath())
def isRootPath: Boolean = roots exists (_ isSame this)
def resolve(other: Path) = if (other.isAbsolute || isEmpty) other else /(other)
@@ -139,7 +140,7 @@ class Path private[io] (val jfile: JFile) {
def createRelativePath(baseSegs: List[String], otherSegs: List[String]) : String = {
(baseSegs, otherSegs) match {
case (b :: bs, o :: os) if b == o => createRelativePath(bs, os)
- case (bs, os) => ((".."+separatorChar)*bs.length)+os.mkString(separatorStr)
+ case (bs, os) => ((".."+separator)*bs.length)+os.mkString(separatorStr)
}
}
@@ -148,7 +149,7 @@ class Path private[io] (val jfile: JFile) {
// derived from identity
def root: Option[Path] = roots find (this startsWith _)
- def segments: List[String] = (path split separatorChar).toList filterNot (_.length == 0)
+ def segments: List[String] = (path split separator).toList filterNot (_.length == 0)
/**
* @return The path of the parent directory, or root if path is already root
*/
@@ -211,7 +212,7 @@ class Path private[io] (val jfile: JFile) {
def isHidden = jfile.isHidden()
def isSymlink = {
val x = parent / name
- x.toCanonical != x.toAbsolute
+ x.normalize != x.toAbsolute
}
def isEmpty = path.length == 0
@@ -223,7 +224,7 @@ class Path private[io] (val jfile: JFile) {
// Boolean path comparisons
def endsWith(other: Path) = segments endsWith other.segments
def startsWith(other: Path) = segments startsWith other.segments
- def isSame(other: Path) = toCanonical == other.toCanonical
+ def isSame(other: Path) = normalize == other.normalize
def isFresher(other: Path) = lastModified > other.lastModified
// creations
diff --git a/src/compiler/scala/tools/nsc/io/PlainFile.scala b/src/compiler/scala/tools/nsc/io/PlainFile.scala
index fb19ec120b..ce4bca490f 100644
--- a/src/compiler/scala/tools/nsc/io/PlainFile.scala
+++ b/src/compiler/scala/tools/nsc/io/PlainFile.scala
@@ -3,9 +3,13 @@
* @author Martin Odersky
*/
+
package scala.tools.nsc
package io
+import java.io.{ FileInputStream, FileOutputStream, IOException }
+import PartialFunction._
+
object PlainFile {
/**
* If the specified File exists, returns an abstract file backed
@@ -20,22 +24,28 @@ object PlainFile {
class PlainFile(val givenPath: Path) extends AbstractFile {
assert(path ne null)
- def name = givenPath.name
- def path = givenPath.path
- def file = givenPath.jfile
- def absolute = new PlainFile(givenPath.toAbsolute)
-
+ val file = givenPath.jfile
override def underlyingSource = Some(this)
+
+ private val fpath = try givenPath.normalize catch { case _: IOException => givenPath.toAbsolute }
+
+ /** Returns the name of this abstract file. */
+ def name = givenPath.name
+
+ /** Returns the path of this abstract file. */
+ def path = givenPath.path
+
+ /** The absolute file. */
+ def absolute = new PlainFile(givenPath.normalize)
+
override def container: AbstractFile = new PlainFile(givenPath.parent)
override def input = givenPath.toFile.inputStream()
override def output = givenPath.toFile.outputStream()
override def sizeOption = Some(givenPath.length.toInt)
- override def hashCode(): Int = path.hashCode
- override def equals(that: Any): Boolean = that match {
- case other: PlainFile => path == other.path
- case _ => false
- }
+ override def hashCode(): Int = fpath.hashCode
+ override def equals(that: Any): Boolean =
+ cond(that) { case other: PlainFile => fpath == other.fpath }
/** Is this abstract file a directory? */
def isDirectory: Boolean = givenPath.isDirectory
diff --git a/src/compiler/scala/tools/nsc/io/Streamable.scala b/src/compiler/scala/tools/nsc/io/Streamable.scala
index c0a56eeda6..03318674ee 100644
--- a/src/compiler/scala/tools/nsc/io/Streamable.scala
+++ b/src/compiler/scala/tools/nsc/io/Streamable.scala
@@ -20,60 +20,14 @@ import Path.fail
*/
object Streamable {
- /** For reading a stream of unknown length. Doesn't buffer the
- * input stream: call the two argument version.
- */
- def toByteArray(in: InputStream): Array[Byte] = {
- val bytes = new ArrayBuffer[Byte]()
- val buf = new Array[Byte](4096)
-
- def loop(): Array[Byte] = {
- val bytesRead = in.read(buf)
- if (bytesRead < 0) sys.error("read error")
- else if (bytesRead == 0) bytes.toArray
- else {
- bytes ++= buf.slice(0, bytesRead)
- loop()
- }
- }
- try loop()
- finally in.close()
- }
- /** This method aspires to be the fastest way to read
- * a stream of known length into memory.
- */
- def toByteArray(input: InputStream, len: Int): Array[Byte] = {
- val in = new BufferedInputStream(input)
- if (len < 0)
- return toByteArray(in)
-
- val arr = new Array[Byte](len)
- var offset = 0
-
- def loop() {
- if (offset < len) {
- val read = in.read(arr, offset, len - offset)
- if (read >= 0) {
- offset += read
- loop()
- }
- }
- }
- try loop()
- finally in.close()
-
- if (offset == arr.length) arr
- else sys.error("Could not read entire source (%d of %d bytes)".format(offset, len))
- }
-
/** Traits which can be viewed as a sequence of bytes. Source types
* which know their length should override def length: Long for more
* efficient method implementations.
*/
trait Bytes {
def inputStream(): InputStream
-
def length: Long = -1
+
def bufferedInput() = new BufferedInputStream(inputStream())
def bytes(): Iterator[Byte] = bytesAsInts() map (_.toByte)
def bytesAsInts(): Iterator[Int] = {
@@ -81,9 +35,33 @@ object Streamable {
Iterator continually in.read() takeWhile (_ != -1)
}
- def toByteArray() = {
- require(length <= Int.MaxValue, length + " larger than Int.MaxValue")
- Streamable.toByteArray(inputStream(), length.toInt)
+ /** This method aspires to be the fastest way to read
+ * a stream of known length into memory.
+ */
+ def toByteArray(): Array[Byte] = {
+ // if we don't know the length, fall back on relative inefficiency
+ if (length == -1L)
+ return (new ArrayBuffer[Byte]() ++= bytes()).toArray
+
+ val arr = new Array[Byte](length.toInt)
+ val len = arr.length
+ lazy val in = bufferedInput()
+ var offset = 0
+
+ def loop() {
+ if (offset < len) {
+ val read = in.read(arr, offset, len - offset)
+ if (read >= 0) {
+ offset += read
+ loop()
+ }
+ }
+ }
+ try loop()
+ finally in.close()
+
+ if (offset == arr.length) arr
+ else fail("Could not read entire source (%d of %d bytes)".format(offset, len))
}
}
diff --git a/src/compiler/scala/tools/nsc/io/package.scala b/src/compiler/scala/tools/nsc/io/package.scala
index 91cf715e33..29174b161f 100644
--- a/src/compiler/scala/tools/nsc/io/package.scala
+++ b/src/compiler/scala/tools/nsc/io/package.scala
@@ -12,6 +12,15 @@ import java.util.jar.{ Attributes }
package object io {
type JManifest = java.util.jar.Manifest
private[io] type JFile = java.io.File
+ // grimly bulldozing through #4338
+ private[io] object JFile {
+ import java.io.{ File => JJFile } // the irony of JFile being ambiguous is not overlooked
+ val createTempFile = JJFile.createTempFile(_: String, _: String, _: JFile)
+ def pathSeparator = JJFile.pathSeparator
+ def separator = JJFile.separator
+ def separatorChar = JJFile.separatorChar
+ def listRoots() = JJFile.listRoots()
+ }
private[io] implicit def installManifestOps(m: JManifest) = new ManifestOps(m)
class ManifestOps(manifest: JManifest) {
def attrs = manifest.getMainAttributes()
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index be31844e60..25c09b6c15 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -165,7 +165,7 @@ object ClassPath {
class JavaContext extends ClassPathContext[AbstractFile] {
def toBinaryName(rep: AbstractFile) = {
val name = rep.name
- assert(endsClass(name), name)
+ assert(name.length > 6 && name.substring(name.length - 6) == ".class", name)
name.substring(0, name.length - 6)
}
def newClassPath(dir: AbstractFile) = new DirectoryClassPath(dir, this)
@@ -175,18 +175,16 @@ object ClassPath {
override def isValidName(name: String) = !isTraitImplementation(name)
}
- @inline private def endsClass(s: String) = s.length > 6 && s.substring(s.length - 6) == ".class"
- @inline private def endsScala(s: String) = s.length > 6 && s.substring(s.length - 6) == ".scala"
- @inline private def endsJava(s: String) = s.length > 5 && s.substring(s.length - 5) == ".java"
-
/** From the source file to its identifier.
*/
def toSourceName(f: AbstractFile): String = {
val name = f.name
-
- if (endsScala(name)) name.substring(0, name.length - 6)
- else if (endsJava(name)) name.substring(0, name.length - 5)
- else throw new FatalError("Unexpected source file ending: " + name)
+ if (name.length > 6 && name.substring(name.length - 6) == ".scala")
+ name.substring(0, name.length - 6)
+ else if (name.length > 5 && name.substring(name.length - 5) == ".java")
+ name.substring(0, name.length - 5)
+ else
+ throw new FatalError("Unexpected source file ending: " + name)
}
}
import ClassPath._
@@ -261,9 +259,10 @@ abstract class ClassPath[T] {
/** Filters for assessing validity of various entities.
*/
- def validClassFile(name: String) = endsClass(name) && context.isValidName(name)
- def validPackage(name: String) = (name != "META-INF") && (name != "") && (name.charAt(0) != '.')
- def validSourceFile(name: String) = endsScala(name) || endsJava(name)
+ def validClassFile(name: String) = (name endsWith ".class") && context.isValidName(name)
+ def validPackage(name: String) = (name != "META-INF") && (name != "") && (name(0) != '.')
+ def validSourceFile(name: String) = validSourceExtensions exists (name endsWith _)
+ def validSourceExtensions = List(".scala", ".java")
/**
* Find a ClassRep given a class name of the form "package.subpackage.ClassName".
@@ -292,7 +291,7 @@ abstract class ClassPath[T] {
case x: ClassPath[_] => this.sortString == x.sortString
case _ => false
}
- override def hashCode = sortString.hashCode()
+ override def hashCode = sortString.##
}
/**
@@ -301,7 +300,10 @@ abstract class ClassPath[T] {
class SourcePath[T](dir: AbstractFile, val context: ClassPathContext[T]) extends ClassPath[T] {
def name = dir.name
override def origin = dir.underlyingSource map (_.path)
- def asURLs = if (dir.file == null) Nil else List(dir.toURL)
+ def asURLs = dir.file match {
+ case null => Nil
+ case file => File(file).toURL :: Nil
+ }
def asClasspathString = dir.path
val sourcepaths: IndexedSeq[AbstractFile] = IndexedSeq(dir)
@@ -324,7 +326,10 @@ class SourcePath[T](dir: AbstractFile, val context: ClassPathContext[T]) extends
class DirectoryClassPath(val dir: AbstractFile, val context: ClassPathContext[AbstractFile]) extends ClassPath[AbstractFile] {
def name = dir.name
override def origin = dir.underlyingSource map (_.path)
- def asURLs = if (dir.file == null) Nil else List(dir.toURL)
+ def asURLs = dir.file match {
+ case null => Nil
+ case file => File(file).toURL :: Nil
+ }
def asClasspathString = dir.path
val sourcepaths: IndexedSeq[AbstractFile] = IndexedSeq()
diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala
index 6cf0a9d94c..e23063640f 100644
--- a/src/partest/scala/tools/partest/nest/FileManager.scala
+++ b/src/partest/scala/tools/partest/nest/FileManager.scala
@@ -27,7 +27,7 @@ trait FileManager {
*/
def compareFiles(f1: File, f2: File): String = {
val diffWriter = new StringWriter
- val args = Array(f1.getPath(), f2.getPath())
+ val args = Array(f1.getCanonicalPath(), f2.getCanonicalPath())
DiffPrint.doDiff(args, diffWriter)
val res = diffWriter.toString
diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala
index b894d7086b..bfa6427d21 100644
--- a/src/partest/scala/tools/partest/nest/Worker.scala
+++ b/src/partest/scala/tools/partest/nest/Worker.scala
@@ -976,7 +976,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
react {
case Timeout(file) =>
- updateStatus(file.getAbsolutePath, TestState.Timeout)
+ updateStatus(file.getCanonicalPath, TestState.Timeout)
val swr = new StringWriter
val wr = new PrintWriter(swr, true)
printInfoStart(file, wr)
@@ -988,7 +988,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
case Result(file, logs) =>
val state = if (succeeded) TestState.Ok else TestState.Fail
- updateStatus(file.getAbsolutePath, state)
+ updateStatus(file.getCanonicalPath, state)
reportResult(
state,
logs.file,