diff --git a/core/src/main/scala/coursier/core/Resolver.scala b/core/src/main/scala/coursier/core/Resolver.scala index dbede60c0..a77be0ece 100644 --- a/core/src/main/scala/coursier/core/Resolver.scala +++ b/core/src/main/scala/coursier/core/Resolver.scala @@ -436,8 +436,7 @@ object Resolver { missingFromCache.isEmpty && isFixPoint } - private def key(dep: Dependency) = - (dep.module.organization, dep.module.name, dep.scope) + private def key(dep: Dependency) = (dep.module, dep.scope) /** * Returns a map giving the dependency that brought each of the dependency of the "next" dependency set, @@ -471,7 +470,7 @@ object Resolver { .map(dep => key(dep) -> dep.exclusions) .toMap - type D = (String, String, Scope) + type D = (Module, Scope) @tailrec def helper[T](reverseDeps: Map[D, Vector[(D, T)]]): Map[D, Vector[(D, T)]] = { diff --git a/core/src/test/scala/coursier/test/ResolverTests.scala b/core/src/test/scala/coursier/test/ResolverTests.scala index a4ea2a752..5a28c3b79 100644 --- a/core/src/test/scala/coursier/test/ResolverTests.scala +++ b/core/src/test/scala/coursier/test/ResolverTests.scala @@ -22,7 +22,7 @@ object ResolverTests extends TestSuite { Project(Module("acme", "play-json"), "2.4.0"), Project(Module("acme", "play"), "2.4.1", - Seq( + dependencies = Seq( Dependency(Module("acme", "play-json"), "${playJsonVersion}"), Dependency(Module("${project.groupId}", "${configName}"), "1.3.0")), properties = Map( @@ -52,9 +52,8 @@ object ResolverTests extends TestSuite { exclusions = Set(("acme", "play-json"))))), Project(Module("se.ikea", "billy"), "18.0", - Seq( - Dependency(Module("acme", "play"), "") - ), + dependencies = Seq( + Dependency(Module("acme", "play"), "")), parent = Some(Module("se.ikea", "parent"), "18.0")), Project(Module("org.gnome", "parent"), "7.0", @@ -62,7 +61,7 @@ object ResolverTests extends TestSuite { Dependency(Module("org.gnu", "glib"), "13.4"))), Project(Module("org.gnome", "panel-legacy"), "7.0", - Seq( + dependencies = Seq( Dependency(Module("org.gnome", "desktop"), "${project.version}")), parent = Some(Module("org.gnome", "parent"), "7.0")), @@ -71,13 +70,13 @@ object ResolverTests extends TestSuite { Dependency(Module("gov.nsa", "crypto"), "536.89"))), Project(Module("com.mailapp", "mail-client"), "2.1", - Seq( + dependencies = Seq( Dependency(Module("gov.nsa", "secure-pgp"), "10.0", exclusions = Set(("*", "${crypto.name}")))), properties = Map("crypto.name" -> "crypto", "dummy" -> "2")), Project(Module("com.thoughtworks.paranamer", "paranamer-parent"), "2.6", - Seq( + dependencies = Seq( Dependency(Module("junit", "junit"), "")), dependencyManagement = Seq( Dependency(Module("junit", "junit"), "4.11", scope = Scope.Test))), @@ -88,44 +87,33 @@ object ResolverTests extends TestSuite { Project(Module("com.github.dummy", "libb"), "0.3.3", profiles = Seq( Profile("default", activeByDefault = Some(true), dependencies = Seq( - Dependency(Module("org.escalier", "librairie-standard"), "2.11.6") - )) - )), + Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))), Project(Module("com.github.dummy", "libb"), "0.4.2", - Seq( - Dependency(Module("org.scalaverification", "scala-verification"), "1.12.4") - ), + dependencies = Seq( + Dependency(Module("org.scalaverification", "scala-verification"), "1.12.4")), profiles = Seq( Profile("default", activeByDefault = Some(true), dependencies = Seq( Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"), - Dependency(Module("org.scalaverification", "scala-verification"), "1.12.4", scope = Scope.Test) - )) - )), + Dependency(Module("org.scalaverification", "scala-verification"), "1.12.4", scope = Scope.Test))))), Project(Module("com.github.dummy", "libb"), "0.5.3", properties = Map("special" -> "true"), profiles = Seq( Profile("default", activation = Profile.Activation(properties = Seq("special" -> None)), dependencies = Seq( - Dependency(Module("org.escalier", "librairie-standard"), "2.11.6") - )) - )), + Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))), Project(Module("com.github.dummy", "libb"), "0.5.4", properties = Map("special" -> "true"), profiles = Seq( Profile("default", activation = Profile.Activation(properties = Seq("special" -> Some("true"))), dependencies = Seq( - Dependency(Module("org.escalier", "librairie-standard"), "2.11.6") - )) - )), + Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))), Project(Module("com.github.dummy", "libb"), "0.5.5", properties = Map("special" -> "true"), profiles = Seq( Profile("default", activation = Profile.Activation(properties = Seq("special" -> Some("!false"))), dependencies = Seq( - Dependency(Module("org.escalier", "librairie-standard"), "2.11.6") - )) - )), + Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))), Project(Module("com.github.dummy", "libb-parent"), "0.5.6", properties = Map("special" -> "true")), @@ -135,9 +123,7 @@ object ResolverTests extends TestSuite { properties = Map("special" -> "true"), profiles = Seq( Profile("default", activation = Profile.Activation(properties = Seq("special" -> Some("!false"))), dependencies = Seq( - Dependency(Module("org.escalier", "librairie-standard"), "2.11.6") - )) - )) + Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))) ) val projectsMap = projects.map(p => p.moduleVersion -> p).toMap @@ -153,8 +139,7 @@ object ResolverTests extends TestSuite { val res = await(resolve( Set.empty, fetchFrom(repositories) - ).runF - ) + ).runF) assert(res == Resolution.empty) } @@ -178,236 +163,215 @@ object ResolverTests extends TestSuite { } 'single{ async { - val dep = Dependency(Module("acme", "config"), "1.3.0") - val res = await(resolve( - Set(dep), - fetchFrom(repositories) - ).runF) + val dep = Dependency(Module("acme", "config"), "1.3.0") + val res = await(resolve( + Set(dep), + fetchFrom(repositories) + ).runF) - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope), - projectsCache = Map(dep.moduleVersion -> (testRepository, projectsMap(dep.moduleVersion))) - ) + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope), + projectsCache = Map(dep.moduleVersion -> (testRepository, projectsMap(dep.moduleVersion))) + ) - assert(res == expected) + assert(res == expected) } } 'oneTransitiveDependency{ async { - val dep = Dependency(Module("acme", "play"), "2.4.0") - val trDep = Dependency(Module("acme", "play-json"), "2.4.0") - val res = await(resolve( - Set(dep), - fetchFrom(repositories) - ).runF) + val dep = Dependency(Module("acme", "play"), "2.4.0") + val trDep = Dependency(Module("acme", "play-json"), "2.4.0") + val res = await(resolve( + Set(dep), + fetchFrom(repositories) + ).runF) - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope, trDep.withCompileScope), - projectsCache = Map( - projectsMap(dep.moduleVersion).kv, - projectsMap(trDep.moduleVersion).kv + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope, trDep.withCompileScope), + projectsCache = Map( + projectsMap(dep.moduleVersion).kv, + projectsMap(trDep.moduleVersion).kv + ) ) - ) - assert(res == expected) + assert(res == expected) } } 'twoTransitiveDependencyWithProps{ async { - val dep = Dependency(Module("acme", "play"), "2.4.1") - val trDeps = Seq( - Dependency(Module("acme", "play-json"), "2.4.0"), - Dependency(Module("acme", "config"), "1.3.0") - ) - val res = await(resolve( - Set(dep), - fetchFrom(repositories) - ).runF) + val dep = Dependency(Module("acme", "play"), "2.4.1") + val trDeps = Seq( + Dependency(Module("acme", "play-json"), "2.4.0"), + Dependency(Module("acme", "config"), "1.3.0") + ) + val res = await(resolve( + Set(dep), + fetchFrom(repositories) + ).runF) - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope), - projectsCache = Map( - projectsMap(dep.moduleVersion).kv - ) ++ trDeps.map(trDep => projectsMap(trDep.moduleVersion).kv) - ) + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope), + projectsCache = Map( + projectsMap(dep.moduleVersion).kv + ) ++ trDeps.map(trDep => projectsMap(trDep.moduleVersion).kv) + ) - assert(res == expected) + assert(res == expected) } } 'exclude{ async { - val dep = Dependency(Module("acme", "play-extra-no-config"), "2.4.1") - val trDeps = Seq( - Dependency(Module("acme", "play"), "2.4.1", - exclusions = Set(("acme", "config"))), - Dependency(Module("acme", "play-json"), "2.4.0", - exclusions = Set(("acme", "config"))) - ) - val res = await(resolve( - Set(dep), - fetchFrom(repositories) - ).runF) + val dep = Dependency(Module("acme", "play-extra-no-config"), "2.4.1") + val trDeps = Seq( + Dependency(Module("acme", "play"), "2.4.1", + exclusions = Set(("acme", "config"))), + Dependency(Module("acme", "play-json"), "2.4.0", + exclusions = Set(("acme", "config"))) + ) + val res = await(resolve( + Set(dep), + fetchFrom(repositories) + ).runF) - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope), - projectsCache = Map( - projectsMap(dep.moduleVersion).kv - ) ++ trDeps.map(trDep => projectsMap(trDep.moduleVersion).kv) - ) + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope), + projectsCache = Map( + projectsMap(dep.moduleVersion).kv + ) ++ trDeps.map(trDep => projectsMap(trDep.moduleVersion).kv) + ) - assert(res == expected) + assert(res == expected) } } 'excludeOrgWildcard{ async { - val dep = Dependency(Module("acme", "play-extra-no-config-no"), "2.4.1") - val trDeps = Seq( - Dependency(Module("acme", "play"), "2.4.1", - exclusions = Set(("*", "config"))), - Dependency(Module("acme", "play-json"), "2.4.0", - exclusions = Set(("*", "config"))) - ) - val res = await(resolve( - Set(dep), - fetchFrom(repositories) - ).runF) + val dep = Dependency(Module("acme", "play-extra-no-config-no"), "2.4.1") + val trDeps = Seq( + Dependency(Module("acme", "play"), "2.4.1", + exclusions = Set(("*", "config"))), + Dependency(Module("acme", "play-json"), "2.4.0", + exclusions = Set(("*", "config"))) + ) + val res = await(resolve( + Set(dep), + fetchFrom(repositories) + ).runF) - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope), - projectsCache = Map( - projectsMap(dep.moduleVersion).kv - ) ++ trDeps.map(trDep => projectsMap(trDep.moduleVersion).kv) - ) + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope), + projectsCache = Map( + projectsMap(dep.moduleVersion).kv + ) ++ trDeps.map(trDep => projectsMap(trDep.moduleVersion).kv) + ) - assert(res == expected) + assert(res == expected) } } 'filter{ async { - val dep = Dependency(Module("hudsucker", "mail"), "10.0") - val res = await(resolve( - Set(dep), - fetchFrom(repositories), - filter = Some(_.scope == Scope.Compile) - ).runF).copy(filter = None) + val dep = Dependency(Module("hudsucker", "mail"), "10.0") + val res = await(resolve( + Set(dep), + fetchFrom(repositories), + filter = Some(_.scope == Scope.Compile) + ).runF).copy(filter = None) - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope), - projectsCache = Map( - projectsMap(dep.moduleVersion).kv + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope), + projectsCache = Map( + projectsMap(dep.moduleVersion).kv + ) ) - ) - assert(res == expected) + assert(res == expected) } } 'parentDepMgmt{ async { - val dep = Dependency(Module("se.ikea", "billy"), "18.0") - val trDeps = Seq( - Dependency(Module("acme", "play"), "2.4.0", - exclusions = Set(("acme", "play-json"))) - ) - val res = await(resolve( - Set(dep), - fetchFrom(repositories), - filter = Some(_.scope == Scope.Compile) - ).runF).copy(filter = None, projectsCache = Map.empty) + val dep = Dependency(Module("se.ikea", "billy"), "18.0") + val trDeps = Seq( + Dependency(Module("acme", "play"), "2.4.0", + exclusions = Set(("acme", "play-json"))) + ) + val res = await(resolve( + Set(dep), + fetchFrom(repositories), + filter = Some(_.scope == Scope.Compile) + ).runF).copy(filter = None, projectsCache = Map.empty) - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope) - ) + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope) + ) - assert(res == expected) + assert(res == expected) } } 'parentDependencies{ async { - val dep = Dependency(Module("org.gnome", "panel-legacy"), "7.0") - val trDeps = Seq( - Dependency(Module("org.gnu", "glib"), "13.4"), - Dependency(Module("org.gnome", "desktop"), "7.0")) - val res = await(resolve( - Set(dep), - fetchFrom(repositories), - filter = Some(_.scope == Scope.Compile) - ).runF).copy(filter = None, projectsCache = Map.empty, errors = Map.empty) + val dep = Dependency(Module("org.gnome", "panel-legacy"), "7.0") + val trDeps = Seq( + Dependency(Module("org.gnu", "glib"), "13.4"), + Dependency(Module("org.gnome", "desktop"), "7.0")) + val res = await(resolve( + Set(dep), + fetchFrom(repositories), + filter = Some(_.scope == Scope.Compile) + ).runF).copy(filter = None, projectsCache = Map.empty, errors = Map.empty) - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope) - ) + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope) + ) - assert(res == expected) + assert(res == expected) } } 'propertiesInExclusions{ async { - val dep = Dependency(Module("com.mailapp", "mail-client"), "2.1") - val trDeps = Seq( - Dependency(Module("gov.nsa", "secure-pgp"), "10.0", exclusions = Set(("*", "crypto")))) - val res = await(resolve( - Set(dep), - fetchFrom(repositories), - filter = Some(_.scope == Scope.Compile) - ).runF).copy(filter = None, projectsCache = Map.empty, errors = Map.empty) + val dep = Dependency(Module("com.mailapp", "mail-client"), "2.1") + val trDeps = Seq( + Dependency(Module("gov.nsa", "secure-pgp"), "10.0", exclusions = Set(("*", "crypto")))) + val res = await(resolve( + Set(dep), + fetchFrom(repositories), + filter = Some(_.scope == Scope.Compile) + ).runF).copy(filter = None, projectsCache = Map.empty, errors = Map.empty) - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope) - ) + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope) + ) - assert(res == expected) + assert(res == expected) } } 'depMgmtInParentDeps{ async { - val dep = Dependency(Module("com.thoughtworks.paranamer", "paranamer"), "2.6") - val res = await(resolve( - Set(dep), - fetchFrom(repositories), - filter = Some(_.scope == Scope.Compile) - ).runF).copy(filter = None, projectsCache = Map.empty, errors = Map.empty) + val dep = Dependency(Module("com.thoughtworks.paranamer", "paranamer"), "2.6") + val res = await(resolve( + Set(dep), + fetchFrom(repositories), + filter = Some(_.scope == Scope.Compile) + ).runF).copy(filter = None, projectsCache = Map.empty, errors = Map.empty) - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope) - ) + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope) + ) - assert(res == expected) + assert(res == expected) } } 'depsFromDefaultProfile{ async { - val dep = Dependency(Module("com.github.dummy", "libb"), "0.3.3") - val trDeps = Seq( - Dependency(Module("org.escalier", "librairie-standard"), "2.11.6")) - val res = await(resolve( - Set(dep), - fetchFrom(repositories), - filter = Some(_.scope == Scope.Compile) - ).runF).copy(filter = None, projectsCache = Map.empty, errors = Map.empty) - - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope) - ) - - assert(res == expected) - } - } - 'depsFromPropertyActivatedProfile{ - val f = - for (version <- Seq("0.5.3", "0.5.4", "0.5.5", "0.5.6")) yield { - async { - val dep = Dependency(Module("com.github.dummy", "libb"), version) + val dep = Dependency(Module("com.github.dummy", "libb"), "0.3.3") val trDeps = Seq( Dependency(Module("org.escalier", "librairie-standard"), "2.11.6")) val res = await(resolve( @@ -423,28 +387,49 @@ object ResolverTests extends TestSuite { assert(res == expected) } - } + } + 'depsFromPropertyActivatedProfile{ + val f = + for (version <- Seq("0.5.3", "0.5.4", "0.5.5", "0.5.6")) yield { + async { + val dep = Dependency(Module("com.github.dummy", "libb"), version) + val trDeps = Seq( + Dependency(Module("org.escalier", "librairie-standard"), "2.11.6")) + val res = await(resolve( + Set(dep), + fetchFrom(repositories), + filter = Some(_.scope == Scope.Compile) + ).runF).copy(filter = None, projectsCache = Map.empty, errors = Map.empty) + + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope) + ) + + assert(res == expected) + } + } scala.concurrent.Future.sequence(f) } 'depsScopeOverrideFromProfile{ async { - // Like com.google.inject:guice:3.0 with org.sonatype.sisu.inject:cglib - val dep = Dependency(Module("com.github.dummy", "libb"), "0.4.2") - val trDeps = Seq( - Dependency(Module("org.escalier", "librairie-standard"), "2.11.6")) - val res = await(resolve( - Set(dep), - fetchFrom(repositories), - filter = Some(_.scope == Scope.Compile) - ).runF).copy(filter = None, projectsCache = Map.empty, errors = Map.empty) + // Like com.google.inject:guice:3.0 with org.sonatype.sisu.inject:cglib + val dep = Dependency(Module("com.github.dummy", "libb"), "0.4.2") + val trDeps = Seq( + Dependency(Module("org.escalier", "librairie-standard"), "2.11.6")) + val res = await(resolve( + Set(dep), + fetchFrom(repositories), + filter = Some(_.scope == Scope.Compile) + ).runF).copy(filter = None, projectsCache = Map.empty, errors = Map.empty) - val expected = Resolution( - rootDependencies = Set(dep.withCompileScope), - dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope) - ) + val expected = Resolution( + rootDependencies = Set(dep.withCompileScope), + dependencies = Set(dep.withCompileScope) ++ trDeps.map(_.withCompileScope) + ) - assert(res == expected) + assert(res == expected) } }