From 1bec7c3284c51364869d97ec0763acfc1321bcea Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Wed, 18 Dec 2024 15:54:23 +0100 Subject: [PATCH] Add missing support for excluding transient dependencies when publishing (#3357) --- .../scala/cli/commands/publish/Ivy.scala | 20 +++++-- .../scala/cli/commands/publish/Publish.scala | 2 +- .../PublishLocalTestDefinitions.scala | 53 +++++++++++++++++-- project/deps.sc | 3 +- 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/Ivy.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/Ivy.scala index 590ae1e0a5..f31668ed43 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/Ivy.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/Ivy.scala @@ -1,6 +1,6 @@ package scala.cli.commands.publish -import coursier.core.{Configuration, ModuleName, Organization, Type} +import coursier.core.{Configuration, MinimizedExclusions, ModuleName, Organization, Type} import coursier.publish.Pom import coursier.publish.Pom.{Developer, License, Scm} @@ -31,7 +31,13 @@ object Ivy { url: Option[String] = None, name: Option[String] = None, // TODO Accept full-fledged coursier.Dependency - dependencies: Seq[(Organization, ModuleName, String, Option[Configuration])] = Nil, + dependencies: Seq[( + Organization, + ModuleName, + String, + Option[Configuration], + MinimizedExclusions + )] = Nil, license: Option[License] = None, scm: Option[Scm] = None, developers: Seq[Developer] = Nil, @@ -110,10 +116,16 @@ object Ivy { nodes += { val depNodes = dependencies.map { - case (org, name, ver, confOpt) => + case (org, name, ver, confOpt, exclusions) => val conf = confOpt.map(_.value).getOrElse("compile") val confSpec = s"$conf->default(compile)" - + val exclusionNodes = + exclusions.data.toSet().map { case (org, module) => + + } + + {exclusionNodes} + } {depNodes} diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala index c5f38e7385..f6a315ff9a 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala @@ -603,7 +603,7 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers { val config = if (build.scope == Scope.Main) None else Some(Configuration(build.scope.name)) - (dep0.module.organization, dep0.module.name, dep0.version, config) + (dep0.module.organization, dep0.module.name, dep0.version, config, dep0.minimizedExclusions) } val url = publishOptions.url.map(_.value) val license = publishOptions.license.map(_.value).map { l => diff --git a/modules/integration/src/test/scala/scala/cli/integration/PublishLocalTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/PublishLocalTestDefinitions.scala index 5aaa223337..7b4173d572 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/PublishLocalTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/PublishLocalTestDefinitions.scala @@ -17,15 +17,19 @@ abstract class PublishLocalTestDefinitions extends ScalaCliSuite with TestScalaV private object PublishTestInputs { def testOrg: String = "test-local-org.sth" def testName: String = "my-proj" - def projFile(message: String): String = + def projFile(message: String, exclude: Boolean = false): String = s"""//> using scala $testedPublishedScalaVersion - |//> using dep com.lihaoyi::os-lib:0.9.1 + |//> using dep com.lihaoyi::os-lib:0.11.3${Some(",exclude=com.lihaoyi%%geny").filter(_ => + exclude + ).getOrElse("")} | |object Project { | def message = "$message" | - | def main(args: Array[String]): Unit = + | def main(args: Array[String]): Unit = { + | os.pwd | println(message) + | } |} |""".stripMargin @@ -39,9 +43,13 @@ abstract class PublishLocalTestDefinitions extends ScalaCliSuite with TestScalaV |""".stripMargin } - def inputs(message: String = "Hello", includePublishVersion: Boolean = true): TestInputs = + def inputs( + message: String = "Hello", + includePublishVersion: Boolean = true, + excludeGeny: Boolean = false + ): TestInputs = TestInputs( - os.rel / "project.scala" -> projFile(message), + os.rel / "project.scala" -> projFile(message, excludeGeny), os.rel / "publish-conf.scala" -> publishConfFile(includePublishVersion) ) } @@ -215,4 +223,39 @@ abstract class PublishLocalTestDefinitions extends ScalaCliSuite with TestScalaV } } + if (actualScalaVersion.startsWith("3")) + test("publish local excluding a transitive dependency") { + PublishTestInputs.inputs(excludeGeny = true).fromRoot { root => + val failPublishAsGenyIsntProvided = + os.proc( + TestUtil.cli, + "--power", + "publish", + "local", + ".", + extraOptions + ) + .call(cwd = root, check = false) + expect(failPublishAsGenyIsntProvided.exitCode == 1) + val genyDep = "com.lihaoyi::geny:1.1.1" + os.proc( + TestUtil.cli, + "--power", + "publish", + "local", + ".", + "--compile-dep", + genyDep, + extraOptions + ) + .call(cwd = root) + val publishedDep = + s"${PublishTestInputs.testOrg}:${PublishTestInputs.testName}_$testedPublishedScalaVersion:$testPublishVersion" + val failRunAsGenyIsntProvided = os.proc(TestUtil.cli, "run", "--dep", publishedDep) + .call(cwd = root, check = false) + expect(failRunAsGenyIsntProvided.exitCode == 1) + os.proc(TestUtil.cli, "run", "--dep", publishedDep, "--dep", genyDep).call(cwd = root) + } + } + } diff --git a/project/deps.sc b/project/deps.sc index f7673723f1..1f5291af07 100644 --- a/project/deps.sc +++ b/project/deps.sc @@ -160,7 +160,7 @@ object Deps { .exclude(("ai.kien", "python-native-libs_2.13")) .exclude(("org.scala-lang.modules", "scala-collection-compat_2.13")) def coursierProxySetup = ivy"io.get-coursier:coursier-proxy-setup:${Versions.coursier}" - def coursierPublish = ivy"io.get-coursier.publish:publish_2.13:0.1.6" + def coursierPublish = ivy"io.get-coursier.publish:publish_2.13:0.2.0" .exclude(("org.scala-lang.modules", "scala-collection-compat_2.13")) .exclude(("com.github.plokhotnyuk.jsoniter-scala", "jsoniter-scala-core_2.13")) def dependency = ivy"io.get-coursier::dependency:0.3.2" @@ -239,6 +239,7 @@ object Deps { .exclude(("com.github.plokhotnyuk.jsoniter-scala", "jsoniter-scala-core_3")) .exclude(("com.github.plokhotnyuk.jsoniter-scala", "jsoniter-scala-macros_3")) .exclude(("com.github.plokhotnyuk.jsoniter-scala", "jsoniter-scala-core_2.13")) + .exclude(("io.get-coursier.publish", "publish_2.13")) .exclude(("org.scala-lang.modules", "scala-collection-compat_2.13")) def slf4jNop = ivy"org.slf4j:slf4j-nop:2.0.16" def sttp = ivy"com.softwaremill.sttp.client3:core_2.13:3.10.1"