diff --git a/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/MavenUtils.java b/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/MavenUtils.java index a540e850a..1b4ed6463 100644 --- a/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/MavenUtils.java +++ b/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/MavenUtils.java @@ -18,6 +18,8 @@ import com.alipay.sofa.ark.common.util.StringUtils; import com.alipay.sofa.ark.tools.ArtifactItem; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.model.Dependency; import org.apache.maven.project.MavenProject; import java.util.Arrays; @@ -26,6 +28,7 @@ import java.util.Optional; import java.util.Set; +import static com.alipay.sofa.ark.spi.constant.Constants.STRING_COLON; import static java.util.Arrays.asList; public class MavenUtils { @@ -113,4 +116,54 @@ private static ArtifactItem getArtifactItem(String lineContent) { public static boolean inUnLogScopes(String scope) { return UN_LOG_SCOPES.contains(scope); } + + public static String getGAVIdentity(Artifact artifact) { + return artifact.getGroupId() + STRING_COLON + artifact.getArtifactId() + STRING_COLON + + artifact.getBaseVersion(); + } + + public static String getArtifactIdentity(Artifact artifact) { + if (artifact.hasClassifier()) { + return artifact.getGroupId() + STRING_COLON + artifact.getArtifactId() + STRING_COLON + + artifact.getBaseVersion() + STRING_COLON + artifact.getClassifier() + + STRING_COLON + artifact.getType(); + } else { + return artifact.getGroupId() + STRING_COLON + artifact.getArtifactId() + STRING_COLON + + artifact.getBaseVersion() + STRING_COLON + artifact.getType(); + } + } + + public static String getArtifactIdentityWithoutVersion(Artifact artifact) { + if (artifact.hasClassifier()) { + return artifact.getGroupId() + STRING_COLON + artifact.getArtifactId() + STRING_COLON + + artifact.getClassifier() + STRING_COLON + artifact.getType(); + } else { + return artifact.getGroupId() + STRING_COLON + artifact.getArtifactId() + STRING_COLON + + artifact.getType(); + } + + } + + public static String getDependencyIdentity(Dependency dependency) { + if (org.apache.commons.lang3.StringUtils.isNotEmpty(dependency.getClassifier())) { + return dependency.getGroupId() + STRING_COLON + dependency.getArtifactId() + + STRING_COLON + dependency.getVersion() + STRING_COLON + + dependency.getClassifier() + STRING_COLON + dependency.getType(); + } else { + return dependency.getGroupId() + STRING_COLON + dependency.getArtifactId() + + STRING_COLON + dependency.getVersion() + STRING_COLON + dependency.getType(); + } + } + + public static String getDependencyIdentityWithoutVersion(Dependency dependency) { + if (org.apache.commons.lang3.StringUtils.isNotEmpty(dependency.getClassifier())) { + return dependency.getGroupId() + STRING_COLON + dependency.getArtifactId() + + STRING_COLON + dependency.getClassifier() + STRING_COLON + + dependency.getType(); + } else { + return dependency.getGroupId() + STRING_COLON + dependency.getArtifactId() + + STRING_COLON + dependency.getType(); + } + } + } diff --git a/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimConfig.java b/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimConfig.java index a8ad89990..ee5576bf8 100644 --- a/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimConfig.java +++ b/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimConfig.java @@ -33,34 +33,34 @@ public class ModuleSlimConfig { * group-a:tracer-core:3.0.10 * group-b:tracer-core:3.0.10:jdk17 */ - private LinkedHashSet excludes = new LinkedHashSet<>(); + private LinkedHashSet excludes = new LinkedHashSet<>(); /** * list of groupId names to exclude (exact match). */ - private LinkedHashSet excludeGroupIds = new LinkedHashSet<>(); + private LinkedHashSet excludeGroupIds = new LinkedHashSet<>(); /** * list of artifact names to exclude (exact match). */ - private LinkedHashSet excludeArtifactIds = new LinkedHashSet<>(); + private LinkedHashSet excludeArtifactIds = new LinkedHashSet<>(); /** * Colon separated groupId, artifactId [and classifier] to exclude (exact match). e.g: * group-a:tracer-core:3.0.10 * group-b:tracer-core:3.0.10:jdk17 */ - private LinkedHashSet includes = new LinkedHashSet<>(); + private LinkedHashSet includes = new LinkedHashSet<>(); /** * list of groupId names to exclude (exact match). */ - private LinkedHashSet includeGroupIds = new LinkedHashSet<>(); + private LinkedHashSet includeGroupIds = new LinkedHashSet<>(); /** * list of artifact names to exclude (exact match). */ - private LinkedHashSet includeArtifactIds = new LinkedHashSet<>(); + private LinkedHashSet includeArtifactIds = new LinkedHashSet<>(); /** * 基座依赖标识,以 ${groupId}:${artifactId}:${version} 标识 @@ -68,9 +68,19 @@ public class ModuleSlimConfig { private String baseDependencyParentIdentity; /** - * 是否排除依赖时,同时排除依赖及间接依赖。如:A依赖B,B依赖C,当 excludes 只配置了 A 时,B 和 C 都会被排除 + * 在排除依赖时,是否同时排除依赖及间接依赖。如:A依赖B,B依赖C,当 excludes 只配置了 A 时,B 和 C 都会被排除 */ - private boolean excludeWithIndirectDependencies = true; + private boolean excludeWithIndirectDependencies = true; + + /** + * 在排除依赖时,是否根据基座依赖标识(baseDependencyParentIdentity)排除与基座相同的依赖(GAV 均相同) + */ + private boolean excludeSameBaseDependency = true; + + /** + * 在排除依赖时,如果排除的依赖与基座不一致,是否构建失败 + */ + private boolean buildFailWhenExcludeBaseDependencyWithDiffVersion = false; public LinkedHashSet getExcludeArtifactIds() { return excludeArtifactIds; @@ -157,4 +167,20 @@ public boolean isExcludeWithIndirectDependencies() { public void setExcludeWithIndirectDependencies(boolean excludeWithIndirectDependencies) { this.excludeWithIndirectDependencies = excludeWithIndirectDependencies; } + + public boolean isExcludeSameBaseDependency() { + return excludeSameBaseDependency; + } + + public void setExcludeSameBaseDependency(boolean excludeSameBaseDependency) { + this.excludeSameBaseDependency = excludeSameBaseDependency; + } + + public boolean isBuildFailWhenExcludeBaseDependencyWithDiffVersion() { + return buildFailWhenExcludeBaseDependencyWithDiffVersion; + } + + public void setBuildFailWhenExcludeBaseDependencyWithDiffVersion(boolean buildFailWhenExcludeBaseDependencyWithDiffVersion) { + this.buildFailWhenExcludeBaseDependencyWithDiffVersion = buildFailWhenExcludeBaseDependencyWithDiffVersion; + } } \ No newline at end of file diff --git a/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimStrategy.java b/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimStrategy.java index e73391201..b2ef88edd 100644 --- a/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimStrategy.java +++ b/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimStrategy.java @@ -50,6 +50,10 @@ import java.util.Set; import java.util.stream.Collectors; +import static com.alipay.sofa.ark.boot.mojo.MavenUtils.getArtifactIdentity; +import static com.alipay.sofa.ark.boot.mojo.MavenUtils.getArtifactIdentityWithoutVersion; +import static com.alipay.sofa.ark.boot.mojo.MavenUtils.getDependencyIdentity; +import static com.alipay.sofa.ark.boot.mojo.MavenUtils.getGAVIdentity; import static com.alipay.sofa.ark.boot.mojo.MavenUtils.inUnLogScopes; import static com.alipay.sofa.ark.boot.mojo.utils.ParseUtils.getBooleanWithDefault; import static com.alipay.sofa.ark.boot.mojo.utils.ParseUtils.getStringSet; @@ -77,9 +81,13 @@ public class ModuleSlimStrategy { private File baseDir; - private static final String EXTENSION_EXCLUDE_WITH_INDIRECT_DEPENDENCIES = "excludeWithIndirectDependencies"; + private static final String EXTENSION_EXCLUDE_WITH_INDIRECT_DEPENDENCIES = "excludeWithIndirectDependencies"; - private static final String DEFAULT_EXCLUDE_RULES = "rules.txt"; + private static final String EXTENSION_EXCLUDE_SAME_BASE_DEPENDENCY = "excludeSameBaseDependency"; + + private static final String EXTENSION_BUILD_FAIL_WHEN_EXCLUDE_DIFF_BASE_DEPENDENCY = "buildFailWhenExcludeDiffBaseDependency"; + + private static final String DEFAULT_EXCLUDE_RULES = "rules.txt"; ModuleSlimStrategy(MavenProject project, DependencyNode projDependencyGraph, ModuleSlimConfig config, File baseDir, Log log) { @@ -92,12 +100,14 @@ public class ModuleSlimStrategy { public Set getSlimmedArtifacts() throws MojoExecutionException, IOException { initSlimStrategyConfig(); - Set toFilterByBase = getArtifactsToFilterByParentIdentity(project.getArtifacts()); + Set toFilterByBase = getArtifactsToFilterByParentIdentity(project.getArtifacts()); Set toFilterByExclude = getArtifactsToFilterByExcludeConfig(project .getArtifacts()); Set toAddByInclude = getArtifactsToAddByIncludeConfig(project.getArtifacts()); + checkExcludeByParentIdentity(toFilterByExclude, toAddByInclude); + Set filteredArtifacts = new HashSet<>(project.getArtifacts()); filteredArtifacts.removeAll(toFilterByBase); filteredArtifacts.removeAll(toFilterByExclude); @@ -105,30 +115,106 @@ public Set getSlimmedArtifacts() throws MojoExecutionException, IOExce return filteredArtifacts; } + protected void checkExcludeByParentIdentity(Set toFilterByExclude, Set toAddByInclude) throws MojoExecutionException { + if (StringUtils.isEmpty(config.getBaseDependencyParentIdentity())) { + return; + } + + Set toFilter = new HashSet<>(toFilterByExclude); + toFilter.removeAll(toAddByInclude); + + Set excludedButNoDependencyInBase = getExcludedButNoDependencyInBase(toFilter); + Set excludedButDifferentVersionDependencyInBase = getExcludedButDifferentVersionDependencyInBase(toFilter); + + if(excludedButNoDependencyInBase.isEmpty() && excludedButDifferentVersionDependencyInBase.isEmpty()){ + getLog().info(String.format("check excludeWithBaseDependencyParentIdentity success with base: %s",config.getBaseDependencyParentIdentity())); + return; + } + + // Dependency not found in base; please add it to the base or do not exclude it in the module + excludedButNoDependencyInBase.forEach(artifact -> { + getLog().error( + String.format( + "error to exclude package jar: %s because no such jar in base, please keep the jar or add it to base", + getArtifactIdentity(artifact))); + }); + + if(!excludedButNoDependencyInBase.isEmpty()){ + throw new MojoExecutionException(String.format("check excludeWithBaseDependencyParentIdentity failed with base: %s",config.getBaseDependencyParentIdentity())); + } + + // The base contains this dependency, but the version and module are inconsistent; Please use the same dependency version as the base in the module. + List baseDependencies = getAllBaseDependencies(); + Map baseDependencyIdentityWithoutVersion = baseDependencies.stream().collect(Collectors.toMap(MavenUtils::getDependencyIdentityWithoutVersion, it -> it)); + excludedButDifferentVersionDependencyInBase.forEach(artifact -> { + Dependency baseDependency = baseDependencyIdentityWithoutVersion.get(getArtifactIdentityWithoutVersion(artifact)); + getLog().error( + String.format( + "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", + getArtifactIdentity(artifact), getDependencyIdentity(baseDependency))); + }); + + if(config.isBuildFailWhenExcludeBaseDependencyWithDiffVersion()){ + throw new MojoExecutionException(String.format("check excludeWithBaseDependencyParentIdentity failed with base: %s",config.getBaseDependencyParentIdentity())); + } + } + protected Set getArtifactsToFilterByParentIdentity(Set artifacts) throws MojoExecutionException { if (StringUtils.isEmpty(config.getBaseDependencyParentIdentity())) { return Collections.emptySet(); } + if (!config.isExcludeSameBaseDependency()) { + return Collections.emptySet(); + } + // 过滤出模块和基座版本一致的依赖,即需要瘦身的依赖 return getSameVersionArtifactsWithBase(artifacts); } private Set getSameVersionArtifactsWithBase(Set artifacts) throws MojoExecutionException { + List baseDependencies = getAllBaseDependencies(); + + Set dependencyIdentities = baseDependencies.stream().map(MavenUtils::getDependencyIdentity).collect(Collectors.toSet()); + + return artifacts.stream().filter(it -> dependencyIdentities.contains(getArtifactIdentity(it))).collect(Collectors.toSet()); + } + + private Set getExcludedButNoDependencyInBase(Set toFilter) throws MojoExecutionException { + List baseDependencies = getAllBaseDependencies(); + + Map baseDependencyIdentityWithoutVersion = baseDependencies.stream().collect(Collectors.toMap(MavenUtils::getDependencyIdentityWithoutVersion, it -> it)); + + return toFilter.stream().filter(it -> !baseDependencyIdentityWithoutVersion.containsKey(getArtifactIdentityWithoutVersion(it))).collect(Collectors.toSet()); + } + + private Set getExcludedButDifferentVersionDependencyInBase(Set toFilter) throws MojoExecutionException { + List baseDependencies = getAllBaseDependencies(); + Map baseDependencyIdentityWithoutVersion = baseDependencies.stream().collect(Collectors.toMap(MavenUtils::getDependencyIdentityWithoutVersion, it -> it)); + return toFilter.stream().filter(artifact -> + { + String identityWithoutVersion = getArtifactIdentityWithoutVersion(artifact); + return baseDependencyIdentityWithoutVersion.containsKey(identityWithoutVersion) + && (!artifact.getBaseVersion().equals(baseDependencyIdentityWithoutVersion.get(identityWithoutVersion).getVersion())); + } + ).collect(Collectors.toSet()); + } + + private List getAllBaseDependencies() throws MojoExecutionException { // 获取基座DependencyParent的原始Model Model baseDependencyPom = getBaseDependencyParentOriginalModel(); - if(null == baseDependencyPom){ - throw new MojoExecutionException(String.format("can not find base dependency parent: %s",config.getBaseDependencyParentIdentity())); + if (null == baseDependencyPom) { + throw new MojoExecutionException( + String.format("can not find base dependency parent: %s", + config.getBaseDependencyParentIdentity())); } - if(null == baseDependencyPom.getDependencyManagement()){ - return Collections.emptySet(); + if (null == baseDependencyPom.getDependencyManagement()) { + return Collections.emptyList(); } - List baseDependencies = baseDependencyPom.getDependencyManagement().getDependencies(); - Set dependencyIdentities = baseDependencies.stream().map(this::getDependencyIdentity).collect(Collectors.toSet()); - return artifacts.stream().filter(it -> dependencyIdentities.contains(getArtifactIdentity(it))).collect(Collectors.toSet()); + return baseDependencyPom.getDependencyManagement().getDependencies(); } protected Model getBaseDependencyParentOriginalModel() { @@ -179,11 +265,22 @@ private String getDependencyIdentity(Dependency dependency) { protected void initSlimStrategyConfig() throws IOException { Map arkYaml = ArkConfigHolder.getArkYaml(baseDir.getAbsolutePath()); Properties prop = ArkConfigHolder.getArkProperties(baseDir.getAbsolutePath()); + config.setExcludeWithIndirectDependencies(getBooleanWithDefault(prop, EXTENSION_EXCLUDE_WITH_INDIRECT_DEPENDENCIES, true)); config.setExcludeWithIndirectDependencies(getBooleanWithDefault(arkYaml, EXTENSION_EXCLUDE_WITH_INDIRECT_DEPENDENCIES, true)); + config.setExcludeSameBaseDependency(getBooleanWithDefault(prop, + EXTENSION_EXCLUDE_SAME_BASE_DEPENDENCY, true)); + config.setExcludeSameBaseDependency(getBooleanWithDefault(arkYaml, + EXTENSION_EXCLUDE_SAME_BASE_DEPENDENCY, true)); + + config.setBuildFailWhenExcludeBaseDependencyWithDiffVersion(getBooleanWithDefault(prop, + EXTENSION_BUILD_FAIL_WHEN_EXCLUDE_DIFF_BASE_DEPENDENCY, false)); + config.setBuildFailWhenExcludeBaseDependencyWithDiffVersion(getBooleanWithDefault(arkYaml, + EXTENSION_BUILD_FAIL_WHEN_EXCLUDE_DIFF_BASE_DEPENDENCY, false)); + initExcludeAndIncludeConfig(); } @@ -222,8 +319,8 @@ protected Set getArtifactsToFilterByExcludeConfig(Set artifa } private Set excludeWithIndirectDependencies(Set literalArtifactsToExclude, Set artifacts) { - Set excludeArtifactIdentities = literalArtifactsToExclude.stream().map(this::getArtifactIdentity).collect(Collectors.toSet()); - Map artifactMap = artifacts.stream().collect(Collectors.toMap(this::getArtifactIdentity,it->it)); + Set excludeArtifactIdentities = literalArtifactsToExclude.stream().map(MavenUtils::getArtifactIdentity).collect(Collectors.toSet()); + Map artifactMap = artifacts.stream().collect(Collectors.toMap(MavenUtils::getArtifactIdentity,it->it)); return getExcludeWithIndirectDependencies(projDependencyGraph,excludeArtifactIdentities,artifactMap); } diff --git a/sofa-ark-parent/support/ark-maven-plugin/src/test/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimStrategyTest.java b/sofa-ark-parent/support/ark-maven-plugin/src/test/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimStrategyTest.java index 09195d54a..12041145b 100644 --- a/sofa-ark-parent/support/ark-maven-plugin/src/test/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimStrategyTest.java +++ b/sofa-ark-parent/support/ark-maven-plugin/src/test/java/com/alipay/sofa/ark/boot/mojo/ModuleSlimStrategyTest.java @@ -29,6 +29,8 @@ import org.apache.maven.project.MavenProject; import org.apache.maven.shared.dependency.graph.DependencyNode; import org.junit.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; import java.io.File; import java.io.IOException; @@ -50,10 +52,12 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anySet; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** @@ -75,6 +79,8 @@ public void testGetSlimmedArtifacts() throws MojoExecutionException, IOException ModuleSlimStrategy strategy = spy(new ModuleSlimStrategy(proj, null, new ModuleSlimConfig(), mockBaseDir(), null)); + + doNothing().when(strategy).checkExcludeByParentIdentity(anySet(), anySet()); doReturn(Sets.newHashSet(a1)).when(strategy).getArtifactsToFilterByParentIdentity(anySet()); doReturn(Sets.newHashSet(a2)).when(strategy).getArtifactsToFilterByExcludeConfig(anySet()); @@ -99,14 +105,17 @@ public void testSlimmedAllArtifacts() throws MojoExecutionException, IOException ModuleSlimStrategy strategy = spy(new ModuleSlimStrategy(proj, null, moduleSlimConfig, mockBaseDir(), null)); - doReturn("a1").when(strategy).getArtifactIdentity(a1); - doReturn("a2").when(strategy).getArtifactIdentity(a2); - doReturn("a3").when(strategy).getArtifactIdentity(a3); - doReturn("a4").when(strategy).getArtifactIdentity(a4); - doReturn("a5").when(strategy).getArtifactIdentity(a5); - doReturn("a6").when(strategy).getArtifactIdentity(a6); - - assertEquals(6, strategy.getSlimmedArtifacts().size()); + doNothing().when(strategy).checkExcludeByParentIdentity(anySet(), anySet()); + try (MockedStatic mockedStatic = Mockito.mockStatic(MavenUtils.class)) { + mockedStatic.when(()->MavenUtils.getArtifactIdentity(a1)).thenReturn("a1"); + mockedStatic.when(()->MavenUtils.getArtifactIdentity(a2)).thenReturn("a2"); + mockedStatic.when(()->MavenUtils.getArtifactIdentity(a3)).thenReturn("a3"); + mockedStatic.when(()->MavenUtils.getArtifactIdentity(a4)).thenReturn("a4"); + mockedStatic.when(()->MavenUtils.getArtifactIdentity(a5)).thenReturn("a5"); + mockedStatic.when(()->MavenUtils.getArtifactIdentity(a6)).thenReturn("a6"); + + assertEquals(6, strategy.getSlimmedArtifacts().size()); + } } @Test @@ -131,10 +140,108 @@ public void testGetArtifactsToFilterByParentIdentity() throws URISyntaxException when(differenceArtifact.getBaseVersion()).thenReturn("2.0-SNAPSHOT"); when(sameArtifact.getType()).thenReturn("jar"); + // case1: excludeSameBaseDependency=false + config.setExcludeSameBaseDependency(false); Set res = strategy.getArtifactsToFilterByParentIdentity(Sets.newHashSet( sameArtifact, differenceArtifact)); - assertTrue(res.contains(sameArtifact)); - assertFalse(res.contains(differenceArtifact)); + assertTrue(res.isEmpty()); + + // case2: excludeSameBaseDependency=true + config.setExcludeSameBaseDependency(true); + Set res1 = strategy.getArtifactsToFilterByParentIdentity(Sets.newHashSet( + sameArtifact, differenceArtifact)); + assertTrue(res1.contains(sameArtifact)); + assertFalse(res1.contains(differenceArtifact)); + } + + @Test + public void testCheckExcludeByParentIdentity() throws URISyntaxException, + MojoExecutionException { + ModuleSlimConfig config = (new ModuleSlimConfig()) + .setBaseDependencyParentIdentity("com.mock:base-dependencies-starter:1.0"); + + Log log = Mockito.mock(Log.class); + doNothing().when(log).info(anyString()); + doNothing().when(log).error(anyString()); + + ModuleSlimStrategy strategy = new ModuleSlimStrategy(getMockBootstrapProject(), null, + config, mockBaseDir(), log); + + // 基座和模块都有该依赖,且版本一致 + Artifact sameArtifact = mock(Artifact.class); + when(sameArtifact.getGroupId()).thenReturn("com.mock"); + when(sameArtifact.getArtifactId()).thenReturn("same-dependency-artifact"); + when(sameArtifact.getVersion()).thenReturn("1.0"); + when(sameArtifact.getBaseVersion()).thenReturn("1.0-SNAPSHOT"); + when(sameArtifact.getType()).thenReturn("jar"); + + // 模块有,但基座没有的依赖 + Artifact differentArtifact = mock(Artifact.class); + when(differentArtifact.getGroupId()).thenReturn("com.mock"); + when(differentArtifact.getArtifactId()).thenReturn("different-artifact"); + when(differentArtifact.getVersion()).thenReturn("1.0"); + when(differentArtifact.getBaseVersion()).thenReturn("1.0-SNAPSHOT"); + when(differentArtifact.getType()).thenReturn("jar"); + + // 模块和基座都有该依赖,但版本不一致 + Artifact differentVersionArtifact = mock(Artifact.class); + when(differentVersionArtifact.getGroupId()).thenReturn("com.mock"); + when(differentVersionArtifact.getArtifactId()).thenReturn("difference-dependency-artifact"); + when(differentVersionArtifact.getVersion()).thenReturn("2.0"); + when(differentVersionArtifact.getBaseVersion()).thenReturn("2.0-SNAPSHOT"); + when(differentVersionArtifact.getType()).thenReturn("jar"); + + Dependency differenceVersionDependency = new Dependency(); + differenceVersionDependency.setArtifactId("difference-dependency-artifact"); + differenceVersionDependency.setGroupId("com.mock"); + differenceVersionDependency.setVersion("1.0-SNAPSHOT"); + + // case1: 排除相同的依赖 + Set toFilterByExclude = Sets.newHashSet(sameArtifact); + strategy.checkExcludeByParentIdentity(toFilterByExclude, Collections.emptySet()); + verify(log) + .info( + eq("check excludeWithBaseDependencyParentIdentity success with base: com.mock:base-dependencies-starter:1.0")); + + // case2: 排除了基座没有的依赖 + toFilterByExclude = Sets.newHashSet(differentArtifact); + try { + strategy.checkExcludeByParentIdentity(toFilterByExclude, Collections.emptySet()); + } catch (MojoExecutionException e) { + // 验证构建失败 + verify(log) + .error( + eq(String + .format( + "error to exclude package jar: %s because no such jar in base, please keep the jar or add it to base", + MavenUtils.getArtifactIdentity(differentArtifact)))); + + assertEquals(String.format( + "check excludeWithBaseDependencyParentIdentity failed with base: %s", + config.getBaseDependencyParentIdentity()), e.getMessage()); + } + + // case3: 排除了不同版本的依赖 + toFilterByExclude = Sets.newHashSet(differentVersionArtifact); + strategy.checkExcludeByParentIdentity(toFilterByExclude, Collections.emptySet()); + verify(log) + .error( + eq(String + .format( + "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", + MavenUtils.getArtifactIdentity(differentVersionArtifact), + MavenUtils.getDependencyIdentity(differenceVersionDependency)))); + + // case4: 配置开关:如果排除的依赖有问题,那么构建报错 + config.setBuildFailWhenExcludeBaseDependencyWithDiffVersion(true); + try { + strategy.checkExcludeByParentIdentity(toFilterByExclude, Collections.emptySet()); + } catch (MojoExecutionException e) { + // 验证构建失败 + assertEquals(String.format( + "check excludeWithBaseDependencyParentIdentity failed with base: %s", + config.getBaseDependencyParentIdentity()), e.getMessage()); + } } @Test