diff --git a/src/main/groovy/nebula/plugin/publishing/ivy/IvyResolvedDependenciesPlugin.groovy b/src/main/groovy/nebula/plugin/publishing/ivy/IvyResolvedDependenciesPlugin.groovy index 8e1d8e31..77e43dde 100644 --- a/src/main/groovy/nebula/plugin/publishing/ivy/IvyResolvedDependenciesPlugin.groovy +++ b/src/main/groovy/nebula/plugin/publishing/ivy/IvyResolvedDependenciesPlugin.groovy @@ -15,10 +15,9 @@ */ package nebula.plugin.publishing.ivy -import org.gradle.api.GradleException +import nebula.plugin.publishing.verification.DirectDependenciesVerifier import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.artifacts.ExcludeRule import org.gradle.api.publish.ivy.IvyPublication /** @@ -30,7 +29,7 @@ class IvyResolvedDependenciesPlugin implements Plugin { project.plugins.apply IvyBasePublishPlugin project.afterEvaluate { - verifyFirstDependencyExclusions(project) + DirectDependenciesVerifier.verify(project) project.publishing { publications { withType(IvyPublication) { @@ -44,22 +43,4 @@ class IvyResolvedDependenciesPlugin implements Plugin { } } } - - private void verifyFirstDependencyExclusions(Project project) { - project.configurations.forEach { configuration -> - configuration.dependencies.forEach { dependency -> - ExcludeRule exclude - try { - exclude = configuration.excludeRules.find { - it.group == dependency.group && it.module == dependency.name - } - } catch (e) { - // leave exclude null in case of unknown configuration - } - if(exclude) { - throw new GradleException("Direct dependency \"${dependency.group}:${dependency.name}\" is excluded, delete direct dependency or stop excluding it") - } - } - } - } } diff --git a/src/main/groovy/nebula/plugin/publishing/maven/MavenResolvedDependenciesPlugin.groovy b/src/main/groovy/nebula/plugin/publishing/maven/MavenResolvedDependenciesPlugin.groovy index 48ba324f..e5fc741f 100644 --- a/src/main/groovy/nebula/plugin/publishing/maven/MavenResolvedDependenciesPlugin.groovy +++ b/src/main/groovy/nebula/plugin/publishing/maven/MavenResolvedDependenciesPlugin.groovy @@ -15,6 +15,7 @@ */ package nebula.plugin.publishing.maven +import nebula.plugin.publishing.verification.DirectDependenciesVerifier import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.publish.maven.MavenPublication @@ -26,8 +27,8 @@ class MavenResolvedDependenciesPlugin implements Plugin { @Override void apply(Project project) { project.plugins.apply MavenBasePublishPlugin - project.afterEvaluate { + DirectDependenciesVerifier.verify(project) project.publishing { publications { withType(MavenPublication) { diff --git a/src/main/groovy/nebula/plugin/publishing/verification/DirectDependenciesVerifier.groovy b/src/main/groovy/nebula/plugin/publishing/verification/DirectDependenciesVerifier.groovy new file mode 100644 index 00000000..dd7823c9 --- /dev/null +++ b/src/main/groovy/nebula/plugin/publishing/verification/DirectDependenciesVerifier.groovy @@ -0,0 +1,44 @@ +/* + * Copyright 2019 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nebula.plugin.publishing.verification + +import groovy.transform.CompileStatic +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.ExcludeRule + +@CompileStatic +class DirectDependenciesVerifier { + static void verify(Project project) { + project.configurations.forEach { Configuration configuration -> + configuration.dependencies.forEach() { Dependency dependency -> + ExcludeRule exclude + try { + exclude = configuration.excludeRules.find { + it.group == dependency.group && it.module == dependency.name + } + } catch (Exception e) { + // leave exclude null in case of unknown configuration + } + if(exclude) { + throw new GradleException("Direct dependency \"${dependency.group}:${dependency.name}\" is excluded, delete direct dependency or stop excluding it") + } + } + } + } +} diff --git a/src/test/groovy/nebula/plugin/publishing/maven/MavenResolvedDependenciesPluginIntegrationSpec.groovy b/src/test/groovy/nebula/plugin/publishing/maven/MavenResolvedDependenciesPluginIntegrationSpec.groovy index f81d9bda..adcdcbfc 100644 --- a/src/test/groovy/nebula/plugin/publishing/maven/MavenResolvedDependenciesPluginIntegrationSpec.groovy +++ b/src/test/groovy/nebula/plugin/publishing/maven/MavenResolvedDependenciesPluginIntegrationSpec.groovy @@ -25,6 +25,7 @@ class MavenResolvedDependenciesPluginIntegrationSpec extends IntegrationTestKitS File publishDir def setup() { + debug = true buildFile << """\ plugins { id 'nebula.maven-resolved-dependencies' @@ -280,6 +281,35 @@ class MavenResolvedDependenciesPluginIntegrationSpec extends IntegrationTestKitS a.version == '1.0.0' } + def 'excluded first order dependencies fail the build'() { + def graph = new DependencyGraphBuilder().addModule('test.resolved:a:1.0.0') + .addModule(new ModuleBuilder('test.resolved:b:1.0.0').addDependency('test.resolved:a:1.0.0').build()) + .build() + File mavenrepo = new GradleDependencyGenerator(graph, "${projectDir}/testrepogen").generateTestMavenRepo() + + buildFile << """\ + apply plugin: 'java' + + repositories { maven { url '${mavenrepo.absolutePath}' } } + + configurations.all { + exclude group: 'test.resolved', module: 'a' + } + + dependencies { + compile 'test.resolved:b:1.0.0' + compile 'test.resolved:a' + } + """.stripIndent() + + when: + def result = runTasksAndFail('publishNebulaPublicationToTestLocalRepository') + + then: + def expectedMessage = 'Direct dependency "test.resolved:a" is excluded, delete direct dependency or stop excluding it' + result.output.contains(expectedMessage) + } + def findDependency(String artifactId) { def root = new XmlSlurper().parseText(new File(publishDir, 'resolvedmaventest-0.1.0.pom').text) def d = root.dependencies.dependency.find {