From 8ac53668af0ff6ea699e5d99105bd74585057bf1 Mon Sep 17 00:00:00 2001 From: Nikolay Tatarinov <5min4eq.unity@gmail.com> Date: Tue, 6 Mar 2018 10:22:01 +0300 Subject: fix optional xml tags in POM (#198) --- scalalib/src/mill/scalalib/publish/Pom.scala | 55 +++--- .../test/src/mill/scalalib/publish/PomTests.scala | 199 +++++++++++++++++++++ 2 files changed, 222 insertions(+), 32 deletions(-) create mode 100644 scalalib/test/src/mill/scalalib/publish/PomTests.scala diff --git a/scalalib/src/mill/scalalib/publish/Pom.scala b/scalalib/src/mill/scalalib/publish/Pom.scala index 382db56a..1a86e7de 100644 --- a/scalalib/src/mill/scalalib/publish/Pom.scala +++ b/scalalib/src/mill/scalalib/publish/Pom.scala @@ -8,29 +8,28 @@ 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 = { - - // source: https://stackoverflow.com/a/5254068/449071 - implicit def optionElem(e: Elem) = new { - def optionnal : 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 - } - } - } - val xml = - {pomSettings.versionControl.connection}.optionnal - {pomSettings.versionControl.developerConnection}.optionnal - {pomSettings.versionControl.tag}.optionnal - {pomSettings.versionControl.browsableRepository}.optionnal + { {pomSettings.versionControl.connection}.optional } + { {pomSettings.versionControl.developerConnection}.optional } + { {pomSettings.versionControl.tag}.optional } + { {pomSettings.versionControl.browsableRepository}.optional } {pomSettings.developers.map(renderDeveloper)} @@ -79,16 +78,8 @@ object Pom { {d.id} {d.name} - { - d.organization.map { org => - {org} - }.getOrElse(NodeSeq.Empty) - } - { - d.organizationUrl.map { orgUrl => - {orgUrl} - }.getOrElse(NodeSeq.Empty) - } + { {d.organization}.optional } + { {d.organizationUrl}.optional } } diff --git a/scalalib/test/src/mill/scalalib/publish/PomTests.scala b/scalalib/test/src/mill/scalalib/publish/PomTests.scala new file mode 100644 index 00000000..31e87446 --- /dev/null +++ b/scalalib/test/src/mill/scalalib/publish/PomTests.scala @@ -0,0 +1,199 @@ +package mill.scalalib.publish + +import utest._ +import mill._ + +import scala.xml.{NodeSeq, XML} + +object PomTests extends TestSuite { + + def tests: Tests = Tests { + val artifactId = "mill-scalalib_2.12" + val artifact = + Artifact("com.lihaoyi", "mill-scalalib_2.12", "0.0.1") + val deps = Agg( + Dependency(Artifact("com.lihaoyi", "mill-main_2.12", "0.1.4"), + Scope.Compile), + Dependency(Artifact("org.scala-sbt", "test-interface", "1.0"), + Scope.Compile) + ) + val settings = PomSettings( + description = "mill-scalalib", + organization = "com.lihaoyi", + url = "https://github.com/lihaoyi/mill", + licenses = Seq(License.`MIT`), + versionControl = VersionControl.github("lihaoyi", "mill"), + developers = List( + Developer("lihaoyi", + "Li Haoyi", + "https://github.com/lihaoyi", + None, + None), + Developer("rockjam", + "Nikolai Tatarinov", + "https://github.com/rockjam", + Some("80pct done Inc."), + Some("https://80pctdone.com/")) + ) + ) + + 'fullPom - { + val fullPom = pomXml(artifact, deps, artifactId, settings) + + 'topLevel - { + assert( + singleText(fullPom \ "modelVersion") == "4.0.0", + singleText(fullPom \ "name") == artifactId, + singleText(fullPom \ "groupId") == artifact.group, + singleText(fullPom \ "artifactId") == artifact.id, + singleText(fullPom \ "packaging") == "jar", + singleText(fullPom \ "description") == settings.description, + singleText(fullPom \ "version") == artifact.version, + singleText(fullPom \ "url") == settings.url + ) + } + + 'licenses - { + val licenses = fullPom \ "licenses" \ "license" + + assert(licenses.size == 1) + + val license = licenses.head + val pomLicense = settings.licenses.head + assert( + singleText(license \ "name") == pomLicense.name, + singleText(license \ "url") == pomLicense.url, + singleText(license \ "distribution") == pomLicense.distribution + ) + } + + 'scm - { + val scm = (fullPom \ "scm").head + val pomScm = settings.versionControl + + assert( + optText(scm \ "connection") == pomScm.connection, + optText(scm \ "developerConnection") == pomScm.developerConnection, + optText(scm \ "tag").isEmpty, + optText(scm \ "url") == pomScm.browsableRepository + ) + } + + 'developers - { + val developers = fullPom \ "developers" \ "developer" + + assert(developers.size == 2) + + val pomDevelopers = settings.developers + + assert( + singleText(developers.head \ "id") == pomDevelopers.head.id, + singleText(developers.head \ "name") == pomDevelopers.head.name, + optText(developers.head \ "organization").isEmpty, + optText(developers.head \ "organizationUrl").isEmpty + ) + + assert( + singleText(developers.last \ "id") == pomDevelopers.last.id, + singleText(developers.last \ "name") == pomDevelopers.last.name, + optText(developers.last \ "organization") == pomDevelopers.last.organization, + optText(developers.last \ "organizationUrl") == pomDevelopers.last.organizationUrl + ) + } + + 'dependencies - { + val dependencies = fullPom \ "dependencies" \ "dependency" + + assert(dependencies.size == 2) + + val pomDeps = deps.indexed + + dependencies.zipWithIndex.foreach { + case (dep, index) => + assert( + singleText(dep \ "groupId") == pomDeps(index).artifact.group, + singleText(dep \ "artifactId") == pomDeps(index).artifact.id, + singleText(dep \ "version") == pomDeps(index).artifact.version, + optText(dep \ "scope").isEmpty + ) + } + } + } + + 'pomEmptyScm - { + val updatedSettings = settings.copy( + versionControl = VersionControl( + browsableRepository = Some("git://github.com/lihaoyi/mill.git"), + connection = None, + developerConnection = None, + tag = None + )) + val pomEmptyScm = pomXml(artifact, deps, artifactId, updatedSettings) + + 'scm - { + val scm = (pomEmptyScm \ "scm").head + val pomScm = updatedSettings.versionControl + + assert( + optText(scm \ "connection").isEmpty, + optText(scm \ "developerConnection").isEmpty, + optText(scm \ "tag").isEmpty, + optText(scm \ "url") == pomScm.browsableRepository + ) + } + } + + 'pomNoLicenses - { + val updatedSettings = settings.copy(licenses = Seq.empty) + val pomNoLicenses = pomXml(artifact, deps, artifactId, updatedSettings) + + 'licenses - { + assert( + (pomNoLicenses \ "licenses").nonEmpty, + (pomNoLicenses \ "licenses" \ "licenses").isEmpty + ) + } + } + + 'pomNoDeps - { + val pomNoDeps = pomXml(artifact, + dependencies = Agg.empty, + artifactId = artifactId, + pomSettings = settings) + + 'dependencies - { + assert( + (pomNoDeps \ "dependencies").nonEmpty, + (pomNoDeps \ "dependencies" \ "dependency").isEmpty + ) + } + } + + 'pomNoDevelopers - { + val updatedSettings = settings.copy(developers = Seq.empty) + val pomNoDevelopers = pomXml(artifact, deps, artifactId, updatedSettings) + + 'developers - { + assert( + (pomNoDevelopers \ "developers").nonEmpty, + (pomNoDevelopers \ "developers" \ "developer").isEmpty + ) + } + } + } + + def pomXml(artifact: Artifact, + dependencies: Agg[Dependency], + artifactId: String, + pomSettings: PomSettings) = + XML.loadString(Pom(artifact, dependencies, artifactId, pomSettings)) + + def singleText(seq: NodeSeq) = + seq + .map(_.text) + .headOption + .getOrElse(throw new RuntimeException("seq was empty")) + + def optText(seq: NodeSeq) = seq.map(_.text).headOption + +} -- cgit v1.2.3