mirror of https://github.com/sbt/sbt.git
**Problem** Excluding artifacts using `.exclude(org, name)` requires you to explicitly set scala version in `name`. **Solution** - Deprecating `.exclude(org, name)` in favor of new `.exclude(OrganizationArtifactName)` - Fixing `lmcoursier.FromSbt` ignores `excludeRule.crossVersion`
This commit is contained in:
parent
1a8ac935f9
commit
12cbd877bc
|
|
@ -9,6 +9,7 @@ import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties
|
|||
import scala.collection.mutable.ListBuffer
|
||||
import sbt.librarymanagement.syntax.*
|
||||
import sbt.util.Logger
|
||||
import sbt.librarymanagement.DependencyBuilders.OrganizationArtifactName
|
||||
|
||||
private[librarymanagement] abstract class ModuleIDExtra {
|
||||
def organization: String
|
||||
|
|
@ -152,9 +153,18 @@ private[librarymanagement] abstract class ModuleIDExtra {
|
|||
def excludeAll(rules: ExclusionRule*): ModuleID = withExclusions(exclusions ++ rules)
|
||||
|
||||
/** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */
|
||||
@deprecated(
|
||||
"`name` parameter must contain scala version if artifact is cross-versioned. Use `exclude(\"org\" %% \"name\")`.",
|
||||
since = "2.0.0"
|
||||
)
|
||||
def exclude(org: String, name: String): ModuleID =
|
||||
excludeAll(ExclusionRule().withOrganization(org).withName(name))
|
||||
|
||||
/** Excludes the dependency from being introduced by this dependency during resolution. */
|
||||
def exclude(rule: OrganizationArtifactName): ModuleID = {
|
||||
excludeAll(rule)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds extra attributes for this module. All keys are prefixed with `e:` if they are not already so prefixed.
|
||||
* This information will only be published in an ivy.xml and not in a pom.xml.
|
||||
|
|
|
|||
|
|
@ -19,19 +19,21 @@ import sbt.librarymanagement.{ Configuration as _, * }
|
|||
|
||||
object FromSbt {
|
||||
|
||||
private def sbtModuleIdName(
|
||||
moduleId: ModuleID,
|
||||
private def sbtCrossName(
|
||||
name: String,
|
||||
crossVersion: CrossVersion,
|
||||
platformOpt: Option[String],
|
||||
scalaVersion: => String,
|
||||
scalaBinaryVersion: => String,
|
||||
optionalCrossVer: Boolean = false,
|
||||
projectPlatform: Option[String],
|
||||
): String = {
|
||||
val name0 = moduleId.name
|
||||
val name0 = name
|
||||
val name1 =
|
||||
moduleId.crossVersion match
|
||||
crossVersion match
|
||||
case _: Disabled => name0
|
||||
case _ => addPlatformSuffix(name0, moduleId.platformOpt, projectPlatform)
|
||||
val updatedName = CrossVersion(moduleId.crossVersion, scalaVersion, scalaBinaryVersion)
|
||||
case _ => addPlatformSuffix(name0, platformOpt, projectPlatform)
|
||||
val updatedName = CrossVersion(crossVersion, scalaVersion, scalaBinaryVersion)
|
||||
.fold(name1)(_(name1))
|
||||
if (!optionalCrossVer || updatedName.length <= name0.length)
|
||||
updatedName
|
||||
|
|
@ -81,7 +83,15 @@ object FromSbt {
|
|||
): (Module, String) = {
|
||||
|
||||
val fullName =
|
||||
sbtModuleIdName(module, scalaVersion, scalaBinaryVersion, optionalCrossVer, projectPlatform)
|
||||
sbtCrossName(
|
||||
module.name,
|
||||
module.crossVersion,
|
||||
module.platformOpt,
|
||||
scalaVersion,
|
||||
scalaBinaryVersion,
|
||||
optionalCrossVer,
|
||||
projectPlatform
|
||||
)
|
||||
|
||||
val module0 = Module(
|
||||
Organization(module.organization),
|
||||
|
|
@ -125,7 +135,16 @@ object FromSbt {
|
|||
Configuration(""),
|
||||
exclusions = module.exclusions.map { rule =>
|
||||
// FIXME Other `rule` fields are ignored here
|
||||
(Organization(rule.organization), ModuleName(rule.name))
|
||||
val ruleFullName = sbtCrossName(
|
||||
rule.name,
|
||||
rule.crossVersion,
|
||||
platformOpt = None,
|
||||
scalaVersion,
|
||||
scalaBinaryVersion,
|
||||
optionalCrossVer,
|
||||
projectPlatform
|
||||
)
|
||||
(Organization(rule.organization), ModuleName(ruleFullName))
|
||||
}.toSet,
|
||||
Publication("", Type(""), Extension(""), Classifier("")),
|
||||
optional = false,
|
||||
|
|
@ -200,8 +219,10 @@ object FromSbt {
|
|||
Module(
|
||||
Organization(projectID.organization),
|
||||
ModuleName(
|
||||
sbtModuleIdName(
|
||||
projectID,
|
||||
sbtCrossName(
|
||||
projectID.name,
|
||||
projectID.crossVersion,
|
||||
projectID.platformOpt,
|
||||
scalaVersion,
|
||||
scalaBinaryVersion,
|
||||
projectPlatform = projectPlatform
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package sbt.internal.librarymanagement
|
|||
import sbt.librarymanagement.*
|
||||
import sbt.librarymanagement.syntax.*
|
||||
import DependencyBuilders.OrganizationArtifactName
|
||||
import scala.annotation.nowarn
|
||||
|
||||
object InclExclSpec extends BaseIvySpecification {
|
||||
val scala210 = Some("2.10.4")
|
||||
|
|
@ -24,6 +25,35 @@ object InclExclSpec extends BaseIvySpecification {
|
|||
testLiftJsonIsMissing(report)
|
||||
}
|
||||
|
||||
test(
|
||||
"it should exclude any version of cross-built lift-json using `.exclude(String, String)` method with direct scala version definition"
|
||||
) {
|
||||
@nowarn
|
||||
val liftDep =
|
||||
("net.liftweb" %% "lift-mapper" % "2.6-M4" % "compile")
|
||||
.exclude("net.liftweb", "lift-json_2.10")
|
||||
val report = getIvyReport(liftDep, scala210)
|
||||
testLiftJsonIsMissing(report)
|
||||
}
|
||||
|
||||
test(
|
||||
"it should exclude any version of cross-built lift-json using `.exclude(OrganizationArtifactName)` method"
|
||||
) {
|
||||
val liftDep =
|
||||
("net.liftweb" %% "lift-mapper" % "2.6-M4" % "compile")
|
||||
.exclude("net.liftweb" %% "lift-json")
|
||||
val report = getIvyReport(liftDep, scala210)
|
||||
testLiftJsonIsMissing(report)
|
||||
}
|
||||
|
||||
test("it should exclude any version of cross-built lift-json using `.excludeAll` method") {
|
||||
val liftDep =
|
||||
("net.liftweb" %% "lift-mapper" % "2.6-M4" % "compile")
|
||||
.excludeAll("net.liftweb" %% "lift-json")
|
||||
val report = getIvyReport(liftDep, scala210)
|
||||
testLiftJsonIsMissing(report)
|
||||
}
|
||||
|
||||
val scala2122 = Some("2.12.2")
|
||||
test("it should exclude a concrete version of lift-json when it's full cross version") {
|
||||
val excluded: ModuleID = ("org.scalameta" % "scalahost" % "1.7.0").cross(CrossVersion.full)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
ThisBuild / csrCacheDirectory := (ThisBuild / baseDirectory).value / "coursier-cache"
|
||||
ivyPaths := IvyPaths(
|
||||
(ThisBuild / baseDirectory).value.toString,
|
||||
Some(((ThisBuild / baseDirectory).value / "ivy" / "cache").toString)
|
||||
)
|
||||
resolvers += "test-resolver" at ((ThisBuild / baseDirectory).value / "repo").toURI.toString
|
||||
|
||||
organization := "org.example"
|
||||
version := "0.1.0-SNAPSHOT"
|
||||
scalaVersion := "2.12.20"
|
||||
|
||||
@scala.annotation.nowarn
|
||||
lazy val libWithExcludedDeps = (project in file("lib"))
|
||||
.settings(
|
||||
name := "lib-with-excluded-deps",
|
||||
libraryDependencies += ("org.typelevel" %% "cats-effect" % "3.6.3")
|
||||
.excludeAll("org.typelevel" %% "cats-effect-kernel")
|
||||
.exclude("org.typelevel", "cats-effect-std_2.12")
|
||||
.exclude("org.typelevel" %% "cats-mtl"),
|
||||
publishTo := Some(Resolver.file("test-publish", (ThisBuild / baseDirectory).value / "repo")),
|
||||
)
|
||||
|
||||
lazy val dependsOnLibWithExcludedDeps = (project in file("."))
|
||||
.settings(
|
||||
name := "depends-on-lib-with-excluded-deps",
|
||||
libraryDependencies += "org.example" %% "lib-with-excluded-deps" % "0.1.0-SNAPSHOT",
|
||||
)
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
|
||||
import scala.util.Try
|
||||
|
||||
object Main {
|
||||
|
||||
def classFound(clsName: String) = Try(
|
||||
Thread.currentThread()
|
||||
.getContextClassLoader()
|
||||
.loadClass(clsName)
|
||||
).toOption.nonEmpty
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
val ioFound = classFound("cats.effect.IO")
|
||||
val asyncFound = classFound("cats.effect.kernel.Async")
|
||||
val mutexFound = classFound("cats.effect.std.Mutex")
|
||||
val askFound = classFound("cats.mtl.Ask")
|
||||
|
||||
assert(
|
||||
ioFound,
|
||||
"Expected to find class from cats-effect"
|
||||
)
|
||||
assert(
|
||||
!asyncFound,
|
||||
"Expected not to find class from cats-effect-kernel"
|
||||
)
|
||||
assert(
|
||||
!mutexFound,
|
||||
"Expected not to find class from cats-effect-std"
|
||||
)
|
||||
assert(
|
||||
!askFound,
|
||||
"Expected not to find class from cats-mtl"
|
||||
)
|
||||
|
||||
Files.write(new File("output").toPath, "OK".getBytes("UTF-8"))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
$ delete output
|
||||
$ delete repo
|
||||
$ delete coursier-cache
|
||||
$ delete ivy
|
||||
|
||||
> set libWithExcludedDeps/publishMavenStyle := true
|
||||
> libWithExcludedDeps/publish
|
||||
> dependsOnLibWithExcludedDeps/run
|
||||
$ exists output
|
||||
|
||||
$ delete output
|
||||
$ delete repo
|
||||
$ delete coursier-cache
|
||||
$ delete ivy
|
||||
|
||||
> set libWithExcludedDeps/publishMavenStyle := false
|
||||
> libWithExcludedDeps/publish
|
||||
> dependsOnLibWithExcludedDeps/run
|
||||
$ exists output
|
||||
Loading…
Reference in New Issue