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
}
}
}
//TODO - not only jar packaging support?
def apply(artifact: Artifact,
dependencies: Agg[Dependency],
name: String,
pomSettings: PomSettings): String = {
val xml =
4.0.0
{name}
{artifact.group}
{artifact.id}
jar
{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)}
{dependencies.map(renderDependency).toSeq}
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.organization}.optional }
{ {d.organizationUrl}.optional }
}
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}
}
}