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} } }