diff --git a/build.sbt b/build.sbt index ebff0e355..285c5c7f3 100644 --- a/build.sbt +++ b/build.sbt @@ -147,6 +147,7 @@ lazy val core = crossProject Seq( // Since 1.0.0-M10 + ProblemFilters.exclude[IncompatibleResultTypeProblem]("coursier.core.Resolution.withParentConfigurations"), // New singleton object, problem for forward compatibility only ProblemFilters.exclude[MissingTypesProblem]("coursier.maven.MavenSource$") ) diff --git a/core/shared/src/main/scala/coursier/core/Definitions.scala b/core/shared/src/main/scala/coursier/core/Definitions.scala index f178a0cab..085b00fe3 100644 --- a/core/shared/src/main/scala/coursier/core/Definitions.scala +++ b/core/shared/src/main/scala/coursier/core/Definitions.scala @@ -25,9 +25,11 @@ final case class Module( .map { case (k, v) => s"$k=$v" } .mkString(";") - override def toString = - s"$organization:$name" + - (if (attributes.nonEmpty) s";$attributesStr" else "") + def nameWithAttributes: String = + name + (if (attributes.nonEmpty) s";$attributesStr" else "") + + override def toString: String = + s"$organization:$nameWithAttributes" override final lazy val hashCode = Module.unapply(this).get.hashCode() } diff --git a/core/shared/src/main/scala/coursier/core/Resolution.scala b/core/shared/src/main/scala/coursier/core/Resolution.scala index 8a2eb6b28..eb421de65 100644 --- a/core/shared/src/main/scala/coursier/core/Resolution.scala +++ b/core/shared/src/main/scala/coursier/core/Resolution.scala @@ -280,7 +280,7 @@ object Resolution { } } - def withParentConfigurations(config: String, configurations: Map[String, Seq[String]]): Set[String] = { + def withParentConfigurations(config: String, configurations: Map[String, Seq[String]]): (String, Set[String]) = { @tailrec def helper(configs: Set[String], acc: Set[String]): Set[String] = if (configs.isEmpty) @@ -306,7 +306,20 @@ object Resolution { case None => config } - helper(Set(config0), Set.empty) + (config0, helper(Set(config0), Set.empty)) + } + + private val mavenScopes = { + val base = Map[String, Set[String]]( + "compile" -> Set("compile"), + "provided" -> Set(), + "runtime" -> Set("compile", "runtime"), + "test" -> Set() + ) + + base ++ Seq( + "default" -> base("runtime") + ) } /** @@ -347,7 +360,12 @@ object Resolution { val properties = propertiesMap(properties0) - val configurations = withParentConfigurations(from.configuration, project.configurations) + val (actualConfig, configurations) = withParentConfigurations(from.configuration, project.configurations) + + // Vague attempt at making the Maven scope model fit into the Ivy configuration one + + val config = if (actualConfig.isEmpty) defaultConfiguration else actualConfig + val keepOpt = mavenScopes.get(config) withExclusions( depsWithDependencyManagement( @@ -359,20 +377,36 @@ object Resolution { ), from.exclusions ) - .map{ - case (config, dep) => - (if (config.isEmpty) defaultConfiguration else config) -> { - if (dep.configuration.isEmpty) - dep.copy(configuration = defaultConfiguration) + .flatMap { + case (config0, dep0) => + // Dependencies from Maven verify + // dep.configuration.isEmpty + // and expect dep.configuration to be filled here + + val dep = + if (from.optional) + dep0.copy(optional = true) else - dep - } - } - .collect{case (config, dep) if configurations(config) => - if (from.optional) - dep.copy(optional = true) - else - dep + dep0 + + val config = if (config0.isEmpty) defaultConfiguration else config0 + + def default = + if (configurations(config)) + Seq(dep) + else + Nil + + if (dep.configuration.nonEmpty) + default + else + keepOpt.fold(default) { keep => + if (keep(config)) + // really keeping the from.configuration, with its fallback config part + Seq(dep.copy(configuration = from.configuration)) + else + Nil + } } } diff --git a/tests/jvm/src/test/scala/coursier/test/IvyLocalTests.scala b/tests/jvm/src/test/scala/coursier/test/IvyLocalTests.scala index 63b55c93a..8e2da8887 100644 --- a/tests/jvm/src/test/scala/coursier/test/IvyLocalTests.scala +++ b/tests/jvm/src/test/scala/coursier/test/IvyLocalTests.scala @@ -12,18 +12,18 @@ object IvyLocalTests extends TestSuite { val tests = TestSuite{ 'coursier{ val module = Module("com.github.alexarchambault", "coursier_2.11") - val version = "1.0.0-M5" + val version = coursier.util.Properties.version val extraRepo = Some(Cache.ivy2Local) - // Assume this module (and the sub-projects it depends on) is published locally - CentralTests.resolutionCheck( + // Assuming this module (and the sub-projects it depends on) is published locally + * - CentralTests.resolutionCheck( module, version, extraRepo ) - async { + * - async { val res = await(CentralTests.resolve( Set(Dependency(module, version)), extraRepo = extraRepo diff --git a/tests/jvm/src/test/scala/coursier/test/IvyTests.scala b/tests/jvm/src/test/scala/coursier/test/IvyTests.scala index 03d54bd14..0b6bc6a56 100644 --- a/tests/jvm/src/test/scala/coursier/test/IvyTests.scala +++ b/tests/jvm/src/test/scala/coursier/test/IvyTests.scala @@ -7,7 +7,7 @@ import utest._ object IvyTests extends TestSuite { - // only tested on the JVM for lack of support of XML attributes in our XML wrappers + // only tested on the JVM for lack of support of XML attributes in the platform-dependent XML stubs val tests = TestSuite { 'dropInfoAttributes - { @@ -23,7 +23,8 @@ object IvyTests extends TestSuite { "[revision]/[type]s/[artifact](-[classifier]).[ext]", dropInfoAttributes = true ) - ) + ), + configuration = "default(compile)" ) } } diff --git a/tests/shared/src/test/resources/resolutions/com.android.tools/sdklib/24.5.0_compile b/tests/shared/src/test/resources/resolutions/com.android.tools/sdklib/24.5.0_compile new file mode 100644 index 000000000..ad3573e9d --- /dev/null +++ b/tests/shared/src/test/resources/resolutions/com.android.tools/sdklib/24.5.0_compile @@ -0,0 +1 @@ +com.android.tools:sdklib:24.5.0:compile diff --git a/tests/shared/src/test/resources/resolutions/com.android.tools/sdklib/24.5.0_runtime b/tests/shared/src/test/resources/resolutions/com.android.tools/sdklib/24.5.0_runtime new file mode 100644 index 000000000..b94a46af8 --- /dev/null +++ b/tests/shared/src/test/resources/resolutions/com.android.tools/sdklib/24.5.0_runtime @@ -0,0 +1,15 @@ +com.android.tools:annotations:24.5.0:runtime +com.android.tools:common:24.5.0:runtime +com.android.tools:dvlib:24.5.0:runtime +com.android.tools:sdklib:24.5.0:runtime +com.android.tools.layoutlib:layoutlib-api:24.5.0:runtime +com.google.code.gson:gson:2.2.4:runtime +com.google.guava:guava:17.0:runtime +com.intellij:annotations:12.0:runtime +commons-codec:commons-codec:1.4:runtime +commons-logging:commons-logging:1.1.1:runtime +net.sf.kxml:kxml2:2.3.0:runtime +org.apache.commons:commons-compress:1.8.1:runtime +org.apache.httpcomponents:httpclient:4.1.1:runtime +org.apache.httpcomponents:httpcore:4.1:runtime +org.apache.httpcomponents:httpmime:4.1:runtime diff --git a/tests/shared/src/test/resources/resolutions/com.github.alexarchambault/coursier_2.11/1.0.0-M5 b/tests/shared/src/test/resources/resolutions/com.github.alexarchambault/coursier_2.11/1.0.0-M5 deleted file mode 100644 index 2f8147e33..000000000 --- a/tests/shared/src/test/resources/resolutions/com.github.alexarchambault/coursier_2.11/1.0.0-M5 +++ /dev/null @@ -1,5 +0,0 @@ -com.github.alexarchambault:coursier_2.11:1.0.0-M5:compile -org.scala-lang.modules:scala-parser-combinators_2.11:1.0.4:compile -org.scala-lang.modules:scala-xml_2.11:1.0.4:compile -org.scala-lang:scala-library:2.11.7:compile -org.scalaz:scalaz-core_2.11:7.1.2:compile diff --git a/tests/shared/src/test/resources/resolutions/com.github.alexarchambault/coursier_2.11/1.0.0-SNAPSHOT b/tests/shared/src/test/resources/resolutions/com.github.alexarchambault/coursier_2.11/1.0.0-SNAPSHOT new file mode 100644 index 000000000..65b593655 --- /dev/null +++ b/tests/shared/src/test/resources/resolutions/com.github.alexarchambault/coursier_2.11/1.0.0-SNAPSHOT @@ -0,0 +1,5 @@ +com.github.alexarchambault:coursier_2.11:1.0.0-SNAPSHOT:compile +org.scala-lang:scala-library:2.11.7:default +org.scala-lang.modules:scala-parser-combinators_2.11:1.0.4:default +org.scala-lang.modules:scala-xml_2.11:1.0.4:default +org.scalaz:scalaz-core_2.11:7.1.2:default diff --git a/tests/shared/src/test/resources/resolutions/com.github.fommil/java-logging/1.2-SNAPSHOT b/tests/shared/src/test/resources/resolutions/com.github.fommil/java-logging/1.2-SNAPSHOT deleted file mode 100644 index ea22dc5fc..000000000 --- a/tests/shared/src/test/resources/resolutions/com.github.fommil/java-logging/1.2-SNAPSHOT +++ /dev/null @@ -1,5 +0,0 @@ -com.github.fommil:java-logging:1.2-SNAPSHOT:runtime -org.slf4j:jcl-over-slf4j:1.7.5:compile -org.slf4j:log4j-over-slf4j:1.7.5:compile -org.slf4j:slf4j-api:1.7.5:compile -org.slf4j:slf4j-jdk14:1.7.5:compile diff --git a/tests/shared/src/test/resources/resolutions/com.github.fommil/java-logging/1.2-SNAPSHOT_runtime b/tests/shared/src/test/resources/resolutions/com.github.fommil/java-logging/1.2-SNAPSHOT_runtime new file mode 100644 index 000000000..92db35f44 --- /dev/null +++ b/tests/shared/src/test/resources/resolutions/com.github.fommil/java-logging/1.2-SNAPSHOT_runtime @@ -0,0 +1,5 @@ +com.github.fommil:java-logging:1.2-SNAPSHOT:runtime +org.slf4j:jcl-over-slf4j:1.7.5:runtime +org.slf4j:log4j-over-slf4j:1.7.5:runtime +org.slf4j:slf4j-api:1.7.5:runtime +org.slf4j:slf4j-jdk14:1.7.5:runtime diff --git a/tests/shared/src/test/resources/resolutions/org.scala-js/sbt-scalajs/sbtVersion_0.13_scalaVersion_2.10/0.6.6 b/tests/shared/src/test/resources/resolutions/org.scala-js/sbt-scalajs/sbtVersion_0.13_scalaVersion_2.10/0.6.6 deleted file mode 100644 index a8b637693..000000000 --- a/tests/shared/src/test/resources/resolutions/org.scala-js/sbt-scalajs/sbtVersion_0.13_scalaVersion_2.10/0.6.6 +++ /dev/null @@ -1,18 +0,0 @@ -args4j:args4j:2.0.16:compile -com.google.code.findbugs:jsr305:1.3.9:compile -com.google.guava:guava:14.0.1:compile -com.google.javascript:closure-compiler:v20130603:compile -com.google.protobuf:protobuf-java:2.4.1:compile -com.googlecode.json-simple:json-simple:1.1.1:compile -io.apigee:rhino:1.7R5pre4:compile -junit:junit:4.10:compile -org.hamcrest:hamcrest-core:1.1:compile -org.json:json:20090211:compile -org.scala-js:sbt-scalajs;sbtVersion=0.13;scalaVersion=2.10:0.6.6:compile -org.scala-js:scalajs-ir_2.10:0.6.6:compile -org.scala-js:scalajs-js-envs_2.10:0.6.6:compile -org.scala-js:scalajs-sbt-test-adapter_2.10:0.6.6:compile -org.scala-js:scalajs-tools_2.10:0.6.6:compile -org.scala-lang:scala-library:2.10.6:compile -org.scala-sbt:test-interface:1.0:compile -org.webjars:envjs:1.2:compile diff --git a/tests/shared/src/test/resources/resolutions/org.scala-js/sbt-scalajs/sbtVersion_0.13_scalaVersion_2.10/0.6.6_default_compile_ b/tests/shared/src/test/resources/resolutions/org.scala-js/sbt-scalajs/sbtVersion_0.13_scalaVersion_2.10/0.6.6_default_compile_ new file mode 100644 index 000000000..f1a683894 --- /dev/null +++ b/tests/shared/src/test/resources/resolutions/org.scala-js/sbt-scalajs/sbtVersion_0.13_scalaVersion_2.10/0.6.6_default_compile_ @@ -0,0 +1,18 @@ +args4j:args4j:2.0.16:default +com.google.code.findbugs:jsr305:1.3.9:default +com.google.guava:guava:14.0.1:default +com.google.javascript:closure-compiler:v20130603:default +com.google.protobuf:protobuf-java:2.4.1:default +com.googlecode.json-simple:json-simple:1.1.1:default +io.apigee:rhino:1.7R5pre4:default +junit:junit:4.10:default +org.hamcrest:hamcrest-core:1.1:default +org.json:json:20090211:default +org.scala-js:sbt-scalajs;sbtVersion=0.13;scalaVersion=2.10:0.6.6:compile +org.scala-js:scalajs-ir_2.10:0.6.6:default +org.scala-js:scalajs-js-envs_2.10:0.6.6:default +org.scala-js:scalajs-sbt-test-adapter_2.10:0.6.6:default +org.scala-js:scalajs-tools_2.10:0.6.6:default +org.scala-lang:scala-library:2.10.6:default +org.scala-sbt:test-interface:1.0:default +org.webjars:envjs:1.2:default diff --git a/tests/shared/src/test/scala/coursier/test/CentralTests.scala b/tests/shared/src/test/scala/coursier/test/CentralTests.scala index 974700b9c..a90aeb56b 100644 --- a/tests/shared/src/test/scala/coursier/test/CentralTests.scala +++ b/tests/shared/src/test/scala/coursier/test/CentralTests.scala @@ -45,16 +45,27 @@ object CentralTests extends TestSuite { val expected = await( - textResource(s"resolutions/${module.organization}/${module.name}$attrPathPart/$version") - ) - .split('\n') - .toSeq + textResource( + Seq( + "resolutions", + module.organization, + module.name, + attrPathPart, + version + ( + if (configuration.isEmpty) + "" + else + "_" + configuration.replace('(', '_').replace(')', '_') + ) + ).filter(_.nonEmpty).mkString("/") + ) + ).split('\n').toSeq val dep = Dependency(module, version, configuration = configuration) val res = await(resolve(Set(dep), extraRepo = extraRepo)) val result = res - .dependencies + .minDependencies .toVector .map { dep => val projOpt = res.projectCache @@ -63,7 +74,7 @@ object CentralTests extends TestSuite { val dep0 = dep.copy( version = projOpt.fold(dep.version)(_.version) ) - (dep0.module.organization, dep0.module.name, dep0.version, dep0.configuration) + (dep0.module.organization, dep0.module.nameWithAttributes, dep0.version, dep0.configuration) } .sorted .distinct @@ -190,6 +201,16 @@ object CentralTests extends TestSuite { "7.0.+" ) } + 'mavenScopes - { + def check(config: String) = resolutionCheck( + Module("com.android.tools", "sdklib"), + "24.5.0", + configuration = config + ) + + 'compile - check("compile") + 'runtime - check("runtime") + } 'packaging - { * - {