diff --git a/notes/0.13.13/maven-plugin-transitive-wildcard-excludes.markdown b/notes/0.13.13/maven-plugin-transitive-wildcard-excludes.markdown new file mode 100644 index 000000000..be0cd68a7 --- /dev/null +++ b/notes/0.13.13/maven-plugin-transitive-wildcard-excludes.markdown @@ -0,0 +1,12 @@ +[@jtgrabowski]: https://github.com/jtgrabowski +[1431]: https://github.com/sbt/sbt/issues/1431 +[sbt-ivy-22]: https://github.com/sbt/ivy/pull/22 +[2731]: https://github.com/sbt/sbt/pull/2731 + +### Fixes with compatibility implications + +### Improvements + +### Bug fixes + +- Support wildcard exclusions when using sbt-maven-resolver-plugin [#1431][1431][sbt/ivy#22][sbt-ivy-22]/[#2731][2731] by [@jtgrabowski][@jtgrabowski] diff --git a/project/Dependencies.scala b/project/Dependencies.scala index ad08b92ab..1c77b9162 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,7 +9,7 @@ object Dependencies { lazy val scala211 = "2.11.7" lazy val jline = "jline" % "jline" % "2.13" - lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435c4fa24f9a" + lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cf13e211b2cb31f0d3b317289dca70eca3362f6" lazy val jsch = "com.jcraft" % "jsch" % "0.1.50" intransitive () lazy val sbinary = "org.scala-tools.sbinary" %% "sbinary" % "0.4.2" lazy val sbtSerialization = "org.scala-sbt" %% "serialization" % "0.1.2" diff --git a/sbt-maven-resolver/src/main/scala/sbt/mavenint/MavenRepositoryResolver.scala b/sbt-maven-resolver/src/main/scala/sbt/mavenint/MavenRepositoryResolver.scala index e550b9c0a..5b36c41aa 100644 --- a/sbt-maven-resolver/src/main/scala/sbt/mavenint/MavenRepositoryResolver.scala +++ b/sbt-maven-resolver/src/main/scala/sbt/mavenint/MavenRepositoryResolver.scala @@ -357,11 +357,12 @@ abstract class MavenRepositoryResolver(settings: IvySettings) extends AbstractRe case _ => tmp } } + val transitive = d.getExclusions.asScala.forall(e => e.getGroupId != "*" || e.getArtifactId != "*") // Note: The previous maven integration ALWAYS set force to true for dependnecies. If we do not do this, for some // reason, Ivy will create dummy nodes when doing dependnecy mediation (e.g. dependencyManagement of one pom overrides version of a dependency) // which was leading to "data not found" exceptions as Ivy would pick the correct IvyNode in the dependency tree but never load it with data.... - val dd = new DefaultDependencyDescriptor(md, drid, /* force */ true, isChanging, true) {} + val dd = new DefaultDependencyDescriptor(md, drid, /* force */ true, isChanging, transitive) {} // TODO - Configuration mappings (are we grabbing scope correctly, or should the default not always be compile?) val scope = Option(d.getScope).filterNot(_.isEmpty).getOrElse("compile") @@ -389,16 +390,18 @@ abstract class MavenRepositoryResolver(settings: IvySettings) extends AbstractRe // TOOD - We may need to fix the configuration mappings here. dd.addDependencyArtifact(optionalizedScope, depArtifact) } - // Include rules and exclude rules. - for (e <- d.getExclusions.asScala) { - val excludedModule = new ModuleId(e.getGroupId, e.getArtifactId) - for (conf <- dd.getModuleConfigurations) { - // TODO - Do we need extra attributes for this? - dd.addExcludeRule(conf, new DefaultExcludeRule(new ArtifactId( - excludedModule, PatternMatcher.ANY_EXPRESSION, - PatternMatcher.ANY_EXPRESSION, - PatternMatcher.ANY_EXPRESSION), - ExactPatternMatcher.INSTANCE, null)) + if (dd.isTransitive) { + // Include rules and exclude rules. + for (e <- d.getExclusions.asScala) { + val excludedModule = new ModuleId(e.getGroupId, e.getArtifactId) + for (conf <- dd.getModuleConfigurations) { + // TODO - Do we need extra attributes for this? + dd.addExcludeRule(conf, new DefaultExcludeRule(new ArtifactId( + excludedModule, PatternMatcher.ANY_EXPRESSION, + PatternMatcher.ANY_EXPRESSION, + PatternMatcher.ANY_EXPRESSION), + ExactPatternMatcher.INSTANCE, null)) + } } } md.addDependency(dd) diff --git a/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/build.sbt b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/build.sbt new file mode 100644 index 000000000..76a9d0885 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/build.sbt @@ -0,0 +1,38 @@ + +resolvers += { + val f = baseDirectory.value / "repository" + "local-test-repo" at f.getCanonicalFile.toURI.toASCIIString +} +libraryDependencies += "exclude.wildcard.test" % "top" % "1.0.0" + +val checkDependencies = taskKey[Unit]("Checks if wildcard excludes work correctly.") + +checkDependencies := { + val hasTopJar = (fullClasspath in Compile).value.exists { jar => jar.data.getName contains "top-1.0.0.jar"} + val hasBottomJar = (fullClasspath in Compile).value.exists { jar => jar.data.getName contains "bottom-1.0.0.jar"} + val hasMiddleJar = (fullClasspath in Compile).value.exists { jar => jar.data.getName contains "middle-1.0.0.jar"} + val errorJarString = (fullClasspath in Compile).value.map(_.data.getName).mkString(" * ", "\n * ", "") + assert(hasTopJar, s"Failed to include dependency with wildcard exclusion on classpath!\nFound:\n$errorJarString") + assert(hasMiddleJar, s"Failed to include dependency with wildcard exclusion on classpath!\nFound:\n$errorJarString") + assert(!hasBottomJar, s"Failed to exclude transitive excluded dependency on classpath!\nFound:\n$errorJarString") + val modules = (for { + c <- update.value.configurations + m <- c.modules + if !m.evicted + } yield m.module).distinct + val hasTopDep = modules exists { m => + (m.organization == "exclude.wildcard.test") && (m.name == "top") + } + val hasMiddleDep = modules exists { m => + (m.organization == "exclude.wildcard.test") && (m.name == "middle") + } + val hasBottomDep = modules exists { m => + (m.organization == "exclude.wildcard.test") && (m.name == "bottom") + } + + val errModuleString = modules.mkString("\n * ", "\n * ", "") + assert(hasTopDep, s"Failed to include dependency with wildcard exclusion!\nFound:\n$errModuleString") + assert(hasMiddleDep, s"Failed to include dependency with wildcard exclusion!\nFound:\n$errModuleString") + assert(!hasBottomDep, s"Failed to exclude transitive excluded dependency!\nFound:\n$errModuleString") + +} \ No newline at end of file diff --git a/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/bottom/1.0.0/bottom-1.0.0.jar b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/bottom/1.0.0/bottom-1.0.0.jar new file mode 100644 index 000000000..e69de29bb diff --git a/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/bottom/1.0.0/bottom-1.0.0.pom b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/bottom/1.0.0/bottom-1.0.0.pom new file mode 100644 index 000000000..f5f1e53b8 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/bottom/1.0.0/bottom-1.0.0.pom @@ -0,0 +1,12 @@ + + 4.0.0 + exclude.wildcard.test + bottom + jar + 1.0.0 + bottom + http://maven.apache.org + + + \ No newline at end of file diff --git a/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/middle/1.0.0/middle-1.0.0.jar b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/middle/1.0.0/middle-1.0.0.jar new file mode 100644 index 000000000..e69de29bb diff --git a/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/middle/1.0.0/middle-1.0.0.pom b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/middle/1.0.0/middle-1.0.0.pom new file mode 100644 index 000000000..a723ae599 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/middle/1.0.0/middle-1.0.0.pom @@ -0,0 +1,17 @@ + + 4.0.0 + exclude.wildcard.test + middle + jar + 1.0.0 + middle + http://maven.apache.org + + + exclude.wildcard.test + bottom + 1.0.0 + + + \ No newline at end of file diff --git a/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/top/1.0.0/top-1.0.0.jar b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/top/1.0.0/top-1.0.0.jar new file mode 100644 index 000000000..e69de29bb diff --git a/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/top/1.0.0/top-1.0.0.pom b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/top/1.0.0/top-1.0.0.pom new file mode 100644 index 000000000..4d220a5a4 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/repository/exclude/wildcard/test/top/1.0.0/top-1.0.0.pom @@ -0,0 +1,23 @@ + + 4.0.0 + exclude.wildcard.test + top + jar + 1.0.0 + top + http://maven.apache.org + + + exclude.wildcard.test + middle + 1.0.0 + + + * + * + + + + + \ No newline at end of file diff --git a/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/test b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/test new file mode 100644 index 000000000..c579cedc3 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/transitive-wildcard-excludes/test @@ -0,0 +1 @@ +> checkDependencies \ No newline at end of file