From 87dc5da93a3b79d27501fc407911d2c7ec65b25e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 25 Jun 2022 18:55:36 -0400 Subject: [PATCH] Fix sbt trying to delete /tmp on ARM Macs Problem ------- There's a bug in ipcsocket cleanup logic that effectively tries to wipe out /tmp. Workaround ---------- We should fix the underlying bug, but we can start by explicitly configuring the temp directories ipcsocket uses. Ref https://github.com/sbt/sbt/issues/6931 --- .../java/sbt/internal/BootServerSocket.java | 2 +- main/src/main/scala/sbt/internal/Load.scala | 6 ++-- .../src/main/scala/sbt/internal/SysProp.scala | 30 +++++++++++++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/main-command/src/main/java/sbt/internal/BootServerSocket.java b/main-command/src/main/java/sbt/internal/BootServerSocket.java index 5cf91dc50..a64c18951 100644 --- a/main-command/src/main/java/sbt/internal/BootServerSocket.java +++ b/main-command/src/main/java/sbt/internal/BootServerSocket.java @@ -310,7 +310,7 @@ public class BootServerSocket implements AutoCloseable { return "sbt-load" + hash; } else { final String alternativeSocketLocation = - System.getenv().getOrDefault("XDG_RUNTIME_DIR", "/tmp"); + System.getenv().getOrDefault("XDG_RUNTIME_DIR", System.getProperty("java.io.tmpdir")); final Path alternativeSocketLocationRoot = Paths.get(alternativeSocketLocation).resolve(".sbt"); final Path locationForSocket = alternativeSocketLocationRoot.resolve("sbt-socket" + hash); diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index 08965b0ce..834257634 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -101,10 +101,8 @@ private[sbt] object Load { val delegates = defaultDelegates val pluginMgmt = PluginManagement(loader) val inject = InjectSettings(injectGlobal(state), Nil, const(Nil)) - System.setProperty( - "swoval.tmpdir", - System.getProperty("swoval.tmpdir", globalBase.getAbsolutePath.toString) - ) + SysProp.setSwovalTempDir() + SysProp.setIpcSocketTempDir() LoadBuildConfiguration( stagingDirectory, classpath, diff --git a/main/src/main/scala/sbt/internal/SysProp.scala b/main/src/main/scala/sbt/internal/SysProp.scala index 737b0b368..ce5760edd 100644 --- a/main/src/main/scala/sbt/internal/SysProp.scala +++ b/main/src/main/scala/sbt/internal/SysProp.scala @@ -9,6 +9,7 @@ package sbt package internal import java.io.File +import java.nio.file.{ Path, Paths } import java.util.Locale import scala.util.control.NonFatal @@ -220,4 +221,33 @@ object SysProp { lazy val sbtCredentialsEnv: Option[Credentials] = sys.env.get("SBT_CREDENTIALS").map(raw => new FileCredentials(new File(raw))) + + private[sbt] def setSwovalTempDir(): Unit = { + val _ = getOrUpdateSwovalTmpDir( + runtimeDirectory.resolve("swoval").toString + ) + } + private[sbt] def setIpcSocketTempDir(): Unit = { + val _ = getOrUpdateIpcSocketTmpDir( + runtimeDirectory.resolve("ipcsocket").toString + ) + } + private[this] lazy val getOrUpdateSwovalTmpDir: String => String = + getOrUpdateSysProp("swoval.tmpdir")(_) + private[this] lazy val getOrUpdateIpcSocketTmpDir: String => String = + getOrUpdateSysProp("sbt.ipcsocket.tmpdir")(_) + private[this] def getOrUpdateSysProp(key: String)(value: String): String = { + val newVal = sys.props.getOrElse(key, value) + sys.props += (key -> newVal) + newVal + } + + /** + * This returns a temporary directory that is friendly to macOS, Linux, + * Windows, and Docker environment. + * Mostly these directories will be used as throw-away location to extract + * native files etc. + */ + private[this] def runtimeDirectory: Path = + Paths.get(sys.env.getOrElse("XDG_RUNTIME_DIR", sys.props("java.io.tmpdir"))).resolve(".sbt") }