[2.0.x] fix: Use Path.userHome (#9866)

**Problem**
user.home can return "?"

**Solution**
This centralize to Path.userHome, which works around the JDK bug.
This commit is contained in:
eugene yokota
2026-10-05 13:59:13 -04:00
committed by Eugene Yokota
parent f1d9bae56e
commit 8be080a446
6 changed files with 18 additions and 13 deletions
@@ -9,10 +9,11 @@ package sbt
package internal
package librarymanagement
import java.io.File
import java.util.Locale
import scala.util.control.NonFatal
object LMSysProp {
object LMSysProp:
def booleanOpt(name: String): Option[Boolean] =
sys.props.get(name).flatMap { x =>
x.toLowerCase(Locale.ENGLISH) match {
@@ -63,4 +64,12 @@ object LMSysProp {
lazy val maxPublishAttempts: Int =
java.lang.Integer.getInteger("sbt.repository.publish.attempts", 3)
}
/**
* Ivy home directory: `sbt.ivy.home`, then `ivy.home`, else `user.home/.ivy2`.
*/
lazy val defaultIvyHome: File =
def prop(name: String): Option[String] = sys.props.get(name).map(_.trim).filter(_.nonEmpty)
prop("sbt.ivy.home").orElse(prop("ivy.home")) match
case Some(home) => File(home)
case None => File(sbt.io.Path.userHome, ".ivy2")
end LMSysProp
@@ -8,6 +8,7 @@ import coursier.core.*
import coursier.params.rule.Strict
import lmcoursier.FallbackDependency
import lmcoursier.definitions.ToCoursier
import sbt.internal.librarymanagement.LMSysProp
import coursier.util.Task
import scala.collection.mutable
@@ -114,7 +115,7 @@ object ResolutionParams {
val ivyHome = sys.props
.get("ivy.home")
.orElse(ivyHomeOpt.map(_.getAbsoluteFile.toURI.getPath))
.getOrElse(new File(sys.props("user.home")).toURI.getPath + ".ivy2")
.getOrElse(LMSysProp.defaultIvyHome.getAbsoluteFile.toURI.getPath)
val sbtIvyHome = sys.props.getOrElse(
"sbt.ivy.home",
@@ -61,7 +61,7 @@ object LMCoursier {
sys.env
.get("LOCALAPPDATA")
.map(absoluteFile)
.getOrElse(absoluteFile(sys.props("user.home")) / "AppData" / "Local")
.getOrElse(sbt.io.Path.userHome.getAbsoluteFile / "AppData" / "Local")
base / "Coursier" / "Cache" / "v1"
}
sys.props
@@ -202,7 +202,7 @@ object SysProp:
def secondaryIdleTimeoutSec: Long = long("sbt.server.secondaryIdleTimeout", 600L)
private def file(value: String): File = new File(value)
private def home: File = file(sys.props("user.home"))
private def home: File = sbt.io.Path.userHome
/**
* Default directory for global sbt config (plugins, settings). Respects XDG Base Directory
+1 -1
View File
@@ -12,7 +12,7 @@ object Dependencies {
sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version")
// sbt modules
val ioVersion = nightlyVersion.getOrElse("1.13.4")
val ioVersion = nightlyVersion.getOrElse("1.13.5")
val zincVersion = nightlyVersion.getOrElse("2.0.4")
private val sbtIO = "org.scala-sbt" %% "io" % ioVersion
@@ -11,7 +11,7 @@ package internal
package inc
import sbt.internal.inc.classpath.ClasspathUtil
import sbt.internal.librarymanagement.JsonUtil
import sbt.internal.librarymanagement.{ JsonUtil, LMSysProp }
import sbt.internal.util.{ BufferedLogger, FullLogger }
import sbt.io.IO
import sbt.librarymanagement.*
@@ -171,12 +171,7 @@ private[sbt] object ZincComponentCompiler {
new ZincCompilerBridgeProvider(None, manager, dependencyResolution, scalaJarsTarget)
private final val LocalIvy =
(sys.props.get("sbt.ivy.home") match {
case Some(home) =>
if (home.endsWith("/")) home
else home + "/"
case _ => s"$${user.home}/.ivy2/"
}) + "local/" + Resolver.localBasePattern
Resolver.resolvePattern(LMSysProp.defaultIvyHome.toString, "local/" + Resolver.localBasePattern)
final val LocalResolver: Resolver = {
val toUse = Vector(LocalIvy)