From 649b6dffc21ad4c7f875f655468c0ecedab310ac Mon Sep 17 00:00:00 2001 From: Sam Desborough Date: Fri, 28 Jun 2024 13:05:54 +0100 Subject: [PATCH] Preserve backslashes in `expandMavenSettings` We use `expandMavenSettings` to turn environment variable expressions in `settings.xml` into their actual values. Before this change, if an environment variable value contained backslashes, they would have been treated as escape characters by `Regex.replaceAllIn` and removed from the returned string. This caused an issue when using backslashes for Windows paths. --- .../sbt/librarymanagement/ResolverExtra.scala | 25 +++++++++++++------ .../librarymanagement/ResolverExtraTest.scala | 7 ++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index ca980b7e..cb0eebe8 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -3,13 +3,15 @@ */ package sbt.librarymanagement -import java.io.{ IOException, File } +import java.io.{ File, IOException } import java.net.{ URI, URL } import scala.annotation.nowarn import scala.xml.XML import org.xml.sax.SAXParseException import sbt.util.Logger + import java.net.URI +import scala.util.matching.Regex final class RawRepository(val resolver: AnyRef, name: String) extends Resolver(name) { override def toString = "Raw(" + resolver.toString + ")" @@ -400,20 +402,29 @@ private[librarymanagement] abstract class ResolverFunctions { def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" - private[librarymanagement] def expandMavenSettings(str: String): String = { + + private[librarymanagement] def expandMavenSettings( + str: String, + envVars: Map[String, String] = sys.env, + props: Map[String, String] = sys.props.toMap + ): String = { // Aren't regular expressions beautifully clear and concise. // This means "find all ${...}" blocks, with the first group of each being the text between curly brackets. - val findQuoted = "\\$\\{([^\\}]*)\\}".r + val findQuoted = "\\$\\{([^}]*)}".r val env = "env\\.(.*)".r findQuoted.replaceAllIn( str, - _.group(1) match { - case env(variable) => sys.env.getOrElse(variable, "") - case property => sys.props.getOrElse(property, "") - } + regexMatch => + Regex.quoteReplacement { + regexMatch.group(1) match { + case env(variable) => envVars.getOrElse(variable, "") + case property => props.getOrElse(property, "") + } + } ) } + private[this] def mavenLocalDir: File = { def loadHomeFromSettings(f: () => File): Option[File] = try { diff --git a/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala index 10cad901..e1a06a94 100644 --- a/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala @@ -33,6 +33,13 @@ object ResolverExtraTest extends BasicTestSuite { ) } + test("expandMavenSettings should preserve backslashes in environment variable values") { + val path = """C:\foo\bar\baz""" + val env = Map("SOME_PATH" -> path) + + assert(Resolver.expandMavenSettings("${env.SOME_PATH}", env) == path) + } + // - Helper functions ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------- def assertExpansion(input: String, expected: String) =