diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala index 93a19c87f..d5050d242 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala @@ -200,7 +200,8 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen interProjectDependencies = interProjectDependencies, res = resolutions, includeSignatures = false, - sbtBootJarOverrides = sbtBootJarOverrides + sbtBootJarOverrides = sbtBootJarOverrides, + classpathOrder = conf.classpathOrder, ) val e = for { diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala index 152290308..b58a6d571 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala @@ -139,9 +139,10 @@ private[internal] object SbtUpdateReport { artifactFileOpt: (Module, String, Attributes, Artifact) => Option[File], log: Logger, keepPomArtifact: Boolean = false, - includeSignatures: Boolean = false - ) = { - val depArtifacts1 = res.dependencyArtifacts(classifiersOpt) + includeSignatures: Boolean = false, + classpathOrder: Boolean, + ): Vector[ModuleReport] = { + val depArtifacts1 = res.dependencyArtifacts(classifiersOpt, classpathOrder) val depArtifacts0 = if (keepPomArtifact) @@ -174,14 +175,16 @@ private[internal] object SbtUpdateReport { } else depArtifacts0 - val groupedDepArtifacts = depArtifacts - .groupBy(_._1) - .mapValues(_.map { case (_, attr, a) => (attr, a) }) - .iterator - .toMap ++ - Map(interProjectDependencies + val groupedDepArtifacts = { + val m = depArtifacts.groupBy(_._1) + val fromLib = depArtifacts.map(_._1).distinct.map { dep => + dep -> m.getOrElse(dep, Nil).map { case (_, pub, a) => (pub, a) } + } + val fromInterProj = interProjectDependencies .filter(p => p.module != thisModule._1) - .map(p => Dependency(p.module, p.version) -> Nil): _*) + .map(p => Dependency(p.module, p.version) -> Nil) + fromLib ++ fromInterProj + } val versions = (Vector(Dependency(thisModule._1, thisModule._2)) ++ res.dependencies.toVector ++ res.rootDependencies.toVector) .map { dep => @@ -202,7 +205,7 @@ private[internal] object SbtUpdateReport { mv == (p.module, p.version) ) } - + val m = Dependency(thisModule._1, "") val directReverseDependencies = res.rootDependencies.toSet.map(clean).map(_.withVersion("")) .map( @@ -220,7 +223,7 @@ private[internal] object SbtUpdateReport { .toVector .toMap ++ directReverseDependencies - groupedDepArtifacts.map { + groupedDepArtifacts.toVector.map { case (dep, artifacts) => val proj = lookupProject(dep.moduleVersion).get @@ -259,7 +262,8 @@ private[internal] object SbtUpdateReport { artifactFileOpt: (Module, String, Attributes, Artifact) => Option[File], log: Logger, keepPomArtifact: Boolean = false, - includeSignatures: Boolean = false + includeSignatures: Boolean = false, + classpathOrder: Boolean, ): UpdateReport = { val configReports = configs.map { @@ -280,7 +284,8 @@ private[internal] object SbtUpdateReport { artifactFileOpt, log, keepPomArtifact = keepPomArtifact, - includeSignatures = includeSignatures + includeSignatures = includeSignatures, + classpathOrder = classpathOrder, ) val reports0 = diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala index f5d0ff23b..d7c20a6f8 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala @@ -16,7 +16,8 @@ final case class UpdateParams( interProjectDependencies: Seq[Project], res: Map[Set[Configuration], Resolution], includeSignatures: Boolean, - sbtBootJarOverrides: Map[(Module, String), File] + sbtBootJarOverrides: Map[(Module, String), File], + classpathOrder: Boolean, ) { def artifactFileOpt( diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala index 4e394ea25..f4230c9b3 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala @@ -93,7 +93,8 @@ object UpdateRun { params.classifiers, params.artifactFileOpt, log, - includeSignatures = params.includeSignatures + includeSignatures = params.includeSignatures, + classpathOrder = params.classpathOrder, ) } diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala index 456bb2d45..3e3577d4a 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala @@ -136,7 +136,8 @@ object UpdateTasks { interProjectDependencies, res, includeSignatures, - sbtBootJarOverrides + sbtBootJarOverrides, + classpathOrder = true, ) val rep = UpdateRun.update(params, verbosityLevel, log) diff --git a/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/build.sbt b/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/build.sbt new file mode 100644 index 000000000..7df3d167c --- /dev/null +++ b/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/build.sbt @@ -0,0 +1,4 @@ +scalaVersion := "2.13.1" + +libraryDependencies += "com.typesafe.play" %% "play-test" % "2.8.0-RC1" % Test // worked around in 2.8.0 +libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % Test diff --git a/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/project/plugins.sbt b/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/project/plugins.sbt new file mode 100644 index 000000000..71a44ffd3 --- /dev/null +++ b/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/project/plugins.sbt @@ -0,0 +1,13 @@ +addSbtPlugin { + + val name = sys.props.getOrElse( + "plugin.name", + sys.error("plugin.name Java property not set") + ) + val version = sys.props.getOrElse( + "plugin.version", + sys.error("plugin.version Java property not set") + ) + + "io.get-coursier" % name % version +} \ No newline at end of file diff --git a/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/src/test/scala/t/UnitSpec.scala b/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/src/test/scala/t/UnitSpec.scala new file mode 100644 index 000000000..d1735b308 --- /dev/null +++ b/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/src/test/scala/t/UnitSpec.scala @@ -0,0 +1,20 @@ +package t + +import com.typesafe.config.ConfigFactory +import org.scalatest.{ MustMatchers, WordSpec } + +class UnitSpec extends WordSpec with MustMatchers { + def conf = ConfigFactory.defaultReference() + + "Config" should { + "return Akka HTTP server provider" in { + val serverProvider = conf.getString("play.server.provider") + serverProvider mustBe "play.core.server.AkkaHttpServerProvider" + } + + "be able to load Netty settings" in { + val nettyTransport = conf.getString("play.server.netty.transport") + nettyTransport mustBe "jdk" + } + } +} diff --git a/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/test b/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/test new file mode 100644 index 000000000..388482c7e --- /dev/null +++ b/modules/sbt-coursier/src/sbt-test/sbt-lm-coursier/cp-order/test @@ -0,0 +1,6 @@ +# https://github.com/coursier/coursier/issues/1466 +> test +# ideally we can flip & assert the test fails +# but need to run this scripted test on sbt 1.3 in order to have a csrConfiguration +# > set csrConfiguration ~= (_.withClasspathOrder(false)) +# -> test diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/scala-jars/src/main/scala/Main.scala b/modules/sbt-coursier/src/sbt-test/shared-2/scala-jars/src/main/scala/Main.scala index 932b548a8..be71ad33a 100644 --- a/modules/sbt-coursier/src/sbt-test/shared-2/scala-jars/src/main/scala/Main.scala +++ b/modules/sbt-coursier/src/sbt-test/shared-2/scala-jars/src/main/scala/Main.scala @@ -22,22 +22,32 @@ object Main extends App { buildCp(Thread.currentThread().getContextClassLoader) + System.err.println("Classpath:") + for (f <- cp) + System.err.println(s" $f") + System.err.println() + val sbtBase = new File(sys.props.getOrElse( "sbt.global.base", sys.props("user.home") + "/.sbt" )) val prefixes = Seq(new File(sbtBase, "boot").getAbsolutePath) ++ - Seq("coursier.sbt-launcher.dirs.scala-jars", "coursier.sbt-launcher.dirs.base") + Seq("coursier.sbt-launcher.dirs.scala-jars", "coursier.sbt-launcher.dirs.base", "user.dir") .flatMap(sys.props.get(_)) .map(new File(_).getAbsolutePath) + val home = new File(sys.props("user.home")).getAbsolutePath - def fromBootAndUnique(name: String): Unit = { + def notFromCoursierCache(name: String): Unit = { val jars = cp.filter(_.getName.startsWith(name)).distinct - assert(jars.length == 1, s"Found 0 or multiple JARs for $name: $jars") + assert(jars.nonEmpty, s"Found no JARs for $name") - val Seq(jar) = jars - - assert(prefixes.exists(jar.getAbsolutePath.startsWith), s"JAR for $name ($jar) not under any of ${prefixes.mkString(", ")}") + for (jar <- jars) + assert( + !jar.getAbsolutePath.startsWith(home) || + !jar.getAbsolutePath.toLowerCase(java.util.Locale.ROOT).contains("coursier") || + prefixes.exists(jar.getAbsolutePath.startsWith), + s"JAR for $name ($jar) under $home and not under any of ${prefixes.mkString(", ")}" + ) } val props = Thread.currentThread() @@ -48,12 +58,8 @@ object Main extends App { .map(_.toString) .sorted - // That one doesn't pass with sbt 1.x, maybe because of classloader filtering? - // fromBootAndUnique("scala-library") + notFromCoursierCache("scala-library") assert(props.lengthCompare(1) == 0, s"Found several library.properties files in classpath: $props") - fromBootAndUnique("scala-reflect") - fromBootAndUnique("scala-compiler") - Files.write(new File("output").toPath, "OK".getBytes("UTF-8")) } diff --git a/project/Settings.scala b/project/Settings.scala index 052320c73..530c8f69d 100644 --- a/project/Settings.scala +++ b/project/Settings.scala @@ -12,7 +12,7 @@ object Settings { def scala212 = "2.12.10" - def sbt10Version = "1.0.2" + def targetSbtVersion = "1.2.8" private lazy val isAtLeastScala213 = Def.setting { import Ordering.Implicits._ @@ -52,7 +52,7 @@ object Settings { shared ++ Seq( // https://github.com/sbt/sbt/issues/5049#issuecomment-528960415 - dependencyOverrides := "org.scala-sbt" % "sbt" % "1.2.8" :: Nil, + dependencyOverrides := "org.scala-sbt" % "sbt" % targetSbtVersion :: Nil, scriptedLaunchOpts ++= Seq( "-Xmx1024M", "-Dplugin.name=" + name.value, @@ -62,7 +62,7 @@ object Settings { ), scriptedBufferLog := false, sbtPlugin := true, - sbtVersion.in(pluginCrossBuild) := sbt10Version + sbtVersion.in(pluginCrossBuild) := targetSbtVersion ) lazy val shading =