All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mill.scalalib.publish.Pom.scala Maven / Gradle / Ivy

The newest version!
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,
    parentProject = None,
    bomDependencies = Agg.empty[Dependency],
    dependencyManagement = Agg.empty[Dependency]
  )

  @deprecated(
    "Use overload with parentProject, bomDependencies, and dependencyManagement parameters instead",
    "Mill 0.12.1"
  )
  def apply(
      artifact: Artifact,
      dependencies: Agg[Dependency],
      name: String,
      pomSettings: PomSettings,
      properties: Map[String, String],
      packagingType: String
  ): String = apply(
    artifact = artifact,
    dependencies = dependencies,
    name = name,
    pomSettings = pomSettings,
    properties = properties,
    packagingType = packagingType,
    parentProject = None,
    bomDependencies = Agg.empty[Dependency],
    dependencyManagement = Agg.empty[Dependency]
  )

  def apply(
      artifact: Artifact,
      dependencies: Agg[Dependency],
      name: String,
      pomSettings: PomSettings,
      properties: Map[String, String],
      packagingType: String,
      parentProject: Option[Artifact]
  ): String =
    apply(
      artifact,
      dependencies,
      name,
      pomSettings,
      properties,
      packagingType,
      parentProject,
      Agg.empty[Dependency],
      Agg.empty[Dependency]
    )

  def apply(
      artifact: Artifact,
      dependencies: Agg[Dependency],
      name: String,
      pomSettings: PomSettings,
      properties: Map[String, String],
      packagingType: String,
      parentProject: Option[Artifact],
      bomDependencies: Agg[Dependency],
      dependencyManagement: Agg[Dependency]
  ): String = {
    val developersSection =
      if (pomSettings.developers.isEmpty) NodeSeq.Empty
      else
        
          {pomSettings.developers.map(renderDeveloper)}
        
    val propertiesSection =
      if (properties.isEmpty) NodeSeq.Empty
      else
        
          {properties.map(renderProperty _).iterator}
        
    val depMgmtSection =
      if (dependencyManagement.isEmpty) NodeSeq.Empty
      else
        
          
            {dependencyManagement.map(renderDependency(_)).iterator}
          
        
    val xml =
      

        4.0.0
        {parentProject.fold(NodeSeq.Empty)(renderParent)}
        {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}
        
        {developersSection}
        {propertiesSection}
        
          {
        dependencies.map(renderDependency(_)).iterator ++
          bomDependencies.map(renderDependency(_, isImport = true)).iterator
      }
        
        {depMgmtSection}
      

    val pp = new PrettyPrinter(120, 4)
    head + pp.format(xml)
  }

  private def renderParent(artifact: Artifact): Elem = {
    
      {artifact.group}
      {artifact.id}
      {artifact.version}
    
  }

  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, isImport: Boolean = false): Elem = {
    val scope =
      if (isImport) import
      else
        d.scope match {
          case Scope.Compile => NodeSeq.Empty
          case Scope.Provided => provided
          case Scope.Test => test
          case Scope.Runtime => runtime
        }

    val `type` = if (isImport) pom else NodeSeq.Empty

    val optional = if (d.optional) true else NodeSeq.Empty

    val version =
      if (d.artifact.version.isEmpty) NodeSeq.Empty
      else {d.artifact.version}

    if (d.exclusions.isEmpty)
      
        {d.artifact.group}
        {d.artifact.id}
        {version}
        {scope}
        {`type`}
        {optional}
      
    else
      
        {d.artifact.group}
        {d.artifact.id}
        {version}
        
          {
        d.exclusions.map(ex => 
              {ex._1}
              {ex._2}
            )
      }
        
        {scope}
        {`type`}
        {optional}
      
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy