Skip to content

Commit a99756a

Browse files
gaosaromalvjing2
andauthored
feat: 模块瘦身检查 && 允许不自动排除和基座相同的依赖 (#1017)
* 优化显示 * fix as bizStateRecords * 更新显示 * feat: add 'build failed when exclude different base dependency'; allow not to exclude same dependency by base-starter automatically * build failed when exclude dependencies not in base * rm all gradle * fix merge * fix ut --------- Co-authored-by: leo james <[email protected]>
1 parent 53fa805 commit a99756a

File tree

4 files changed

+313
-30
lines changed

4 files changed

+313
-30
lines changed

sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/MavenUtils.java

+53
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import com.alipay.sofa.ark.common.util.StringUtils;
2020
import com.alipay.sofa.ark.tools.ArtifactItem;
21+
import org.apache.maven.artifact.Artifact;
22+
import org.apache.maven.model.Dependency;
2123
import org.apache.maven.project.MavenProject;
2224

2325
import java.util.Arrays;
@@ -26,6 +28,7 @@
2628
import java.util.Optional;
2729
import java.util.Set;
2830

31+
import static com.alipay.sofa.ark.spi.constant.Constants.STRING_COLON;
2932
import static java.util.Arrays.asList;
3033

3134
public class MavenUtils {
@@ -113,4 +116,54 @@ private static ArtifactItem getArtifactItem(String lineContent) {
113116
public static boolean inUnLogScopes(String scope) {
114117
return UN_LOG_SCOPES.contains(scope);
115118
}
119+
120+
public static String getGAVIdentity(Artifact artifact) {
121+
return artifact.getGroupId() + STRING_COLON + artifact.getArtifactId() + STRING_COLON
122+
+ artifact.getBaseVersion();
123+
}
124+
125+
public static String getArtifactIdentity(Artifact artifact) {
126+
if (artifact.hasClassifier()) {
127+
return artifact.getGroupId() + STRING_COLON + artifact.getArtifactId() + STRING_COLON
128+
+ artifact.getBaseVersion() + STRING_COLON + artifact.getClassifier()
129+
+ STRING_COLON + artifact.getType();
130+
} else {
131+
return artifact.getGroupId() + STRING_COLON + artifact.getArtifactId() + STRING_COLON
132+
+ artifact.getBaseVersion() + STRING_COLON + artifact.getType();
133+
}
134+
}
135+
136+
public static String getArtifactIdentityWithoutVersion(Artifact artifact) {
137+
if (artifact.hasClassifier()) {
138+
return artifact.getGroupId() + STRING_COLON + artifact.getArtifactId() + STRING_COLON
139+
+ artifact.getClassifier() + STRING_COLON + artifact.getType();
140+
} else {
141+
return artifact.getGroupId() + STRING_COLON + artifact.getArtifactId() + STRING_COLON
142+
+ artifact.getType();
143+
}
144+
145+
}
146+
147+
public static String getDependencyIdentity(Dependency dependency) {
148+
if (org.apache.commons.lang3.StringUtils.isNotEmpty(dependency.getClassifier())) {
149+
return dependency.getGroupId() + STRING_COLON + dependency.getArtifactId()
150+
+ STRING_COLON + dependency.getVersion() + STRING_COLON
151+
+ dependency.getClassifier() + STRING_COLON + dependency.getType();
152+
} else {
153+
return dependency.getGroupId() + STRING_COLON + dependency.getArtifactId()
154+
+ STRING_COLON + dependency.getVersion() + STRING_COLON + dependency.getType();
155+
}
156+
}
157+
158+
public static String getDependencyIdentityWithoutVersion(Dependency dependency) {
159+
if (org.apache.commons.lang3.StringUtils.isNotEmpty(dependency.getClassifier())) {
160+
return dependency.getGroupId() + STRING_COLON + dependency.getArtifactId()
161+
+ STRING_COLON + dependency.getClassifier() + STRING_COLON
162+
+ dependency.getType();
163+
} else {
164+
return dependency.getGroupId() + STRING_COLON + dependency.getArtifactId()
165+
+ STRING_COLON + dependency.getType();
166+
}
167+
}
168+
116169
}

sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimConfig.java

+34-8
Original file line numberDiff line numberDiff line change
@@ -33,44 +33,54 @@ public class ModuleSlimConfig {
3333
* group-a:tracer-core:3.0.10
3434
* group-b:tracer-core:3.0.10:jdk17
3535
*/
36-
private LinkedHashSet<String> excludes = new LinkedHashSet<>();
36+
private LinkedHashSet<String> excludes = new LinkedHashSet<>();
3737

3838
/**
3939
* list of groupId names to exclude (exact match).
4040
*/
41-
private LinkedHashSet<String> excludeGroupIds = new LinkedHashSet<>();
41+
private LinkedHashSet<String> excludeGroupIds = new LinkedHashSet<>();
4242

4343
/**
4444
* list of artifact names to exclude (exact match).
4545
*/
46-
private LinkedHashSet<String> excludeArtifactIds = new LinkedHashSet<>();
46+
private LinkedHashSet<String> excludeArtifactIds = new LinkedHashSet<>();
4747

4848
/**
4949
* Colon separated groupId, artifactId [and classifier] to exclude (exact match). e.g:
5050
* group-a:tracer-core:3.0.10
5151
* group-b:tracer-core:3.0.10:jdk17
5252
*/
53-
private LinkedHashSet<String> includes = new LinkedHashSet<>();
53+
private LinkedHashSet<String> includes = new LinkedHashSet<>();
5454

5555
/**
5656
* list of groupId names to exclude (exact match).
5757
*/
58-
private LinkedHashSet<String> includeGroupIds = new LinkedHashSet<>();
58+
private LinkedHashSet<String> includeGroupIds = new LinkedHashSet<>();
5959

6060
/**
6161
* list of artifact names to exclude (exact match).
6262
*/
63-
private LinkedHashSet<String> includeArtifactIds = new LinkedHashSet<>();
63+
private LinkedHashSet<String> includeArtifactIds = new LinkedHashSet<>();
6464

6565
/**
6666
* 基座依赖标识,以 ${groupId}:${artifactId}:${version} 标识
6767
*/
6868
private String baseDependencyParentIdentity;
6969

7070
/**
71-
* 是否排除依赖时,同时排除依赖及间接依赖。如:A依赖B,B依赖C,当 excludes 只配置了 A 时,B 和 C 都会被排除
71+
* 在排除依赖时,是否同时排除依赖及间接依赖。如:A依赖B,B依赖C,当 excludes 只配置了 A 时,B 和 C 都会被排除
7272
*/
73-
private boolean excludeWithIndirectDependencies = true;
73+
private boolean excludeWithIndirectDependencies = true;
74+
75+
/**
76+
* 在排除依赖时,是否根据基座依赖标识(baseDependencyParentIdentity)排除与基座相同的依赖(GAV 均相同)
77+
*/
78+
private boolean excludeSameBaseDependency = true;
79+
80+
/**
81+
* 在排除依赖时,如果排除的依赖与基座不一致,是否构建失败
82+
*/
83+
private boolean buildFailWhenExcludeBaseDependencyWithDiffVersion = false;
7484

7585
public LinkedHashSet<String> getExcludeArtifactIds() {
7686
return excludeArtifactIds;
@@ -157,4 +167,20 @@ public boolean isExcludeWithIndirectDependencies() {
157167
public void setExcludeWithIndirectDependencies(boolean excludeWithIndirectDependencies) {
158168
this.excludeWithIndirectDependencies = excludeWithIndirectDependencies;
159169
}
170+
171+
public boolean isExcludeSameBaseDependency() {
172+
return excludeSameBaseDependency;
173+
}
174+
175+
public void setExcludeSameBaseDependency(boolean excludeSameBaseDependency) {
176+
this.excludeSameBaseDependency = excludeSameBaseDependency;
177+
}
178+
179+
public boolean isBuildFailWhenExcludeBaseDependencyWithDiffVersion() {
180+
return buildFailWhenExcludeBaseDependencyWithDiffVersion;
181+
}
182+
183+
public void setBuildFailWhenExcludeBaseDependencyWithDiffVersion(boolean buildFailWhenExcludeBaseDependencyWithDiffVersion) {
184+
this.buildFailWhenExcludeBaseDependencyWithDiffVersion = buildFailWhenExcludeBaseDependencyWithDiffVersion;
185+
}
160186
}

sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimStrategy.java

+109-12
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050
import java.util.Set;
5151
import java.util.stream.Collectors;
5252

53+
import static com.alipay.sofa.ark.boot.mojo.MavenUtils.getArtifactIdentity;
54+
import static com.alipay.sofa.ark.boot.mojo.MavenUtils.getArtifactIdentityWithoutVersion;
55+
import static com.alipay.sofa.ark.boot.mojo.MavenUtils.getDependencyIdentity;
56+
import static com.alipay.sofa.ark.boot.mojo.MavenUtils.getGAVIdentity;
5357
import static com.alipay.sofa.ark.boot.mojo.MavenUtils.inUnLogScopes;
5458
import static com.alipay.sofa.ark.boot.mojo.utils.ParseUtils.getBooleanWithDefault;
5559
import static com.alipay.sofa.ark.boot.mojo.utils.ParseUtils.getStringSet;
@@ -77,9 +81,13 @@ public class ModuleSlimStrategy {
7781

7882
private File baseDir;
7983

80-
private static final String EXTENSION_EXCLUDE_WITH_INDIRECT_DEPENDENCIES = "excludeWithIndirectDependencies";
84+
private static final String EXTENSION_EXCLUDE_WITH_INDIRECT_DEPENDENCIES = "excludeWithIndirectDependencies";
8185

82-
private static final String DEFAULT_EXCLUDE_RULES = "rules.txt";
86+
private static final String EXTENSION_EXCLUDE_SAME_BASE_DEPENDENCY = "excludeSameBaseDependency";
87+
88+
private static final String EXTENSION_BUILD_FAIL_WHEN_EXCLUDE_DIFF_BASE_DEPENDENCY = "buildFailWhenExcludeDiffBaseDependency";
89+
90+
private static final String DEFAULT_EXCLUDE_RULES = "rules.txt";
8391

8492
ModuleSlimStrategy(MavenProject project, DependencyNode projDependencyGraph,
8593
ModuleSlimConfig config, File baseDir, Log log) {
@@ -92,43 +100,121 @@ public class ModuleSlimStrategy {
92100

93101
public Set<Artifact> getSlimmedArtifacts() throws MojoExecutionException, IOException {
94102
initSlimStrategyConfig();
95-
Set<Artifact> toFilterByBase = getArtifactsToFilterByParentIdentity(project.getArtifacts());
96103

104+
Set<Artifact> toFilterByBase = getArtifactsToFilterByParentIdentity(project.getArtifacts());
97105
Set<Artifact> toFilterByExclude = getArtifactsToFilterByExcludeConfig(project
98106
.getArtifacts());
99107
Set<Artifact> toAddByInclude = getArtifactsToAddByIncludeConfig(project.getArtifacts());
100108

109+
checkExcludeByParentIdentity(toFilterByExclude, toAddByInclude);
110+
101111
Set<Artifact> filteredArtifacts = new HashSet<>(project.getArtifacts());
102112
filteredArtifacts.removeAll(toFilterByBase);
103113
filteredArtifacts.removeAll(toFilterByExclude);
104114
filteredArtifacts.addAll(toAddByInclude);
105115
return filteredArtifacts;
106116
}
107117

118+
protected void checkExcludeByParentIdentity(Set<Artifact> toFilterByExclude, Set<Artifact> toAddByInclude) throws MojoExecutionException {
119+
if (StringUtils.isEmpty(config.getBaseDependencyParentIdentity())) {
120+
return;
121+
}
122+
123+
Set<Artifact> toFilter = new HashSet<>(toFilterByExclude);
124+
toFilter.removeAll(toAddByInclude);
125+
126+
Set<Artifact> excludedButNoDependencyInBase = getExcludedButNoDependencyInBase(toFilter);
127+
Set<Artifact> excludedButDifferentVersionDependencyInBase = getExcludedButDifferentVersionDependencyInBase(toFilter);
128+
129+
if(excludedButNoDependencyInBase.isEmpty() && excludedButDifferentVersionDependencyInBase.isEmpty()){
130+
getLog().info(String.format("check excludeWithBaseDependencyParentIdentity success with base: %s",config.getBaseDependencyParentIdentity()));
131+
return;
132+
}
133+
134+
// Dependency not found in base; please add it to the base or do not exclude it in the module
135+
excludedButNoDependencyInBase.forEach(artifact -> {
136+
getLog().error(
137+
String.format(
138+
"error to exclude package jar: %s because no such jar in base, please keep the jar or add it to base",
139+
getArtifactIdentity(artifact)));
140+
});
141+
142+
if(!excludedButNoDependencyInBase.isEmpty()){
143+
throw new MojoExecutionException(String.format("check excludeWithBaseDependencyParentIdentity failed with base: %s",config.getBaseDependencyParentIdentity()));
144+
}
145+
146+
// The base contains this dependency, but the version and module are inconsistent; Please use the same dependency version as the base in the module.
147+
List<Dependency> baseDependencies = getAllBaseDependencies();
148+
Map<String,Dependency> baseDependencyIdentityWithoutVersion = baseDependencies.stream().collect(Collectors.toMap(MavenUtils::getDependencyIdentityWithoutVersion, it -> it));
149+
excludedButDifferentVersionDependencyInBase.forEach(artifact -> {
150+
Dependency baseDependency = baseDependencyIdentityWithoutVersion.get(getArtifactIdentityWithoutVersion(artifact));
151+
getLog().error(
152+
String.format(
153+
"error to exclude package jar: %s because it has different version with: %s in base, please keep the jar or set same version with base",
154+
getArtifactIdentity(artifact), getDependencyIdentity(baseDependency)));
155+
});
156+
157+
if(config.isBuildFailWhenExcludeBaseDependencyWithDiffVersion()){
158+
throw new MojoExecutionException(String.format("check excludeWithBaseDependencyParentIdentity failed with base: %s",config.getBaseDependencyParentIdentity()));
159+
}
160+
}
161+
108162
protected Set<Artifact> getArtifactsToFilterByParentIdentity(Set<Artifact> artifacts)
109163
throws MojoExecutionException {
110164
if (StringUtils.isEmpty(config.getBaseDependencyParentIdentity())) {
111165
return Collections.emptySet();
112166
}
113167

168+
if (!config.isExcludeSameBaseDependency()) {
169+
return Collections.emptySet();
170+
}
171+
114172
// 过滤出模块和基座版本一致的依赖,即需要瘦身的依赖
115173
return getSameVersionArtifactsWithBase(artifacts);
116174
}
117175

118176
private Set<Artifact> getSameVersionArtifactsWithBase(Set<Artifact> artifacts) throws MojoExecutionException {
177+
List<Dependency> baseDependencies = getAllBaseDependencies();
178+
179+
Set<String> dependencyIdentities = baseDependencies.stream().map(MavenUtils::getDependencyIdentity).collect(Collectors.toSet());
180+
181+
return artifacts.stream().filter(it -> dependencyIdentities.contains(getArtifactIdentity(it))).collect(Collectors.toSet());
182+
}
183+
184+
private Set<Artifact> getExcludedButNoDependencyInBase(Set<Artifact> toFilter) throws MojoExecutionException {
185+
List<Dependency> baseDependencies = getAllBaseDependencies();
186+
187+
Map<String,Dependency> baseDependencyIdentityWithoutVersion = baseDependencies.stream().collect(Collectors.toMap(MavenUtils::getDependencyIdentityWithoutVersion, it -> it));
188+
189+
return toFilter.stream().filter(it -> !baseDependencyIdentityWithoutVersion.containsKey(getArtifactIdentityWithoutVersion(it))).collect(Collectors.toSet());
190+
}
191+
192+
private Set<Artifact> getExcludedButDifferentVersionDependencyInBase(Set<Artifact> toFilter) throws MojoExecutionException {
193+
List<Dependency> baseDependencies = getAllBaseDependencies();
194+
Map<String,Dependency> baseDependencyIdentityWithoutVersion = baseDependencies.stream().collect(Collectors.toMap(MavenUtils::getDependencyIdentityWithoutVersion, it -> it));
195+
return toFilter.stream().filter(artifact ->
196+
{
197+
String identityWithoutVersion = getArtifactIdentityWithoutVersion(artifact);
198+
return baseDependencyIdentityWithoutVersion.containsKey(identityWithoutVersion)
199+
&& (!artifact.getBaseVersion().equals(baseDependencyIdentityWithoutVersion.get(identityWithoutVersion).getVersion()));
200+
}
201+
).collect(Collectors.toSet());
202+
}
203+
204+
private List<Dependency> getAllBaseDependencies() throws MojoExecutionException {
119205
// 获取基座DependencyParent的原始Model
120206
Model baseDependencyPom = getBaseDependencyParentOriginalModel();
121-
if(null == baseDependencyPom){
122-
throw new MojoExecutionException(String.format("can not find base dependency parent: %s",config.getBaseDependencyParentIdentity()));
207+
if (null == baseDependencyPom) {
208+
throw new MojoExecutionException(
209+
String.format("can not find base dependency parent: %s",
210+
config.getBaseDependencyParentIdentity()));
123211
}
124212

125-
if(null == baseDependencyPom.getDependencyManagement()){
126-
return Collections.emptySet();
213+
if (null == baseDependencyPom.getDependencyManagement()) {
214+
return Collections.emptyList();
127215
}
128216

129-
List<Dependency> baseDependencies = baseDependencyPom.getDependencyManagement().getDependencies();
130-
Set<String> dependencyIdentities = baseDependencies.stream().map(this::getDependencyIdentity).collect(Collectors.toSet());
131-
return artifacts.stream().filter(it -> dependencyIdentities.contains(getArtifactIdentity(it))).collect(Collectors.toSet());
217+
return baseDependencyPom.getDependencyManagement().getDependencies();
132218
}
133219

134220
protected Model getBaseDependencyParentOriginalModel() {
@@ -179,11 +265,22 @@ private String getDependencyIdentity(Dependency dependency) {
179265
protected void initSlimStrategyConfig() throws IOException {
180266
Map<String, Object> arkYaml = ArkConfigHolder.getArkYaml(baseDir.getAbsolutePath());
181267
Properties prop = ArkConfigHolder.getArkProperties(baseDir.getAbsolutePath());
268+
182269
config.setExcludeWithIndirectDependencies(getBooleanWithDefault(prop,
183270
EXTENSION_EXCLUDE_WITH_INDIRECT_DEPENDENCIES, true));
184271
config.setExcludeWithIndirectDependencies(getBooleanWithDefault(arkYaml,
185272
EXTENSION_EXCLUDE_WITH_INDIRECT_DEPENDENCIES, true));
186273

274+
config.setExcludeSameBaseDependency(getBooleanWithDefault(prop,
275+
EXTENSION_EXCLUDE_SAME_BASE_DEPENDENCY, true));
276+
config.setExcludeSameBaseDependency(getBooleanWithDefault(arkYaml,
277+
EXTENSION_EXCLUDE_SAME_BASE_DEPENDENCY, true));
278+
279+
config.setBuildFailWhenExcludeBaseDependencyWithDiffVersion(getBooleanWithDefault(prop,
280+
EXTENSION_BUILD_FAIL_WHEN_EXCLUDE_DIFF_BASE_DEPENDENCY, false));
281+
config.setBuildFailWhenExcludeBaseDependencyWithDiffVersion(getBooleanWithDefault(arkYaml,
282+
EXTENSION_BUILD_FAIL_WHEN_EXCLUDE_DIFF_BASE_DEPENDENCY, false));
283+
187284
initExcludeAndIncludeConfig();
188285
}
189286

@@ -222,8 +319,8 @@ protected Set<Artifact> getArtifactsToFilterByExcludeConfig(Set<Artifact> artifa
222319
}
223320

224321
private Set<Artifact> excludeWithIndirectDependencies(Set<Artifact> literalArtifactsToExclude, Set<Artifact> artifacts) {
225-
Set<String> excludeArtifactIdentities = literalArtifactsToExclude.stream().map(this::getArtifactIdentity).collect(Collectors.toSet());
226-
Map<String,Artifact> artifactMap = artifacts.stream().collect(Collectors.toMap(this::getArtifactIdentity,it->it));
322+
Set<String> excludeArtifactIdentities = literalArtifactsToExclude.stream().map(MavenUtils::getArtifactIdentity).collect(Collectors.toSet());
323+
Map<String,Artifact> artifactMap = artifacts.stream().collect(Collectors.toMap(MavenUtils::getArtifactIdentity,it->it));
227324
return getExcludeWithIndirectDependencies(projDependencyGraph,excludeArtifactIdentities,artifactMap);
228325
}
229326

0 commit comments

Comments
 (0)