From b11acd5b5a252455ef5765f6c093562082a8c618 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 17 Sep 2019 17:11:51 -0400 Subject: [PATCH 1/4] Mima check against 1.3.0 --- build.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sbt b/build.sbt index a75f4528..bbdf2fdb 100644 --- a/build.sbt +++ b/build.sbt @@ -78,6 +78,7 @@ val io = (project in file("io")) "1.0.0", "1.0.1", "1.0.2", "1.1.0", "1.1.1", "1.1.2", "1.1.3", "1.1.4", "1.2.0", + "1.3.0", ) map (version => organization.value %% moduleName.value % version) }), mimaBinaryIssueFilters ++= Seq( From f118394f132a9782200b26e8bebcf3641565e5f6 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Thu, 19 Sep 2019 10:57:43 -0700 Subject: [PATCH 2/4] Bump sbt to 1.3.0 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 2bdd560f..080a737e 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.3.0-RC4 +sbt.version=1.3.0 From 7e50d3f028b54c46f4d1f3133c300d471299ab17 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Thu, 19 Sep 2019 11:38:30 -0700 Subject: [PATCH 3/4] Use JavaMilli for jdk >= 11 In jdk >= 11, java returns millisecond precision timestamps if the file system supports it. It's better to avoid the jna if we can. --- io/src/main/scala/sbt/internal/io/Milli.scala | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/io/src/main/scala/sbt/internal/io/Milli.scala b/io/src/main/scala/sbt/internal/io/Milli.scala index a03f67fe..dd347dc0 100644 --- a/io/src/main/scala/sbt/internal/io/Milli.scala +++ b/io/src/main/scala/sbt/internal/io/Milli.scala @@ -28,6 +28,7 @@ import sbt.io.JavaMilli import scala.collection.JavaConverters.mapAsJavaMapConverter import scala.reflect.{ ClassTag, classTag } +import scala.util.control.NonFatal private abstract class Stat[Time_T](size: Int) extends NativeMapped { val buffer = ByteBuffer.allocate(size).order(ByteOrder.nativeOrder()) @@ -341,8 +342,18 @@ object Milli { // "false", disable native millisecond-accurate modification timestamps. // private val jdkTimestamps = { - val prop = System.getProperty("sbt.io.jdktimestamps") - !(prop eq null) && (prop.toLowerCase != "false") + System.getProperty("sbt.io.jdktimestamps") match { + case null => + System.getProperty("java.specification.version") match { + case null => false + case sv => + try sv.split("\\.").last.toInt match { + case v if v >= 11 => true + case _ => false + } catch { case NonFatal(_) => false } + } + case p => p.toLowerCase != "false" + } } private val milli = From 500238d054273c81f8c0264c9c9e9ea3dea5826a Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Thu, 19 Sep 2019 11:40:28 -0700 Subject: [PATCH 4/4] Fix last modified for long paths on windows It is necessary to prefix the file name passed into CreateFile with "\\?\" to allow file names with more than max_path (260) characters on windows: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea.. Fixes https://github.com/sbt/sbt/issues/5098. --- io/src/main/scala/sbt/internal/io/Milli.scala | 2 +- .../test/scala/sbt/io/LastModifiedSpec.scala | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 io/src/test/scala/sbt/io/LastModifiedSpec.scala diff --git a/io/src/main/scala/sbt/internal/io/Milli.scala b/io/src/main/scala/sbt/internal/io/Milli.scala index dd347dc0..b05b5246 100644 --- a/io/src/main/scala/sbt/internal/io/Milli.scala +++ b/io/src/main/scala/sbt/internal/io/Milli.scala @@ -263,7 +263,7 @@ private object WinMilli extends MilliNative[FILETIME] { private def getHandle(lpFileName: String, dwDesiredAccess: Int, dwShareMode: Int): HANDLE = { val hFile = CreateFile( - lpFileName, + "\\\\?\\" + lpFileName, dwDesiredAccess, dwShareMode, null, diff --git a/io/src/test/scala/sbt/io/LastModifiedSpec.scala b/io/src/test/scala/sbt/io/LastModifiedSpec.scala new file mode 100644 index 00000000..2848c193 --- /dev/null +++ b/io/src/test/scala/sbt/io/LastModifiedSpec.scala @@ -0,0 +1,31 @@ +/* + * sbt IO + * + * Copyright 2011 - 2019, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + */ + +package sbt.io + +import java.nio.file.Files + +import org.scalatest.FlatSpec + +class LastModifiedSpec extends FlatSpec { + "IO.getModifiedTimeOrZero" should "work with long path names" in IO.withTemporaryDirectory { + dir => + val fileName = "a" * 32 + val nested = + (1 to 8).foldLeft(dir.toPath) { + case (d, _) => Files.createDirectories(d.resolve(fileName)) + } + val file = Files.createFile(nested.resolve(fileName)).toFile + // in case target platform only has second precision round to nearest second + val lm = (System.currentTimeMillis / 1000) * 1000 + IO.setModifiedTimeOrFalse(file, lm) + assert(IO.getModifiedTimeOrZero(file) == lm) + } +}