1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.enforcer.rules;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.HashSet;
27 import java.util.LinkedHashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Objects;
31 import java.util.Set;
32 import java.util.regex.Pattern;
33
34 import org.apache.maven.artifact.Artifact;
35 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
36 import org.apache.maven.execution.MavenSession;
37 import org.apache.maven.project.MavenProject;
38
39
40
41
42
43 @Named("requireSameVersions")
44 public final class RequireSameVersions extends AbstractStandardEnforcerRule {
45 private boolean uniqueVersions;
46
47 private Set<String> dependencies = new HashSet<>();
48
49 private Set<String> plugins = new HashSet<>();
50
51 private Set<String> buildPlugins = new HashSet<>();
52
53 private Set<String> reportPlugins = new HashSet<>();
54
55 private boolean sameModuleVersions;
56
57 private final MavenProject project;
58
59 private final MavenSession session;
60
61 @Inject
62 public RequireSameVersions(MavenProject project, MavenSession session) {
63 this.project = Objects.requireNonNull(project);
64 this.session = Objects.requireNonNull(session);
65 }
66
67 @Override
68 public void execute() throws EnforcerRuleException {
69
70 Map<String, List<String>> versionMembers = new LinkedHashMap<>();
71
72 Set<String> allBuildPlugins = new HashSet<>(buildPlugins);
73 allBuildPlugins.addAll(plugins);
74 Set<String> allReportPlugins = new HashSet<>(reportPlugins);
75 allReportPlugins.addAll(plugins);
76
77 versionMembers.putAll(collectVersionMembers(project.getArtifacts(), dependencies, " (dependency)"));
78 versionMembers.putAll(collectVersionMembers(project.getPluginArtifacts(), allBuildPlugins, " (buildPlugin)"));
79 versionMembers.putAll(collectVersionMembers(project.getReportArtifacts(), allReportPlugins, " (reportPlugin)"));
80
81
82 if (versionMembers.size() > 1) {
83 StringBuilder builder = new StringBuilder("Found entries with different versions" + System.lineSeparator());
84 for (Map.Entry<String, List<String>> entry : versionMembers.entrySet()) {
85 builder.append("Entries with version ").append(entry.getKey()).append(System.lineSeparator());
86 for (String conflictId : entry.getValue()) {
87 builder.append("- ").append(conflictId).append(System.lineSeparator());
88 }
89 }
90 throw new EnforcerRuleException(builder.toString());
91 }
92
93 if (sameModuleVersions) {
94 MavenProject topLevelProject = session.getTopLevelProject();
95 if (!Objects.equals(topLevelProject.getVersion(), project.getVersion())) {
96 throw new EnforcerRuleException("Top level project has version " + topLevelProject.getVersion()
97 + " but current module has different version " + project.getVersion());
98 }
99 }
100 }
101
102 private Map<String, List<String>> collectVersionMembers(
103 Set<Artifact> artifacts, Collection<String> patterns, String source) {
104 Map<String, List<String>> versionMembers = new LinkedHashMap<>();
105
106 List<Pattern> regExs = new ArrayList<>();
107 for (String pattern : patterns) {
108 String regex = pattern.replace(".", "\\.")
109 .replace("*", ".*")
110 .replace(":", "\\:")
111 .replace('?', '.');
112
113
114 regExs.add(Pattern.compile(regex + "(\\:.+)?"));
115 }
116
117 for (Artifact artifact : artifacts) {
118 for (Pattern regEx : regExs) {
119 if (regEx.matcher(artifact.getDependencyConflictId()).matches()) {
120 String version = uniqueVersions ? artifact.getVersion() : artifact.getBaseVersion();
121 versionMembers
122 .computeIfAbsent(version, unused -> new ArrayList<>())
123 .add(artifact.getDependencyConflictId() + source);
124 }
125 }
126 }
127 return versionMembers;
128 }
129
130 void addDependency(String dependency) {
131 dependencies.add(dependency);
132 }
133
134 void addPlugin(String plugin) {
135 plugins.add(plugin);
136 }
137
138 void addBuildPlugin(String buildPlugin) {
139 buildPlugins.add(buildPlugin);
140 }
141
142 void addReportPlugin(String reportPlugin) {
143 reportPlugins.add(reportPlugin);
144 }
145
146 @Override
147 public String toString() {
148 return String.format(
149 "RequireSameVersions[dependencies=%s, buildPlugins=%s, reportPlugins=%s, plugins=%s, uniqueVersions=%b, sameModuleVersions=%b]",
150 dependencies, buildPlugins, reportPlugins, plugins, uniqueVersions, sameModuleVersions);
151 }
152 }