From becc47cb5ecfec59d828a041a188624a03b8b88f Mon Sep 17 00:00:00 2001 From: Daniel Spiewak Date: Tue, 14 Aug 2018 18:20:26 -0600 Subject: Added gpgWarnOnFailure (#6) * Added gpgWarnOnFailure key (name subject to bikeshedding) and associated semantics * Added stderr redirect to gpg command * Corrected test to use `publish / packagedArtifacts` * Updated README for new fail-on-failure default for publish (and tweaked a couple other things) --- src/main/scala/SbtGpg.scala | 71 ++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 20 deletions(-) (limited to 'src/main/scala/SbtGpg.scala') diff --git a/src/main/scala/SbtGpg.scala b/src/main/scala/SbtGpg.scala index 17eff8d..d3d82b9 100644 --- a/src/main/scala/SbtGpg.scala +++ b/src/main/scala/SbtGpg.scala @@ -10,48 +10,79 @@ object SbtGpg extends AutoPlugin { override def trigger = allRequirements object autoImport { + + val gpgWarnOnFailure = settingKey[Boolean]( + "If true, only issue a warning when signing fails. If false, error " + + "and fail the build. Defaults to true in publishLocal, false in publish.") + val gpgCommand = settingKey[String]("Path to GnuPG executable.") + val gpgOptions = settingKey[Seq[String]]("Additional global options to pass to gpg.") + val gpgKey = taskKey[Option[String]]( "Key ID used to sign artifacts. Setting this to None will " + "cause sbt-gpg to fall back to using gpg's default key. When set, " + "it is equivalent to gpg's `--local-user` option.") + val gpg = taskKey[Gpg]("Utility wrapper to the underlying gpg executable.") } + + def packagedArtifactsImpl( + arts: Map[Artifact, File], + gpg: Gpg, + warnOnFailure: Boolean)(warn: String => Unit): Map[Artifact, File] = { + + val (signatures, failure) = arts.foldLeft((Map[Artifact, File](), false)) { + case ((acc, false), (art, file)) => + gpg.sign(file) match { + case Some(signed) => + (acc + (art.withExtension(art.extension + ".asc") -> signed), false) + + case None => + val report: String => Unit = + if (warnOnFailure) warn else sys.error(_) + + report("GPG reported an error. Artifacts won't be signed.") + (acc, true) + } + + case (pair @ (_, true), _) => pair + } + + // if we fail the signing part-way through, we throw out *all* the signatures + if (failure) arts else signatures ++ arts + } + import autoImport._ lazy val gpgSettings: Seq[Setting[_]] = Seq( + gpgWarnOnFailure := false, + publishLocal / gpgWarnOnFailure := true, gpgCommand := "gpg", gpgOptions := Seq("--yes"), gpgKey := Credentials.forHost(credentials.value, "gpg").map(_.userName), gpg := { val log = streams.value.log - new Gpg(gpgCommand.value, gpgOptions.value, gpgKey.value)(log.warn(_)) + new Gpg(gpgCommand.value, gpgOptions.value, gpgKey.value)(log.info(_), + log.warn(_)) } ) lazy val signingSettings: Seq[Setting[_]] = Seq( - packagedArtifacts := { - val log = streams.value.log - val arts: Map[Artifact, File] = packagedArtifacts.value - var failed = false - arts.flatMap { - case (art, file) if !failed => - gpg.value.sign(file) match { - case Some(signed) => - Map( - art -> file, - art.withExtension(art.extension + ".asc") -> signed - ) - case None => - log.warn("GPG reported an error. Artifacts won't be signed.") - failed = true - Map(art -> file) - } - case (art, file) => Map(art -> file) - } + publish / packagedArtifacts := { + packagedArtifactsImpl( + (publish / packagedArtifacts).value, + gpg.value, + (publish / gpgWarnOnFailure).value)(streams.value.log.warn(_)) + }, + publishLocal / packagedArtifacts := { + packagedArtifactsImpl( + (publishLocal / packagedArtifacts).value, + gpg.value, + (publishLocal / gpgWarnOnFailure).value)(streams.value.log.warn(_)) + } ) -- cgit v1.2.3