Throw error if you run sbt from /

Fixes #1458

Running sbt from `/` results to sbt getting stuck trying to load the directories recursively, and eventually erroring with a java.lang.OutOfMemoryError (after freezing for a long time) even on an Alpine container.

To prevent it, this adds a check to see if the absolute path is `/` or not.

```
/ $ sbt -Dsbt.version=1.4.0-SNAPSHOT
[error] java.lang.IllegalStateException: cannot run sbt from root directory without -Dsbt.rootdir=true; see sbt/sbt#1458
[error] Use 'last' for the full log.
```
This commit is contained in:
Eugene Yokota 2019-09-21 18:28:16 -04:00
parent d07c2b4520
commit 563bcb93aa
2 changed files with 23 additions and 3 deletions

View File

@ -9,7 +9,7 @@ package sbt
import java.io.{ File, IOException }
import java.net.URI
import java.nio.file.{ FileAlreadyExistsException, Files }
import java.nio.file.{ FileAlreadyExistsException, Files, FileSystems }
import java.util.concurrent.ForkJoinPool
import java.util.concurrent.atomic.AtomicBoolean
import java.util.{ Locale, Properties }
@ -940,14 +940,33 @@ object BuiltinCommands {
state.remainingCommands exists (_.commandLine == TemplateCommand)
private def writeSbtVersion(state: State) =
if (SysProp.genBuildProps && !intendsToInvokeNew(state))
if (SysProp.genBuildProps && !intendsToInvokeNew(state)) {
writeSbtVersionUnconditionally(state)
}
private def checkRoot(state: State): Unit =
if (SysProp.allowRootDir) ()
else {
val baseDir = state.baseDir
import scala.collection.JavaConverters._
// this should return / on Unix and C:\ for Windows.
val rootOpt = FileSystems.getDefault.getRootDirectories.asScala.toList.headOption
rootOpt foreach { root =>
if (baseDir.getAbsolutePath == root.toString) {
throw new IllegalStateException(
"cannot run sbt from root directory without -Dsbt.rootdir=true; see sbt/sbt#1458"
)
}
}
}
private def WriteSbtVersion = "writeSbtVersion"
private def writeSbtVersion: Command =
Command.command(WriteSbtVersion) { state =>
writeSbtVersion(state); state
checkRoot(state)
writeSbtVersion(state)
state
}
private def intendsToInvokeCompile(state: State) =

View File

@ -69,6 +69,7 @@ object SysProp {
def traces: Boolean = getOrFalse("sbt.traces")
def client: Boolean = getOrFalse("sbt.client")
def ci: Boolean = getOrFalse("sbt.ci")
def allowRootDir: Boolean = getOrFalse("sbt.rootdir")
def watchMode: String =
sys.props.get("sbt.watch.mode").getOrElse("auto")