From c31e0b6b550b9da9f98d3a8289283df9ade11323 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 11 Jul 2019 14:15:33 -0400 Subject: [PATCH 1/2] add allCredentials to emulate credential registration Fixes #4802 For Ivy integration sbt uses credential task in a peculiar way. https://github.com/sbt/sbt/blob/9fa25de84cf6fb521aa5f161c866837200ec17c4/main/src/main/scala/sbt/Defaults.scala#L2271-L2275 This lets the build user put `credential` task in various places, like metabuild or root project, but they would all act as if they were scoped globally. This PR adds `allCredentials` task to emulate the behavior to pass credentials into lm-coursier. --- main/src/main/scala/sbt/Defaults.scala | 1 + main/src/main/scala/sbt/Keys.scala | 1 + .../sbt/coursierint/CoursierInputsTasks.scala | 2 +- .../scala/sbt/coursierint/LMCoursier.scala | 18 ++++++++++++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index d103829ae..2bc1c71ff 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2364,6 +2364,7 @@ object Classpaths { ), ivySbt := ivySbt0.value, ivyModule := { val is = ivySbt.value; new is.Module(moduleSettings.value) }, + allCredentials := LMCoursier.allCredentialsTask.value, transitiveUpdate := transitiveUpdateTask.value, updateCacheName := { val binVersion = scalaBinaryVersion.value diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index b50013d8c..a7bea565c 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -376,6 +376,7 @@ object Keys { val packagedArtifacts = taskKey[Map[Artifact, File]]("Packages all artifacts for publishing and maps the Artifact definition to the generated file.").withRank(CTask) val publishMavenStyle = settingKey[Boolean]("Configures whether to generate and publish a pom (true) or Ivy file (false).").withRank(BSetting) val credentials = taskKey[Seq[Credentials]]("The credentials to use for updating and publishing.").withRank(BMinusTask) + val allCredentials = taskKey[Seq[Credentials]]("Aggregated credentials.").withRank(DTask) val makePom = taskKey[File]("Generates a pom for publishing when publishing Maven-style.").withRank(BPlusTask) val deliver = taskKey[File]("Generates the Ivy file for publishing to a repository.").withRank(BTask) diff --git a/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala b/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala index 4836e1335..655eff843 100644 --- a/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala +++ b/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala @@ -204,7 +204,7 @@ object CoursierInputsTasks { val credentialsTask = Def.task { val log = streams.value.log - val creds = sbt.Keys.credentials.value + val creds = sbt.Keys.allCredentials.value .flatMap { case dc: IvyDirectCredentials => List(dc) case fc: FileCredentials => diff --git a/main/src/main/scala/sbt/coursierint/LMCoursier.scala b/main/src/main/scala/sbt/coursierint/LMCoursier.scala index f84a19afa..c8fbd71ca 100644 --- a/main/src/main/scala/sbt/coursierint/LMCoursier.scala +++ b/main/src/main/scala/sbt/coursierint/LMCoursier.scala @@ -9,6 +9,7 @@ package sbt package coursierint import java.io.File +import scala.collection.mutable import lmcoursier.definitions.{ Classifier, Configuration => CConfiguration, @@ -19,11 +20,15 @@ import lmcoursier._ import lmcoursier.credentials.Credentials import Keys._ import sbt.librarymanagement._ +import sbt.librarymanagement.ivy.{ Credentials => IvyCredentials } import sbt.util.Logger import sbt.io.syntax._ import xsbti.AppConfiguration object LMCoursier { + private[sbt] val credentialRegistry: mutable.Map[(String, String), IvyCredentials] = + mutable.Map.empty + def defaultCacheLocation: File = sys.props.get("sbt.coursier.home") match { case Some(home) => new File(home).getAbsoluteFile / "cache" @@ -188,4 +193,17 @@ object LMCoursier { def publicationsSetting(packageConfigs: Seq[(Configuration, CConfiguration)]): Def.Setting[_] = { csrPublications := CoursierArtifactsTasks.coursierPublicationsTask(packageConfigs: _*).value } + + private[sbt] def registerCredentials(creds: IvyCredentials): Unit = { + val d = IvyCredentials.toDirect(creds) + credentialRegistry((d.host, d.realm)) = d + } + + // This emulates Ivy's credential registration which basically keeps mutating global registry + def allCredentialsTask: Def.Initialize[Task[Seq[IvyCredentials]]] = Def.task { + (Keys.credentials in ThisBuild).value foreach registerCredentials + (Keys.credentials in LocalRootProject).value foreach registerCredentials + Keys.credentials.value foreach registerCredentials + credentialRegistry.values.toVector + } } From 9755234a1618ba5024baa2c424f016af8ccd5882 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 12 Jul 2019 10:52:02 -0400 Subject: [PATCH 2/2] address review --- main/src/main/scala/sbt/Keys.scala | 2 +- main/src/main/scala/sbt/coursierint/LMCoursier.scala | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index a7bea565c..242b75579 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -376,7 +376,7 @@ object Keys { val packagedArtifacts = taskKey[Map[Artifact, File]]("Packages all artifacts for publishing and maps the Artifact definition to the generated file.").withRank(CTask) val publishMavenStyle = settingKey[Boolean]("Configures whether to generate and publish a pom (true) or Ivy file (false).").withRank(BSetting) val credentials = taskKey[Seq[Credentials]]("The credentials to use for updating and publishing.").withRank(BMinusTask) - val allCredentials = taskKey[Seq[Credentials]]("Aggregated credentials.").withRank(DTask) + val allCredentials = taskKey[Seq[Credentials]]("Aggregated credentials across current and root subprojects. Do not rewire this task.").withRank(DTask) val makePom = taskKey[File]("Generates a pom for publishing when publishing Maven-style.").withRank(BPlusTask) val deliver = taskKey[File]("Generates the Ivy file for publishing to a repository.").withRank(BTask) diff --git a/main/src/main/scala/sbt/coursierint/LMCoursier.scala b/main/src/main/scala/sbt/coursierint/LMCoursier.scala index c8fbd71ca..11c9badb3 100644 --- a/main/src/main/scala/sbt/coursierint/LMCoursier.scala +++ b/main/src/main/scala/sbt/coursierint/LMCoursier.scala @@ -9,7 +9,7 @@ package sbt package coursierint import java.io.File -import scala.collection.mutable +import java.util.concurrent.ConcurrentHashMap import lmcoursier.definitions.{ Classifier, Configuration => CConfiguration, @@ -26,8 +26,8 @@ import sbt.io.syntax._ import xsbti.AppConfiguration object LMCoursier { - private[sbt] val credentialRegistry: mutable.Map[(String, String), IvyCredentials] = - mutable.Map.empty + private[this] val credentialRegistry: ConcurrentHashMap[(String, String), IvyCredentials] = + new ConcurrentHashMap def defaultCacheLocation: File = sys.props.get("sbt.coursier.home") match { @@ -196,14 +196,16 @@ object LMCoursier { private[sbt] def registerCredentials(creds: IvyCredentials): Unit = { val d = IvyCredentials.toDirect(creds) - credentialRegistry((d.host, d.realm)) = d + credentialRegistry.put((d.host, d.realm), d) + () } // This emulates Ivy's credential registration which basically keeps mutating global registry def allCredentialsTask: Def.Initialize[Task[Seq[IvyCredentials]]] = Def.task { + import scala.collection.JavaConverters._ (Keys.credentials in ThisBuild).value foreach registerCredentials (Keys.credentials in LocalRootProject).value foreach registerCredentials Keys.credentials.value foreach registerCredentials - credentialRegistry.values.toVector + credentialRegistry.values.asScala.toVector } }