mill.scalalib.publish.Pom.scala Maven / Gradle / Ivy
package mill.scalalib.publish
import mill.api.Loose.Agg
import scala.xml.{Atom, Elem, NodeSeq, PrettyPrinter}
object Pom {
val head = "\n"
implicit class XmlOps(val e: Elem) extends AnyVal {
// source: https://stackoverflow.com/a/5254068/449071
def optional: NodeSeq = {
require(e.child.length == 1)
e.child.head match {
case atom: Atom[Option[_]] => atom.data match {
case None => NodeSeq.Empty
case Some(x) => e.copy(child = x match {
case n: NodeSeq => n
case x => new Atom(x)
})
}
case _ => e
}
}
}
@deprecated("Use overload with packagingType parameter instead", "Mill 0.11.8")
def apply(
artifact: Artifact,
dependencies: Agg[Dependency],
name: String,
pomSettings: PomSettings,
properties: Map[String, String]
): String = apply(
artifact = artifact,
dependencies = dependencies,
name = name,
pomSettings = pomSettings,
properties = properties,
packagingType = pomSettings.packaging
)
def apply(
artifact: Artifact,
dependencies: Agg[Dependency],
name: String,
pomSettings: PomSettings,
properties: Map[String, String],
packagingType: String
): String = {
val xml =
4.0.0
{name}
{artifact.group}
{artifact.id}
{packagingType}
{pomSettings.description}
{artifact.version}
{pomSettings.url}
{pomSettings.licenses.map(renderLicense)}
{{pomSettings.versionControl.connection} .optional}
{
{
pomSettings.versionControl.developerConnection
} .optional
}
{{pomSettings.versionControl.tag} .optional}
{{pomSettings.versionControl.browsableRepository} .optional}
{pomSettings.developers.map(renderDeveloper)}
{properties.map(renderProperty _).iterator}
{dependencies.map(renderDependency).iterator}
val pp = new PrettyPrinter(120, 4)
head + pp.format(xml)
}
private def renderLicense(l: License): Elem = {
{l.name}
{l.url}
{l.distribution}
}
private def renderDeveloper(d: Developer): Elem = {
{d.id}
{d.name}
{d.url}
{{d.organization} .optional}
{{d.organizationUrl} .optional}
}
private def renderProperty(property: (String, String)): Elem = {
{property._2} .copy(label = property._1)
}
private def renderDependency(d: Dependency): Elem = {
val scope = d.scope match {
case Scope.Compile => NodeSeq.Empty
case Scope.Provided => provided
case Scope.Test => test
case Scope.Runtime => runtime
}
val optional = if (d.optional) true else NodeSeq.Empty
if (d.exclusions.isEmpty)
{d.artifact.group}
{d.artifact.id}
{d.artifact.version}
{scope}
{optional}
else
{d.artifact.group}
{d.artifact.id}
{d.artifact.version}
{
d.exclusions.map(ex =>
{ex._1}
{ex._2}
)
}
{scope}
{optional}
}
}