diff --git a/main/src/main/scala/sbt/internal/PomGenerator.scala b/main/src/main/scala/sbt/internal/PomGenerator.scala index b7036799e..99816eb16 100644 --- a/main/src/main/scala/sbt/internal/PomGenerator.scala +++ b/main/src/main/scala/sbt/internal/PomGenerator.scala @@ -221,7 +221,7 @@ private[sbt] object PomGenerator: {versionNode} {scopeElem(scope)} {optionalElem(optional)} - {classifierElem(dep)} + {typeAndClassifierElems(dep)} {exclusions(dep)} result @@ -265,10 +265,19 @@ private[sbt] object PomGenerator: private def optionalElem(opt: Boolean): NodeSeq = if opt then true else NodeSeq.Empty - private def classifierElem(dep: ModuleID): NodeSeq = - dep.explicitArtifacts.headOption.flatMap(_.classifier) match - case Some(c) => {c} - case None => NodeSeq.Empty + private def typeAndClassifierElems(dep: ModuleID): NodeSeq = + dep.explicitArtifacts.headOption match + case None => NodeSeq.Empty + case Some(art) => + val classifier = art.classifier + val baseType = Option(art.`type`).filter(_ != Artifact.DefaultType) + val tpe = (classifier, baseType) match + case (Some(c), Some(t)) if Artifact.classifierType(c) == t => None + case _ => baseType + val typeNode = tpe.map(t => {t}).getOrElse(NodeSeq.Empty) + val classifierNode = + classifier.map(c => {c}).getOrElse(NodeSeq.Empty) + typeNode ++ classifierNode private def exclusions(dep: ModuleID): NodeSeq = if dep.exclusions.isEmpty then NodeSeq.Empty diff --git a/sbt-app/src/sbt-test/dependency-management/pom-artifact-type/build.sbt b/sbt-app/src/sbt-test/dependency-management/pom-artifact-type/build.sbt new file mode 100644 index 000000000..07570f4c5 --- /dev/null +++ b/sbt-app/src/sbt-test/dependency-management/pom-artifact-type/build.sbt @@ -0,0 +1,38 @@ +lazy val checkPom = taskKey[Unit]("check pom emits for non-jar explicit artifacts") + +lazy val root = (project in file(".")) + .settings( + scalaVersion := "2.13.16", + autoScalaLibrary := false, + libraryDependencies += "org.eclipse.jetty" % "jetty-webapp" % "11.0.15" artifacts (Artifact("jetty-webapp", "war", "war")), + libraryDependencies += "com.typesafe" % "config" % "1.4.3", + // classified artifact with non-default type: both and must appear + libraryDependencies += ("com.example" % "classified-war" % "1.0") + .artifacts(Artifact("classified-war", "war", "war").withClassifier(Some("client"))), + checkPom := { + val converter = fileConverter.value + val pomFile = makePom.value + val pom = xml.XML.loadFile(converter.toPath(pomFile).toFile) + val deps = pom \ "dependencies" \ "dependency" + + // WAR dependency should be present with war + val warDep = deps.find(d => (d \ "artifactId").text == "jetty-webapp") + assert(warDep.isDefined, s"jetty-webapp dependency missing from POM.\nDeps: ${deps.map(d => (d \ "artifactId").text)}") + val warType = (warDep.get \ "type").text + assert(warType == "war", s"Expected war for jetty-webapp, got: '$warType'") + + // JAR dependency should NOT have (jar is the Maven default) + val jarDep = deps.find(d => (d \ "artifactId").text == "config") + assert(jarDep.isDefined, "config dependency missing from POM") + val jarType = (jarDep.get \ "type").text + assert(jarType == "", s"Expected no for config (jar is default), got: '$jarType'") + + // Classified WAR: must have both war and client + val cwDep = deps.find(d => (d \ "artifactId").text == "classified-war") + assert(cwDep.isDefined, s"classified-war dependency missing from POM.\nDeps: ${deps.map(d => (d \ "artifactId").text)}") + val cwType = (cwDep.get \ "type").text + assert(cwType == "war", s"Expected war for classified-war, got: '$cwType'") + val cwClassifier = (cwDep.get \ "classifier").text + assert(cwClassifier == "client", s"Expected client for classified-war, got: '$cwClassifier'") + }, + ) diff --git a/sbt-app/src/sbt-test/dependency-management/pom-artifact-type/test b/sbt-app/src/sbt-test/dependency-management/pom-artifact-type/test new file mode 100644 index 000000000..8d831496e --- /dev/null +++ b/sbt-app/src/sbt-test/dependency-management/pom-artifact-type/test @@ -0,0 +1 @@ +> checkPom