diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala
index c39c30565..21c6cf6e2 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala
@@ -422,7 +422,7 @@ private[sbt] object IvySbt {
def toID(m: ModuleID) =
{
import m._
- ModuleRevisionId.newInstance(organization, name, revision, javaMap(extraAttributes))
+ ModuleRevisionId.newInstance(organization, name, branchName.orNull, revision, javaMap(extraAttributes))
}
private def substituteCross(m: ModuleSettings): ModuleSettings =
@@ -490,7 +490,8 @@ private[sbt] object IvySbt {
}
private[this] def defaultInfo(module: ModuleID): scala.xml.Elem = {
import module._
-
+ val base =
+ branchName.fold(base) { br => base % new scala.xml.UnprefixedAttribute("branch", br, scala.xml.Null) }
}
private[this] def addExtraAttributes(elem: scala.xml.Elem, extra: Map[String, String]): scala.xml.Elem =
(elem /: extra) { case (e, (key, value)) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) }
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala
index 8d646ee65..6f131f049 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala
@@ -298,6 +298,8 @@ object IvyActions {
private[this] def restrictedCopy(m: ModuleID, confs: Boolean) =
ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if (confs) m.configurations else None)
+ .branch(m.branchName)
+
private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) =
{
val resolveOptions = new ResolveOptions
@@ -365,7 +367,7 @@ object IvyActions {
{
val mextra = IvySbt.javaMap(mid.extraAttributes, true)
val aextra = IvySbt.extra(art, true)
- IvyPatternHelper.substitute(pattern, mid.organization, mid.name, mid.revision, art.name, art.`type`, art.extension, conf, mextra, aextra)
+ IvyPatternHelper.substitute(pattern, mid.organization, mid.name, mid.branchName.orNull, mid.revision, art.name, art.`type`, art.extension, conf, null, mextra, aextra)
}
import UpdateLogging.{ Quiet, Full, DownloadOnly, Default }
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala
index 765af3ab1..0432719d5 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala
@@ -154,6 +154,7 @@ object IvyRetrieve {
def toModuleID(revID: ModuleRevisionId): ModuleID =
ModuleID(revID.getOrganisation, revID.getName, revID.getRevision, extraAttributes = IvySbt.getExtraAttributes(revID))
+ .branch(nonEmptyString(revID.getBranch))
def toArtifact(art: IvyArtifact): Artifact =
{
diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala
index 26b85b0b7..a480c8ed3 100644
--- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala
+++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala
@@ -88,5 +88,5 @@ private[sbt] object ResolutionCache {
private val Name = "sbt-resolution-cache"
// use sbt-specific extra attributes so that resolved xml files do not get overwritten when using different Scala/sbt versions
- private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "[revision]/[artifact].[ext]"
+ private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "([branch]/)[revision]/[artifact].[ext]"
}
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala
index 46b63ce39..1da5a1e0a 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala
@@ -8,7 +8,7 @@ import java.net.URL
import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties
import sbt.serialization._
-final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) {
+final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled, branchName: Option[String] = None) {
override def toString: String =
organization + ":" + name + ":" + revision +
(configurations match { case Some(s) => ":" + s; case None => "" }) +
@@ -118,7 +118,15 @@ final case class ModuleID(organization: String, name: String, revision: String,
* as when adding a dependency on an artifact with a classifier.
*/
def jar() = artifacts(Artifact(name))
+
+ /**
+ * Sets the Ivy branch of this module.
+ */
+ def branch(branchName: String) = copy(branchName = Some(branchName))
+
+ def branch(branchName: Option[String]) = copy(branchName = branchName)
}
+
object ModuleID {
implicit val pickler: Pickler[ModuleID] with Unpickler[ModuleID] = PicklerUnpickler.generate[ModuleID]
diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala
index 6831a2520..62227ce18 100644
--- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala
+++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala
@@ -349,7 +349,7 @@ object Resolver {
def defaultPatterns = mavenStylePatterns
def mavenStyleBasePattern = "[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]"
- def localBasePattern = "[organisation]/[module]/" + PluginPattern + "[revision]/[type]s/[artifact](-[classifier]).[ext]"
+ def localBasePattern = "[organisation]/[module]/" + PluginPattern + "(/[branch])/[revision]/[type]s/[artifact](-[classifier]).[ext]"
def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]"
final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)"
private[this] def mavenLocalDir: File = {