@@ -311,7 +311,13 @@ class BuildPlugin implements Plugin<Project> {
311311 /**
312312 * Returns a closure which can be used with a MavenPom for fixing problems with gradle generated poms.
313313 *
314- * The current fixup is to set compile time deps back to compile from runtime (known issue with maven-publish plugin).
314+ * <ul >
315+ * <li >Remove transitive dependencies. We currently exclude all artifacts explicitly instead of using wildcards
316+ * as Ivy incorrectly translates POMs with * excludes to Ivy XML with * excludes which results in the main artifact
317+ * being excluded as well (see https://issues.apache.org/jira/browse/IVY-1531). Note that Gradle 2.14+ automatically
318+ * translates non-transitive dependencies to * excludes. We should revisit this when upgrading Gradle.</li>
319+ * <li >Set compile time deps back to compile from runtime (known issue with maven-publish plugin)</li>
320+ * </ul>
315321 */
316322 private static Closure fixupDependencies (Project project ) {
317323 return { XmlProvider xml ->
@@ -321,15 +327,53 @@ class BuildPlugin implements Plugin<Project> {
321327 return
322328 }
323329
324- // fix deps incorrectly marked as runtime back to compile time deps
325- // see https://discuss.gradle.org/t/maven-publish-plugin-generated-pom-making-dependency-scope-runtime/7494/4
330+ // check each dependency for any transitive deps
326331 for (Node depNode : depsNodes. get(0 ). children()) {
332+ String groupId = depNode. get(' groupId' ). get(0 ). text()
333+ String artifactId = depNode. get(' artifactId' ). get(0 ). text()
334+ String version = depNode. get(' version' ). get(0 ). text()
335+
336+ // fix deps incorrectly marked as runtime back to compile time deps
337+ // see https://discuss.gradle.org/t/maven-publish-plugin-generated-pom-making-dependency-scope-runtime/7494/4
327338 boolean isCompileDep = project. configurations. compile. allDependencies. find { dep ->
328339 dep. name == depNode. artifactId. text()
329340 }
330341 if (depNode. scope. text() == ' runtime' && isCompileDep) {
331342 depNode. scope* . value = ' compile'
332343 }
344+
345+ // remove any exclusions added by gradle, they contain wildcards and systems like ivy have bugs with wildcards
346+ // see https://github.com/elastic/elasticsearch/issues/24490
347+ NodeList exclusionsNode = depNode. get(' exclusions' )
348+ if (exclusionsNode. size() > 0 ) {
349+ depNode. remove(exclusionsNode. get(0 ))
350+ }
351+
352+ // collect the transitive deps now that we know what this dependency is
353+ String depConfig = transitiveDepConfigName(groupId, artifactId, version)
354+ Configuration configuration = project. configurations. findByName(depConfig)
355+ if (configuration == null ) {
356+ continue // we did not make this dep non-transitive
357+ }
358+ Set<ResolvedArtifact > artifacts = configuration. resolvedConfiguration. resolvedArtifacts
359+ if (artifacts. size() <= 1 ) {
360+ // this dep has no transitive deps (or the only artifact is itself)
361+ continue
362+ }
363+
364+ // we now know we have something to exclude, so add exclusions for all artifacts except the main one
365+ Node exclusions = depNode. appendNode(' exclusions' )
366+ for (ResolvedArtifact artifact : artifacts) {
367+ ModuleVersionIdentifier moduleVersionIdentifier = artifact. moduleVersion. id;
368+ String depGroupId = moduleVersionIdentifier. group
369+ String depArtifactId = moduleVersionIdentifier. name
370+ // add exclusions for all artifacts except the main one
371+ if (depGroupId != groupId || depArtifactId != artifactId) {
372+ Node exclusion = exclusions. appendNode(' exclusion' )
373+ exclusion. appendNode(' groupId' , depGroupId)
374+ exclusion. appendNode(' artifactId' , depArtifactId)
375+ }
376+ }
333377 }
334378 }
335379 }
0 commit comments