Skip to content

Commit

Permalink
Update relativize method for java 9
Browse files Browse the repository at this point in the history
I noticed the io spec was failing on my mac on jdk9 (but passing on
travis, which was running jdk 8). The relativize method arguably didn't
work correctly on pre jdk 9 jres (at least on osx). For example, I ran
the following in the console:

scala> import java.nio.file._

scala> val base = Paths.get("/foo/bar/..")
val base = Paths.get("/foo/bar/..")
base: java.nio.file.Path = /foo/bar/..

scala> val file = Paths.get("/foo/buzz")
val file = Paths.get("/foo/buzz")
file: java.nio.file.Path = /foo/buzz

scala> val relative = base.relativize(file)
val relative = base.relativize(file)
                            ^
relative: java.nio.file.Path = ../../buzz

scala> base.resolve(relative).normalize
base.resolve(relative).normalize
                            ^
res5: java.nio.file.Path = /buzz

This result is certainly not what I would expect. The fix is very easy,
just always normalize the paths (which is not very expensive, especially
compared to any file system operation).
  • Loading branch information
eatkins committed Aug 2, 2018
1 parent c7a83d4 commit 212b407
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 5 deletions.
10 changes: 6 additions & 4 deletions io/src/main/scala/sbt/io/IO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -608,12 +608,14 @@ object IO {
* If `file` or `base` are not absolute, they are first resolved against the current working directory.
*/
def relativize(base: File, file: File): Option[String] = {
val basePath = (if (base.isAbsolute) base else base.getCanonicalFile).toPath
val filePath = (if (file.isAbsolute) file else file.getCanonicalFile).toPath
if ((filePath startsWith basePath) || (filePath.normalize() startsWith basePath.normalize())) {
val basePath = (if (base.isAbsolute) base else base.getCanonicalFile).toPath.normalize()
val filePath = (if (file.isAbsolute) file else file.getCanonicalFile).toPath.normalize()
if (filePath startsWith basePath) {
val relativePath = catching(classOf[IllegalArgumentException]) opt (basePath relativize filePath)
relativePath map (_.toString)
} else None
} else {
None
}
}

def copy(sources: Traversable[(File, File)]): Set[File] = copy(sources, CopyOptions())
Expand Down
2 changes: 1 addition & 1 deletion io/src/test/scala/sbt/io/IOSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class IOSpec extends FlatSpec with Matchers {
val relativeRootDir = new File(nestedDir, "..")

IO.relativize(rootDir.toFile, nestedFile).map(file) shouldBe Some(file("meh.file"))
IO.relativize(relativeRootDir, nestedFile).map(file) shouldBe Some(file("../../meh.file"))
IO.relativize(relativeRootDir, nestedFile).map(file) shouldBe Some(file("meh.file"))
}

it should "relativize . dirs" in {
Expand Down

0 comments on commit 212b407

Please sign in to comment.