Skip to content

Commit d146bcb

Browse files
committed
Add CheckClasspathForProhibitedDependencies
Issues gh-10499 gh-10501
1 parent c8713b1 commit d146bcb

File tree

4 files changed

+181
-0
lines changed

4 files changed

+181
-0
lines changed

build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,8 @@ tasks.register('checkSamples') {
166166
s101 {
167167
configurationDirectory = project.file("etc/s101")
168168
}
169+
170+
tasks.register('checkForProhibitedDependencies', check -> {
171+
check.setGroup(LifecycleBasePlugin.VERIFICATION_GROUP)
172+
check.setDescription("Checks for prohibited dependencies")
173+
})

buildSrc/src/main/groovy/io/spring/gradle/convention/SpringModulePlugin.groovy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import org.gradle.api.Project
2020
import org.gradle.api.plugins.JavaLibraryPlugin;
2121
import org.gradle.api.plugins.MavenPlugin;
2222
import org.gradle.api.plugins.PluginManager
23+
import org.springframework.gradle.classpath.CheckClasspathForProhibitedDependenciesPlugin;
2324
import org.springframework.gradle.maven.SpringMavenPlugin;
2425

2526
/**
@@ -32,6 +33,7 @@ class SpringModulePlugin extends AbstractSpringJavaPlugin {
3233
PluginManager pluginManager = project.getPluginManager();
3334
pluginManager.apply(JavaLibraryPlugin.class)
3435
pluginManager.apply(SpringMavenPlugin.class);
36+
pluginManager.apply(CheckClasspathForProhibitedDependenciesPlugin.class);
3537
pluginManager.apply("io.spring.convention.jacoco");
3638

3739
def deployArtifacts = project.task("deployArtifacts")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright 2012-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.gradle.classpath;
18+
19+
import org.gradle.api.DefaultTask;
20+
import org.gradle.api.GradleException;
21+
import org.gradle.api.Task;
22+
import org.gradle.api.artifacts.Configuration;
23+
import org.gradle.api.artifacts.ModuleVersionIdentifier;
24+
import org.gradle.api.artifacts.ResolvedConfiguration;
25+
import org.gradle.api.file.FileCollection;
26+
import org.gradle.api.tasks.Classpath;
27+
import org.gradle.api.tasks.TaskAction;
28+
29+
import java.io.IOException;
30+
import java.util.TreeSet;
31+
import java.util.stream.Collectors;
32+
33+
/**
34+
* A {@link Task} for checking the classpath for prohibited dependencies.
35+
*
36+
* @author Andy Wilkinson
37+
*/
38+
public class CheckClasspathForProhibitedDependencies extends DefaultTask {
39+
40+
private Configuration classpath;
41+
42+
public CheckClasspathForProhibitedDependencies() {
43+
getOutputs().upToDateWhen((task) -> true);
44+
}
45+
46+
public void setClasspath(Configuration classpath) {
47+
this.classpath = classpath;
48+
}
49+
50+
@Classpath
51+
public FileCollection getClasspath() {
52+
return this.classpath;
53+
}
54+
55+
@TaskAction
56+
public void checkForProhibitedDependencies() throws IOException {
57+
ResolvedConfiguration resolvedConfiguration = this.classpath.getResolvedConfiguration();
58+
TreeSet<String> prohibited = resolvedConfiguration.getResolvedArtifacts().stream()
59+
.map((artifact) -> artifact.getModuleVersion().getId()).filter(this::prohibited)
60+
.map((id) -> id.getGroup() + ":" + id.getName()).collect(Collectors.toCollection(TreeSet::new));
61+
if (!prohibited.isEmpty()) {
62+
StringBuilder message = new StringBuilder(String.format("Found prohibited dependencies in '%s':%n", this.classpath.getName()));
63+
for (String dependency : prohibited) {
64+
message.append(String.format(" %s%n", dependency));
65+
}
66+
throw new GradleException(message.toString());
67+
}
68+
}
69+
70+
private boolean prohibited(ModuleVersionIdentifier id) {
71+
String group = id.getGroup();
72+
if (group.equals("javax.batch")) {
73+
return false;
74+
}
75+
if (group.equals("javax.cache")) {
76+
return false;
77+
}
78+
if (group.equals("javax.money")) {
79+
return false;
80+
}
81+
if (group.startsWith("javax")) {
82+
return true;
83+
}
84+
if (group.equals("commons-logging")) {
85+
return true;
86+
}
87+
if (group.equals("org.slf4j") && id.getName().equals("jcl-over-slf4j")) {
88+
return true;
89+
}
90+
if (group.startsWith("org.jboss.spec")) {
91+
return true;
92+
}
93+
if (group.equals("org.apache.geronimo.specs")) {
94+
return true;
95+
}
96+
return false;
97+
}
98+
99+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2012-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.gradle.classpath;
18+
19+
import org.gradle.api.Plugin;
20+
import org.gradle.api.Project;
21+
import org.gradle.api.Task;
22+
import org.gradle.api.artifacts.Configuration;
23+
import org.gradle.api.artifacts.ConfigurationContainer;
24+
import org.gradle.api.plugins.JavaBasePlugin;
25+
import org.gradle.api.tasks.SourceSetContainer;
26+
import org.gradle.api.tasks.TaskProvider;
27+
import org.gradle.language.base.plugins.LifecycleBasePlugin;
28+
import org.springframework.util.StringUtils;
29+
30+
/**
31+
* @author Andy Wilkinson
32+
* @author Rob Winch
33+
*/
34+
public class CheckClasspathForProhibitedDependenciesPlugin implements Plugin<Project> {
35+
public static final String CHECK_PROHIBITED_DEPENDENCIES_TASK_NAME = "checkForProhibitedDependencies";
36+
37+
@Override
38+
public void apply(Project project) {
39+
project.getPlugins().withType(JavaBasePlugin.class, javaBasePlugin -> {
40+
configureProhibitedDependencyChecks(project);
41+
});
42+
}
43+
44+
private void configureProhibitedDependencyChecks(Project project) {
45+
TaskProvider<Task> checkProhibitedDependencies = project.getTasks().register(CHECK_PROHIBITED_DEPENDENCIES_TASK_NAME, task -> {
46+
task.setGroup(JavaBasePlugin.VERIFICATION_GROUP);
47+
task.setDescription("Checks both the compile/runtime classpath of every SourceSet for prohibited dependencies");
48+
});
49+
project.getTasks().named(JavaBasePlugin.CHECK_TASK_NAME, checkTask -> {
50+
checkTask.dependsOn(checkProhibitedDependencies);
51+
});
52+
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
53+
sourceSets.all((sourceSet) -> createProhibitedDependenciesChecks(project,
54+
sourceSet.getCompileClasspathConfigurationName(), sourceSet.getRuntimeClasspathConfigurationName()));
55+
}
56+
57+
private void createProhibitedDependenciesChecks(Project project, String... configurationNames) {
58+
ConfigurationContainer configurations = project.getConfigurations();
59+
for (String configurationName : configurationNames) {
60+
Configuration configuration = configurations.getByName(configurationName);
61+
createProhibitedDependenciesCheck(configuration, project);
62+
}
63+
}
64+
65+
private void createProhibitedDependenciesCheck(Configuration classpath, Project project) {
66+
String taskName = "check" + StringUtils.capitalize(classpath.getName() + "ForProhibitedDependencies");
67+
TaskProvider<CheckClasspathForProhibitedDependencies> checkClasspathTask = project.getTasks().register(taskName,
68+
CheckClasspathForProhibitedDependencies.class, checkClasspath -> {
69+
checkClasspath.setGroup(LifecycleBasePlugin.CHECK_TASK_NAME);
70+
checkClasspath.setDescription("Checks " + classpath.getName() + " for prohibited dependencies");
71+
checkClasspath.setClasspath(classpath);
72+
});
73+
project.getTasks().named(CHECK_PROHIBITED_DEPENDENCIES_TASK_NAME, checkProhibitedTask -> checkProhibitedTask.dependsOn(checkClasspathTask));
74+
}
75+
}

0 commit comments

Comments
 (0)