diff --git a/build.sbt b/build.sbt index 4af38b5c57..b283f1f66e 100644 --- a/build.sbt +++ b/build.sbt @@ -381,6 +381,11 @@ lazy val protobufV3 = pekkoModule("protobuf-v3") // https://github.com/sbt/sbt-assembly/issues/400 .inLibrary(Dependencies.Compile.Provided.protobufRuntime) .inProject), + assembly / assemblyMergeStrategy := { + case "META-INF/LICENSE" | "META-INF/NOTICE" => sbtassembly.MergeStrategy.concat + case "META-INF/COPYING.protobuf" => sbtassembly.MergeStrategy.first + case path => (assembly / assemblyMergeStrategy).value(path) + }, assembly / assemblyOption := (assembly / assemblyOption).value.withIncludeScala(false).withIncludeBin(true), autoScalaLibrary := false, // do not include scala dependency in pom exportJars := true, // in dependent projects, use assembled and shaded jar diff --git a/project/AddMetaInfLicenseFiles.scala b/project/AddMetaInfLicenseFiles.scala index 77458d9afd..287f457f6e 100644 --- a/project/AddMetaInfLicenseFiles.scala +++ b/project/AddMetaInfLicenseFiles.scala @@ -25,11 +25,40 @@ import org.mdedetrich.apache.sonatype.ApacheSonatypePlugin.autoImport._ */ object AddMetaInfLicenseFiles extends AutoPlugin { + object autoImport { + lazy val checkPackageBinMetaInfLegalFiles = + taskKey[Unit]("Checks that packaged jars contain META-INF/LICENSE and META-INF/NOTICE files.") + } + + import autoImport._ + private lazy val baseDir = LocalRootProject / baseDirectory + private val requiredPackageBinEntries = Seq("META-INF/LICENSE", "META-INF/NOTICE") + override lazy val projectSettings = Seq( apacheSonatypeLicenseFile := baseDir.value / "legal" / "StandardLicense.txt", - apacheSonatypeNoticeFile := baseDir.value / "legal" / "PekkoNotice.txt") + apacheSonatypeNoticeFile := baseDir.value / "legal" / "PekkoNotice.txt", + Compile / checkPackageBinMetaInfLegalFiles := Def.taskDyn { + if ((publish / skip).value) { + Def.task { + streams.value.log.debug("Skipping META-INF legal files check for non-published project.") + } + } else { + Def.task { + val packageBinJar = (Compile / packageBin).value + val publishedJar = (Compile / packageBin / packagedArtifact).value._2 + val missingEntries = Seq(packageBinJar, publishedJar).distinct.flatMap { jar => + missingPackageBinEntries(jar).map(entry => s"${jar.getAbsolutePath}: $entry") + } + + if (missingEntries.nonEmpty) { + throw new MessageOnlyException( + "Packaged jars are missing required META-INF legal files:\n" + missingEntries.mkString("\n")) + } + } + } + }.value) /** * Settings specific for Pekko actor subproject which requires a different license file. @@ -80,4 +109,10 @@ object AddMetaInfLicenseFiles extends AutoPlugin { override lazy val trigger = allRequirements override lazy val requires = ApacheSonatypePlugin + + private def missingPackageBinEntries(jar: File): Seq[String] = { + val zip = new java.util.zip.ZipFile(jar) + try requiredPackageBinEntries.filter(entry => zip.getEntry(entry) == null) + finally zip.close() + } } diff --git a/project/ValidatePullRequest.scala b/project/ValidatePullRequest.scala index 246e98b6f3..2f13a5029c 100644 --- a/project/ValidatePullRequest.scala +++ b/project/ValidatePullRequest.scala @@ -124,3 +124,12 @@ object UnidocWithPrValidation extends AutoPlugin { override lazy val trigger = noTrigger override lazy val projectSettings = Seq(additionalTasks += Compile / unidoc) } + +object MetaInfLicenseFilesWithPrValidation extends AutoPlugin { + import AddMetaInfLicenseFiles.autoImport._ + import PekkoValidatePullRequest._ + + override lazy val trigger = allRequirements + override lazy val requires = PekkoValidatePullRequest && AddMetaInfLicenseFiles + override lazy val projectSettings = Seq(additionalTasks += Compile / checkPackageBinMetaInfLegalFiles) +}