mirror of https://github.com/sbt/sbt.git
Add support for HTTP authentication in SBT plugin
This commit is contained in:
parent
265d79b156
commit
0ccabd0820
|
|
@ -19,6 +19,7 @@ object CoursierPlugin extends AutoPlugin {
|
|||
val coursierSourceRepositories = Keys.coursierSourceRepositories
|
||||
val coursierResolvers = Keys.coursierResolvers
|
||||
val coursierSbtResolvers = Keys.coursierSbtResolvers
|
||||
val coursierCredentials = Keys.coursierCredentials
|
||||
val coursierFallbackDependencies = Keys.coursierFallbackDependencies
|
||||
val coursierCache = Keys.coursierCache
|
||||
val coursierProject = Keys.coursierProject
|
||||
|
|
@ -61,6 +62,7 @@ object CoursierPlugin extends AutoPlugin {
|
|||
coursierSourceRepositories := Nil,
|
||||
coursierResolvers <<= Tasks.coursierResolversTask,
|
||||
coursierSbtResolvers <<= externalResolvers in updateSbtClassifiers,
|
||||
coursierCredentials := Map.empty,
|
||||
coursierFallbackDependencies <<= Tasks.coursierFallbackDependenciesTask,
|
||||
coursierCache := Cache.default,
|
||||
update <<= Tasks.updateTask(withClassifiers = false),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package coursier
|
||||
|
||||
import java.io.{File, FileInputStream}
|
||||
import java.util.Properties
|
||||
|
||||
import coursier.core.Authentication
|
||||
|
||||
sealed abstract class Credentials extends Product with Serializable {
|
||||
def user: String
|
||||
def password: String
|
||||
|
||||
def authentication: Authentication =
|
||||
Authentication(user, password)
|
||||
}
|
||||
|
||||
object Credentials {
|
||||
|
||||
case class Direct(user: String, password: String) extends Credentials {
|
||||
override def toString = s"Direct($user, ******)"
|
||||
}
|
||||
|
||||
case class FromFile(file: File) extends Credentials {
|
||||
|
||||
private lazy val props = {
|
||||
val p = new Properties()
|
||||
p.load(new FileInputStream(file))
|
||||
p
|
||||
}
|
||||
|
||||
private def findKey(keys: Seq[String]) = keys
|
||||
.iterator
|
||||
.map(props.getProperty)
|
||||
.filter(_ != null)
|
||||
.toStream
|
||||
.headOption
|
||||
.getOrElse {
|
||||
throw new NoSuchElementException(s"${keys.head} key in $file")
|
||||
}
|
||||
|
||||
lazy val user: String = findKey(FromFile.fileUserKeys)
|
||||
lazy val password: String = findKey(FromFile.filePasswordKeys)
|
||||
}
|
||||
|
||||
object FromFile {
|
||||
// from sbt.Credentials
|
||||
private val fileUserKeys = Seq("user", "user.name", "username")
|
||||
private val filePasswordKeys = Seq("password", "pwd", "pass", "passwd")
|
||||
}
|
||||
|
||||
|
||||
def apply(user: String, password: String): Credentials =
|
||||
Direct(user, password)
|
||||
|
||||
def apply(file: File): Credentials =
|
||||
FromFile(file)
|
||||
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import coursier.ivy.{ IvyXml, IvyRepository }
|
|||
|
||||
import java.net.{ MalformedURLException, URL }
|
||||
|
||||
import coursier.core.Authentication
|
||||
import sbt.{ Resolver, CrossVersion, ModuleID }
|
||||
import sbt.mavenint.SbtPomExtraProperties
|
||||
|
||||
|
|
@ -145,11 +146,21 @@ object FromSbt {
|
|||
} else
|
||||
None
|
||||
|
||||
private def mavenRepositoryOpt(root: String, log: sbt.Logger): Option[MavenRepository] =
|
||||
private def mavenRepositoryOpt(
|
||||
root: String,
|
||||
log: sbt.Logger,
|
||||
authentication: Option[Authentication]
|
||||
): Option[MavenRepository] =
|
||||
try {
|
||||
Cache.url(root) // ensure root is a URL whose protocol can be handled here
|
||||
val root0 = if (root.endsWith("/")) root else root + "/"
|
||||
Some(MavenRepository(root0, sbtAttrStub = true))
|
||||
Some(
|
||||
MavenRepository(
|
||||
root0,
|
||||
sbtAttrStub = true,
|
||||
authentication = authentication
|
||||
)
|
||||
)
|
||||
} catch {
|
||||
case e: MalformedURLException =>
|
||||
log.warn(
|
||||
|
|
@ -165,11 +176,12 @@ object FromSbt {
|
|||
def repository(
|
||||
resolver: Resolver,
|
||||
ivyProperties: Map[String, String],
|
||||
log: sbt.Logger
|
||||
log: sbt.Logger,
|
||||
authentication: Option[Authentication]
|
||||
): Option[Repository] =
|
||||
resolver match {
|
||||
case sbt.MavenRepository(_, root) =>
|
||||
mavenRepositoryOpt(root, log)
|
||||
mavenRepositoryOpt(root, log, authentication)
|
||||
|
||||
case sbt.FileRepository(_, _, patterns)
|
||||
if patterns.ivyPatterns.lengthCompare(1) == 0 &&
|
||||
|
|
@ -184,10 +196,11 @@ object FromSbt {
|
|||
metadataPatternOpt = Some("file://" + patterns.ivyPatterns.head),
|
||||
changing = Some(true),
|
||||
properties = ivyProperties,
|
||||
dropInfoAttributes = true
|
||||
dropInfoAttributes = true,
|
||||
authentication = authentication
|
||||
))
|
||||
case Some(mavenCompatibleBase) =>
|
||||
mavenRepositoryOpt("file://" + mavenCompatibleBase, log)
|
||||
mavenRepositoryOpt("file://" + mavenCompatibleBase, log, authentication)
|
||||
}
|
||||
|
||||
case sbt.URLRepository(_, patterns)
|
||||
|
|
@ -203,10 +216,11 @@ object FromSbt {
|
|||
metadataPatternOpt = Some(patterns.ivyPatterns.head),
|
||||
changing = None,
|
||||
properties = ivyProperties,
|
||||
dropInfoAttributes = true
|
||||
dropInfoAttributes = true,
|
||||
authentication = authentication
|
||||
))
|
||||
case Some(mavenCompatibleBase) =>
|
||||
mavenRepositoryOpt(mavenCompatibleBase, log)
|
||||
mavenRepositoryOpt(mavenCompatibleBase, log, authentication)
|
||||
}
|
||||
|
||||
case other =>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ object Keys {
|
|||
val coursierSourceRepositories = SettingKey[Seq[File]]("coursier-source-repositories")
|
||||
val coursierResolvers = TaskKey[Seq[Resolver]]("coursier-resolvers")
|
||||
val coursierSbtResolvers = TaskKey[Seq[Resolver]]("coursier-sbt-resolvers")
|
||||
val coursierCredentials = TaskKey[Map[String, Credentials]]("coursier-credentials")
|
||||
|
||||
val coursierCache = SettingKey[File]("coursier-cache")
|
||||
|
||||
|
|
|
|||
|
|
@ -371,6 +371,8 @@ object Tasks {
|
|||
"ivy.home" -> (new File(sys.props("user.home")).toURI.getPath + ".ivy2")
|
||||
) ++ sys.props
|
||||
|
||||
val credentials = coursierCredentials.value
|
||||
|
||||
val sourceRepositories0 = sourceRepositories.map {
|
||||
base =>
|
||||
MavenRepository(base.toURI.toString, changing = Some(true))
|
||||
|
|
@ -393,7 +395,14 @@ object Tasks {
|
|||
val repositories =
|
||||
Seq(globalPluginsRepo, interProjectRepo) ++
|
||||
sourceRepositories0 ++
|
||||
resolvers.flatMap(FromSbt.repository(_, ivyProperties, log)) ++
|
||||
resolvers.flatMap { resolver =>
|
||||
FromSbt.repository(
|
||||
resolver,
|
||||
ivyProperties,
|
||||
log,
|
||||
credentials.get(resolver.name).map(_.authentication)
|
||||
)
|
||||
} ++
|
||||
fallbackDependenciesRepositories
|
||||
|
||||
def resolution = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
scalaVersion := "2.11.8"
|
||||
|
||||
resolvers += "authenticated" at "http://localhost:8080"
|
||||
|
||||
coursierCredentials += "authenticated" -> coursier.Credentials(file("credentials"))
|
||||
|
||||
coursierCachePolicies := Seq(coursier.CachePolicy.ForceDownload)
|
||||
|
||||
libraryDependencies += "com.abc" % "test" % "0.1"
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
user=user
|
||||
password=pass
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
val pluginVersion = sys.props.getOrElse(
|
||||
"plugin.version",
|
||||
throw new RuntimeException(
|
||||
"""|The system property 'plugin.version' is not defined.
|
||||
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
|
||||
)
|
||||
)
|
||||
|
||||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % pluginVersion)
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
object Main extends App
|
||||
|
|
@ -0,0 +1 @@
|
|||
> coursierResolution
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
scalaVersion := "2.11.8"
|
||||
|
||||
resolvers += "authenticated" at "http://localhost:8080"
|
||||
|
||||
coursierCredentials += "authenticated" -> coursier.Credentials("user", "pass")
|
||||
|
||||
coursierCachePolicies := Seq(coursier.CachePolicy.ForceDownload)
|
||||
|
||||
libraryDependencies += "com.abc" % "test" % "0.1"
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
val pluginVersion = sys.props.getOrElse(
|
||||
"plugin.version",
|
||||
throw new RuntimeException(
|
||||
"""|The system property 'plugin.version' is not defined.
|
||||
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
|
||||
)
|
||||
)
|
||||
|
||||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % pluginVersion)
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
object Main extends App
|
||||
|
|
@ -0,0 +1 @@
|
|||
> coursierResolution
|
||||
Loading…
Reference in New Issue