From ec5bdc2381855311d4d0e1d384786a7ca62d2023 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 18 Dec 2017 23:07:25 -0500 Subject: [PATCH 01/15] Add Windows testing --- .appveyor.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 000000000..1cc9a9906 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,26 @@ +build: off + +init: + - git config --global core.autocrlf input + +install: + - cinst nodejs -params 'installdir=C:\\nodejs' + - SET PATH=C:\nodejs\bin;%PATH% + - cinst jdk8 -params 'installdir=C:\\jdk8' + - SET JAVA_HOME=C:\jdk8 + - SET PATH=C:\jdk8\bin;%PATH% + + - ps: | + Add-Type -AssemblyName System.IO.Compression.FileSystem + if (!(Test-Path -Path "C:\sbt" )) { + (new-object System.Net.WebClient).DownloadFile( + 'https://github.com/sbt/sbt/releases/download/v1.0.4/sbt-1.0.4.zip', + 'C:\sbt-bin.zip' + ) + [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\sbt-bin.zip", "C:\sbt") + } + - SET PATH=C:\sbt\sbt\bin;%PATH% + - SET SBT_OPTS=-XX:MaxPermSize=2g -Xmx4g -Dfile.encoding=UTF8 +test_script: + - sbt "scripted actions/*" + - sbt "scripted server/*" From c920919c2c13d66d36a7a257ea56b0eebd63b3d2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 19 Dec 2017 00:17:46 -0500 Subject: [PATCH 02/15] Fix build so it works on Windows --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index ec5065942..368393d59 100644 --- a/build.sbt +++ b/build.sbt @@ -34,6 +34,7 @@ def buildLevelSettings: Seq[Setting[_]] = scmInfo := Some(ScmInfo(url("https://github.com/sbt/sbt"), "git@github.com:sbt/sbt.git")), resolvers += Resolver.mavenLocal, scalafmtOnCompile := true, + scalafmtOnCompile in Sbt := false, scalafmtVersion := "1.3.0", )) @@ -463,10 +464,9 @@ lazy val sbtIgnoredProblems = { } def runNpm(command: String, base: File, log: sbt.internal.util.ManagedLogger) = { - val npm = if (sbt.internal.util.Util.isWindows) "npm.cmd" else "npm" import scala.sys.process._ try { - val exitCode = Process(s"$npm $command", Option(base)) ! log + val exitCode = Process(s"npm $command", Option(base)) ! log if (exitCode != 0) throw new Exception("Process returned exit code: " + exitCode) } catch { case e: java.io.IOException => log.warn("failed to run npm " + e.getMessage) From 294110e2b8074e13c50aeb8e4e734fe77651433c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 19 Dec 2017 00:44:31 -0500 Subject: [PATCH 03/15] Remove JNA from sbt/sbt There's a conflict in JNA version difference between sbt and IO. Fixes #3821 --- build.sbt | 3 +-- project/Dependencies.scala | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index 368393d59..dcedffd62 100644 --- a/build.sbt +++ b/build.sbt @@ -311,8 +311,7 @@ lazy val commandProj = (project in file("main-command")) .settings( testedBaseSettings, name := "Command", - libraryDependencies ++= Seq(launcherInterface, sjsonNewScalaJson.value, templateResolverApi, - jna, jnaPlatform), + libraryDependencies ++= Seq(launcherInterface, sjsonNewScalaJson.value, templateResolverApi), managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f8e14429f..73405aea8 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -106,8 +106,6 @@ object Dependencies { val specs2 = "org.specs2" %% "specs2-junit" % "4.0.1" val junit = "junit" % "junit" % "4.11" val templateResolverApi = "org.scala-sbt" % "template-resolver" % "0.1" - val jna = "net.java.dev.jna" % "jna" % "4.1.0" - val jnaPlatform = "net.java.dev.jna" % "jna-platform" % "4.1.0" private def scala211Module(name: String, moduleVersion: String) = Def setting ( scalaBinaryVersion.value match { From 3507403a360cdac49950574394c157c53e53e4c1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 19 Dec 2017 02:12:03 -0500 Subject: [PATCH 04/15] -Djna.nosys=true --- .appveyor.yml | 6 ++---- build.sbt | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 1cc9a9906..45e3cfd3f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -4,8 +4,6 @@ init: - git config --global core.autocrlf input install: - - cinst nodejs -params 'installdir=C:\\nodejs' - - SET PATH=C:\nodejs\bin;%PATH% - cinst jdk8 -params 'installdir=C:\\jdk8' - SET JAVA_HOME=C:\jdk8 - SET PATH=C:\jdk8\bin;%PATH% @@ -22,5 +20,5 @@ install: - SET PATH=C:\sbt\sbt\bin;%PATH% - SET SBT_OPTS=-XX:MaxPermSize=2g -Xmx4g -Dfile.encoding=UTF8 test_script: - - sbt "scripted actions/*" - - sbt "scripted server/*" + - sbt "-Djna.nosys=true" "scripted actions/*" + - sbt "-Djna.nosys=true" "scripted server/*" diff --git a/build.sbt b/build.sbt index dcedffd62..8000bd603 100644 --- a/build.sbt +++ b/build.sbt @@ -572,7 +572,7 @@ def otherRootSettings = scriptedUnpublished := scriptedUnpublishedTask.evaluated, scriptedSource := (sourceDirectory in sbtProj).value / "sbt-test", // scriptedPrescripted := { addSbtAlternateResolver _ }, - scriptedLaunchOpts := List("-Xmx1500M", "-Xms512M", "-server"), + scriptedLaunchOpts := List("-Xmx1500M", "-Xms512M", "-server", "-Djna.nosys=true"), publishAll := { val _ = (publishLocal).all(ScopeFilter(inAnyProject)).value }, publishLocalBinAll := { val _ = (publishLocalBin).all(ScopeFilter(inAnyProject)).value }, aggregate in bintrayRelease := false From bc4d3d5031152b06162b7c2ad1a44991041dd967 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 19 Dec 2017 03:24:51 -0500 Subject: [PATCH 05/15] just scripted actions/* --- .appveyor.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 45e3cfd3f..0b15d875f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -21,4 +21,3 @@ install: - SET SBT_OPTS=-XX:MaxPermSize=2g -Xmx4g -Dfile.encoding=UTF8 test_script: - sbt "-Djna.nosys=true" "scripted actions/*" - - sbt "-Djna.nosys=true" "scripted server/*" From ad2d71cae4cc5d6bbb9f9cf942eedb332500aca1 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 19 Dec 2017 13:25:58 +0000 Subject: [PATCH 06/15] Upgrade to sbt-houserules 0.3.5 --- project/plugins.sbt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 66097a8b9..7ea70f8ea 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,8 +1,7 @@ -scalaVersion := "2.12.3" +scalaVersion := "2.12.4" scalacOptions ++= Seq("-feature", "-language:postfixOps") -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.4") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.5") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.2") -addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.14") addSbtPlugin("de.heikoseeberger" % "sbt-header" % "3.0.2") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.7.0") From 4c3b770b279a261a0ddbaa1df5de47d7faca5be7 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 19 Dec 2017 20:57:09 -0500 Subject: [PATCH 07/15] bump to sbt 1.0.4 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 94005e587..394cb75cf 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.0 +sbt.version=1.0.4 From 06ffb4f4406156e423ba7135178a45aa5f72b099 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 19 Dec 2017 21:01:02 -0500 Subject: [PATCH 08/15] warn about multiple instance once Fixes #3823 When you launch a second instance of sbt on a build, prior to this change it was displaying `java.io.IOException: sbt server is already running` on every command. This make it a bit less aggressive, and just display a warning once. ``` [warn] Is another instance of sbt is running on this build? [warn] Running multiple instances is unsupported ``` --- .../main/scala/sbt/internal/server/Server.scala | 4 +++- .../scala/sbt/internal/CommandExchange.scala | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/main-command/src/main/scala/sbt/internal/server/Server.scala b/main-command/src/main/scala/sbt/internal/server/Server.scala index 4fb8a7cb4..521c8d399 100644 --- a/main-command/src/main/scala/sbt/internal/server/Server.scala +++ b/main-command/src/main/scala/sbt/internal/server/Server.scala @@ -97,7 +97,7 @@ private[sbt] object Server { case Failure(e) => () case Success(socket) => socket.close() - throw new IOException("sbt server is already running.") + throw new AlreadyRunningException() } } else () } @@ -210,3 +210,5 @@ private[sbt] case class ServerConnection( } } } + +private[sbt] class AlreadyRunningException extends IOException("sbt server is already running.") diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index 39259ee28..acbe78bb6 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -10,7 +10,7 @@ package internal import java.io.IOException import java.util.concurrent.ConcurrentLinkedQueue -import java.util.concurrent.atomic.AtomicInteger +import java.util.concurrent.atomic._ import scala.collection.mutable.ListBuffer import scala.annotation.tailrec import BasicKeys.{ @@ -48,6 +48,7 @@ private[sbt] final class CommandExchange { } getOrElse true private val lock = new AnyRef {} private var server: Option[ServerInstance] = None + private val firstInstance: AtomicBoolean = new AtomicBoolean(true) private var consoleChannel: Option[ConsoleChannel] = None private val commandQueue: ConcurrentLinkedQueue[Exec] = new ConcurrentLinkedQueue() private val channelBuffer: ListBuffer[CommandChannel] = new ListBuffer() @@ -90,7 +91,6 @@ private[sbt] final class CommandExchange { else s } - private def newChannelName: String = s"channel-${nextChannelId.incrementAndGet()}" private def newNetworkName: String = s"network-${nextChannelId.incrementAndGet()}" /** @@ -132,7 +132,8 @@ private[sbt] final class CommandExchange { subscribe(channel) } server match { - case Some(_) => // do nothing + case Some(_) => // do nothing + case None if !firstInstance.get => // there's another server case _ => val portfile = (new File(".")).getAbsoluteFile / "project" / "target" / "active.json" val h = Hash.halfHashString(IO.toURI(portfile).toString) @@ -154,6 +155,11 @@ private[sbt] final class CommandExchange { case Some(Success(_)) => // rememeber to shutdown only when the server comes up server = Some(x) + case Some(Failure(e: AlreadyRunningException)) => + s.log.warn("sbt server could not start because there's another instance of sbt running on this build.") + s.log.warn("Running multiple instances is unsupported") + server = None + firstInstance.set(false) case Some(Failure(e)) => s.log.error(e.toString) server = None @@ -191,6 +197,7 @@ private[sbt] final class CommandExchange { case xs => lock.synchronized { channelBuffer --= xs + () } } } @@ -247,6 +254,7 @@ private[sbt] final class CommandExchange { case xs => lock.synchronized { channelBuffer --= xs + () } } } @@ -288,6 +296,7 @@ private[sbt] final class CommandExchange { case xs => lock.synchronized { channelBuffer --= xs + () } } } @@ -339,6 +348,7 @@ private[sbt] final class CommandExchange { case xs => lock.synchronized { channelBuffer --= xs + () } } } From d8609ced7feb3ae8b878958d01632064806bc1d0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 20 Dec 2017 22:36:07 -0500 Subject: [PATCH 09/15] formatting --- main/src/main/scala/sbt/internal/CommandExchange.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index acbe78bb6..99f1e1418 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -156,7 +156,8 @@ private[sbt] final class CommandExchange { // rememeber to shutdown only when the server comes up server = Some(x) case Some(Failure(e: AlreadyRunningException)) => - s.log.warn("sbt server could not start because there's another instance of sbt running on this build.") + s.log.warn( + "sbt server could not start because there's another instance of sbt running on this build.") s.log.warn("Running multiple instances is unsupported") server = None firstInstance.set(false) From 13e1862c2f12f633b13d4b68715d933fef8baf31 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 21 Dec 2017 00:08:56 -0500 Subject: [PATCH 10/15] set jna.nosys to true programmatically Previously I was seeing the error upon the first scripted test. I thought it was because Main was somehow not early enough. It might just be because scripted technically runs as part of the build. Ref sbt/io#110 --- .appveyor.yml | 2 +- build.sbt | 2 +- main/src/main/scala/sbt/Main.scala | 3 +++ project/Scripted.scala | 3 +++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 0b15d875f..b9a894ee2 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -20,4 +20,4 @@ install: - SET PATH=C:\sbt\sbt\bin;%PATH% - SET SBT_OPTS=-XX:MaxPermSize=2g -Xmx4g -Dfile.encoding=UTF8 test_script: - - sbt "-Djna.nosys=true" "scripted actions/*" + - sbt "scripted actions/*" diff --git a/build.sbt b/build.sbt index 8000bd603..dcedffd62 100644 --- a/build.sbt +++ b/build.sbt @@ -572,7 +572,7 @@ def otherRootSettings = scriptedUnpublished := scriptedUnpublishedTask.evaluated, scriptedSource := (sourceDirectory in sbtProj).value / "sbt-test", // scriptedPrescripted := { addSbtAlternateResolver _ }, - scriptedLaunchOpts := List("-Xmx1500M", "-Xms512M", "-server", "-Djna.nosys=true"), + scriptedLaunchOpts := List("-Xmx1500M", "-Xms512M", "-server"), publishAll := { val _ = (publishLocal).all(ScopeFilter(inAnyProject)).value }, publishLocalBinAll := { val _ = (publishLocalBin).all(ScopeFilter(inAnyProject)).value }, aggregate in bintrayRelease := false diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 6c605056e..da44d0cb8 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -128,6 +128,9 @@ object StandardMain { def initialState(configuration: xsbti.AppConfiguration, initialDefinitions: Seq[Command], preCommands: Seq[String]): State = { + // This is to workaround https://github.com/sbt/io/issues/110 + sys.props.put("jna.nosys", "true") + import BasicCommandStrings.isEarlyCommand val userCommands = configuration.arguments.map(_.trim) val (earlyCommands, normalCommands) = (preCommands ++ userCommands).partition(isEarlyCommand) diff --git a/project/Scripted.scala b/project/Scripted.scala index 932d55a0f..788f1d60e 100644 --- a/project/Scripted.scala +++ b/project/Scripted.scala @@ -37,6 +37,9 @@ trait ScriptedKeys { } object Scripted { + // This is to workaround https://github.com/sbt/io/issues/110 + sys.props.put("jna.nosys", "true") + lazy val MavenResolverPluginTest = config("mavenResolverPluginTest") extend Compile lazy val RepoOverrideTest = config("repoOverrideTest") extend Compile From ebff7919e90730e03ff4c5e3a1bfd4dca980ac7a Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Mon, 18 Dec 2017 17:37:03 +0100 Subject: [PATCH 11/15] Revert *ModifiedTime() calls to *lastModified*() calls There are just too many instances in which sbt's code relies on the `lastModified`/`setLastModified` semantics, so instead of moving to `get`/`setModifiedTime`, we use new IO calls that offer the new timestamp precision, but retain the old semantics. --- main-actions/src/main/scala/sbt/compiler/Eval.scala | 9 ++++----- main/src/main/scala/sbt/Defaults.scala | 2 +- main/src/main/scala/sbt/internal/LibraryManagement.scala | 2 +- project/SiteMap.scala | 4 ++-- project/Util.scala | 4 ++-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/main-actions/src/main/scala/sbt/compiler/Eval.scala b/main-actions/src/main/scala/sbt/compiler/Eval.scala index a075f61a8..78235cdb3 100644 --- a/main-actions/src/main/scala/sbt/compiler/Eval.scala +++ b/main-actions/src/main/scala/sbt/compiler/Eval.scala @@ -485,12 +485,11 @@ private[sbt] object Eval { def filesModifiedBytes(fs: Array[File]): Array[Byte] = if (fs eq null) filesModifiedBytes(Array[File]()) else seqBytes(fs)(fileModifiedBytes) def fileModifiedBytes(f: File): Array[Byte] = - (if (f.isDirectory) filesModifiedBytes(f listFiles classDirFilter) + (if (f.isDirectory) + filesModifiedBytes(f listFiles classDirFilter) else - bytes( - try IO.getModifiedTime(f) - catch { case _: java.io.FileNotFoundException => 0L })) ++ - bytes(f.getAbsolutePath) + bytes(IO.lastModified(f)) + ) ++ bytes(f.getAbsolutePath) def fileExistsBytes(f: File): Array[Byte] = bytes(f.exists) ++ bytes(f.getAbsolutePath) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index b006c115d..5d9d2fb8b 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2315,7 +2315,7 @@ object Classpaths { case Some(period) => val fullUpdateOutput = cacheDirectory / "out" val now = System.currentTimeMillis - val diff = now - IO.getModifiedTime(fullUpdateOutput) + val diff = now - IO.lastModified(fullUpdateOutput) val elapsedDuration = new FiniteDuration(diff, TimeUnit.MILLISECONDS) fullUpdateOutput.exists() && elapsedDuration > period } diff --git a/main/src/main/scala/sbt/internal/LibraryManagement.scala b/main/src/main/scala/sbt/internal/LibraryManagement.scala index fc832ffff..b40956fad 100644 --- a/main/src/main/scala/sbt/internal/LibraryManagement.scala +++ b/main/src/main/scala/sbt/internal/LibraryManagement.scala @@ -127,7 +127,7 @@ private[sbt] object LibraryManagement { } private[this] def fileUptodate(file: File, stamps: Map[File, Long]): Boolean = - stamps.get(file).forall(_ == IO.getModifiedTime(file)) + stamps.get(file).forall(_ == IO.lastModified(file)) private[sbt] def transitiveScratch( lm: DependencyResolution, diff --git a/project/SiteMap.scala b/project/SiteMap.scala index 2cfb5d8ea..046031775 100644 --- a/project/SiteMap.scala +++ b/project/SiteMap.scala @@ -68,8 +68,8 @@ object SiteMap { // generates a string suitable for a sitemap file representing the last modified time of the given File private[this] def lastModifiedString(f: File): String = { val formatter = new java.text.SimpleDateFormat("yyyy-MM-dd") - // TODO: replace lastModified() with sbt.io.Milli.getModifiedTime(), once the build - // has been upgraded to a version of sbt that includes sbt.io.Milli. + // TODO: replace lastModified() with sbt.io.IO.lastModified(), once the build + // has been upgraded to a version of sbt that includes that call. formatter.format(new java.util.Date(f.lastModified)) } // writes the provided XML node to `output` and then gzips it to `gzipped` if `gzip` is true diff --git a/project/Util.scala b/project/Util.scala index 0b87b02db..c04734285 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -105,8 +105,8 @@ object Util { val timestamp = formatter.format(new Date) val content = versionLine(version) + "\ntimestamp=" + timestamp val f = dir / "xsbt.version.properties" - // TODO: replace lastModified() with sbt.io.Milli.getModifiedTime(), once the build - // has been upgraded to a version of sbt that includes sbt.io.Milli. + // TODO: replace lastModified() with sbt.io.IO.lastModified(), once the build + // has been upgraded to a version of sbt that includes that call. if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) { s.log.info("Writing version information to " + f + " :\n" + content) IO.write(f, content) From 94e36a14c80027a4e316505574d4c49fdcb14948 Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Fri, 22 Dec 2017 01:49:59 +0100 Subject: [PATCH 12/15] Change modifiedTime definitions --- main-actions/src/main/scala/sbt/compiler/Eval.scala | 3 +-- main/src/main/scala/sbt/Defaults.scala | 2 +- main/src/main/scala/sbt/internal/LibraryManagement.scala | 2 +- project/SiteMap.scala | 2 +- project/Util.scala | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/main-actions/src/main/scala/sbt/compiler/Eval.scala b/main-actions/src/main/scala/sbt/compiler/Eval.scala index 78235cdb3..a9d97246a 100644 --- a/main-actions/src/main/scala/sbt/compiler/Eval.scala +++ b/main-actions/src/main/scala/sbt/compiler/Eval.scala @@ -488,8 +488,7 @@ private[sbt] object Eval { (if (f.isDirectory) filesModifiedBytes(f listFiles classDirFilter) else - bytes(IO.lastModified(f)) - ) ++ bytes(f.getAbsolutePath) + bytes(IO.getModifiedTimeOrZero(f))) ++ bytes(f.getAbsolutePath) def fileExistsBytes(f: File): Array[Byte] = bytes(f.exists) ++ bytes(f.getAbsolutePath) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 5d9d2fb8b..4fd8d1585 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2315,7 +2315,7 @@ object Classpaths { case Some(period) => val fullUpdateOutput = cacheDirectory / "out" val now = System.currentTimeMillis - val diff = now - IO.lastModified(fullUpdateOutput) + val diff = now - IO.getModifiedTimeOrZero(fullUpdateOutput) val elapsedDuration = new FiniteDuration(diff, TimeUnit.MILLISECONDS) fullUpdateOutput.exists() && elapsedDuration > period } diff --git a/main/src/main/scala/sbt/internal/LibraryManagement.scala b/main/src/main/scala/sbt/internal/LibraryManagement.scala index b40956fad..d247a9d99 100644 --- a/main/src/main/scala/sbt/internal/LibraryManagement.scala +++ b/main/src/main/scala/sbt/internal/LibraryManagement.scala @@ -127,7 +127,7 @@ private[sbt] object LibraryManagement { } private[this] def fileUptodate(file: File, stamps: Map[File, Long]): Boolean = - stamps.get(file).forall(_ == IO.lastModified(file)) + stamps.get(file).forall(_ == IO.getModifiedTimeOrZero(file)) private[sbt] def transitiveScratch( lm: DependencyResolution, diff --git a/project/SiteMap.scala b/project/SiteMap.scala index 046031775..95e038eab 100644 --- a/project/SiteMap.scala +++ b/project/SiteMap.scala @@ -68,7 +68,7 @@ object SiteMap { // generates a string suitable for a sitemap file representing the last modified time of the given File private[this] def lastModifiedString(f: File): String = { val formatter = new java.text.SimpleDateFormat("yyyy-MM-dd") - // TODO: replace lastModified() with sbt.io.IO.lastModified(), once the build + // TODO: replace lastModified() with sbt.io.IO.getModifiedTimeOrZero(), once the build // has been upgraded to a version of sbt that includes that call. formatter.format(new java.util.Date(f.lastModified)) } diff --git a/project/Util.scala b/project/Util.scala index c04734285..8c68f4ced 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -105,7 +105,7 @@ object Util { val timestamp = formatter.format(new Date) val content = versionLine(version) + "\ntimestamp=" + timestamp val f = dir / "xsbt.version.properties" - // TODO: replace lastModified() with sbt.io.IO.lastModified(), once the build + // TODO: replace lastModified() with sbt.io.IO.getModifiedTimeOrZero(), once the build // has been upgraded to a version of sbt that includes that call. if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) { s.log.info("Writing version information to " + f + " :\n" + content) From 7f0ff7c90aa3c3935337229d79a8f7f496d9ea66 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Dec 2017 11:45:31 -0500 Subject: [PATCH 13/15] IO 1.1.3, Zinc 1.1.0-RC4 --- project/Dependencies.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 73405aea8..21de56080 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -12,10 +12,10 @@ object Dependencies { val baseScalaVersion = scala212 // sbt modules - private val ioVersion = "1.1.2" - private val utilVersion = "1.1.1" - private val lmVersion = "1.1.1" - private val zincVersion = "1.1.0-RC3" + private val ioVersion = "1.1.3" + private val utilVersion = "1.1.2" + private val lmVersion = "1.1.2" + private val zincVersion = "1.1.0-RC4" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 0a3900f53dfbd4db14e849960d853a8f05513886 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Dec 2017 15:38:17 -0500 Subject: [PATCH 14/15] Add Library interface Fixes #3821 Initially I missed why #3821 was failing. Looking at it again, the error message reads: ``` Caused by: java.lang.IllegalArgumentException: Interface (NGWin32NamedPipeLibrary) of library=kernel32 does not extend Library at com.sun.jna.Native.loadLibrary(Native.java:566) at sbt.internal.NGWin32NamedPipeLibrary.(NGWin32NamedPipeLibrary.java:38) ... 7 more ``` Inside `Native.loadLibrary`, it requires the "library" interface to extend `com.sun.jna.Library`, which this adds. --- .appveyor.yml | 2 +- .../src/main/java/sbt/internal/NGWin32NamedPipeLibrary.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index b9a894ee2..a0d3292f1 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -20,4 +20,4 @@ install: - SET PATH=C:\sbt\sbt\bin;%PATH% - SET SBT_OPTS=-XX:MaxPermSize=2g -Xmx4g -Dfile.encoding=UTF8 test_script: - - sbt "scripted actions/*" + - sbt "scripted actions/* server/*" diff --git a/main-command/src/main/java/sbt/internal/NGWin32NamedPipeLibrary.java b/main-command/src/main/java/sbt/internal/NGWin32NamedPipeLibrary.java index ba535691f..dd4d8f15a 100644 --- a/main-command/src/main/java/sbt/internal/NGWin32NamedPipeLibrary.java +++ b/main-command/src/main/java/sbt/internal/NGWin32NamedPipeLibrary.java @@ -29,7 +29,7 @@ import com.sun.jna.ptr.IntByReference; import com.sun.jna.win32.W32APIOptions; -public interface NGWin32NamedPipeLibrary extends WinNT { +public interface NGWin32NamedPipeLibrary extends Library, WinNT { int PIPE_ACCESS_DUPLEX = 3; int PIPE_UNLIMITED_INSTANCES = 255; int FILE_FLAG_FIRST_PIPE_INSTANCE = 524288; From 0aebb92ef5a8004da26c86e2c597bbb80442dc6b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Dec 2017 16:14:05 -0500 Subject: [PATCH 15/15] don't block the build when server can't get up --- .../main/scala/sbt/internal/CommandExchange.scala | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index 99f1e1418..d7b52280d 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -26,7 +26,7 @@ import sjsonnew.JsonFormat import sjsonnew.shaded.scalajson.ast.unsafe._ import scala.concurrent.Await import scala.concurrent.duration.Duration -import scala.util.{ Success, Failure } +import scala.util.{ Success, Failure, Try } import sbt.io.syntax._ import sbt.io.{ Hash, IO } import sbt.internal.server._ @@ -150,7 +150,10 @@ private[sbt] final class CommandExchange { socketfile, pipeName) val x = Server.start(connection, onIncomingSocket, s.log) - Await.ready(x.ready, Duration("10s")) + + // don't throw exception when it times out + val d = "10s" + Try(Await.ready(x.ready, Duration(d))) x.ready.value match { case Some(Success(_)) => // rememeber to shutdown only when the server comes up @@ -164,7 +167,10 @@ private[sbt] final class CommandExchange { case Some(Failure(e)) => s.log.error(e.toString) server = None - case None => // this won't happen because we awaited + case None => + s.log.warn(s"sbt server could not start in $d") + server = None + firstInstance.set(false) } } s