From 8e7dfb4b203e6d14924db0604e81429ca990f3b5 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 8 Feb 2018 09:08:13 +0000 Subject: [PATCH 1/4] Handle very long socket file paths on UNIX Fixes #3930 --- .../scala/sbt/internal/CommandExchange.scala | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index 69cb89477..cfc48c69a 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -9,6 +9,7 @@ package sbt package internal import java.io.IOException +import java.nio.file.Files import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.atomic._ import scala.collection.mutable.ListBuffer @@ -23,6 +24,7 @@ import BasicKeys.{ logLevel } import java.net.Socket +import org.scalasbt.ipcsocket.UnixDomainSocketLibrary import sjsonnew.JsonFormat import sjsonnew.shaded.scalajson.ast.unsafe._ import scala.concurrent.Await @@ -32,7 +34,7 @@ import sbt.io.syntax._ import sbt.io.{ Hash, IO } import sbt.internal.server._ import sbt.internal.langserver.{ LogMessageParams, MessageType } -import sbt.internal.util.{ StringEvent, ObjectEvent, MainAppender } +import sbt.internal.util.{ StringEvent, ObjectEvent, MainAppender, Util } import sbt.internal.util.codec.JValueFormats import sbt.protocol.{ EventMessage, ExecStatusEvent } import sbt.util.{ Level, Logger, LogExchange } @@ -140,7 +142,18 @@ private[sbt] final class CommandExchange { val portfile = s.baseDir / "project" / "target" / "active.json" val h = Hash.halfHashString(IO.toURI(portfile).toString) val tokenfile = BuildPaths.getGlobalBase(s) / "server" / h / "token.json" - val socketfile = BuildPaths.getGlobalBase(s) / "server" / h / "sock" + val socketfile = { + val socketfile = BuildPaths.getGlobalBase(s) / "server" / h / "sock" + connectionType match { + case ConnectionType.Local if !Util.isWindows => + val maxSocketLength = new UnixDomainSocketLibrary.SockaddrUn().sunPath.length - 1 + if (socketfile.absolutePath.length > maxSocketLength) + Files.createTempFile("sbt-server", ".sock").toFile // assuming this is short enough.. + else + socketfile + case _ => socketfile + } + } val pipeName = "sbt-server-" + h val connection = ServerConnection( connectionType, From 4e038c91ce93196efff6490e1c1182ba5e8ee9fe Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 12 Feb 2018 17:56:53 +0000 Subject: [PATCH 2/4] Introduce SBT_GLOBAL_SERVER_DIR env var to override too long paths --- .../scala/sbt/internal/server/Server.scala | 11 ++++++++-- .../scala/sbt/internal/CommandExchange.scala | 21 +++++-------------- 2 files changed, 14 insertions(+), 18 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 f45019fb5..05b86c48a 100644 --- a/main-command/src/main/scala/sbt/internal/server/Server.scala +++ b/main-command/src/main/scala/sbt/internal/server/Server.scala @@ -60,9 +60,16 @@ private[sbt] object Server { // Named pipe already has an exclusive lock. addServerError(new Win32NamedPipeServerSocket(pipeName)) case ConnectionType.Local => - tryClient(new UnixDomainSocket(socketfile.getAbsolutePath)) + val maxSocketLength = new UnixDomainSocketLibrary.SockaddrUn().sunPath.length - 1 + val path = socketfile.getAbsolutePath + if (path.length > maxSocketLength) + sys.error("socket file absolute path too long; " + + "either switch to another connection type " + + "or define a short \"SBT_GLOBAL_SERVER_DIR\" value. " + + s"Current path: ${path}") + tryClient(new UnixDomainSocket(path)) prepareSocketfile() - addServerError(new UnixDomainServerSocket(socketfile.getAbsolutePath)) + addServerError(new UnixDomainServerSocket(path)) case ConnectionType.Tcp => tryClient(new Socket(InetAddress.getByName(host), port)) addServerError(new ServerSocket(port, 50, InetAddress.getByName(host))) diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index cfc48c69a..873946340 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -9,7 +9,6 @@ package sbt package internal import java.io.IOException -import java.nio.file.Files import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.atomic._ import scala.collection.mutable.ListBuffer @@ -24,7 +23,6 @@ import BasicKeys.{ logLevel } import java.net.Socket -import org.scalasbt.ipcsocket.UnixDomainSocketLibrary import sjsonnew.JsonFormat import sjsonnew.shaded.scalajson.ast.unsafe._ import scala.concurrent.Await @@ -34,7 +32,7 @@ import sbt.io.syntax._ import sbt.io.{ Hash, IO } import sbt.internal.server._ import sbt.internal.langserver.{ LogMessageParams, MessageType } -import sbt.internal.util.{ StringEvent, ObjectEvent, MainAppender, Util } +import sbt.internal.util.{ StringEvent, ObjectEvent, MainAppender } import sbt.internal.util.codec.JValueFormats import sbt.protocol.{ EventMessage, ExecStatusEvent } import sbt.util.{ Level, Logger, LogExchange } @@ -141,19 +139,10 @@ private[sbt] final class CommandExchange { if (server.isEmpty && firstInstance.get) { val portfile = s.baseDir / "project" / "target" / "active.json" val h = Hash.halfHashString(IO.toURI(portfile).toString) - val tokenfile = BuildPaths.getGlobalBase(s) / "server" / h / "token.json" - val socketfile = { - val socketfile = BuildPaths.getGlobalBase(s) / "server" / h / "sock" - connectionType match { - case ConnectionType.Local if !Util.isWindows => - val maxSocketLength = new UnixDomainSocketLibrary.SockaddrUn().sunPath.length - 1 - if (socketfile.absolutePath.length > maxSocketLength) - Files.createTempFile("sbt-server", ".sock").toFile // assuming this is short enough.. - else - socketfile - case _ => socketfile - } - } + val serverDir = + sys.env get "SBT_GLOBAL_SERVER_DIR" map file getOrElse BuildPaths.getGlobalBase(s) / "server" + val tokenfile = serverDir / h / "token.json" + val socketfile = serverDir / h / "sock" val pipeName = "sbt-server-" + h val connection = ServerConnection( connectionType, From e8d1a304744ebe5602878a1d2b0310a162641d25 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 14 Feb 2018 10:53:37 +0000 Subject: [PATCH 3/4] Update mimaPreviousArtifacts/sbt.version --- build.sbt | 5 ++++- project/build.properties | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 59cf7394c..82fcd4ef6 100644 --- a/build.sbt +++ b/build.sbt @@ -77,7 +77,10 @@ def testedBaseSettings: Seq[Setting[_]] = val mimaSettings = Def settings ( mimaPreviousArtifacts := { - ((0 to 4).map(v => s"1.0.$v") ++ (0 to 0).map(v => s"1.1.$v")).map{ v => + Seq( + "1.0.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4", + "1.1.0", "1.1.1", + ).map { v => organization.value % moduleName.value % v cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) }.toSet } diff --git a/project/build.properties b/project/build.properties index 394cb75cf..31334bbd3 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.4 +sbt.version=1.1.1 From 20367938b180e5f76b7eb8dfeff6edc27d3d9d52 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 14 Feb 2018 14:38:25 +0000 Subject: [PATCH 4/4] version := "1.2.0-SNAPSHOT" --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 431491cb9..893c2c9f1 100644 --- a/build.sbt +++ b/build.sbt @@ -9,7 +9,7 @@ def buildLevelSettings: Seq[Setting[_]] = inThisBuild( Seq( organization := "org.scala-sbt", - version := "1.1.2-SNAPSHOT", + version := "1.2.0-SNAPSHOT", description := "sbt is an interactive build tool", bintrayOrganization := Some("sbt"), bintrayRepository := {