From 212b407eb633c0468848be58d1b64204d4813bd1 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Wed, 1 Aug 2018 17:41:05 -0700 Subject: [PATCH] Update relativize method for java 9 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). --- io/src/main/scala/sbt/io/IO.scala | 10 ++++++---- io/src/test/scala/sbt/io/IOSpec.scala | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/io/src/main/scala/sbt/io/IO.scala b/io/src/main/scala/sbt/io/IO.scala index 176a34d2..d32b5d6e 100644 --- a/io/src/main/scala/sbt/io/IO.scala +++ b/io/src/main/scala/sbt/io/IO.scala @@ -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()) diff --git a/io/src/test/scala/sbt/io/IOSpec.scala b/io/src/test/scala/sbt/io/IOSpec.scala index 3be2d718..531f4208 100644 --- a/io/src/test/scala/sbt/io/IOSpec.scala +++ b/io/src/test/scala/sbt/io/IOSpec.scala @@ -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 {