mirror of https://github.com/sbt/sbt.git
[2.x] fix: Ensure correct platform suffix in published artifact names
This commit is contained in:
parent
fcd247e7c6
commit
8884488146
|
|
@ -106,11 +106,7 @@ private[librarymanagement] abstract class ArtifactFunctions {
|
|||
val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary)
|
||||
val withPlatform = module.crossVersion match {
|
||||
case _: Disabled => artifact.name
|
||||
case _ =>
|
||||
module.platformOpt match {
|
||||
case Some(p) if p.nonEmpty && p != Platform.jvm => s"${artifact.name}_$p"
|
||||
case _ => artifact.name
|
||||
}
|
||||
case _ => CrossVersion.addPlatformSuffix(artifact.name, module.platformOpt, None)
|
||||
}
|
||||
val base = CrossVersion.applyCross(withPlatform, cross)
|
||||
base + "-" + module.revision + classifierStr + "." + artifact.extension
|
||||
|
|
|
|||
|
|
@ -166,6 +166,20 @@ private[librarymanagement] abstract class CrossVersionFunctions {
|
|||
private[sbt] def crossName(name: String, cross: String): String =
|
||||
name + "_" + cross
|
||||
|
||||
/**
|
||||
* Appends the platform suffix (e.g. `native0.5`, `sjs1`) to `name`, preferring an explicit
|
||||
* `platformOpt` over the `projectPlatform`. `""` and `jvm` add no suffix.
|
||||
*/
|
||||
def addPlatformSuffix(
|
||||
name: String,
|
||||
platformOpt: Option[String],
|
||||
projectPlatform: Option[String]
|
||||
): String =
|
||||
(platformOpt orElse projectPlatform) match {
|
||||
case Some(p) if p.nonEmpty && p != Platform.jvm => crossName(name, p)
|
||||
case _ => name
|
||||
}
|
||||
|
||||
/** Cross-versions `exclude` according to its `crossVersion`. */
|
||||
private[sbt] def substituteCross(
|
||||
exclude: ExclusionRule,
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ object FromSbt {
|
|||
val name1 =
|
||||
crossVersion match
|
||||
case _: Disabled => name0
|
||||
case _ => addPlatformSuffix(name0, platformOpt, projectPlatform)
|
||||
case _ => CrossVersion.addPlatformSuffix(name0, platformOpt, projectPlatform)
|
||||
val updatedName = CrossVersion(crossVersion, scalaVersion, scalaBinaryVersion)
|
||||
.fold(name1)(_(name1))
|
||||
if (!optionalCrossVer || updatedName.length <= name0.length)
|
||||
|
|
@ -46,25 +46,6 @@ object FromSbt {
|
|||
}
|
||||
}
|
||||
|
||||
private def addPlatformSuffix(
|
||||
name: String,
|
||||
platformOpt: Option[String],
|
||||
projectPlatform: Option[String]
|
||||
): String = {
|
||||
def addSuffix(platformName: String): String =
|
||||
platformName match {
|
||||
case "" | "jvm" => name
|
||||
case _ => s"${name}_$platformName"
|
||||
}
|
||||
(platformOpt, projectPlatform) match {
|
||||
case (Some(p), _) =>
|
||||
addSuffix(p) // Use explicit platform if set (don't override with project platform)
|
||||
case (None, Some(p)) =>
|
||||
addSuffix(p) // Only use project platform if dependency has no explicit platform
|
||||
case _ => name
|
||||
}
|
||||
}
|
||||
|
||||
private def attributes(attr: Map[String, String]): Map[String, String] =
|
||||
attr
|
||||
.map { (k, v) =>
|
||||
|
|
|
|||
|
|
@ -234,8 +234,18 @@ object IvyActions {
|
|||
}
|
||||
private def crossVersionMap(moduleSettings: ModuleSettings): Option[String => String] =
|
||||
moduleSettings match {
|
||||
case i: InlineConfiguration => CrossVersion(i.module, i.scalaModuleInfo)
|
||||
case _ => None
|
||||
case i: InlineConfiguration =>
|
||||
// Platform suffix before cross suffix, matching the coordinate (sbt/sbt#9117).
|
||||
CrossVersion(i.module, i.scalaModuleInfo).map { fn => (name: String) =>
|
||||
fn(
|
||||
CrossVersion.addPlatformSuffix(
|
||||
name,
|
||||
i.module.platformOpt,
|
||||
i.scalaModuleInfo.flatMap(_.platform)
|
||||
)
|
||||
)
|
||||
}
|
||||
case _ => None
|
||||
}
|
||||
def mapArtifacts(
|
||||
module: ModuleDescriptor,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ object CoursierArtifactsTasks {
|
|||
val projId = sbt.Keys.projectID.value
|
||||
val sv = sbt.Keys.scalaVersion.value
|
||||
val sbv = sbt.Keys.scalaBinaryVersion.value
|
||||
val projectPlatform = sbt.Keys.scalaModuleInfo.value.flatMap(_.platform)
|
||||
val ivyConfs = sbt.Keys.ivyConfigurations.value
|
||||
val extracted = Project.extract(s)
|
||||
import extracted.*
|
||||
|
|
@ -97,8 +98,13 @@ object CoursierArtifactsTasks {
|
|||
|
||||
def artifactPublication(artifact: Artifact) = {
|
||||
|
||||
// Platform suffix before cross suffix, matching the coordinate
|
||||
val base = projId.crossVersion match
|
||||
case _: Disabled => artifact.name
|
||||
case _ =>
|
||||
CrossVersion.addPlatformSuffix(artifact.name, projId.platformOpt, projectPlatform)
|
||||
val name = CrossVersion(projId.crossVersion, sv, sbv)
|
||||
.fold(artifact.name)(_(artifact.name))
|
||||
.fold(base)(_(base))
|
||||
|
||||
CPublication(
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -61,9 +61,14 @@ private[sbt] object PomGenerator:
|
|||
</project>
|
||||
|
||||
private def crossVersionDep(dep: ModuleID, scalaInfo: Option[ScalaModuleInfo]): ModuleID =
|
||||
// Platform suffix before cross suffix, matching the coordinate (sbt/sbt#9117).
|
||||
val base = dep.crossVersion match
|
||||
case _: Disabled => dep.name
|
||||
case _ =>
|
||||
CrossVersion.addPlatformSuffix(dep.name, dep.platformOpt, scalaInfo.flatMap(_.platform))
|
||||
val crossFn = CrossVersion(dep, scalaInfo)
|
||||
val crossDep = crossFn match
|
||||
case Some(fn) => dep.withName(fn(dep.name)).withCrossVersion(CrossVersion.disabled)
|
||||
case Some(fn) => dep.withName(fn(base)).withCrossVersion(CrossVersion.disabled)
|
||||
case None => dep
|
||||
if crossDep.exclusions.isEmpty || scalaInfo.isEmpty then crossDep
|
||||
else
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
// sbt/sbt#9117: published artifact filenames must carry the platform suffix
|
||||
// (e.g. _native0.5), matching the module coordinate / directory.
|
||||
|
||||
ThisBuild / organization := "com.example"
|
||||
ThisBuild / version := "0.1.0-SNAPSHOT"
|
||||
ThisBuild / scalaVersion := "3.8.3"
|
||||
ThisBuild / csrCacheDirectory := (ThisBuild / baseDirectory).value / "coursier-cache"
|
||||
|
||||
ThisBuild / platform := "native0.5"
|
||||
ThisBuild / crossVersion := CrossVersion.binary
|
||||
// expected cross+platform base name, identical to the coordinate directory
|
||||
def expected(name: String) = s"${name}_native0.5_3"
|
||||
|
||||
// ivyless backend: the published filenames come from the coursier publication names,
|
||||
// and the POM artifactId from PomGenerator.
|
||||
lazy val ivyless = (project in file("ivyless"))
|
||||
.settings(
|
||||
useIvy := false,
|
||||
ivyPaths := IvyPaths(baseDirectory.value.toString, Some((target.value / "ivy2").toString)),
|
||||
TaskKey[Unit]("check") := {
|
||||
val nm = expected(moduleName.value)
|
||||
val dir = target.value / "ivy2" / "local" / organization.value / nm / version.value
|
||||
def req(f: File): Unit = assert(f.exists, s"expected $f to exist")
|
||||
req(dir / "jars" / s"$nm.jar")
|
||||
req(dir / "srcs" / s"$nm-sources.jar")
|
||||
val pom = dir / "poms" / s"$nm.pom"
|
||||
req(pom)
|
||||
assert(IO.read(pom).contains(s"<artifactId>$nm</artifactId>"), s"POM artifactId must be $nm: ${IO.read(pom)}")
|
||||
}
|
||||
)
|
||||
|
||||
// Ivy backend (sbt-ivy): the published filenames come from CrossVersion.substituteCross.
|
||||
lazy val ivyfull = (project in file("ivyfull"))
|
||||
.settings(
|
||||
useIvy := true,
|
||||
publishMavenStyle := true,
|
||||
ivyPaths := IvyPaths(baseDirectory.value.toString, Some((target.value / "ivy2").toString)),
|
||||
publishTo := Some(MavenCache("test-maven", target.value / "maven-repo")),
|
||||
TaskKey[Unit]("check") := {
|
||||
val nm = expected(moduleName.value)
|
||||
val ver = version.value
|
||||
def req(f: File): Unit = assert(f.exists, s"expected $f to exist")
|
||||
val ivyDir = target.value / "ivy2" / "local" / organization.value / nm / ver
|
||||
req(ivyDir / "jars" / s"$nm.jar")
|
||||
req(ivyDir / "srcs" / s"$nm-sources.jar")
|
||||
req(ivyDir / "poms" / s"$nm.pom")
|
||||
val mvnDir = target.value / "maven-repo" / organization.value.replace('.', '/') / nm / ver
|
||||
req(mvnDir / s"$nm-$ver.jar")
|
||||
req(mvnDir / s"$nm-$ver.pom")
|
||||
}
|
||||
)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package lib
|
||||
|
||||
object Lib:
|
||||
def greeting: String = "hi"
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package lib
|
||||
|
||||
object Lib:
|
||||
def greeting: String = "hi"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
// sbt-ivy provides the Ivy publish backend exercised by the `ivyfull` project.
|
||||
libraryDependencies += {
|
||||
val sbtV = sbtVersion.value
|
||||
("org.scala-sbt" % s"sbt-ivy_sbt${sbtV}_${scalaBinaryVersion.value}" % sbtV).intransitive()
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# sbt/sbt#9117: published artifact filenames must carry the platform suffix
|
||||
# (_native0.5), matching the coordinate, on both the ivyless and Ivy backends.
|
||||
|
||||
# ivyless backend: publication names + POM artifactId
|
||||
> ivyless/publishLocal
|
||||
> ivyless/check
|
||||
|
||||
# Ivy backend (useIvy := true): publishLocal (ivy layout) and publish (maven layout)
|
||||
> ivyfull/publishLocal
|
||||
> ivyfull/publish
|
||||
> ivyfull/check
|
||||
Loading…
Reference in New Issue