Skip to content

Commit

Permalink
Support "pom" packaging type in PublishModule (#3222)
Browse files Browse the repository at this point in the history
Deprecated the `packaging` field in `PomSettings` which had only one
valid value (`jar`). We need this value as a pure `def` so the `publish`
targets don't need to depend on the various `jar` producing targets when
the value is `pom`.

Added new `PublishModuleTests` test suite and moved all publish tests
there.

Fix #3206

Pull request: #3222
  • Loading branch information
lefou authored Jun 21, 2024
1 parent 5e3872a commit 4f6742d
Show file tree
Hide file tree
Showing 7 changed files with 285 additions and 131 deletions.
49 changes: 36 additions & 13 deletions scalalib/src/mill/scalalib/PublishModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ trait PublishModule extends JavaModule { outer =>
)
}

/**
* The packaging type. See [[PackagingType]] for specially handled values.
*/
def pomPackagingType: String = PackagingType.Jar

/**
* Configuration for the `pom.xml` metadata file published with this module
*/
Expand Down Expand Up @@ -76,8 +81,14 @@ trait PublishModule extends JavaModule { outer =>
}

def pom: Target[PathRef] = T {
val pom =
Pom(artifactMetadata(), publishXmlDeps(), artifactId(), pomSettings(), publishProperties())
val pom = Pom(
artifactMetadata(),
publishXmlDeps(),
artifactId(),
pomSettings(),
publishProperties(),
packagingType = pomPackagingType
)
val pomPath = T.dest / s"${artifactId()}-${publishVersion()}.pom"
os.write.over(pomPath, pom)
PathRef(pomPath)
Expand Down Expand Up @@ -182,17 +193,29 @@ trait PublishModule extends JavaModule { outer =>

def sonatypeSnapshotUri: String = "https://oss.sonatype.org/content/repositories/snapshots"

def publishArtifacts = T {
val baseName = s"${artifactId()}-${publishVersion()}"
PublishModule.PublishData(
artifactMetadata(),
Seq(
jar() -> s"$baseName.jar",
sourceJar() -> s"$baseName-sources.jar",
docJar() -> s"$baseName-javadoc.jar",
pom() -> s"$baseName.pom"
) ++ extraPublish().map(p => (p.file, s"$baseName${p.classifierPart}.${p.ext}"))
)
def publishArtifacts: T[PublishModule.PublishData] = {
val baseNameTask: Task[String] = T.task { s"${artifactId()}-${publishVersion()}" }
val defaultPayloadTask: Task[Seq[(PathRef, String)]] = pomPackagingType match {
case PackagingType.Pom => T.task { Seq.empty[(PathRef, String)] }
case PackagingType.Jar | _ => T.task {
val baseName = baseNameTask()
Seq(
jar() -> s"$baseName.jar",
sourceJar() -> s"$baseName-sources.jar",
docJar() -> s"$baseName-javadoc.jar",
pom() -> s"$baseName.pom"
)
}
}
T {
val baseName = baseNameTask()
PublishModule.PublishData(
meta = artifactMetadata(),
payload = defaultPayloadTask() ++ extraPublish().map(p =>
(p.file, s"$baseName${p.classifierPart}.${p.ext}")
)
)
}
}

/**
Expand Down
19 changes: 18 additions & 1 deletion scalalib/src/mill/scalalib/publish/Pom.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,29 @@ object Pom {
}
}

@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
)

def apply(
artifact: Artifact,
dependencies: Agg[Dependency],
name: String,
pomSettings: PomSettings,
properties: Map[String, String],
packagingType: String
): String = {
val xml =
<project
Expand All @@ -42,7 +59,7 @@ object Pom {
<name>{name}</name>
<groupId>{artifact.group}</groupId>
<artifactId>{artifact.id}</artifactId>
<packaging>{pomSettings.packaging}</packaging>
<packaging>{packagingType}</packaging>
<description>{pomSettings.description}</description>

<version>{artifact.version}</version>
Expand Down
8 changes: 7 additions & 1 deletion scalalib/src/mill/scalalib/publish/settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,11 @@ case class PomSettings(
licenses: Seq[License],
versionControl: VersionControl,
developers: Seq[Developer],
packaging: String = "jar"
@deprecated("Value will be ignored. Use PublishModule.pomPackageingType instead", "Mill 0.11.8")
packaging: String = PackagingType.Jar
)

object PackagingType {
val Pom = "pom"
val Jar = "jar"
}
1 change: 1 addition & 0 deletions scalalib/test/resources/publish/core/resources/dummy.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dummy
115 changes: 0 additions & 115 deletions scalalib/test/src/mill/scalalib/HelloWorldTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ import java.io.{ByteArrayOutputStream, PrintStream}
import java.util.jar.JarFile
import scala.jdk.CollectionConverters._
import scala.util.{Properties, Using}
import scala.xml.NodeSeq
import mill._
import mill.api.Result
import mill.define.NamedTask
import mill.eval.{Evaluator, EvaluatorPaths}
import mill.scalalib.publish.{VersionControl, _}
import mill.util.{TestEvaluator, TestUtil}
import utest._
import utest.framework.TestPath
Expand Down Expand Up @@ -213,27 +211,6 @@ object HelloWorldTests extends TestSuite {
}
}

object HelloWorldWithPublish extends HelloBase {
object core extends HelloWorldModule with PublishModule {
override def artifactName = "hello-world"
override def publishVersion = "0.0.1"
override def pomSettings = PomSettings(
organization = "com.lihaoyi",
description = "hello world ready for real world publishing",
url = "https://github.com/lihaoyi/hello-world-publish",
licenses = Seq(License.Common.Apache2),
versionControl = VersionControl.github("lihaoyi", "hello-world-publish"),
developers =
Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi"))
)
override def versionScheme = Some(VersionScheme.EarlySemVer)

def checkSonatypeCreds(sonatypeCreds: String) = T.command {
PublishModule.checkSonatypeCreds(sonatypeCreds)
}
}
}

object HelloWorldScalaOverride extends HelloBase {
object core extends HelloWorldModule {
override def scalaVersion: Target[String] = scala213Version
Expand Down Expand Up @@ -1340,98 +1317,6 @@ object HelloWorldTests extends TestSuite {
assert(evalCount > 0)
}

"pom" - {
"should include scala-library dependency" - workspaceTest(HelloWorldWithPublish) { eval =>
val Right((result, evalCount)) = eval.apply(HelloWorldWithPublish.core.pom)

assert(
os.exists(result.path),
evalCount > 0
)

val pomXml = scala.xml.XML.loadFile(result.path.toString)
val scalaLibrary = pomXml \ "dependencies" \ "dependency"
assert(
(scalaLibrary \ "artifactId").text == "scala-library",
(scalaLibrary \ "groupId").text == "org.scala-lang"
)
}
"versionScheme" - workspaceTest(HelloWorldWithPublish) { eval =>
val Right((result, evalCount)) = eval.apply(HelloWorldWithPublish.core.pom)

assert(
os.exists(result.path),
evalCount > 0
)

val pomXml = scala.xml.XML.loadFile(result.path.toString)
val versionScheme = pomXml \ "properties" \ "info.versionScheme"
assert(versionScheme.text == "early-semver")
}
}

"publish" - {
"should retrieve credentials from environment variables if direct argument is empty" - workspaceTest(
HelloWorldWithPublish,
env = Evaluator.defaultEnv ++ Seq(
"SONATYPE_USERNAME" -> "user",
"SONATYPE_PASSWORD" -> "password"
)
) { eval =>
val Right((credentials, evalCount)) =
eval.apply(HelloWorldWithPublish.core.checkSonatypeCreds(""))

assert(
credentials == "user:password",
evalCount > 0
)
}
"should prefer direct argument as credentials over environment variables" - workspaceTest(
HelloWorldWithPublish,
env = Evaluator.defaultEnv ++ Seq(
"SONATYPE_USERNAME" -> "user",
"SONATYPE_PASSWORD" -> "password"
)
) { eval =>
val directValue = "direct:value"
val Right((credentials, evalCount)) =
eval.apply(HelloWorldWithPublish.core.checkSonatypeCreds(directValue))

assert(
credentials == directValue,
evalCount > 0
)
}
"should throw exception if neither environment variables or direct argument were not passed" - workspaceTest(
HelloWorldWithPublish
) { eval =>
val Left(Result.Failure(msg, None)) =
eval.apply(HelloWorldWithPublish.core.checkSonatypeCreds(""))

assert(
msg.contains("Consider using SONATYPE_USERNAME/SONATYPE_PASSWORD environment variables")
)
}
}

"ivy" - {
"should include scala-library dependency" - workspaceTest(HelloWorldWithPublish) { eval =>
val Right((result, evalCount)) = eval.apply(HelloWorldWithPublish.core.ivy)

assert(
os.exists(result.path),
evalCount > 0
)

val ivyXml = scala.xml.XML.loadFile(result.path.toString)
val deps: NodeSeq = (ivyXml \ "dependencies" \ "dependency")
assert(deps.exists(n =>
(n \ "@conf").text == "compile->default(compile)" &&
(n \ "@name").text == "scala-library" && (n \ "@org").text == "org.scala-lang"
))
}
}

"replAmmoniteMainClass" - workspaceTest(AmmoniteReplMainClass) { eval =>
val Right((oldResult, _)) = eval.apply(AmmoniteReplMainClass.oldAmmonite.ammoniteMainClass)
assert(oldResult == "ammonite.Main")
Expand Down
Loading

0 comments on commit 4f6742d

Please sign in to comment.