mirror of https://github.com/sbt/sbt.git
Merge pull request #571 from coursier/topic/sbt-pgp-coursier
Add sbt-pgp-coursier plugin
This commit is contained in:
commit
f6493a2d5a
16
build.sbt
16
build.sbt
|
|
@ -188,6 +188,19 @@ lazy val `sbt-coursier` = project
|
||||||
.dependsOn(coreJvm, cache, extra)
|
.dependsOn(coreJvm, cache, extra)
|
||||||
.settings(plugin)
|
.settings(plugin)
|
||||||
|
|
||||||
|
lazy val `sbt-pgp-coursier` = project
|
||||||
|
.dependsOn(`sbt-coursier`)
|
||||||
|
.settings(
|
||||||
|
plugin,
|
||||||
|
libs ++= {
|
||||||
|
scalaBinaryVersion.value match {
|
||||||
|
case "2.10" | "2.12" =>
|
||||||
|
Seq(Deps.sbtPgp.value)
|
||||||
|
case _ => Nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
lazy val `sbt-shading` = project
|
lazy val `sbt-shading` = project
|
||||||
.enablePlugins(ShadingPlugin)
|
.enablePlugins(ShadingPlugin)
|
||||||
.dependsOn(`sbt-coursier`)
|
.dependsOn(`sbt-coursier`)
|
||||||
|
|
@ -258,6 +271,7 @@ lazy val jvm = project
|
||||||
extra,
|
extra,
|
||||||
cli,
|
cli,
|
||||||
`sbt-coursier`,
|
`sbt-coursier`,
|
||||||
|
`sbt-pgp-coursier`,
|
||||||
`sbt-shading`,
|
`sbt-shading`,
|
||||||
`sbt-launcher`,
|
`sbt-launcher`,
|
||||||
doc,
|
doc,
|
||||||
|
|
@ -293,6 +307,7 @@ lazy val `sbt-plugins` = project
|
||||||
cache,
|
cache,
|
||||||
extra,
|
extra,
|
||||||
`sbt-coursier`,
|
`sbt-coursier`,
|
||||||
|
`sbt-pgp-coursier`,
|
||||||
`sbt-shading`
|
`sbt-shading`
|
||||||
)
|
)
|
||||||
.settings(
|
.settings(
|
||||||
|
|
@ -314,6 +329,7 @@ lazy val coursier = project
|
||||||
extra,
|
extra,
|
||||||
cli,
|
cli,
|
||||||
`sbt-coursier`,
|
`sbt-coursier`,
|
||||||
|
`sbt-pgp-coursier`,
|
||||||
`sbt-shading`,
|
`sbt-shading`,
|
||||||
`sbt-launcher`,
|
`sbt-launcher`,
|
||||||
web,
|
web,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
import sbt._
|
import sbt._
|
||||||
|
import sbt.Defaults.sbtPluginExtra
|
||||||
import sbt.Keys._
|
import sbt.Keys._
|
||||||
|
|
||||||
object Deps {
|
object Deps {
|
||||||
|
|
@ -19,6 +20,17 @@ object Deps {
|
||||||
def typesafeConfig = "com.typesafe" % "config" % "1.3.1"
|
def typesafeConfig = "com.typesafe" % "config" % "1.3.1"
|
||||||
def argonautShapeless = "com.github.alexarchambault" %% "argonaut-shapeless_6.2" % "1.2.0-M5"
|
def argonautShapeless = "com.github.alexarchambault" %% "argonaut-shapeless_6.2" % "1.2.0-M5"
|
||||||
|
|
||||||
|
def sbtPgp = Def.setting {
|
||||||
|
val sbtv = CrossVersion.binarySbtVersion(sbtVersion.value)
|
||||||
|
val sv = scalaBinaryVersion.value
|
||||||
|
val ver = sv match {
|
||||||
|
case "2.10" => "1.0.1"
|
||||||
|
case "2.12" => "1.1.0-M1"
|
||||||
|
case _ => "foo" // unused
|
||||||
|
}
|
||||||
|
sbtPluginExtra("com.jsuereth" % "sbt-pgp" % ver, sbtv, sv)
|
||||||
|
}
|
||||||
|
|
||||||
def scalaAsync = Def.setting {
|
def scalaAsync = Def.setting {
|
||||||
|
|
||||||
val version =
|
val version =
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ object CoursierPlugin extends AutoPlugin {
|
||||||
val coursierDependencyInverseTree = Keys.coursierDependencyInverseTree
|
val coursierDependencyInverseTree = Keys.coursierDependencyInverseTree
|
||||||
|
|
||||||
val coursierArtifacts = Keys.coursierArtifacts
|
val coursierArtifacts = Keys.coursierArtifacts
|
||||||
|
val coursierSignedArtifacts = Keys.coursierSignedArtifacts
|
||||||
val coursierClassifiersArtifacts = Keys.coursierClassifiersArtifacts
|
val coursierClassifiersArtifacts = Keys.coursierClassifiersArtifacts
|
||||||
val coursierSbtClassifiersArtifacts = Keys.coursierSbtClassifiersArtifacts
|
val coursierSbtClassifiersArtifacts = Keys.coursierSbtClassifiersArtifacts
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +98,7 @@ object CoursierPlugin extends AutoPlugin {
|
||||||
coursierFallbackDependencies := Tasks.coursierFallbackDependenciesTask.value,
|
coursierFallbackDependencies := Tasks.coursierFallbackDependenciesTask.value,
|
||||||
coursierCache := Cache.default,
|
coursierCache := Cache.default,
|
||||||
coursierArtifacts := Tasks.artifactFilesOrErrors(withClassifiers = false).value,
|
coursierArtifacts := Tasks.artifactFilesOrErrors(withClassifiers = false).value,
|
||||||
|
coursierSignedArtifacts := Tasks.artifactFilesOrErrors(withClassifiers = false, includeSignatures = true).value,
|
||||||
coursierClassifiersArtifacts := Tasks.artifactFilesOrErrors(
|
coursierClassifiersArtifacts := Tasks.artifactFilesOrErrors(
|
||||||
withClassifiers = true
|
withClassifiers = true
|
||||||
).value,
|
).value,
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ object Keys {
|
||||||
)
|
)
|
||||||
|
|
||||||
val coursierArtifacts = TaskKey[Map[Artifact, FileError \/ File]]("coursier-artifacts")
|
val coursierArtifacts = TaskKey[Map[Artifact, FileError \/ File]]("coursier-artifacts")
|
||||||
|
val coursierSignedArtifacts = TaskKey[Map[Artifact, FileError \/ File]]("coursier-signed-artifacts")
|
||||||
val coursierClassifiersArtifacts = TaskKey[Map[Artifact, FileError \/ File]]("coursier-classifiers-artifacts")
|
val coursierClassifiersArtifacts = TaskKey[Map[Artifact, FileError \/ File]]("coursier-classifiers-artifacts")
|
||||||
val coursierSbtClassifiersArtifacts = TaskKey[Map[Artifact, FileError \/ File]]("coursier-sbt-classifiers-artifacts")
|
val coursierSbtClassifiersArtifacts = TaskKey[Map[Artifact, FileError \/ File]]("coursier-sbt-classifiers-artifacts")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -840,7 +840,8 @@ object Tasks {
|
||||||
def artifactFilesOrErrors(
|
def artifactFilesOrErrors(
|
||||||
withClassifiers: Boolean,
|
withClassifiers: Boolean,
|
||||||
sbtClassifiers: Boolean = false,
|
sbtClassifiers: Boolean = false,
|
||||||
ignoreArtifactErrors: Boolean = false
|
ignoreArtifactErrors: Boolean = false,
|
||||||
|
includeSignatures: Boolean = false
|
||||||
) = Def.task {
|
) = Def.task {
|
||||||
|
|
||||||
// let's update only one module at once, for a better output
|
// let's update only one module at once, for a better output
|
||||||
|
|
@ -878,12 +879,21 @@ object Tasks {
|
||||||
else
|
else
|
||||||
None
|
None
|
||||||
|
|
||||||
val allArtifacts =
|
val allArtifacts0 =
|
||||||
classifiers match {
|
classifiers match {
|
||||||
case None => res.flatMap(_.artifacts)
|
case None => res.flatMap(_.artifacts)
|
||||||
case Some(cl) => res.flatMap(_.classifiersArtifacts(cl))
|
case Some(cl) => res.flatMap(_.classifiersArtifacts(cl))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val allArtifacts =
|
||||||
|
if (includeSignatures)
|
||||||
|
allArtifacts0.flatMap { a =>
|
||||||
|
val sigOpt = a.extra.get("sig").map(_.copy(attributes = Attributes()))
|
||||||
|
Seq(a) ++ sigOpt.toSeq
|
||||||
|
}
|
||||||
|
else
|
||||||
|
allArtifacts0
|
||||||
|
|
||||||
var pool: ExecutorService = null
|
var pool: ExecutorService = null
|
||||||
var artifactsLogger: TermDisplay = null
|
var artifactsLogger: TermDisplay = null
|
||||||
|
|
||||||
|
|
@ -1022,7 +1032,8 @@ object Tasks {
|
||||||
shadedConfigOpt: Option[(String, String)],
|
shadedConfigOpt: Option[(String, String)],
|
||||||
withClassifiers: Boolean,
|
withClassifiers: Boolean,
|
||||||
sbtClassifiers: Boolean = false,
|
sbtClassifiers: Boolean = false,
|
||||||
ignoreArtifactErrors: Boolean = false
|
ignoreArtifactErrors: Boolean = false,
|
||||||
|
includeSignatures: Boolean = false
|
||||||
) = Def.task {
|
) = Def.task {
|
||||||
|
|
||||||
def grouped[K, V](map: Seq[(K, V)])(mapKey: K => K): Map[K, Seq[V]] =
|
def grouped[K, V](map: Seq[(K, V)])(mapKey: K => K): Map[K, Seq[V]] =
|
||||||
|
|
@ -1134,7 +1145,9 @@ object Tasks {
|
||||||
Keys.coursierSbtClassifiersArtifacts
|
Keys.coursierSbtClassifiersArtifacts
|
||||||
else
|
else
|
||||||
Keys.coursierClassifiersArtifacts
|
Keys.coursierClassifiersArtifacts
|
||||||
} else
|
} else if (includeSignatures)
|
||||||
|
Keys.coursierSignedArtifacts
|
||||||
|
else
|
||||||
Keys.coursierArtifacts
|
Keys.coursierArtifacts
|
||||||
).value
|
).value
|
||||||
|
|
||||||
|
|
@ -1178,7 +1191,9 @@ object Tasks {
|
||||||
_,
|
_,
|
||||||
_,
|
_,
|
||||||
_
|
_
|
||||||
)
|
),
|
||||||
|
log,
|
||||||
|
includeSignatures = includeSignatures
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,22 +116,42 @@ object ToSbt {
|
||||||
res: Resolution,
|
res: Resolution,
|
||||||
classifiersOpt: Option[Seq[String]],
|
classifiersOpt: Option[Seq[String]],
|
||||||
artifactFileOpt: (Module, String, Artifact) => Option[File],
|
artifactFileOpt: (Module, String, Artifact) => Option[File],
|
||||||
keepPomArtifact: Boolean = false
|
log: sbt.Logger,
|
||||||
|
keepPomArtifact: Boolean = false,
|
||||||
|
includeSignatures: Boolean = false
|
||||||
) = {
|
) = {
|
||||||
val depArtifacts0 =
|
val depArtifacts1 =
|
||||||
classifiersOpt match {
|
classifiersOpt match {
|
||||||
case None => res.dependencyArtifacts
|
case None => res.dependencyArtifacts
|
||||||
case Some(cl) => res.dependencyClassifiersArtifacts(cl)
|
case Some(cl) => res.dependencyClassifiersArtifacts(cl)
|
||||||
}
|
}
|
||||||
|
|
||||||
val depArtifacts =
|
val depArtifacts0 =
|
||||||
if (keepPomArtifact)
|
if (keepPomArtifact)
|
||||||
depArtifacts0
|
depArtifacts1
|
||||||
else
|
else
|
||||||
depArtifacts0.filter {
|
depArtifacts1.filter {
|
||||||
case (_, a) => a.attributes != Attributes("pom", "")
|
case (_, a) => a.attributes != Attributes("pom", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val depArtifacts =
|
||||||
|
if (includeSignatures) {
|
||||||
|
|
||||||
|
val notFound = depArtifacts0.filter(!_._2.extra.contains("sig"))
|
||||||
|
|
||||||
|
if (notFound.isEmpty)
|
||||||
|
depArtifacts0.flatMap {
|
||||||
|
case (dep, a) =>
|
||||||
|
Seq(dep -> a) ++ a.extra.get("sig").toSeq.map(dep -> _)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for ((_, a) <- notFound)
|
||||||
|
log.error(s"No signature found for ${a.url}")
|
||||||
|
sys.error(s"${notFound.length} signature(s) not found")
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
depArtifacts0
|
||||||
|
|
||||||
val groupedDepArtifacts = grouped(depArtifacts)
|
val groupedDepArtifacts = grouped(depArtifacts)
|
||||||
|
|
||||||
val versions = res.dependencies.toVector.map { dep =>
|
val versions = res.dependencies.toVector.map { dep =>
|
||||||
|
|
@ -184,7 +204,9 @@ object ToSbt {
|
||||||
configs: Map[String, Set[String]],
|
configs: Map[String, Set[String]],
|
||||||
classifiersOpt: Option[Seq[String]],
|
classifiersOpt: Option[Seq[String]],
|
||||||
artifactFileOpt: (Module, String, Artifact) => Option[File],
|
artifactFileOpt: (Module, String, Artifact) => Option[File],
|
||||||
keepPomArtifact: Boolean = false
|
log: sbt.Logger,
|
||||||
|
keepPomArtifact: Boolean = false,
|
||||||
|
includeSignatures: Boolean = false
|
||||||
): sbt.UpdateReport = {
|
): sbt.UpdateReport = {
|
||||||
|
|
||||||
val configReports = configs.map {
|
val configReports = configs.map {
|
||||||
|
|
@ -192,7 +214,14 @@ object ToSbt {
|
||||||
val configDeps = extends0.flatMap(configDependencies.getOrElse(_, Nil))
|
val configDeps = extends0.flatMap(configDependencies.getOrElse(_, Nil))
|
||||||
val subRes = resolutions(config).subset(configDeps)
|
val subRes = resolutions(config).subset(configDeps)
|
||||||
|
|
||||||
val reports = ToSbt.moduleReports(subRes, classifiersOpt, artifactFileOpt, keepPomArtifact)
|
val reports = ToSbt.moduleReports(
|
||||||
|
subRes,
|
||||||
|
classifiersOpt,
|
||||||
|
artifactFileOpt,
|
||||||
|
log,
|
||||||
|
keepPomArtifact = keepPomArtifact,
|
||||||
|
includeSignatures = includeSignatures
|
||||||
|
)
|
||||||
|
|
||||||
ConfigurationReport(
|
ConfigurationReport(
|
||||||
config,
|
config,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package coursier
|
||||||
|
|
||||||
|
import com.typesafe.sbt.pgp.PgpKeys.updatePgpSignatures
|
||||||
|
import sbt.AutoPlugin
|
||||||
|
|
||||||
|
object CoursierSbtPgpPlugin extends AutoPlugin {
|
||||||
|
|
||||||
|
override def trigger = allRequirements
|
||||||
|
|
||||||
|
override def requires = com.typesafe.sbt.SbtPgp && coursier.CoursierPlugin
|
||||||
|
|
||||||
|
override val projectSettings = Seq(
|
||||||
|
updatePgpSignatures := {
|
||||||
|
Tasks.updateTask(
|
||||||
|
None,
|
||||||
|
withClassifiers = false,
|
||||||
|
includeSignatures = true
|
||||||
|
).value
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
scalaVersion := "2.11.8"
|
||||||
|
|
||||||
|
libraryDependencies += "com.github.alexarchambault" %% "argonaut-shapeless_6.2" % "1.2.0-M5"
|
||||||
|
|
||||||
|
lazy val check = TaskKey[Unit]("check")
|
||||||
|
|
||||||
|
check := {
|
||||||
|
val report = com.typesafe.sbt.pgp.PgpKeys.updatePgpSignatures.value
|
||||||
|
val configReport = report
|
||||||
|
.configurations
|
||||||
|
.find { confRep =>
|
||||||
|
confRep.configuration == "compile"
|
||||||
|
}
|
||||||
|
.getOrElse {
|
||||||
|
sys.error("No configuration report found for configuration 'compile'")
|
||||||
|
}
|
||||||
|
val moduleReports = configReport.modules
|
||||||
|
val artifacts = moduleReports.flatMap(_.artifacts.map(_._1))
|
||||||
|
val signatures = moduleReports
|
||||||
|
.flatMap(_.artifacts)
|
||||||
|
.filter(_._1.extension == "jar.asc")
|
||||||
|
.map(_._2)
|
||||||
|
assert(
|
||||||
|
signatures.nonEmpty,
|
||||||
|
"No signatures found"
|
||||||
|
)
|
||||||
|
assert(
|
||||||
|
signatures.forall(_.getAbsolutePath.contains("/.coursier/cache/")),
|
||||||
|
s"Found signatures not provided by coursier:\n${signatures.map(" " + _).mkString("\n")}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -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-pgp-coursier" % pluginVersion)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
> checkPgpSignatures
|
||||||
|
> check
|
||||||
|
|
@ -83,7 +83,8 @@ is212() {
|
||||||
}
|
}
|
||||||
|
|
||||||
runSbtCoursierTests() {
|
runSbtCoursierTests() {
|
||||||
sbt ++$SCALA_VERSION coreJVM/publishLocal cache/publishLocal extra/publishLocal "sbt-coursier/scripted sbt-coursier/*"
|
addPgpKeys
|
||||||
|
sbt ++$SCALA_VERSION sbt-plugins/publishLocal "sbt-coursier/scripted sbt-coursier/*" sbt-pgp-coursier/scripted
|
||||||
if [ "$SCALA_VERSION" = "2.10" ]; then
|
if [ "$SCALA_VERSION" = "2.10" ]; then
|
||||||
sbt ++$SCALA_VERSION "sbt-coursier/scripted sbt-coursier-0.13/*"
|
sbt ++$SCALA_VERSION "sbt-coursier/scripted sbt-coursier-0.13/*"
|
||||||
fi
|
fi
|
||||||
|
|
@ -212,6 +213,12 @@ testBootstrap() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addPgpKeys() {
|
||||||
|
for key in b41f2bce 9fa47a44 ae548ced b4493b94 53a97466 36ee59d9 dc426429 3b80305d 69e0a56c fdd5c0cd 35543c27 70173ee5 111557de 39c263a9; do
|
||||||
|
gpg --keyserver keyserver.ubuntu.com --recv "$key"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# TODO Add coverage once https://github.com/scoverage/sbt-scoverage/issues/111 is fixed
|
# TODO Add coverage once https://github.com/scoverage/sbt-scoverage/issues/111 is fixed
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue