Merge pull request #3088 from eed3si9n/wip/windows_file

Improve IO.toFile for Windows
This commit is contained in:
eugene yokota 2017-04-08 12:17:39 -07:00 committed by GitHub
commit c31dfda4ba
3 changed files with 30 additions and 16 deletions

View File

@ -12,8 +12,8 @@
[repositories]
local
local-preloaded-ivy: file://${sbt.preloaded-${sbt.global.base-${user.home}/.sbt}/preloaded/}, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]
local-preloaded: file://${sbt.preloaded-${sbt.global.base-${user.home}/.sbt}/preloaded/}
local-preloaded-ivy: file:${sbt.preloaded-${sbt.global.base-${user.home}/.sbt}/preloaded/}, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]
local-preloaded: file:${sbt.preloaded-${sbt.global.base-${user.home}/.sbt}/preloaded/}
maven-central
typesafe-ivy-releases: https://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly
sbt-ivy-snapshots: https://repo.scala-sbt.org/scalasbt/ivy-snapshots/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly

View File

@ -1939,7 +1939,7 @@ object Classpaths {
i.url.getProtocol match {
case "file" =>
// This hackery is to deal suitably with UNC paths on Windows. Once we can assume Java7, Paths should save us from this.
val file = try { new File(i.url.toURI) } catch { case e: java.net.URISyntaxException => new File(i.url.getPath) }
val file = IO.toFile(i.url)
Resolver.file(i.id, file)(patterns)
case _ => Resolver.url(i.id, i.url)(patterns)
}

View File

@ -122,9 +122,17 @@ object IO {
/**
* Constructs a File corresponding to `url`, which must have a scheme of `file`.
* This method properly works around an issue with a simple conversion to URI and then to a File.
*
* On Windows this can accept the following patterns of URLs:
*
* `val u0 = new URL("file:C:\\Users\\foo/.sbt/preloaded")`,
* `val u1 = new URL("file:/C:\\Users\\foo/.sbt/preloaded")`,
* `val u2 = new URL("file://unc/Users/foo/.sbt/preloaded")`,
* `val u3 = new URL("file:///C:\\Users\\foo/.sbt/preloaded")`, and
* `val u4 = new URL("file:////unc/Users/foo/.sbt/preloaded")`.
*/
def toFile(url: URL): File =
try { new File(url.toURI) }
try { uriToFile(url.toURI) }
catch { case _: URISyntaxException => new File(url.getPath) }
/** Converts the given URL to a File. If the URL is for an entry in a jar, the File for the jar is returned. */
@ -139,20 +147,26 @@ object IO {
case _ => None
}
private[this] def uriToFile(uriString: String): File =
private[this] def uriToFile(uriString: String): File = uriToFile(new URI(uriString))
/**
* Converts the given file URI to a File.
*/
private[this] def uriToFile(uri: URI): File =
{
val uri = new URI(uriString)
assert(uri.getScheme == FileScheme, "Expected protocol to be '" + FileScheme + "' in URI " + uri)
if (uri.getAuthority eq null)
new File(uri)
else {
/* https://github.com/sbt/sbt/issues/564
* http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5086147
* The specific problem here is that `uri` will have a defined authority component for UNC names like //foo/bar/some/path.jar
* but the File constructor requires URIs with an undefined authority component.
*/
new File(uri.getSchemeSpecificPart)
val part = uri.getSchemeSpecificPart
Option(uri.getAuthority) match {
case None if part startsWith "/" => new File(uri)
case _ =>
// https://github.com/sbt/sbt/issues/564
// https://github.com/sbt/sbt/issues/3086
// http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5086147
// The specific problem here is that `uri` will have a defined authority component for UNC names like //foo/bar/some/path.jar
// but the File constructor requires URIs with an undefined authority component.
if (part startsWith "/") new File(part)
else new File("//" + part)
}
}