project/SbtMavenPlugin.scala (76 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one or more * license agreements; and to You under the Apache License, version 2.0: * * https://www.apache.org/licenses/LICENSE-2.0 * * This file is part of the Apache Pekko project, which was derived from Akka. */ package org.apache.pekko.grpc import java.io.File import sbt.{ CrossVersion, IO, Logger, ModuleID, ModuleInfo, _ } import sbt.Keys._ import sbt.plugins.JvmPlugin import scala.util.Try import scala.xml.{ Elem, PrettyPrinter, XML } /** * Inspired by https://github.com/lagom/lagom/blob/master/project/SbtMavenPlugin.scala */ object SbtMavenPlugin extends AutoPlugin { override lazy val trigger = noTrigger override lazy val requires = JvmPlugin object autoImport { lazy val mavenGeneratePluginXml = taskKey[Seq[File]]("Generate the maven plugin xml") } import autoImport._ override lazy val projectSettings: Seq[Setting[_]] = inConfig(Compile)(unscopedSettings) lazy val unscopedSettings = Seq( (mavenGeneratePluginXml / sourceDirectory) := sourceDirectory.value / "maven", (mavenGeneratePluginXml / sources) := Seq((mavenGeneratePluginXml / sourceDirectory).value / "plugin.xml").filter(_.exists()), (mavenGeneratePluginXml / target) := target.value / "maven-plugin-xml", managedResourceDirectories += (mavenGeneratePluginXml / target).value, mavenGeneratePluginXml := { val files = (mavenGeneratePluginXml / sources).value val outDir = (mavenGeneratePluginXml / target).value / "META-INF" / "maven" IO.createDirectory(outDir) val pid = projectID.value val pi = projectInfo.value val deps = allDependencies.value val sv = scalaVersion.value val sbv = scalaBinaryVersion.value val log = streams.value.log val configHash = Seq(pid.toString, pi.toString, deps.toString, sv, sbv).hashCode() val cacheFile = streams.value.cacheDirectory / "maven.plugin.xml.cache" val cachedHash = Some(cacheFile).filter(_.exists()).flatMap { file => Try(IO.read(file).toInt).toOption } val configChanged = cachedHash.forall(_ != configHash) val outFiles = files.map { file => val outFile = outDir / file.getName if (file.lastModified() > outFile.lastModified() || configChanged) { log.info(s"Generating $outFile from template") val template = XML.loadFile(file) val processed = processTemplate(template, pid, pi, deps, CrossVersion(sv, sbv), log) IO.write(outFile, new PrettyPrinter(120, 2).format(processed)) } outFile } IO.write(cacheFile, configHash.toString) outFiles }, resourceGenerators += mavenGeneratePluginXml.taskValue) def processTemplate( xml: Elem, moduleID: ModuleID, moduleInfo: ModuleInfo, dependencies: Seq[ModuleID], crossVersion: ModuleID => ModuleID, log: Logger) = { // Add project meta data val withProjectInfo = Seq( "name" -> moduleInfo.nameFormal, "description" -> moduleInfo.description, "groupId" -> moduleID.organization, "artifactId" -> moduleID.name, "version" -> moduleID.revision).foldRight(xml) { case ((label, value), elem) => prependIfAbsent(elem, createElement(label, value)) } withProjectInfo } private def createElement(label: String, value: String): Elem = <elem>{value}</elem>.copy(label = label) private def prependIfAbsent(parent: Elem, elem: Elem) = if (parent.child.exists(_.label == elem.label)) { parent } else { parent.copy(child = elem +: parent.child) } }